Update to OMT 3.14 (#50)

* initial update step: 3.13.1 bumped to 3.14

* automated update steps: regenerate-openmaptiles.sh v3.14 + mvn spotless:apply

* riverbank was removed from waterway -> replaced with dock un the unit test

* riverbank was removed from waterway -> testRiverbank() changed into testDock()

* riverbank was removed in OpenMapTiles v3.14

* parcel_locker (with brand, operator and/or ref) was added in OpenMapTiles v3.14

* bus_guideway was added in OpenMapTiles v3.14

* support for county seats (capital=6) was added in OpenMapTiles v3.14

* spotless:apply

* gn_ascii replaced with name_en

gn_ascii was removed from NE5 - see commit b14da2ea in OMT for more
details

* merging of buildings at Z13 replicated also for landuse from Z9 (or for some from Z6) to Z13 to match updates in OpenMapTiles v3.14

* landuse_merge_z9_to_z13 argument removed since it has negligible perf. overhead hence no need to have it

* cover a corner case for parcel_locker: no brand, no operator, just ref

* corrected landuse polygon merging to better match OpenMapTiles 3.14 (1)

* corrected landuse polygon merging to better match OpenMapTiles 3.14 (1): merge only landuse=residential

* clean-up: since evaluation in Landuse is simpler than in Landcover, streaming and Collectors.partitioningBy() used

* clean-up of naming: splitList -> splitLists

* land-use merging unit test adjusted and extended to match recent changes

* other unit tests adjusted to match recent changes

* spotless:apply

* clean-up: added comment, to match Landover

* 3.13.1 bumped to 3.14 (follow-up/fix for e26e13a6f)

* adjusted WOOD_OR_FOREST handling for Z8 to match change in OMT (osm_landcover_gen_z8)

* updated unit test to match adjusted WOOD_OR_FOREST handling for Z8

* clean-up: if-else replaced with switch

* clean-up: conditional grouped to make it more readable
This commit is contained in:
Peter Hanecak
2022-12-28 13:36:12 +01:00
committed by GitHub
parent d378521372
commit c662ef2d30
18 changed files with 400 additions and 146 deletions

View File

@@ -149,7 +149,7 @@ script with the
OpenMapTiles release tag: OpenMapTiles release tag:
```bash ```bash
./scripts/regenerate-openmaptiles.sh v3.13.1 ./scripts/regenerate-openmaptiles.sh v3.14
``` ```
Then follow the instructions it prints for reformatting generated code. Then follow the instructions it prints for reformatting generated code.
@@ -157,7 +157,7 @@ Then follow the instructions it prints for reformatting generated code.
If you want to regenerate from a different repository than the default openmaptiles, you can specify the url like this: If you want to regenerate from a different repository than the default openmaptiles, you can specify the url like this:
```bash ```bash
./scripts/regenerate-openmaptiles.sh v3.13.1 https://raw.githubusercontent.com/openmaptiles/openmaptiles/ ./scripts/regenerate-openmaptiles.sh v3.14 https://raw.githubusercontent.com/openmaptiles/openmaptiles/
``` ```
## License ## License

View File

@@ -22,7 +22,7 @@
<groupId>org.openmaptiles</groupId> <groupId>org.openmaptiles</groupId>
<artifactId>planetiler-openmaptiles</artifactId> <artifactId>planetiler-openmaptiles</artifactId>
<version>3.13.1</version> <version>3.14.0</version>
<name>OpenMapTiles Vector Tile Schema implementation for Planetiler tool</name> <name>OpenMapTiles Vector Tile Schema implementation for Planetiler tool</name>

View File

@@ -4,7 +4,7 @@ set -o errexit
set -o pipefail set -o pipefail
set -o nounset set -o nounset
TAG="${1:-"v3.13.1"}" TAG="${1:-"v3.14"}"
echo "tag=${TAG}" echo "tag=${TAG}"
BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}" BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}"

View File

