diff --git a/README.md b/README.md index 440e963..e31395a 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ script with the OpenMapTiles release tag: ```bash -./scripts/regenerate-openmaptiles.sh v3.13.1 +./scripts/regenerate-openmaptiles.sh v3.14 ``` 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: ```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 diff --git a/pom.xml b/pom.xml index d372639..9ddba8b 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.openmaptiles planetiler-openmaptiles - 3.13.1 + 3.14.0 OpenMapTiles Vector Tile Schema implementation for Planetiler tool diff --git a/scripts/regenerate-openmaptiles.sh b/scripts/regenerate-openmaptiles.sh index 47c8fa5..54fb8d7 100755 --- a/scripts/regenerate-openmaptiles.sh +++ b/scripts/regenerate-openmaptiles.sh @@ -4,7 +4,7 @@ set -o errexit set -o pipefail set -o nounset -TAG="${1:-"v3.13.1"}" +TAG="${1:-"v3.14"}" echo "tag=${TAG}" BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}" diff --git a/src/main/java/org/openmaptiles/Generate.java b/src/main/java/org/openmaptiles/Generate.java index f15d1db..fab937b 100644 --- a/src/main/java/org/openmaptiles/Generate.java +++ b/src/main/java/org/openmaptiles/Generate.java @@ -128,7 +128,7 @@ public class Generate { public static void main(String[] args) throws IOException { Arguments arguments = Arguments.fromArgsOrConfigFile(args); 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", "https://raw.githubusercontent.com/openmaptiles/openmaptiles/"); String base = baseUrl + tag + "/"; diff --git a/src/main/java/org/openmaptiles/generated/OpenMapTilesSchema.java b/src/main/java/org/openmaptiles/generated/OpenMapTilesSchema.java index 3d9e8ba..8ae534a 100644 --- a/src/main/java/org/openmaptiles/generated/OpenMapTilesSchema.java +++ b/src/main/java/org/openmaptiles/generated/OpenMapTilesSchema.java @@ -37,10 +37,7 @@ See https://github.com/openmaptiles/openmaptiles/blob/master/LICENSE.md for deta package org.openmaptiles.generated; -import static com.onthegomap.planetiler.expression.Expression.FALSE; -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 static com.onthegomap.planetiler.expression.Expression.*; import com.onthegomap.planetiler.config.PlanetilerConfig; 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 - * OpenMapTiles vector tile schema - * v3.13.1. + * OpenMapTiles vector tile schema + * v3.14. */ @SuppressWarnings("unused") public class OpenMapTilesSchema { 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 VERSION = "3.13.1"; + public static final String VERSION = "3.14.0"; public static final String ATTRIBUTION = "© OpenMapTiles © OpenStreetMap contributors"; public static final List 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. * * Generated from - * water.yaml + * water.yaml */ public interface Water extends Layer { double BUFFER_SIZE = 4.0; @@ -121,7 +118,6 @@ public class OpenMapTilesSchema { /** * All water polygons from OpenStreetMapData have the class * ocean. Water bodies with the - * waterway=riverbank or * water=river tag are classified as * river. Wet and dry docks tagged * waterway=dock are classified as @@ -179,8 +175,8 @@ public class OpenMapTilesSchema { final class FieldMappings { public static final MultiExpression Class = MultiExpression.of(List.of(MultiExpression.entry("dock", matchAny("waterway", "dock")), - MultiExpression.entry("river", or(matchAny("water", "river"), matchAny("waterway", "riverbank"))), - MultiExpression.entry("lake", FALSE), MultiExpression.entry("ocean", FALSE), + MultiExpression.entry("river", matchAny("water", "river")), MultiExpression.entry("lake", FALSE), + MultiExpression.entry("ocean", FALSE), MultiExpression.entry("swimming_pool", matchAny("leisure", "swimming_pool")))); } } @@ -192,7 +188,7 @@ public class OpenMapTilesSchema { * field applied. Waterways do not have a subclass field. * * Generated from - * waterway.yaml + * waterway.yaml */ public interface Waterway extends Layer { double BUFFER_SIZE = 4.0; @@ -277,7 +273,7 @@ public class OpenMapTilesSchema { * layer is to style wood (class=wood) and grass (class=grass) areas. * * Generated from landcover.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/landcover/landcover.yaml">landcover.yaml */ public interface Landcover extends Layer { double BUFFER_SIZE = 4.0; @@ -321,6 +317,7 @@ public class OpenMapTilesSchema { *
  • "bog" *
  • "dune" *
  • "scrub" + *
  • "shrubbery" *
  • "farm" *
  • "farmland" *
  • "fell" @@ -372,6 +369,7 @@ public class OpenMapTilesSchema { public static final String SUBCLASS_BOG = "bog"; public static final String SUBCLASS_DUNE = "dune"; 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_FARMLAND = "farmland"; 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_WOOD = "wood"; public static final Set SUBCLASS_VALUES = - Set.of("allotments", "bare_rock", "beach", "bog", "dune", "scrub", "farm", "farmland", "fell", "forest", - "garden", "glacier", "grass", "grassland", "golf_course", "heath", "mangrove", "marsh", "meadow", "orchard", - "park", "plant_nursery", "recreation_ground", "reedbed", "saltern", "saltmarsh", "sand", "scree", "swamp", - "tidalflat", "tundra", "village_green", "vineyard", "wet_meadow", "wetland", "wood"); + Set.of("allotments", "bare_rock", "beach", "bog", "dune", "scrub", "shrubbery", "farm", "farmland", "fell", + "forest", "garden", "glacier", "grass", "grassland", "golf_course", "heath", "mangrove", "marsh", "meadow", + "orchard", "park", "plant_nursery", "recreation_ground", "reedbed", "saltern", "saltmarsh", "sand", "scree", + "swamp", "tidalflat", "tundra", "village_green", "vineyard", "wet_meadow", "wetland", "wood"); } /** Complex mappings to generate attribute values from OSM element tags in the landcover layer. */ final class FieldMappings { @@ -419,8 +417,8 @@ public class OpenMapTilesSchema { MultiExpression.entry("wood", matchAny("subclass", "wood", "forest")), MultiExpression.entry("rock", matchAny("subclass", "bare_rock", "scree")), MultiExpression.entry("grass", - matchAny("subclass", "fell", "grassland", "heath", "scrub", "tundra", "grass", "meadow", "allotments", - "park", "village_green", "recreation_ground", "garden", "golf_course")), + matchAny("subclass", "fell", "grassland", "heath", "scrub", "shrubbery", "tundra", "grass", "meadow", + "allotments", "park", "village_green", "recreation_ground", "garden", "golf_course")), MultiExpression.entry("wetland", matchAny("subclass", "wetland", "bog", "swamp", "wet_meadow", "marsh", "reedbed", "saltern", "tidalflat", "saltmarsh", "mangrove")), @@ -432,7 +430,7 @@ public class OpenMapTilesSchema { * residential (urban) areas and at higher zoom levels mostly OSM landuse tags. * * Generated from - * landuse.yaml + * landuse.yaml */ public interface Landuse extends Layer { double BUFFER_SIZE = 4.0; @@ -481,6 +479,7 @@ public class OpenMapTilesSchema { *
  • "quarter" *
  • "neighbourhood" *
  • "dam" + *
  • "quarry" * */ 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_NEIGHBOURHOOD = "neighbourhood"; public static final String CLASS_DAM = "dam"; + public static final String CLASS_QUARRY = "quarry"; public static final Set CLASS_VALUES = Set.of("railway", "cemetery", "military", "residential", "commercial", "industrial", "garages", "retail", "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. */ final class FieldMappings { @@ -526,7 +526,7 @@ public class OpenMapTilesSchema { * Natural peaks * * Generated from mountain_peak.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/mountain_peak/mountain_peak.yaml">mountain_peak.yaml */ public interface MountainPeak extends Layer { double BUFFER_SIZE = 64.0; @@ -601,7 +601,7 @@ public class OpenMapTilesSchema { * leisure=nature_reserve. * * Generated from - * park.yaml + * park.yaml */ public interface Park extends Layer { double BUFFER_SIZE = 4.0; @@ -661,7 +661,7 @@ public class OpenMapTilesSchema { * but for most styles it makes sense to just style admin_level=2 and admin_level=4. * * Generated from - * boundary.yaml + * boundary.yaml */ public interface Boundary extends Layer { double BUFFER_SIZE = 4.0; @@ -762,7 +762,7 @@ public class OpenMapTilesSchema { * in the aeroway layer. * * Generated from - * aeroway.yaml + * aeroway.yaml */ public interface Aeroway extends Layer { double BUFFER_SIZE = 4.0; @@ -822,7 +822,7 @@ public class OpenMapTilesSchema { * features like plazas. * * Generated from transportation.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/transportation/transportation.yaml">transportation.yaml */ public interface Transportation extends Layer { double BUFFER_SIZE = 4.0; @@ -858,6 +858,8 @@ public class OpenMapTilesSchema { *
  • track *
  • raceway *
  • busway + *
  • bus_guideway + *
  • ferry *
  • motorway_construction *
  • trunk_construction *
  • primary_construction @@ -897,6 +899,7 @@ public class OpenMapTilesSchema { *
  • "bridleway" *
  • "corridor" *
  • "platform" + *
  • "ferry (DEPRECATED - use class)" * */ 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_RACEWAY = "raceway"; 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_TRUNK_CONSTRUCTION = "trunk_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_TRACK_CONSTRUCTION = "track_construction"; public static final String CLASS_RACEWAY_CONSTRUCTION = "raceway_construction"; - public static final Set CLASS_VALUES = Set.of("motorway", "trunk", "primary", "secondary", "tertiary", - "minor", "path", "service", "track", "raceway", "busway", "motorway_construction", "trunk_construction", - "primary_construction", "secondary_construction", "tertiary_construction", "minor_construction", - "path_construction", "service_construction", "track_construction", "raceway_construction"); + public static final Set CLASS_VALUES = + Set.of("motorway", "trunk", "primary", "secondary", "tertiary", "minor", "path", "service", "track", "raceway", + "busway", "bus_guideway", "ferry", "motorway_construction", "trunk_construction", "primary_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_NARROW_GAUGE = "narrow_gauge"; 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_CORRIDOR = "corridor"; public static final String SUBCLASS_PLATFORM = "platform"; + public static final String SUBCLASS_FERRY = "ferry"; public static final Set SUBCLASS_VALUES = 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_TUNNEL = "tunnel"; 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. */ final class FieldMappings { - public static final MultiExpression Class = - MultiExpression.of(List.of(MultiExpression.entry("motorway", matchAny("highway", "motorway", "motorway_link")), - MultiExpression.entry("trunk", matchAny("highway", "trunk", "trunk_link")), - MultiExpression.entry("primary", matchAny("highway", "primary", "primary_link")), - MultiExpression.entry("secondary", matchAny("highway", "secondary", "secondary_link")), - MultiExpression.entry("tertiary", matchAny("highway", "tertiary", "tertiary_link")), - MultiExpression.entry("minor", matchAny("highway", "unclassified", "residential", "living_street", "road")), - MultiExpression.entry("path", - or(matchAny("highway", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"), - matchAny("public_transport", "platform"))), - MultiExpression.entry("service", matchAny("highway", "service")), - MultiExpression.entry("track", matchAny("highway", "track")), - MultiExpression.entry("raceway", matchAny("highway", "raceway")), - MultiExpression.entry("busway", matchAny("highway", "busway")), - MultiExpression.entry("motorway_construction", - and(matchAny("highway", "construction"), matchAny("construction", "motorway", "motorway_link"))), - MultiExpression.entry("trunk_construction", - and(matchAny("highway", "construction"), matchAny("construction", "trunk", "trunk_link"))), - MultiExpression.entry("primary_construction", - and(matchAny("highway", "construction"), matchAny("construction", "primary", "primary_link"))), - MultiExpression.entry("secondary_construction", - and(matchAny("highway", "construction"), matchAny("construction", "secondary", "secondary_link"))), - MultiExpression.entry("tertiary_construction", - and(matchAny("highway", "construction"), matchAny("construction", "tertiary", "tertiary_link"))), - MultiExpression.entry( - "minor_construction", - and(matchAny("highway", "construction"), - matchAny("construction", "", "unclassified", "residential", "living_street", "road"))), - MultiExpression.entry("path_construction", and(matchAny("highway", "construction"), + public static final MultiExpression Class = MultiExpression.of(List.of( + MultiExpression.entry("motorway", matchAny("highway", "motorway", "motorway_link")), + MultiExpression.entry("trunk", matchAny("highway", "trunk", "trunk_link")), + MultiExpression.entry("primary", matchAny("highway", "primary", "primary_link")), + MultiExpression.entry("secondary", matchAny("highway", "secondary", "secondary_link")), + MultiExpression.entry("tertiary", matchAny("highway", "tertiary", "tertiary_link")), + MultiExpression.entry("minor", matchAny("highway", "unclassified", "residential", "living_street", "road")), + MultiExpression.entry("path", + or(matchAny("highway", "pedestrian", "path", "footway", "cycleway", "steps", "bridleway", "corridor"), + matchAny("public_transport", "platform"))), + MultiExpression.entry("service", matchAny("highway", "service")), + MultiExpression.entry("track", matchAny("highway", "track")), + MultiExpression.entry("raceway", matchAny("highway", "raceway")), + MultiExpression.entry("busway", matchAny("highway", "busway")), + MultiExpression.entry("bus_guideway", matchAny("highway", "bus_guideway")), + MultiExpression.entry("ferry", matchAny("highway", "shipway")), + MultiExpression.entry("motorway_construction", + and(matchAny("highway", "construction"), matchAny("construction", "motorway", "motorway_link"))), + MultiExpression.entry("trunk_construction", + and(matchAny("highway", "construction"), matchAny("construction", "trunk", "trunk_link"))), + MultiExpression.entry("primary_construction", + and(matchAny("highway", "construction"), matchAny("construction", "primary", "primary_link"))), + MultiExpression.entry("secondary_construction", + and(matchAny("highway", "construction"), matchAny("construction", "secondary", "secondary_link"))), + MultiExpression.entry("tertiary_construction", + and(matchAny("highway", "construction"), matchAny("construction", "tertiary", "tertiary_link"))), + MultiExpression.entry("minor_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"), matchAny("public_transport", "platform")))), - MultiExpression.entry("service_construction", - and(matchAny("highway", "construction"), matchAny("construction", "service"))), - MultiExpression.entry("track_construction", - and(matchAny("highway", "construction"), matchAny("construction", "track"))), - MultiExpression.entry("raceway_construction", - and(matchAny("highway", "construction"), matchAny("construction", "raceway"))))); + MultiExpression.entry("service_construction", + and(matchAny("highway", "construction"), matchAny("construction", "service"))), + MultiExpression.entry("track_construction", + and(matchAny("highway", "construction"), matchAny("construction", "track"))), + MultiExpression.entry("raceway_construction", + and(matchAny("highway", "construction"), matchAny("construction", "raceway"))))); } } /** @@ -1157,7 +1166,7 @@ public class OpenMapTilesSchema { * location:underground are excluded. * * Generated from - * building.yaml + * building.yaml */ public interface Building extends Layer { double BUFFER_SIZE = 4.0; @@ -1199,7 +1208,7 @@ public class OpenMapTilesSchema { * from OSM water bodies. Only the most important lakes contain labels. * * Generated from water_name.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/water_name/water_name.yaml">water_name.yaml */ public interface WaterName extends Layer { double BUFFER_SIZE = 256.0; @@ -1264,7 +1273,7 @@ public class OpenMapTilesSchema { * while for other roads you should use name. * * Generated from transportation_name.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/transportation_name/transportation_name.yaml">transportation_name.yaml */ public interface TransportationName extends Layer { double BUFFER_SIZE = 8.0; @@ -1481,7 +1490,7 @@ public class OpenMapTilesSchema { * create a text hierarchy. * * Generated from - * place.yaml + * place.yaml */ public interface Place extends Layer { double BUFFER_SIZE = 256.0; @@ -1509,7 +1518,10 @@ public class OpenMapTilesSchema { * allowed values: *
      *
    • 2 + *
    • 3 *
    • 4 + *
    • 5 + *
    • 6 *
    */ public static final String CAPITAL = "capital"; @@ -1586,7 +1598,7 @@ public class OpenMapTilesSchema { * housenumber. * * Generated from housenumber.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/housenumber/housenumber.yaml">housenumber.yaml */ public interface Housenumber extends Layer { double BUFFER_SIZE = 8.0; @@ -1615,7 +1627,7 @@ public class OpenMapTilesSchema { * Points of interests containing a of a variety * of OpenStreetMap tags. Mostly contains amenities, sport, shop and tourist POIs. * - * Generated from poi.yaml + * Generated from poi.yaml */ public interface Poi extends Layer { 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", "dormitory")), 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("school", matchAny("subclass", "school", "kindergarten")), MultiExpression.entry("alcohol_shop", matchAny("subclass", "alcohol", "beverages", "wine")), @@ -1834,7 +1846,7 @@ public class OpenMapTilesSchema { * Aerodrome labels * * Generated from aerodrome_label.yaml + * "https://github.com/openmaptiles/openmaptiles/blob/v3.14/layers/aerodrome_label/aerodrome_label.yaml">aerodrome_label.yaml */ public interface AerodromeLabel extends Layer { double BUFFER_SIZE = 64.0; diff --git a/src/main/java/org/openmaptiles/generated/Tables.java b/src/main/java/org/openmaptiles/generated/Tables.java index 14fc996..a29e15e 100644 --- a/src/main/java/org/openmaptiles/generated/Tables.java +++ b/src/main/java/org/openmaptiles/generated/Tables.java @@ -50,7 +50,7 @@ import java.util.Map; /** * OSM element parsers generated from the imposm3 table definitions - * in the OpenMapTiles vector tile + * in the OpenMapTiles vector tile * schema. * * 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". */ - public static final Expression MAPPING = - and(or(matchAny("landuse", "reservoir", "basin", "salt_pond"), matchAny("leisure", "swimming_pool"), - matchAny("natural", "water", "bay", "spring"), matchAny("waterway", "riverbank", "dock"), - matchAny("water", "river")), not(matchAny("covered", "yes")), matchType("polygon")); + public static final Expression MAPPING = and( + or(matchAny("landuse", "reservoir", "basin", "salt_pond"), matchAny("leisure", "swimming_pool"), + matchAny("natural", "water", "bay", "spring"), matchAny("waterway", "dock"), matchAny("water", "river")), + not(matchAny("covered", "yes")), matchType("polygon")); /** * 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( matchAny("landuse", "allotments", "farm", "farmland", "orchard", "plant_nursery", "vineyard", "grass", "grassland", "meadow", "forest", "village_green", "recreation_ground"), - matchAny("natural", "wood", "wetland", "fell", "grassland", "heath", "scrub", "tundra", "glacier", "bare_rock", - "scree", "beach", "sand", "dune"), + matchAny("natural", "wood", "wetland", "fell", "grassland", "heath", "scrub", "shrubbery", "tundra", "glacier", + "bare_rock", "scree", "beach", "sand", "dune"), matchAny("leisure", "park", "garden", "golf_course"), matchAny("wetland", "bog", "swamp", "wet_meadow", "marsh", "reedbed", "saltern", "tidalflat", "saltmarsh", "mangrove")), matchType("polygon")); @@ -178,8 +178,8 @@ public class Tables { /** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */ public static final Expression MAPPING = and(or( - matchAny("landuse", "railway", "cemetery", "military", "residential", "commercial", "industrial", "garages", - "retail"), + matchAny("landuse", "railway", "cemetery", "military", "quarry", "residential", "commercial", "industrial", + "garages", "retail"), matchAny("amenity", "bus_station", "school", "university", "kindergarten", "college", "library", "hospital", "grave_yard"), 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", "secondary_link", "tertiary", "tertiary_link", "unclassified", "residential", "living_street", "road", "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("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. */ 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 information, @Override String uicRef, @Override String religion, @Override long level, - @Override boolean indoor, @Override long layer, @Override String sport, @Override String operator, - @Override String network, @Override SourceFeature source) implements Row, WithName, WithNameEn, WithNameDe, - WithSubclass, WithMappingKey, WithStation, WithFunicular, WithInformation, WithUicRef, WithReligion, WithLevel, - WithIndoor, WithLayer, WithSport, WithOperator, WithNetwork, WithSource { + @Override String information, @Override String uicRef, @Override String ref, @Override String religion, + @Override long level, @Override boolean indoor, @Override long layer, @Override String sport, + @Override String operator, @Override String network, @Override String brand, @Override SourceFeature source) + implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular, + WithInformation, WithUicRef, WithRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithOperator, + WithNetwork, WithBrand, WithSource { public OsmPoiPoint(SourceFeature source, String mappingKey) { this(source.getString("name"), source.getString("name:en"), source.getString("name:de"), source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"), - source.getString("information"), source.getString("uic_ref"), source.getString("religion"), - source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), source.getString("sport"), - source.getString("operator"), source.getString("network"), source); + source.getString("information"), source.getString("uic_ref"), source.getString("ref"), + source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), + 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". */ @@ -709,8 +711,8 @@ public class Tables { "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", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", - "parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", - "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", + "parking", "pharmacy", "place_of_worship", "police", "parcel_locker", "post_box", "post_office", "prison", + "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"), matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", "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. */ 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 information, @Override String uicRef, @Override String religion, @Override long level, - @Override boolean indoor, @Override long layer, @Override String sport, @Override String operator, - @Override String network, @Override SourceFeature source) implements Row, WithName, WithNameEn, WithNameDe, - WithSubclass, WithMappingKey, WithStation, WithFunicular, WithInformation, WithUicRef, WithReligion, WithLevel, - WithIndoor, WithLayer, WithSport, WithOperator, WithNetwork, WithSource { + @Override String information, @Override String uicRef, @Override String ref, @Override String religion, + @Override long level, @Override boolean indoor, @Override long layer, @Override String sport, + @Override String operator, @Override String network, @Override String brand, @Override SourceFeature source) + implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular, + WithInformation, WithUicRef, WithRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithOperator, + WithNetwork, WithBrand, WithSource { public OsmPoiPolygon(SourceFeature source, String mappingKey) { this(source.getString("name"), source.getString("name:en"), source.getString("name:de"), source.getString(mappingKey), mappingKey, source.getString("station"), source.getString("funicular"), - source.getString("information"), source.getString("uic_ref"), source.getString("religion"), - source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), source.getString("sport"), - source.getString("operator"), source.getString("network"), source); + source.getString("information"), source.getString("uic_ref"), source.getString("ref"), + source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"), source.getLong("layer"), + 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". */ @@ -777,8 +781,8 @@ public class Tables { "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", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", - "parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", - "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", + "parking", "pharmacy", "place_of_worship", "police", "parcel_locker", "post_box", "post_office", "prison", + "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket"), matchAny("barrier", "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", "toll_booth"), @@ -886,6 +890,11 @@ public class Tables { String boundary(); } + /** Rows with a String brand attribute. */ + public interface WithBrand { + String brand(); + } + /** Rows with a String building attribute. */ public interface WithBuilding { String building(); diff --git a/src/main/java/org/openmaptiles/layers/Landcover.java b/src/main/java/org/openmaptiles/layers/Landcover.java index d581822..0f23d55 100644 --- a/src/main/java/org/openmaptiles/layers/Landcover.java +++ b/src/main/java/org/openmaptiles/layers/Landcover.java @@ -158,14 +158,14 @@ public class Landcover implements } else { // don't merge result.add(item); } - } else if (zoom == 9) { + } else if (zoom >= 8 && zoom <= 9) { if (WOOD_OR_FOREST.contains(subclass)) { attrs.put(tempGroupKey, numPoints < 300 ? "<300" : ">300"); toMerge.add(item); } else { // don't merge result.add(item); } - } else { // zoom between 7 and 8 + } else { // zoom 7 toMerge.add(item); } } else { diff --git a/src/main/java/org/openmaptiles/layers/Landuse.java b/src/main/java/org/openmaptiles/layers/Landuse.java index 101281a..a3799c1 100644 --- a/src/main/java/org/openmaptiles/layers/Landuse.java +++ b/src/main/java/org/openmaptiles/layers/Landuse.java @@ -39,14 +39,19 @@ import static org.openmaptiles.util.Utils.coalesce; import static org.openmaptiles.util.Utils.nullIfEmpty; 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.geo.GeometryException; import com.onthegomap.planetiler.reader.SourceFeature; import com.onthegomap.planetiler.stats.Stats; import com.onthegomap.planetiler.util.Parse; import com.onthegomap.planetiler.util.Translations; import com.onthegomap.planetiler.util.ZoomFunction; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.openmaptiles.OpenMapTilesProfile; import org.openmaptiles.generated.OpenMapTilesSchema; import org.openmaptiles.generated.Tables; @@ -61,6 +66,7 @@ import org.openmaptiles.generated.Tables; public class Landuse implements OpenMapTilesSchema.Landuse, OpenMapTilesProfile.NaturalEarthProcessor, + OpenMapTilesProfile.FeaturePostProcessor, Tables.OsmLandusePolygon.Handler { private static final ZoomFunction MIN_PIXEL_SIZE_THRESHOLDS = ZoomFunction.fromMaxZoomThresholds(Map.of( @@ -103,10 +109,36 @@ public class Landuse implements if ("grave_yard".equals(clazz)) { clazz = FieldValues.CLASS_CEMETERY; } - features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE) + var feature = features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE) .setAttr(Fields.CLASS, clazz) - .setMinPixelSizeOverrides(MIN_PIXEL_SIZE_THRESHOLDS) .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 postProcess(int zoom, + List items) throws GeometryException { + if (zoom < 6 || zoom > 12) { + return items; + } else { + // merging only merges polygons with class "residential" for z6-z12 + Map> splitLists = + items.stream().collect(Collectors.partitioningBy( + i -> FieldValues.CLASS_RESIDENTIAL.equals(i.attrs().get(Fields.CLASS))) + ); + List result = splitLists.get(Boolean.FALSE); + List toMerge = splitLists.get(Boolean.TRUE); + var merged = FeatureMerge.mergeNearbyPolygons(toMerge, 1, 1, 0.1, 0.1); + result.addAll(merged); + return result; } } } diff --git a/src/main/java/org/openmaptiles/layers/Place.java b/src/main/java/org/openmaptiles/layers/Place.java index 072f144..9df1cb9 100644 --- a/src/main/java/org/openmaptiles/layers/Place.java +++ b/src/main/java/org/openmaptiles/layers/Place.java @@ -184,7 +184,7 @@ public class Place implements feature.getString("name"), feature.getString("wikidataid"), (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) .map(s -> s.toLowerCase(Locale.ROOT)) .collect(Collectors.toSet()) @@ -356,10 +356,14 @@ public class Place implements feature.setPointLabelGridLimit(LABEL_GRID_LIMITS); } - if ("2".equals(capital) || "yes".equals(capital)) { - feature.setAttr(Fields.CAPITAL, 2); - } else if ("4".equals(capital)) { - feature.setAttr(Fields.CAPITAL, 4); + if (capital != null) { // with Java 18, we can handle that with "case null", see https://openjdk.org/jeps/420) + switch (capital) { + case "2", "yes" -> feature.setAttr(Fields.CAPITAL, 2); + 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); + } } } diff --git a/src/main/java/org/openmaptiles/layers/Poi.java b/src/main/java/org/openmaptiles/layers/Poi.java index b73febe..b12b830 100644 --- a/src/main/java/org/openmaptiles/layers/Poi.java +++ b/src/main/java/org/openmaptiles/layers/Poi.java @@ -136,7 +136,7 @@ public class Poi implements setupPoiFeature(element, features.centroidIfConvex(LAYER_NAME)); } - private void setupPoiFeature( + private void setupPoiFeature( T element, FeatureCollector.Feature output) { String rawSubclass = element.subclass(); 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) { case "information" -> nullIfEmpty(element.information()); case "place_of_worship" -> nullIfEmpty(element.religion()); diff --git a/src/main/java/org/openmaptiles/layers/Transportation.java b/src/main/java/org/openmaptiles/layers/Transportation.java index dd5e161..22ca920 100644 --- a/src/main/java/org/openmaptiles/layers/Transportation.java +++ b/src/main/java/org/openmaptiles/layers/Transportation.java @@ -174,6 +174,7 @@ public class Transportation implements entry(FieldValues.CLASS_RACEWAY, 12), entry(FieldValues.CLASS_TERTIARY, 11), entry(FieldValues.CLASS_BUSWAY, 11), + entry(FieldValues.CLASS_BUS_GUIDEWAY, 11), entry(FieldValues.CLASS_SECONDARY, 9), entry(FieldValues.CLASS_PRIMARY, 7), entry(FieldValues.CLASS_TRUNK, 5), diff --git a/src/main/java/org/openmaptiles/layers/Water.java b/src/main/java/org/openmaptiles/layers/Water.java index 0b040a2..8a3d9a9 100644 --- a/src/main/java/org/openmaptiles/layers/Water.java +++ b/src/main/java/org/openmaptiles/layers/Water.java @@ -112,8 +112,7 @@ public class Water implements @Override public void process(Tables.OsmWaterPolygon element, FeatureCollector features) { if (!"bay".equals(element.natural())) { - String clazz = "riverbank".equals(element.waterway()) ? FieldValues.CLASS_RIVER : - classMapping.getOrElse(element.source(), FieldValues.CLASS_LAKE); + String clazz = classMapping.getOrElse(element.source(), FieldValues.CLASS_LAKE); features.polygon(LAYER_NAME) .setBufferPixels(BUFFER_SIZE) .setMinPixelSizeBelowZoom(11, 2) diff --git a/src/test/java/org/openmaptiles/layers/LandcoverTest.java b/src/test/java/org/openmaptiles/layers/LandcoverTest.java index 6dc07f0..f00cf1b 100644 --- a/src/test/java/org/openmaptiles/layers/LandcoverTest.java +++ b/src/test/java/org/openmaptiles/layers/LandcoverTest.java @@ -171,17 +171,17 @@ class LandcoverTest extends AbstractLayerTest { } @Test - void testMergeNonForestsBelowZ9() throws GeometryException { + void testMergeNonForestsBelowZ8() throws GeometryException { Map map = Map.of("subclass", "dune"); assertMerges(List.of(map, map), List.of( feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) - ), 9); + ), 8); assertMerges(List.of(map), List.of( feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) - ), 8); + ), 7); assertMerges(List.of(map, map), List.of( feature(rectangle(10, 20), Map.of("_numpoints", 48, "subclass", "dune")), feature(rectangle(12, 18), Map.of("_numpoints", 301, "subclass", "dune")) diff --git a/src/test/java/org/openmaptiles/layers/LanduseTest.java b/src/test/java/org/openmaptiles/layers/LanduseTest.java index 57b9999..b1edf34 100644 --- a/src/test/java/org/openmaptiles/layers/LanduseTest.java +++ b/src/test/java/org/openmaptiles/layers/LanduseTest.java @@ -2,10 +2,13 @@ package org.openmaptiles.layers; import static com.onthegomap.planetiler.TestUtils.rectangle; +import com.onthegomap.planetiler.VectorTile; import com.onthegomap.planetiler.geo.GeoUtils; +import com.onthegomap.planetiler.geo.GeometryException; import com.onthegomap.planetiler.reader.SimpleFeature; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.openmaptiles.OpenMapTilesProfile; @@ -86,9 +89,43 @@ class LanduseTest extends AbstractLayerTest { "class", "residential", "_minzoom", 6, "_maxzoom", 14, - "_minpixelsize", 2d + "_minpixelsize", 0.1d )), process(polygonFeature(Map.of( "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() + ); + } } diff --git a/src/test/java/org/openmaptiles/layers/PlaceTest.java b/src/test/java/org/openmaptiles/layers/PlaceTest.java index c8d7a64..d12a6e4 100644 --- a/src/test/java/org/openmaptiles/layers/PlaceTest.java +++ b/src/test/java/org/openmaptiles/layers/PlaceTest.java @@ -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", "" + )), 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 void testCityWithoutNaturalEarthMatch() { diff --git a/src/test/java/org/openmaptiles/layers/PoiTest.java b/src/test/java/org/openmaptiles/layers/PoiTest.java index dd556af..11a9a70 100644 --- a/src/test/java/org/openmaptiles/layers/PoiTest.java +++ b/src/test/java/org/openmaptiles/layers/PoiTest.java @@ -236,4 +236,42 @@ class PoiTest extends AbstractLayerTest { "network", "ATM name" )))); } + + @Test + void testParcelLocker() { + List> 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> 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" + )))); + } } diff --git a/src/test/java/org/openmaptiles/layers/TransportationTest.java b/src/test/java/org/openmaptiles/layers/TransportationTest.java index 31cafa5..1160df4 100644 --- a/src/test/java/org/openmaptiles/layers/TransportationTest.java +++ b/src/test/java/org/openmaptiles/layers/TransportationTest.java @@ -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); { diff --git a/src/test/java/org/openmaptiles/layers/WaterTest.java b/src/test/java/org/openmaptiles/layers/WaterTest.java index d396c68..ee900dc 100644 --- a/src/test/java/org/openmaptiles/layers/WaterTest.java +++ b/src/test/java/org/openmaptiles/layers/WaterTest.java @@ -144,20 +144,27 @@ class WaterTest extends AbstractLayerTest { "natural", "water", "covered", "yes" )))); - assertFeatures(14, List.of(Map.of( - "class", "river", - "brunnel", "bridge", - "intermittent", 1, + assertFeatures(14, List.of( + Map.of( + "class", "dock", + "intermittent", 1, - "_layer", "water", - "_type", "polygon", - "_minzoom", 6, - "_maxzoom", 14 - )), process(polygonFeature(Map.of( - "waterway", "riverbank", - "bridge", "1", - "intermittent", "1" - )))); + "_layer", "water", + "_type", "polygon", + "_minzoom", 6, + "_maxzoom", 14), + Map.of( + "class", "harbor", + "subclass", "dock", + + "_layer", "poi", + "_type", "point", + "_minzoom", 14, + "_maxzoom", 14 + )), process(polygonFeature(Map.of( + "waterway", "dock", + "intermittent", "1" + )))); assertFeatures(11, List.of(Map.of( "class", "lake", "brunnel", "", @@ -175,14 +182,19 @@ class WaterTest extends AbstractLayerTest { } @Test - void testRiverbank() { - assertFeatures(11, List.of(Map.of( - "class", "river", - "_layer", "water", - "_type", "polygon" - )), process(polygonFeature(Map.of( - "waterway", "riverbank" - )))); + void testDock() { + assertFeatures(11, List.of( + Map.of( + "class", "dock", + "_layer", "water", + "_type", "polygon"), + Map.of( + "class", "harbor", + "_layer", "poi", + "_type", "point" + )), process(polygonFeature(Map.of( + "waterway", "dock" + )))); } @Test