@@ -128,7 +128,7 @@ public class Generate {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
Arguments arguments = Arguments.fromArgsOrConfigFile(args); Arguments arguments = Arguments.fromArgsOrConfigFile(args);
PlanetilerConfig planetilerConfig = PlanetilerConfig.from(arguments); PlanetilerConfig planetilerConfig = PlanetilerConfig.from(arguments);
String tag = arguments.getString("tag", "openmaptiles tag to use", "v3.13.1"); String tag = arguments.getString("tag", "openmaptiles tag to use", "v3.14.0");
String baseUrl = arguments.getString("base-url", "the url used to download the openmaptiles.yml", String baseUrl = arguments.getString("base-url", "the url used to download the openmaptiles.yml",
"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"); "https://raw.githubusercontent.com/openmaptiles/openmaptiles/");
String base = baseUrl + tag + "/"; String base = baseUrl + tag + "/";

View File

@@ -37,10 +37,7 @@ See https://github.com/openmaptiles/openmaptiles/blob/master/LICENSE.md for deta
package org.openmaptiles.generated; package org.openmaptiles.generated;
import static com.onthegomap.planetiler.expression.Expression.FALSE; import static com.onthegomap.planetiler.expression.Expression.*;
import static com.onthegomap.planetiler.expression.Expression.and;
import static com.onthegomap.planetiler.expression.Expression.matchAny;
import static com.onthegomap.planetiler.expression.Expression.or;
import com.onthegomap.planetiler.config.PlanetilerConfig; import com.onthegomap.planetiler.config.PlanetilerConfig;
import com.onthegomap.planetiler.expression.MultiExpression; import com.onthegomap.planetiler.expression.MultiExpression;
@@ -52,14 +49,14 @@ import org.openmaptiles.Layer;
/** /**
* All vector tile layer definitions, attributes, and allowed values generated from the * All vector tile layer definitions, attributes, and allowed values generated from the
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/openmaptiles.yaml">OpenMapTiles vector tile schema * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/openmaptiles.yaml">OpenMapTiles vector tile schema
* v3.13.1</a>. * v3.14</a>.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class OpenMapTilesSchema { public class OpenMapTilesSchema {
public static final String NAME = "OpenMapTiles"; public static final String NAME = "OpenMapTiles";
public static final String DESCRIPTION = "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org"; public static final String DESCRIPTION = "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org";
public static final String VERSION = "3.13.1"; public static final String VERSION = "3.14.0";
public static final String ATTRIBUTION = public static final String ATTRIBUTION =
"<a href=\"https://www.openmaptiles.org/\" target=\"_blank\">&copy; OpenMapTiles</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">&copy; OpenStreetMap contributors</a>"; "<a href=\"https://www.openmaptiles.org/\" target=\"_blank\">&copy; OpenMapTiles</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">&copy; OpenStreetMap contributors</a>";
public static final List<String> LANGUAGES = List.of("am", "ar", "az", "be", "bg", "br", "bs", "ca", "co", "cs", "cy", public static final List<String> LANGUAGES = List.of("am", "ar", "az", "be", "bg", "br", "bs", "ca", "co", "cs", "cy",
@@ -99,7 +96,7 @@ public class OpenMapTilesSchema {
* boundaries show up. So you might not be able to use border styling for ocean water features. * boundaries show up. So you might not be able to use border styling for ocean water features.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/water/water.yaml">water.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/water/water.yaml">water.yaml</a>
*/ */
public interface Water extends Layer { public interface Water extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -121,7 +118,6 @@ public class OpenMapTilesSchema {
/** /**
* All water polygons from <a href="http://osmdata.openstreetmap.de/">OpenStreetMapData</a> have the class * All water polygons from <a href="http://osmdata.openstreetmap.de/">OpenStreetMapData</a> have the class
* <code>ocean</code>. Water bodies with the * <code>ocean</code>. Water bodies with the
* <a href="http://wiki.openstreetmap.org/wiki/Tag:waterway=riverbank"><code>waterway=riverbank</code></a> or
* <a href="http://wiki.openstreetmap.org/wiki/Tag:water=river"><code>water=river</code></a> tag are classified as * <a href="http://wiki.openstreetmap.org/wiki/Tag:water=river"><code>water=river</code></a> tag are classified as
* river. Wet and dry docks tagged * river. Wet and dry docks tagged
* <a href="http://wiki.openstreetmap.org/wiki/Tag:waterway=dock"><code>waterway=dock</code></a> are classified as * <a href="http://wiki.openstreetmap.org/wiki/Tag:waterway=dock"><code>waterway=dock</code></a> are classified as
@@ -179,8 +175,8 @@ public class OpenMapTilesSchema {
final class FieldMappings { final class FieldMappings {
public static final MultiExpression<String> Class = public static final MultiExpression<String> Class =
MultiExpression.of(List.of(MultiExpression.entry("dock", matchAny("waterway", "dock")), MultiExpression.of(List.of(MultiExpression.entry("dock", matchAny("waterway", "dock")),
MultiExpression.entry("river", or(matchAny("water", "river"), matchAny("waterway", "riverbank"))), MultiExpression.entry("river", matchAny("water", "river")), MultiExpression.entry("lake", FALSE),
MultiExpression.entry("lake", FALSE), MultiExpression.entry("ocean", FALSE), MultiExpression.entry("ocean", FALSE),
MultiExpression.entry("swimming_pool", matchAny("leisure", "swimming_pool")))); MultiExpression.entry("swimming_pool", matchAny("leisure", "swimming_pool"))));
} }
} }
@@ -192,7 +188,7 @@ public class OpenMapTilesSchema {
* field applied. Waterways do not have a <code>subclass</code> field. * field applied. Waterways do not have a <code>subclass</code> field.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/waterway/waterway.yaml">waterway.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/waterway/waterway.yaml">waterway.yaml</a>
*/ */
public interface Waterway extends Layer { public interface Waterway extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -277,7 +273,7 @@ public class OpenMapTilesSchema {
* layer is to style wood (<code>class=wood</code>) and grass (<code>class=grass</code>) areas. * layer is to style wood (<code>class=wood</code>) and grass (<code>class=grass</code>) areas.
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/landcover/landcover.yaml">landcover.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/landcover/landcover.yaml">landcover.yaml</a>
*/ */
public interface Landcover extends Layer { public interface Landcover extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -321,6 +317,7 @@ public class OpenMapTilesSchema {
* <li>"bog" * <li>"bog"
* <li>"dune" * <li>"dune"
* <li>"scrub" * <li>"scrub"
* <li>"shrubbery"
* <li>"farm" * <li>"farm"
* <li>"farmland" * <li>"farmland"
* <li>"fell" * <li>"fell"
@@ -372,6 +369,7 @@ public class OpenMapTilesSchema {
public static final String SUBCLASS_BOG = "bog"; public static final String SUBCLASS_BOG = "bog";
public static final String SUBCLASS_DUNE = "dune"; public static final String SUBCLASS_DUNE = "dune";
public static final String SUBCLASS_SCRUB = "scrub"; public static final String SUBCLASS_SCRUB = "scrub";
public static final String SUBCLASS_SHRUBBERY = "shrubbery";
public static final String SUBCLASS_FARM = "farm"; public static final String SUBCLASS_FARM = "farm";
public static final String SUBCLASS_FARMLAND = "farmland"; public static final String SUBCLASS_FARMLAND = "farmland";
public static final String SUBCLASS_FELL = "fell"; public static final String SUBCLASS_FELL = "fell";
@@ -403,10 +401,10 @@ public class OpenMapTilesSchema {
public static final String SUBCLASS_WETLAND = "wetland"; public static final String SUBCLASS_WETLAND = "wetland";
public static final String SUBCLASS_WOOD = "wood"; public static final String SUBCLASS_WOOD = "wood";
public static final Set<String> SUBCLASS_VALUES = public static final Set<String> SUBCLASS_VALUES =
Set.of("allotments", "bare_rock", "beach", "bog", "dune", "scrub", "farm", "farmland", "fell", "forest", Set.of("allotments", "bare_rock", "beach", "bog", "dune", "scrub", "shrubbery", "farm", "farmland", "fell",
"garden", "glacier", "grass", "grassland", "golf_course", "heath", "mangrove", "marsh", "meadow", "orchard", "forest", "garden", "glacier", "grass", "grassland", "golf_course", "heath", "mangrove", "marsh", "meadow",
"park", "plant_nursery", "recreation_ground", "reedbed", "saltern", "saltmarsh", "sand", "scree", "swamp", "orchard", "park", "plant_nursery", "recreation_ground", "reedbed", "saltern", "saltmarsh", "sand", "scree",
"tidalflat", "tundra", "village_green", "vineyard", "wet_meadow", "wetland", "wood"); "swamp", "tidalflat", "tundra", "village_green", "vineyard", "wet_meadow", "wetland", "wood");
} }
/** Complex mappings to generate attribute values from OSM element tags in the landcover layer. */ /** Complex mappings to generate attribute values from OSM element tags in the landcover layer. */
final class FieldMappings { final class FieldMappings {
@@ -419,8 +417,8 @@ public class OpenMapTilesSchema {
MultiExpression.entry("wood", matchAny("subclass", "wood", "forest")), MultiExpression.entry("wood", matchAny("subclass", "wood", "forest")),
MultiExpression.entry("rock", matchAny("subclass", "bare_rock", "scree")), MultiExpression.entry("rock", matchAny("subclass", "bare_rock", "scree")),
MultiExpression.entry("grass", MultiExpression.entry("grass",
matchAny("subclass", "fell", "grassland", "heath", "scrub", "tundra", "grass", "meadow", "allotments", matchAny("subclass", "fell", "grassland", "heath", "scrub", "shrubbery", "tundra", "grass", "meadow",
"park", "village_green", "recreation_ground", "garden", "golf_course")), "allotments", "park", "village_green", "recreation_ground", "garden", "golf_course")),
MultiExpression.entry("wetland", MultiExpression.entry("wetland",
matchAny("subclass", "wetland", "bog", "swamp", "wet_meadow", "marsh", "reedbed", "saltern", "tidalflat", matchAny("subclass", "wetland", "bog", "swamp", "wet_meadow", "marsh", "reedbed", "saltern", "tidalflat",
"saltmarsh", "mangrove")), "saltmarsh", "mangrove")),
@@ -432,7 +430,7 @@ public class OpenMapTilesSchema {
* residential (urban) areas and at higher zoom levels mostly OSM <code>landuse</code> tags. * residential (urban) areas and at higher zoom levels mostly OSM <code>landuse</code> tags.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/landuse/landuse.yaml">landuse.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/landuse/landuse.yaml">landuse.yaml</a>
*/ */
public interface Landuse extends Layer { public interface Landuse extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -481,6 +479,7 @@ public class OpenMapTilesSchema {
* <li>"quarter" * <li>"quarter"
* <li>"neighbourhood" * <li>"neighbourhood"
* <li>"dam" * <li>"dam"
* <li>"quarry"
* </ul> * </ul>
*/ */
public static final String CLASS = "class"; public static final String CLASS = "class";
@@ -512,10 +511,11 @@ public class OpenMapTilesSchema {
public static final String CLASS_QUARTER = "quarter"; public static final String CLASS_QUARTER = "quarter";
public static final String CLASS_NEIGHBOURHOOD = "neighbourhood"; public static final String CLASS_NEIGHBOURHOOD = "neighbourhood";
public static final String CLASS_DAM = "dam"; public static final String CLASS_DAM = "dam";
public static final String CLASS_QUARRY = "quarry";
public static final Set<String> CLASS_VALUES = public static final Set<String> CLASS_VALUES =
Set.of("railway", "cemetery", "military", "residential", "commercial", "industrial", "garages", "retail", Set.of("railway", "cemetery", "military", "residential", "commercial", "industrial", "garages", "retail",
"bus_station", "school", "university", "kindergarten", "college", "library", "hospital", "stadium", "pitch", "bus_station", "school", "university", "kindergarten", "college", "library", "hospital", "stadium", "pitch",
"playground", "track", "theme_park", "zoo", "suburb", "quarter", "neighbourhood", "dam"); "playground", "track", "theme_park", "zoo", "suburb", "quarter", "neighbourhood", "dam", "quarry");
} }
/** Complex mappings to generate attribute values from OSM element tags in the landuse layer. */ /** Complex mappings to generate attribute values from OSM element tags in the landuse layer. */
final class FieldMappings { final class FieldMappings {
@@ -526,7 +526,7 @@ public class OpenMapTilesSchema {
* <a href="http://wiki.openstreetmap.org/wiki/Tag:natural%3Dpeak">Natural peaks</a> * <a href="http://wiki.openstreetmap.org/wiki/Tag:natural%3Dpeak">Natural peaks</a>
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/mountain_peak/mountain_peak.yaml">mountain_peak.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/mountain_peak/mountain_peak.yaml">mountain_peak.yaml</a>
*/ */
public interface MountainPeak extends Layer { public interface MountainPeak extends Layer {
double BUFFER_SIZE = 64.0; double BUFFER_SIZE = 64.0;
@@ -601,7 +601,7 @@ public class OpenMapTilesSchema {
* <a href="http://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve"><code>leisure=nature_reserve</code></a>. * <a href="http://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve"><code>leisure=nature_reserve</code></a>.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/park/park.yaml">park.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/park/park.yaml">park.yaml</a>
*/ */
public interface Park extends Layer { public interface Park extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -661,7 +661,7 @@ public class OpenMapTilesSchema {
* but for most styles it makes sense to just style <code>admin_level=2</code> and <code>admin_level=4</code>. * but for most styles it makes sense to just style <code>admin_level=2</code> and <code>admin_level=4</code>.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/boundary/boundary.yaml">boundary.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/boundary/boundary.yaml">boundary.yaml</a>
*/ */
public interface Boundary extends Layer { public interface Boundary extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -762,7 +762,7 @@ public class OpenMapTilesSchema {
* in the <strong>aeroway</strong> layer. * in the <strong>aeroway</strong> layer.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/aeroway/aeroway.yaml">aeroway.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/aeroway/aeroway.yaml">aeroway.yaml</a>
*/ */
public interface Aeroway extends Layer { public interface Aeroway extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -822,7 +822,7 @@ public class OpenMapTilesSchema {
* features like plazas. * features like plazas.
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/transportation/transportation.yaml">transportation.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/transportation/transportation.yaml">transportation.yaml</a>
*/ */
public interface Transportation extends Layer { public interface Transportation extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -858,6 +858,8 @@ public class OpenMapTilesSchema {
* <li>track * <li>track
* <li>raceway * <li>raceway
* <li>busway * <li>busway
* <li>bus_guideway
* <li>ferry
* <li>motorway_construction * <li>motorway_construction
* <li>trunk_construction * <li>trunk_construction
* <li>primary_construction * <li>primary_construction
@@ -897,6 +899,7 @@ public class OpenMapTilesSchema {
* <li>"bridleway" * <li>"bridleway"
* <li>"corridor" * <li>"corridor"
* <li>"platform" * <li>"platform"
* <li>"ferry (DEPRECATED - use class)"
* </ul> * </ul>
*/ */
public static final String SUBCLASS = "subclass"; public static final String SUBCLASS = "subclass";
@@ -1060,6 +1063,8 @@ public class OpenMapTilesSchema {
public static final String CLASS_TRACK = "track"; public static final String CLASS_TRACK = "track";
public static final String CLASS_RACEWAY = "raceway"; public static final String CLASS_RACEWAY = "raceway";
public static final String CLASS_BUSWAY = "busway"; public static final String CLASS_BUSWAY = "busway";
public static final String CLASS_BUS_GUIDEWAY = "bus_guideway";
public static final String CLASS_FERRY = "ferry";
public static final String CLASS_MOTORWAY_CONSTRUCTION = "motorway_construction"; public static final String CLASS_MOTORWAY_CONSTRUCTION = "motorway_construction";
public static final String CLASS_TRUNK_CONSTRUCTION = "trunk_construction"; public static final String CLASS_TRUNK_CONSTRUCTION = "trunk_construction";
public static final String CLASS_PRIMARY_CONSTRUCTION = "primary_construction"; public static final String CLASS_PRIMARY_CONSTRUCTION = "primary_construction";
@@ -1070,10 +1075,11 @@ public class OpenMapTilesSchema {
public static final String CLASS_SERVICE_CONSTRUCTION = "service_construction"; public static final String CLASS_SERVICE_CONSTRUCTION = "service_construction";
public static final String CLASS_TRACK_CONSTRUCTION = "track_construction"; public static final String CLASS_TRACK_CONSTRUCTION = "track_construction";
public static final String CLASS_RACEWAY_CONSTRUCTION = "raceway_construction"; public static final String CLASS_RACEWAY_CONSTRUCTION = "raceway_construction";
public static final Set<String> CLASS_VALUES = Set.of("motorway", "trunk", "primary", "secondary", "tertiary", public static final Set<String> CLASS_VALUES =
"minor", "path", "service", "track", "raceway", "busway", "motorway_construction", "trunk_construction", Set.of("motorway", "trunk", "primary", "secondary", "tertiary", "minor", "path", "service", "track", "raceway",
"primary_construction", "secondary_construction", "tertiary_construction", "minor_construction", "busway", "bus_guideway", "ferry", "motorway_construction", "trunk_construction", "primary_construction",
"path_construction", "service_construction", "track_construction", "raceway_construction"); "secondary_construction", "tertiary_construction", "minor_construction", "path_construction",
"service_construction", "track_construction", "raceway_construction");
public static final String SUBCLASS_RAIL = "rail"; public static final String SUBCLASS_RAIL = "rail";
public static final String SUBCLASS_NARROW_GAUGE = "narrow_gauge"; public static final String SUBCLASS_NARROW_GAUGE = "narrow_gauge";
public static final String SUBCLASS_PRESERVED = "preserved"; public static final String SUBCLASS_PRESERVED = "preserved";
@@ -1090,9 +1096,10 @@ public class OpenMapTilesSchema {
public static final String SUBCLASS_BRIDLEWAY = "bridleway"; public static final String SUBCLASS_BRIDLEWAY = "bridleway";
public static final String SUBCLASS_CORRIDOR = "corridor"; public static final String SUBCLASS_CORRIDOR = "corridor";
public static final String SUBCLASS_PLATFORM = "platform"; public static final String SUBCLASS_PLATFORM = "platform";
public static final String SUBCLASS_FERRY = "ferry";
public static final Set<String> SUBCLASS_VALUES = public static final Set<String> SUBCLASS_VALUES =
Set.of("rail", "narrow_gauge", "preserved", "funicular", "subway", "light_rail", "monorail", "tram", Set.of("rail", "narrow_gauge", "preserved", "funicular", "subway", "light_rail", "monorail", "tram",
"pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor", "platform"); "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor", "platform", "ferry");
public static final String BRUNNEL_BRIDGE = "bridge"; public static final String BRUNNEL_BRIDGE = "bridge";
public static final String BRUNNEL_TUNNEL = "tunnel"; public static final String BRUNNEL_TUNNEL = "tunnel";
public static final String BRUNNEL_FORD = "ford"; public static final String BRUNNEL_FORD = "ford";
@@ -1112,43 +1119,45 @@ public class OpenMapTilesSchema {
} }
/** Complex mappings to generate attribute values from OSM element tags in the transportation layer. */ /** Complex mappings to generate attribute values from OSM element tags in the transportation layer. */
final class FieldMappings { final class FieldMappings {
public static final MultiExpression<String> Class = public static final MultiExpression<String> Class = MultiExpression.of(List.of(
MultiExpression.of(List.of(MultiExpression.entry("motorway", matchAny("highway", "motorway", "motorway_link")), MultiExpression.entry("motorway", matchAny("highway", "motorway", "motorway_link")),
MultiExpression.entry("trunk", matchAny("highway", "trunk", "trunk_link")), MultiExpression.entry("trunk", matchAny("highway", "trunk", "trunk_link")),
MultiExpression.entry("primary", matchAny("highway", "primary", "primary_link")), MultiExpression.entry("primary", matchAny("highway", "primary", "primary_link")),
MultiExpression.entry("secondary", matchAny("highway", "secondary", "secondary_link")), MultiExpression.entry("secondary", matchAny("highway", "secondary", "secondary_link")),
MultiExpression.entry("tertiary", matchAny("highway", "tertiary", "tertiary_link")), MultiExpression.entry("tertiary", matchAny("highway", "tertiary", "tertiary_link")),
MultiExpression.entry("minor", matchAny("highway", "unclassified", "residential", "living_street", "road")), MultiExpression.entry("minor", matchAny("highway", "unclassified", "residential", "living_street", "road")),
MultiExpression.entry("path", MultiExpression.entry("path",
or(matchAny("highway", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"), or(matchAny("highway", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"),
matchAny("public_transport", "platform"))), matchAny("public_transport", "platform"))),
MultiExpression.entry("service", matchAny("highway", "service")), MultiExpression.entry("service", matchAny("highway", "service")),
MultiExpression.entry("track", matchAny("highway", "track")), MultiExpression.entry("track", matchAny("highway", "track")),
MultiExpression.entry("raceway", matchAny("highway", "raceway")), MultiExpression.entry("raceway", matchAny("highway", "raceway")),
MultiExpression.entry("busway", matchAny("highway", "busway")), MultiExpression.entry("busway", matchAny("highway", "busway")),
MultiExpression.entry("motorway_construction", MultiExpression.entry("bus_guideway", matchAny("highway", "bus_guideway")),
and(matchAny("highway", "construction"), matchAny("construction", "motorway", "motorway_link"))), MultiExpression.entry("ferry", matchAny("highway", "shipway")),
MultiExpression.entry("trunk_construction", MultiExpression.entry("motorway_construction",
and(matchAny("highway", "construction"), matchAny("construction", "trunk", "trunk_link"))), and(matchAny("highway", "construction"), matchAny("construction", "motorway", "motorway_link"))),
MultiExpression.entry("primary_construction", MultiExpression.entry("trunk_construction",
and(matchAny("highway", "construction"), matchAny("construction", "primary", "primary_link"))), and(matchAny("highway", "construction"), matchAny("construction", "trunk", "trunk_link"))),
MultiExpression.entry("secondary_construction", MultiExpression.entry("primary_construction",
and(matchAny("highway", "construction"), matchAny("construction", "secondary", "secondary_link"))), and(matchAny("highway", "construction"), matchAny("construction", "primary", "primary_link"))),
MultiExpression.entry("tertiary_construction", MultiExpression.entry("secondary_construction",
and(matchAny("highway", "construction"), matchAny("construction", "tertiary", "tertiary_link"))), and(matchAny("highway", "construction"), matchAny("construction", "secondary", "secondary_link"))),
MultiExpression.entry( MultiExpression.entry("tertiary_construction",
"minor_construction", and(matchAny("highway", "construction"), matchAny("construction", "tertiary", "tertiary_link"))),
and(matchAny("highway", "construction"), MultiExpression.entry("minor_construction",
matchAny("construction", "", "unclassified", "residential", "living_street", "road"))), and(matchAny("highway", "construction"),
MultiExpression.entry("path_construction", and(matchAny("highway", "construction"), matchAny("construction", "", "unclassified", "residential", "living_street", "road"))),
MultiExpression.entry("path_construction",
and(matchAny("highway", "construction"),
or(matchAny("construction", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"), or(matchAny("construction", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"),
matchAny("public_transport", "platform")))), matchAny("public_transport", "platform")))),
MultiExpression.entry("service_construction", MultiExpression.entry("service_construction",
and(matchAny("highway", "construction"), matchAny("construction", "service"))), and(matchAny("highway", "construction"), matchAny("construction", "service"))),
MultiExpression.entry("track_construction", MultiExpression.entry("track_construction",
and(matchAny("highway", "construction"), matchAny("construction", "track"))), and(matchAny("highway", "construction"), matchAny("construction", "track"))),
MultiExpression.entry("raceway_construction", MultiExpression.entry("raceway_construction",
and(matchAny("highway", "construction"), matchAny("construction", "raceway"))))); and(matchAny("highway", "construction"), matchAny("construction", "raceway")))));
} }
} }
/** /**
@@ -1157,7 +1166,7 @@ public class OpenMapTilesSchema {
* location:underground are excluded. * location:underground are excluded.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/building/building.yaml">building.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/building/building.yaml">building.yaml</a>
*/ */
public interface Building extends Layer { public interface Building extends Layer {
double BUFFER_SIZE = 4.0; double BUFFER_SIZE = 4.0;
@@ -1199,7 +1208,7 @@ public class OpenMapTilesSchema {
* from OSM water bodies. Only the most important lakes contain labels. * from OSM water bodies. Only the most important lakes contain labels.
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/water_name/water_name.yaml">water_name.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/water_name/water_name.yaml">water_name.yaml</a>
*/ */
public interface WaterName extends Layer { public interface WaterName extends Layer {
double BUFFER_SIZE = 256.0; double BUFFER_SIZE = 256.0;
@@ -1264,7 +1273,7 @@ public class OpenMapTilesSchema {
* while for other roads you should use <code>name</code>. * while for other roads you should use <code>name</code>.
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/transportation_name/transportation_name.yaml">transportation_name.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/transportation_name/transportation_name.yaml">transportation_name.yaml</a>
*/ */
public interface TransportationName extends Layer { public interface TransportationName extends Layer {
double BUFFER_SIZE = 8.0; double BUFFER_SIZE = 8.0;
@@ -1481,7 +1490,7 @@ public class OpenMapTilesSchema {
* create a text hierarchy. * create a text hierarchy.
* *
* Generated from * Generated from
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/place/place.yaml">place.yaml</a> * <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/place/place.yaml">place.yaml</a>
*/ */
public interface Place extends Layer { public interface Place extends Layer {
double BUFFER_SIZE = 256.0; double BUFFER_SIZE = 256.0;
@@ -1509,7 +1518,10 @@ public class OpenMapTilesSchema {
* allowed values: * allowed values:
* <ul> * <ul>
* <li>2 * <li>2
* <li>3
* <li>4 * <li>4
* <li>5
* <li>6
* </ul> * </ul>
*/ */
public static final String CAPITAL = "capital"; public static final String CAPITAL = "capital";
@@ -1586,7 +1598,7 @@ public class OpenMapTilesSchema {
* housenumber. * housenumber.
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/housenumber/housenumber.yaml">housenumber.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/housenumber/housenumber.yaml">housenumber.yaml</a>
*/ */
public interface Housenumber extends Layer { public interface Housenumber extends Layer {
double BUFFER_SIZE = 8.0; double BUFFER_SIZE = 8.0;
@@ -1615,7 +1627,7 @@ public class OpenMapTilesSchema {
* <a href="http://wiki.openstreetmap.org/wiki/Points_of_interest">Points of interests</a> containing a of a variety * <a href="http://wiki.openstreetmap.org/wiki/Points_of_interest">Points of interests</a> containing a of a variety
* of OpenStreetMap tags. Mostly contains amenities, sport, shop and tourist POIs. * of OpenStreetMap tags. Mostly contains amenities, sport, shop and tourist POIs.
* *
* Generated from <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/poi/poi.yaml">poi.yaml</a> * Generated from <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/poi/poi.yaml">poi.yaml</a>
*/ */
public interface Poi extends Layer { public interface Poi extends Layer {
double BUFFER_SIZE = 64.0; double BUFFER_SIZE = 64.0;
@@ -1810,7 +1822,7 @@ public class OpenMapTilesSchema {
matchAny("subclass", "hotel", "motel", "bed_and_breakfast", "guest_house", "hostel", "chalet", "alpine_hut", matchAny("subclass", "hotel", "motel", "bed_and_breakfast", "guest_house", "hostel", "chalet", "alpine_hut",
"dormitory")), "dormitory")),
MultiExpression.entry("ice_cream", matchAny("subclass", "chocolate", "confectionery")), MultiExpression.entry("ice_cream", matchAny("subclass", "chocolate", "confectionery")),
MultiExpression.entry("post", matchAny("subclass", "post_box", "post_office")), MultiExpression.entry("post", matchAny("subclass", "post_box", "post_office", "parcel_locker")),
MultiExpression.entry("cafe", matchAny("subclass", "cafe")), MultiExpression.entry("cafe", matchAny("subclass", "cafe")),
MultiExpression.entry("school", matchAny("subclass", "school", "kindergarten")), MultiExpression.entry("school", matchAny("subclass", "school", "kindergarten")),
MultiExpression.entry("alcohol_shop", matchAny("subclass", "alcohol", "beverages", "wine")), MultiExpression.entry("alcohol_shop", matchAny("subclass", "alcohol", "beverages", "wine")),
@@ -1834,7 +1846,7 @@ public class OpenMapTilesSchema {
* <a href="http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome">Aerodrome labels</a> * <a href="http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome">Aerodrome labels</a>
* *
* Generated from <a href= * Generated from <a href=
* "https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/layers/aerodrome_label/aerodrome_label.yaml">aerodrome_label.yaml</a> * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/aerodrome_label/aerodrome_label.yaml">aerodrome_label.yaml</a>
*/ */
public interface AerodromeLabel extends Layer { public interface AerodromeLabel extends Layer {
double BUFFER_SIZE = 64.0; double BUFFER_SIZE = 64.0;

View File

@@ -50,7 +50,7 @@ import java.util.Map;
/** /**
* OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions * OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/openmaptiles.yaml">OpenMapTiles vector tile * in the <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.14/openmaptiles.yaml">OpenMapTiles vector tile
* schema</a>. * schema</a>.
* *
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the columns * These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the columns
@@ -106,10 +106,10 @@ public class Tables {
} }
/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */ /** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
public static final Expression MAPPING = public static final Expression MAPPING = and(
and(or(matchAny("landuse", "reservoir", "basin", "salt_pond"), matchAny("leisure", "swimming_pool"), or(matchAny("landuse", "reservoir", "basin", "salt_pond"), matchAny("leisure", "swimming_pool"),
matchAny("natural", "water", "bay", "spring"), matchAny("waterway", "riverbank", "dock"), matchAny("natural", "water", "bay", "spring"), matchAny("waterway", "dock"), matchAny("water", "river")),
matchAny("water", "river")), not(matchAny("covered", "yes")), matchType("polygon")); not(matchAny("covered", "yes")), matchType("polygon"));
/** /**
* Interface for layer implementations to extend to subscribe to OSM elements filtered and parsed as * Interface for layer implementations to extend to subscribe to OSM elements filtered and parsed as
@@ -153,8 +153,8 @@ public class Tables {
public static final Expression MAPPING = and(or( public static final Expression MAPPING = and(or(
matchAny("landuse", "allotments", "farm", "farmland", "orchard", "plant_nursery", "vineyard", "grass", matchAny("landuse", "allotments", "farm", "farmland", "orchard", "plant_nursery", "vineyard", "grass",
"grassland", "meadow", "forest", "village_green", "recreation_ground"), "grassland", "meadow", "forest", "village_green", "recreation_ground"),
matchAny("natural", "wood", "wetland", "fell", "grassland", "heath", "scrub", "tundra", "glacier", "bare_rock", matchAny("natural", "wood", "wetland", "fell", "grassland", "heath", "scrub", "shrubbery", "tundra", "glacier",
"scree", "beach", "sand", "dune"), "bare_rock", "scree", "beach", "sand", "dune"),
matchAny("leisure", "park", "garden", "golf_course"), matchAny("wetland", "bog", "swamp", "wet_meadow", "marsh", matchAny("leisure", "park", "garden", "golf_course"), matchAny("wetland", "bog", "swamp", "wet_meadow", "marsh",
"reedbed", "saltern", "tidalflat", "saltmarsh", "mangrove")), "reedbed", "saltern", "tidalflat", "saltmarsh", "mangrove")),
matchType("polygon")); matchType("polygon"));
@@ -178,8 +178,8 @@ public class Tables {
/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */ /** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
public static final Expression MAPPING = and(or( public static final Expression MAPPING = and(or(
matchAny("landuse", "railway", "cemetery", "military", "residential", "commercial", "industrial", "garages", matchAny("landuse", "railway", "cemetery", "military", "quarry", "residential", "commercial", "industrial",
"retail"), "garages", "retail"),
matchAny("amenity", "bus_station", "school", "university", "kindergarten", "college", "library", "hospital", matchAny("amenity", "bus_station", "school", "university", "kindergarten", "college", "library", "hospital",
"grave_yard"), "grave_yard"),
matchAny("leisure", "stadium", "pitch", "playground", "track"), matchAny("tourism", "theme_park", "zoo"), matchAny("leisure", "stadium", "pitch", "playground", "track"), matchAny("tourism", "theme_park", "zoo"),
@@ -345,7 +345,7 @@ public class Tables {
matchAny("highway", "motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", matchAny("highway", "motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary",
"secondary_link", "tertiary", "tertiary_link", "unclassified", "residential", "living_street", "road", "secondary_link", "tertiary", "tertiary_link", "unclassified", "residential", "living_street", "road",
"pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor", "service", "track", "raceway", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor", "service", "track", "raceway",
"busway", "construction"), "busway", "bus_guideway", "construction"),
matchAny("public_transport", "platform"), matchAny("man_made", "pier"), matchAny("public_transport", "platform"), matchAny("man_made", "pier"),
matchAny("service", "driveway", "parking_aisle")), matchType("linestring")); matchAny("service", "driveway", "parking_aisle")), matchType("linestring"));
@@ -690,17 +690,19 @@ public class Tables {
/** An OSM element that would appear in the {@code osm_poi_point} table generated by imposm3. */ /** An OSM element that would appear in the {@code osm_poi_point} table generated by imposm3. */
public record OsmPoiPoint(@Override String name, @Override String nameEn, @Override String nameDe, public record OsmPoiPoint(@Override String name, @Override String nameEn, @Override String nameDe,
@Override String subclass, @Override String mappingKey, @Override String station, @Override String funicular, @Override String subclass, @Override String mappingKey, @Override String station, @Override String funicular,
@Override String information, @Override String uicRef, @Override String religion, @Override long level, @Override String information, @Override String uicRef, @Override String ref, @Override String religion,
@Override boolean indoor, @Override long layer, @Override String sport, @Override String operator, @Override long level, @Override boolean indoor, @Override long layer, @Override String sport,
@Override String network, @Override SourceFeature source) implements Row, WithName, WithNameEn, WithNameDe, @Override String operator, @Override String network, @Override String brand, @Override SourceFeature source)
WithSubclass, WithMappingKey, WithStation, WithFunicular, WithInformation, WithUicRef, WithReligion, WithLevel, implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular,
WithIndoor, WithLayer, WithSport, WithOperator, WithNetwork, WithSource { WithInformation, WithUicRef, WithRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithOperator,
WithNetwork, WithBrand, WithSource {
public OsmPoiPoint(SourceFeature source, String mappingKey) { public OsmPoiPoint(SourceFeature source, String mappingKey) {
this(source.getString("name"), source.getString("name:en"), source.getString("name:de"), this(source.getString("name"), source.getString("name:en"), source.getString("name:de"),
source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"), source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"),
source.getString("information"), source.getString("uic_ref"), source.getString("religion"), source.getString("information"), source.getString("uic_ref"), source.getString("ref"),
source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), source.getString("sport"), source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"),
source.getString("operator"), source.getString("network"), source); source.getString("sport"), source.getString("operator"), source.getString("network"), source.getString("brand"),
source);
} }
/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */ /** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
@@ -709,8 +711,8 @@ public class Tables {
"bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors", "bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors",
"drinking_water", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital", "drinking_water", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital",
"ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home",
"parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", "parking", "pharmacy", "place_of_worship", "police", "parcel_locker", "post_box", "post_office", "prison",
"public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone",
"theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"), "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"),
matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile",
"toll_booth"), "toll_booth"),
@@ -758,17 +760,19 @@ public class Tables {
/** An OSM element that would appear in the {@code osm_poi_polygon} table generated by imposm3. */ /** An OSM element that would appear in the {@code osm_poi_polygon} table generated by imposm3. */
public record OsmPoiPolygon(@Override String name, @Override String nameEn, @Override String nameDe, public record OsmPoiPolygon(@Override String name, @Override String nameEn, @Override String nameDe,
@Override String subclass, @Override String mappingKey, @Override String station, @Override String funicular, @Override String subclass, @Override String mappingKey, @Override String station, @Override String funicular,
@Override String information, @Override String uicRef, @Override String religion, @Override long level, @Override String information, @Override String uicRef, @Override String ref, @Override String religion,
@Override boolean indoor, @Override long layer, @Override String sport, @Override String operator, @Override long level, @Override boolean indoor, @Override long layer, @Override String sport,
@Override String network, @Override SourceFeature source) implements Row, WithName, WithNameEn, WithNameDe, @Override String operator, @Override String network, @Override String brand, @Override SourceFeature source)
WithSubclass, WithMappingKey, WithStation, WithFunicular, WithInformation, WithUicRef, WithReligion, WithLevel, implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular,
WithIndoor, WithLayer, WithSport, WithOperator, WithNetwork, WithSource { WithInformation, WithUicRef, WithRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithOperator,
WithNetwork, WithBrand, WithSource {
public OsmPoiPolygon(SourceFeature source, String mappingKey) { public OsmPoiPolygon(SourceFeature source, String mappingKey) {
this(source.getString("name"), source.getString("name:en"), source.getString("name:de"), this(source.getString("name"), source.getString("name:en"), source.getString("name:de"),
source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"), source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"),
source.getString("information"), source.getString("uic_ref"), source.getString("religion"), source.getString("information"), source.getString("uic_ref"), source.getString("ref"),
source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), source.getString("sport"), source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"),
source.getString("operator"), source.getString("network"), source); source.getString("sport"), source.getString("operator"), source.getString("network"), source.getString("brand"),
source);
} }
/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */ /** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
@@ -777,8 +781,8 @@ public class Tables {
"bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors", "bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors",
"drinking_water", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital", "drinking_water", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital",
"ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home",
"parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", "parking", "pharmacy", "place_of_worship", "police", "parcel_locker", "post_box", "post_office", "prison",
"public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone",
"theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"), "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"),
matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile",
"toll_booth"), "toll_booth"),
@@ -886,6 +890,11 @@ public class Tables {
String boundary(); String boundary();
} }
/** Rows with a String brand attribute. */
public interface WithBrand {
String brand();
}
/** Rows with a String building attribute. */ /** Rows with a String building attribute. */
public interface WithBuilding { public interface WithBuilding {
String building(); String building();

View File

@@ -158,14 +158,14 @@ public class Landcover implements
} else { // don't merge } else { // don't merge
result.add(item); result.add(item);
} }
} else if (zoom == 9) { } else if (zoom >= 8 && zoom <= 9) {
if (WOOD_OR_FOREST.contains(subclass)) { if (WOOD_OR_FOREST.contains(subclass)) {
attrs.put(tempGroupKey, numPoints < 300 ? "<300" : ">300"); attrs.put(tempGroupKey, numPoints < 300 ? "<300" : ">300");
toMerge.add(item); toMerge.add(item);
} else { // don't merge } else { // don't merge
result.add(item); result.add(item);
} }
} else { // zoom between 7 and 8 } else { // zoom 7
toMerge.add(item); toMerge.add(item);
} }
} else { } else {

View File

@@ -39,14 +39,19 @@ import static org.openmaptiles.util.Utils.coalesce;
import static org.openmaptiles.util.Utils.nullIfEmpty; import static org.openmaptiles.util.Utils.nullIfEmpty;
import com.onthegomap.planetiler.FeatureCollector; import com.onthegomap.planetiler.FeatureCollector;
import com.onthegomap.planetiler.FeatureMerge;
import com.onthegomap.planetiler.VectorTile;
import com.onthegomap.planetiler.config.PlanetilerConfig; import com.onthegomap.planetiler.config.PlanetilerConfig;
import com.onthegomap.planetiler.geo.GeometryException;
import com.onthegomap.planetiler.reader.SourceFeature; import com.onthegomap.planetiler.reader.SourceFeature;
import com.onthegomap.planetiler.stats.Stats; import com.onthegomap.planetiler.stats.Stats;
import com.onthegomap.planetiler.util.Parse; import com.onthegomap.planetiler.util.Parse;
import com.onthegomap.planetiler.util.Translations; import com.onthegomap.planetiler.util.Translations;
import com.onthegomap.planetiler.util.ZoomFunction; import com.onthegomap.planetiler.util.ZoomFunction;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.openmaptiles.OpenMapTilesProfile; import org.openmaptiles.OpenMapTilesProfile;
import org.openmaptiles.generated.OpenMapTilesSchema; import org.openmaptiles.generated.OpenMapTilesSchema;
import org.openmaptiles.generated.Tables; import org.openmaptiles.generated.Tables;
@@ -61,6 +66,7 @@ import org.openmaptiles.generated.Tables;
public class Landuse implements public class Landuse implements
OpenMapTilesSchema.Landuse, OpenMapTilesSchema.Landuse,
OpenMapTilesProfile.NaturalEarthProcessor, OpenMapTilesProfile.NaturalEarthProcessor,
OpenMapTilesProfile.FeaturePostProcessor,
Tables.OsmLandusePolygon.Handler { Tables.OsmLandusePolygon.Handler {
private static final ZoomFunction<Number> MIN_PIXEL_SIZE_THRESHOLDS = ZoomFunction.fromMaxZoomThresholds(Map.of( private static final ZoomFunction<Number> MIN_PIXEL_SIZE_THRESHOLDS = ZoomFunction.fromMaxZoomThresholds(Map.of(
@@ -103,10 +109,36 @@ public class Landuse implements
if ("grave_yard".equals(clazz)) { if ("grave_yard".equals(clazz)) {
clazz = FieldValues.CLASS_CEMETERY; clazz = FieldValues.CLASS_CEMETERY;
} }
features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE) var feature = features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE)
.setAttr(Fields.CLASS, clazz) .setAttr(Fields.CLASS, clazz)
.setMinPixelSizeOverrides(MIN_PIXEL_SIZE_THRESHOLDS)
.setMinZoom(Z6_CLASSES.contains(clazz) ? 6 : 9); .setMinZoom(Z6_CLASSES.contains(clazz) ? 6 : 9);
if (FieldValues.CLASS_RESIDENTIAL.equals(clazz)) {
feature
.setMinPixelSize(0.1)
.setPixelTolerance(0.25);
} else {
feature
.setMinPixelSizeOverrides(MIN_PIXEL_SIZE_THRESHOLDS);
}
}
}
@Override
public List<VectorTile.Feature> postProcess(int zoom,
List<VectorTile.Feature> items) throws GeometryException {
if (zoom < 6 || zoom > 12) {
return items;
} else {
// merging only merges polygons with class "residential" for z6-z12
Map<Boolean, List<VectorTile.Feature>> splitLists =
items.stream().collect(Collectors.partitioningBy(
i -> FieldValues.CLASS_RESIDENTIAL.equals(i.attrs().get(Fields.CLASS)))
);
List<VectorTile.Feature> result = splitLists.get(Boolean.FALSE);
List<VectorTile.Feature> toMerge = splitLists.get(Boolean.TRUE);
var merged = FeatureMerge.mergeNearbyPolygons(toMerge, 1, 1, 0.1, 0.1);
result.addAll(merged);
return result;
} }
} }
} }

View File

@@ -184,7 +184,7 @@ public class Place implements
feature.getString("name"), feature.getString("name"),
feature.getString("wikidataid"), feature.getString("wikidataid"),
(int) feature.getLong("scalerank"), (int) feature.getLong("scalerank"),
Stream.of("name", "namealt", "meganame", "gn_ascii", "nameascii").map(feature::getString) Stream.of("name", "namealt", "meganame", "name_en", "nameascii").map(feature::getString)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(s -> s.toLowerCase(Locale.ROOT)) .map(s -> s.toLowerCase(Locale.ROOT))
.collect(Collectors.toSet()) .collect(Collectors.toSet())
@@ -356,10 +356,14 @@ public class Place implements
feature.setPointLabelGridLimit(LABEL_GRID_LIMITS); feature.setPointLabelGridLimit(LABEL_GRID_LIMITS);
} }
if ("2".equals(capital) || "yes".equals(capital)) { if (capital != null) { // with Java 18, we can handle that with "case null", see https://openjdk.org/jeps/420)
feature.setAttr(Fields.CAPITAL, 2); switch (capital) {
} else if ("4".equals(capital)) { case "2", "yes" -> feature.setAttr(Fields.CAPITAL, 2);
feature.setAttr(Fields.CAPITAL, 4); case "3" -> feature.setAttr(Fields.CAPITAL, 3);
case "4" -> feature.setAttr(Fields.CAPITAL, 4);
case "5" -> feature.setAttr(Fields.CAPITAL, 5);
case "6" -> feature.setAttr(Fields.CAPITAL, 6);
}
} }
} }

View File

@@ -136,7 +136,7 @@ public class Poi implements
setupPoiFeature(element, features.centroidIfConvex(LAYER_NAME)); setupPoiFeature(element, features.centroidIfConvex(LAYER_NAME));
} }
private <T extends Tables.WithSubclass & Tables.WithStation & Tables.WithFunicular & Tables.WithSport & Tables.WithInformation & Tables.WithReligion & Tables.WithMappingKey & Tables.WithName & Tables.WithIndoor & Tables.WithLayer & Tables.WithSource & Tables.WithOperator & Tables.WithNetwork> void setupPoiFeature( private <T extends Tables.WithSubclass & Tables.WithStation & Tables.WithFunicular & Tables.WithSport & Tables.WithInformation & Tables.WithReligion & Tables.WithMappingKey & Tables.WithName & Tables.WithIndoor & Tables.WithLayer & Tables.WithSource & Tables.WithOperator & Tables.WithNetwork & Tables.WithBrand & Tables.WithRef> void setupPoiFeature(
T element, FeatureCollector.Feature output) { T element, FeatureCollector.Feature output) {
String rawSubclass = element.subclass(); String rawSubclass = element.subclass();
if ("station".equals(rawSubclass) && "subway".equals(element.station())) { if ("station".equals(rawSubclass) && "subway".equals(element.station())) {
@@ -156,6 +156,18 @@ public class Poi implements
} }
} }
// Parcel locker without name: use either brand or operator and add ref if present
if ("parcel_locker".equals(rawSubclass) && nullOrEmpty(name)) {
name = coalesce(nullIfEmpty(element.brand()), nullIfEmpty(element.operator()));
String ref = nullIfEmpty(element.ref());
if (ref != null) {
name = name == null ? ref : (name + " " + ref);
}
if (name != null) {
tags.put("name", name);
}
}
String subclass = switch (rawSubclass) { String subclass = switch (rawSubclass) {
case "information" -> nullIfEmpty(element.information()); case "information" -> nullIfEmpty(element.information());
case "place_of_worship" -> nullIfEmpty(element.religion()); case "place_of_worship" -> nullIfEmpty(element.religion());

View File

@@ -174,6 +174,7 @@ public class Transportation implements
entry(FieldValues.CLASS_RACEWAY, 12), entry(FieldValues.CLASS_RACEWAY, 12),
entry(FieldValues.CLASS_TERTIARY, 11), entry(FieldValues.CLASS_TERTIARY, 11),
entry(FieldValues.CLASS_BUSWAY, 11), entry(FieldValues.CLASS_BUSWAY, 11),
entry(FieldValues.CLASS_BUS_GUIDEWAY, 11),
entry(FieldValues.CLASS_SECONDARY, 9), entry(FieldValues.CLASS_SECONDARY, 9),
entry(FieldValues.CLASS_PRIMARY, 7), entry(FieldValues.CLASS_PRIMARY, 7),
entry(FieldValues.CLASS_TRUNK, 5), entry(FieldValues.CLASS_TRUNK, 5),

View File

@@ -112,8 +112,7 @@ public class Water implements
@Override @Override
public void process(Tables.OsmWaterPolygon element, FeatureCollector features) { public void process(Tables.OsmWaterPolygon element, FeatureCollector features) {
if (!"bay".equals(element.natural())) { if (!"bay".equals(element.natural())) {
String clazz = "riverbank".equals(element.waterway()) ? FieldValues.CLASS_RIVER : String clazz = classMapping.getOrElse(element.source(), FieldValues.CLASS_LAKE);
classMapping.getOrElse(element.source(), FieldValues.CLASS_LAKE);
features.polygon(LAYER_NAME) features.polygon(LAYER_NAME)
.setBufferPixels(BUFFER_SIZE) .setBufferPixels(BUFFER_SIZE)
.setMinPixelSizeBelowZoom(11, 2) .setMinPixelSizeBelowZoom(11, 2)

View File

@@ -171,17 +171,17 @@ class LandcoverTest extends AbstractLayerTest {
} }
@Test @Test
void testMergeNonForestsBelowZ9() throws GeometryException { void testMergeNonForestsBelowZ8() throws GeometryException {
Map<String, Object> map = Map.of("subclass", "dune"); Map<String, Object> map = Map.of("subclass", "dune");
assertMerges(List.of(map, map), List.of( assertMerges(List.of(map, map), List.of(
feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")),
feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune"))
), 9); ), 8);
assertMerges(List.of(map), List.of( assertMerges(List.of(map), List.of(
feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")),
feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune"))
), 8); ), 7);
assertMerges(List.of(map, map), List.of( assertMerges(List.of(map, map), List.of(
feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")),
feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune"))

View File

@@ -2,10 +2,13 @@ package org.openmaptiles.layers;
import static com.onthegomap.planetiler.TestUtils.rectangle; import static com.onthegomap.planetiler.TestUtils.rectangle;
import com.onthegomap.planetiler.VectorTile;
import com.onthegomap.planetiler.geo.GeoUtils; import com.onthegomap.planetiler.geo.GeoUtils;
import com.onthegomap.planetiler.geo.GeometryException;
import com.onthegomap.planetiler.reader.SimpleFeature; import com.onthegomap.planetiler.reader.SimpleFeature;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openmaptiles.OpenMapTilesProfile; import org.openmaptiles.OpenMapTilesProfile;
@@ -86,9 +89,43 @@ class LanduseTest extends AbstractLayerTest {
"class", "residential", "class", "residential",
"_minzoom", 6, "_minzoom", 6,
"_maxzoom", 14, "_maxzoom", 14,
"_minpixelsize", 2d "_minpixelsize", 0.1d
)), process(polygonFeature(Map.of( )), process(polygonFeature(Map.of(
"landuse", "residential" "landuse", "residential"
)))); ))));
} }
@Test
void testMergePolygonsZ12() throws GeometryException {
var poly1 = new VectorTile.Feature(
Landuse.LAYER_NAME,
1,
VectorTile.encodeGeometry(rectangle(10, 20)),
Map.of("class", "residential"),
0
);
var poly2 = new VectorTile.Feature(
Landuse.LAYER_NAME,
1,
VectorTile.encodeGeometry(rectangle(20, 10, 22, 20)),
Map.of("class", "residential"),
0
);
var poly3 = new VectorTile.Feature(
Landuse.LAYER_NAME,
1,
VectorTile.encodeGeometry(rectangle(10, 20, 20, 22)),
Map.of("class", "suburb"),
0
);
Assertions.assertEquals(
3,
profile.postProcessLayerFeatures(Landuse.LAYER_NAME, 13, List.of(poly1, poly2, poly3)).size()
);
Assertions.assertEquals(
2,
profile.postProcessLayerFeatures(Landuse.LAYER_NAME, 12, List.of(poly1, poly2, poly3)).size()
);
}
} }

View File

@@ -430,6 +430,81 @@ class PlaceTest extends AbstractLayerTest {
)))); ))));
} }
@Test
void testCountyCapital() {
process(SimpleFeature.create(
newPoint(0, 0),
Map.of(
"name", "Pueblo",
"scalerank", 7,
"wikidataid", "Q675576"
),
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
"ne_10m_populated_places",
0
));
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"name", "Pueblo",
"rank", 7,
"capital", 6,
"_type", "point",
"_minzoom", 6
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Pueblo",
"population", "111876",
"capital", "6"
))));
// no match when far away
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"name", "Pueblo",
"rank", "<null>"
)), process(SimpleFeature.create(
newPoint(1, 1),
Map.of(
"place", "city",
"name", "Pueblo",
"wikidata", "Q675576",
"population", "111876",
"capital", "6"
),
OpenMapTilesProfile.OSM_SOURCE,
null,
0
)));
// unaccented name match
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"rank", 7
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Pueblo",
"population", "111876",
"capital", "6"
))));
// wikidata only match
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"rank", 7
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Other name",
"population", "111876",
"wikidata", "Q675576",
"capital", "6"
))));
}
@Test @Test
void testCityWithoutNaturalEarthMatch() { void testCityWithoutNaturalEarthMatch() {

View File

@@ -236,4 +236,42 @@ class PoiTest extends AbstractLayerTest {
"network", "ATM name" "network", "ATM name"
)))); ))));
} }
@Test
void testParcelLocker() {
List<Map<String, Object>> expected = List.of(Map.of(
"_layer", "poi",
"class", "post",
"subclass", "parcel_locker",
"name", "Parcel Locker name"
));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "parcel_locker",
"brand", "Parcel Locker name"
))));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "parcel_locker",
"operator", "Parcel Locker name"
))));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "parcel_locker",
"operator", "Parcel Locker",
"ref", "name"
))));
}
@Test
void testParcelLockerCornerCase() {
List<Map<String, Object>> expected = List.of(Map.of(
"_layer", "poi",
"class", "post",
"subclass", "parcel_locker",
"name", "Corner Case"
));
// no brand, no operator, just ref
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "parcel_locker",
"ref", "Corner Case"
))));
}
} }

View File

@@ -724,6 +724,29 @@ class TransportationTest extends AbstractLayerTest {
)))); ))));
} }
@Test
void testBusGuideway() {
assertFeatures(13, List.of(Map.of(
"_layer", "transportation",
"class", "bus_guideway",
"brunnel", "tunnel",
"_minzoom", 11
), Map.of(
"_layer", "transportation_name",
"class", "bus_guideway",
"name", "Silver Line",
"_minzoom", 12
)), process(lineFeature(Map.of(
"access", "no",
"bus", "yes",
"highway", "bus_guideway",
"layer", "-1",
"name", "Silver Line",
"trolley_wire", "yes",
"tunnel", "yes"
))));
}
final OsmElement.Relation relUS = new OsmElement.Relation(1); final OsmElement.Relation relUS = new OsmElement.Relation(1);
{ {

View File

@@ -144,20 +144,27 @@ class WaterTest extends AbstractLayerTest {
"natural", "water", "natural", "water",
"covered", "yes" "covered", "yes"
)))); ))));
assertFeatures(14, List.of(Map.of( assertFeatures(14, List.of(
"class", "river", Map.of(
"brunnel", "bridge", "class", "dock",
"intermittent", 1, "intermittent", 1,
"_layer", "water", "_layer", "water",
"_type", "polygon", "_type", "polygon",
"_minzoom", 6, "_minzoom", 6,
"_maxzoom", 14 "_maxzoom", 14),
)), process(polygonFeature(Map.of( Map.of(
"waterway", "riverbank", "class", "harbor",
"bridge", "1", "subclass", "dock",
"intermittent", "1"
)))); "_layer", "poi",
"_type", "point",
"_minzoom", 14,
"_maxzoom", 14
)), process(polygonFeature(Map.of(
"waterway", "dock",
"intermittent", "1"
))));
assertFeatures(11, List.of(Map.of( assertFeatures(11, List.of(Map.of(
"class", "lake", "class", "lake",
"brunnel", "<null>", "brunnel", "<null>",
@@ -175,14 +182,19 @@ class WaterTest extends AbstractLayerTest {
} }
@Test @Test
void testRiverbank() { void testDock() {
assertFeatures(11, List.of(Map.of( assertFeatures(11, List.of(
"class", "river", Map.of(
"_layer", "water", "class", "dock",
"_type", "polygon" "_layer", "water",
)), process(polygonFeature(Map.of( "_type", "polygon"),
"waterway", "riverbank" Map.of(
)))); "class", "harbor",
"_layer", "poi",
"_type", "point"
)), process(polygonFeature(Map.of(
"waterway", "dock"
))));
} }
@Test @Test