Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade basemap profile to OpenMapTiles v3.13.1 #227

Merged
merged 7 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ download regularly-updated tilesets.
using [JTS geometry utilities](https://github.com/locationtech/jts)
- Merge nearby lines or polygons with the same tags before emitting vector tiles
- Automatically fixes self-intersecting polygons
- Built-in basemap profile based on [OpenMapTiles](https://openmaptiles.org/) v3.13
- Built-in basemap profile based on [OpenMapTiles](https://openmaptiles.org/) v3.13.1
- Optionally download additional name translations for elements from Wikidata
- Export real-time stats to a [prometheus push gateway](https://github.com/prometheus/pushgateway) using
`--pushgateway=http://user:password@ip` argument (and a [grafana dashboard](grafana.json) for viewing)
Expand Down
9 changes: 6 additions & 3 deletions planetiler-basemap/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Planetiler Basemap Profile

This basemap profile is based on [OpenMapTiles](https://github.com/openmaptiles/openmaptiles) v3.13.
This basemap profile is based on [OpenMapTiles](https://github.com/openmaptiles/openmaptiles) v3.13.1.
See [README.md](../README.md) in the parent directory for instructions on how to run.

## Differences from OpenMapTiles
Expand All @@ -11,6 +11,9 @@ See [README.md](../README.md) in the parent directory for instructions on how to
lines, to revert this behavior set `--transportation-name-brunnel=true`
- `rank` field on `mountain_peak` linestrings only has 3 levels (1: has wikipedia page and name, 2: has name, 3: no name
or wikipedia page or name)
- `rank` field on `mountain_peak` linestrings only has 3 levels (1: has wikipedia page and name, 2: has name, 3: no name
or wikipedia page or name)
- `id` field on `water` polygons is only populated for openstreetmap lakes, not natural earth lakes at lower zoom levels

## Code Layout

Expand Down Expand Up @@ -41,15 +44,15 @@ To run `Generate.java`, use [scripts/regenerate-openmaptiles.sh](../scripts/rege
OpenMapTiles release tag:

```bash
./scripts/regenerate-openmaptiles.sh v3.13
./scripts/regenerate-openmaptiles.sh v3.13.1
```

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 https://raw.githubusercontent.com/openmaptiles/openmaptiles/
./scripts/regenerate-openmaptiles.sh v3.13.1 https://raw.githubusercontent.com/openmaptiles/openmaptiles/
```

## License and Attribution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static JsonNode parseYaml(String string) {
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");
String tag = arguments.getString("tag", "openmaptiles tag to use", "v3.13.1");
String baseUrl = arguments.getString("base-url", "the url used to download the openmaptiles.yml",
"https://raw.githubusercontent.com/openmaptiles/openmaptiles/");
String base = baseUrl + tag + "/";
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

/**
* 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/openmaptiles.yaml">OpenMapTiles vector tile
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.13.1/openmaptiles.yaml">OpenMapTiles vector tile
* schema</a>.
*
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the columns
Expand Down Expand Up @@ -94,15 +94,15 @@ public record RowHandlerAndClass<T extends Row> (
) {}
/** An OSM element that would appear in the {@code osm_water_polygon} table generated by imposm3. */
public record OsmWaterPolygon(@Override String name, @Override String nameEn, @Override String nameDe,
@Override String natural, @Override String landuse, @Override String waterway, @Override String water,
@Override boolean isIntermittent, @Override boolean isTunnel, @Override boolean isBridge,
@Override String natural, @Override String landuse, @Override String waterway, @Override String leisure,
@Override String water, @Override boolean isIntermittent, @Override boolean isTunnel, @Override boolean isBridge,
@Override SourceFeature source) implements Row, WithName, WithNameEn, WithNameDe, WithNatural, WithLanduse,
WithWaterway, WithWater, WithIsIntermittent, WithIsTunnel, WithIsBridge, WithSource {
WithWaterway, WithLeisure, WithWater, WithIsIntermittent, WithIsTunnel, WithIsBridge, WithSource {
public OsmWaterPolygon(SourceFeature source, String mappingKey) {
this(source.getString("name"), source.getString("name:en"), source.getString("name:de"),
source.getString("natural"), source.getString("landuse"), source.getString("waterway"),
source.getString("water"), source.getBoolean("intermittent"), source.getBoolean("tunnel"),
source.getBoolean("bridge"), source);
source.getString("leisure"), source.getString("water"), source.getBoolean("intermittent"),
source.getBoolean("tunnel"), source.getBoolean("bridge"), source);
}

/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
Expand Down Expand Up @@ -405,8 +405,8 @@ public OsmAerialwayLinestring(SourceFeature source, String mappingKey) {
}

/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
public static final Expression MAPPING =
and(matchAny("aerialway", "cable_car", "gondola"), matchType("linestring"));
public static final Expression MAPPING = and(matchAny("aerialway", "chair_lift", "drag_lift", "platter", "t-bar",
"gondola", "cable_car", "j-bar", "mixed_lift"), matchType("linestring"));

/**
* Interface for layer implementations to extend to subscribe to OSM elements filtered and parsed as
Expand Down Expand Up @@ -691,20 +691,21 @@ public interface Handler {
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 SourceFeature source)
implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular,
WithInformation, WithUicRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithSource {
@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 {
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);
source.getString("operator"), source.getString("network"), source);
}

/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
public static final Expression MAPPING = and(or(matchAny("aerialway", "station"),
matchAny("amenity", "arts_centre", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten",
matchAny("amenity", "arts_centre", "atm", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten",
"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",
Expand Down Expand Up @@ -758,20 +759,21 @@ public interface Handler {
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 SourceFeature source)
implements Row, WithName, WithNameEn, WithNameDe, WithSubclass, WithMappingKey, WithStation, WithFunicular,
WithInformation, WithUicRef, WithReligion, WithLevel, WithIndoor, WithLayer, WithSport, WithSource {
@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 {
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);
source.getString("operator"), source.getString("network"), source);
}

/** Imposm3 "mapping" to filter OSM elements that should appear in this "table". */
public static final Expression MAPPING = and(or(matchAny("aerialway", "station"),
matchAny("amenity", "arts_centre", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten",
matchAny("amenity", "arts_centre", "atm", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten",
"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",
Expand Down Expand Up @@ -1144,6 +1146,11 @@ public interface WithNetwork {
String network();
}

/** Rows with a String operator attribute. */
public interface WithOperator {
String operator();
}

/** Rows with a String osmcSymbol attribute. */
public interface WithOsmcSymbol {
String osmcSymbol();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

import com.carrotsearch.hppc.LongIntMap;
import com.onthegomap.planetiler.FeatureCollector;
import com.onthegomap.planetiler.ForwardingProfile;
import com.onthegomap.planetiler.VectorTile;
import com.onthegomap.planetiler.basemap.BasemapProfile;
import com.onthegomap.planetiler.basemap.generated.OpenMapTilesSchema;
import com.onthegomap.planetiler.basemap.generated.Tables;
import com.onthegomap.planetiler.basemap.util.LanguageUtils;
Expand All @@ -68,7 +68,7 @@ public class Poi implements
OpenMapTilesSchema.Poi,
Tables.OsmPoiPoint.Handler,
Tables.OsmPoiPolygon.Handler,
BasemapProfile.FeaturePostProcessor {
ForwardingProfile.FeaturePostProcessor {

/*
* process() creates the raw POI feature from OSM elements and postProcess()
Expand Down Expand Up @@ -136,7 +136,7 @@ public void process(Tables.OsmPoiPolygon element, FeatureCollector features) {
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> 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> void setupPoiFeature(
T element, FeatureCollector.Feature output) {
String rawSubclass = element.subclass();
if ("station".equals(rawSubclass) && "subway".equals(element.station())) {
Expand All @@ -146,6 +146,16 @@ private <T extends Tables.WithSubclass & Tables.WithStation & Tables.WithFunicul
rawSubclass = "halt";
}

// ATM names fall back to operator, or else network
String name = element.name();
var tags = element.source().tags();
if ("atm".equals(rawSubclass) && nullOrEmpty(name)) {
name = coalesce(nullIfEmpty(element.operator()), nullIfEmpty(element.network()));
if (name != null) {
tags.put("name", name);
}
}

String subclass = switch (rawSubclass) {
case "information" -> nullIfEmpty(element.information());
case "place_of_worship" -> nullIfEmpty(element.religion());
Expand All @@ -154,7 +164,7 @@ private <T extends Tables.WithSubclass & Tables.WithStation & Tables.WithFunicul
};
String poiClass = poiClass(rawSubclass, element.mappingKey());
int poiClassRank = poiClassRank(poiClass);
int rankOrder = poiClassRank + ((nullOrEmpty(element.name())) ? 2000 : 0);
int rankOrder = poiClassRank + ((nullOrEmpty(name)) ? 2000 : 0);

output.setBufferPixels(BUFFER_SIZE)
.setAttr(Fields.CLASS, poiClass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ record WaterInfo(int minZoom, int maxZoom, String clazz) {}
case "ne_50m_ocean" -> new WaterInfo(2, 4, FieldValues.CLASS_OCEAN);
case "ne_10m_ocean" -> new WaterInfo(5, 5, FieldValues.CLASS_OCEAN);

// TODO: get OSM ID from low-zoom natural earth lakes
case "ne_110m_lakes" -> new WaterInfo(0, 1, FieldValues.CLASS_LAKE);
case "ne_50m_lakes" -> new WaterInfo(2, 3, FieldValues.CLASS_LAKE);
case "ne_10m_lakes" -> new WaterInfo(4, 5, FieldValues.CLASS_LAKE);
Expand Down Expand Up @@ -109,6 +110,7 @@ public void process(Tables.OsmWaterPolygon element, FeatureCollector features) {
.setBufferPixels(BUFFER_SIZE)
.setMinPixelSizeBelowZoom(11, 2)
.setMinZoom(6)
.setAttr(Fields.ID, element.source().id())
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
.setAttrWithMinzoom(Fields.BRUNNEL, Utils.brunnel(element.isBridge(), element.isTunnel()), 12)
.setAttr(Fields.CLASS, clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,34 @@ void testLocksmith() {
"name", "The Locksmith"
))));
}

@Test
void testAtm() {
List<Map<String, Object>> expected = List.of(Map.of(
"_layer", "poi",
"class", "atm",
"subclass", "atm",
"name", "ATM name"
));
// prefer name, otherwise fall back to operator, or else network
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "atm",
"name", "ATM name"
))));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "atm",
"name", "ATM name",
"operator", "ATM operator",
"network", "ATM network"
))));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "atm",
"operator", "ATM name",
"network", "ATM network"
))));
assertFeatures(14, expected, process(pointFeature(Map.of(
"amenity", "atm",
"network", "ATM name"
))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class TransportationTest extends AbstractLayerTest {

Expand Down Expand Up @@ -1061,32 +1063,33 @@ void testNarrowGauge() {
))));
}

@Test
void testAerialway() {
@ParameterizedTest
@ValueSource(strings = {"gondola", "chair_lift", "j-bar", "mixed_lift"})
void testAerialway(String aerialway) {
assertFeatures(12, List.of(Map.of(
"_layer", "transportation",
"class", "aerialway",
"subclass", "gondola",
"subclass", aerialway,

"_minzoom", 12,
"_maxzoom", 14,
"_type", "line"
), Map.of(
"_layer", "transportation_name",
"class", "aerialway",
"subclass", "gondola",
"subclass", aerialway,
"name", "Summit Gondola",

"_minzoom", 12,
"_maxzoom", 14,
"_type", "line"
)), process(lineFeature(Map.of(
"aerialway", "gondola",
"aerialway", aerialway,
"name", "Summit Gondola"
))));
assertFeatures(10, List.of(),
process(polygonFeature(Map.of(
"aerialway", "gondola",
"aerialway", aerialway,
"name", "Summit Gondola"
))));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import static com.onthegomap.planetiler.basemap.BasemapProfile.OSM_SOURCE;
import static com.onthegomap.planetiler.basemap.BasemapProfile.WATER_POLYGON_SOURCE;

import com.onthegomap.planetiler.geo.GeoUtils;
import com.onthegomap.planetiler.reader.SimpleFeature;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -88,6 +90,28 @@ void testWaterOsmWaterPolygon() {
)));
}

@Test
void testWaterOsmId() {
long id = 123;
assertFeatures(14, List.of(Map.of(
"class", "lake",
"id", id,
"_layer", "water",
"_type", "polygon",
"_minzoom", 6,
"_maxzoom", 14
)), process(SimpleFeature.create(
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
new HashMap<>(Map.<String, Object>of(
"natural", "water",
"water", "reservoir"
)),
OSM_SOURCE,
null,
id
)));
}

@Test
void testWater() {
assertFeatures(14, List.of(Map.of(
Expand All @@ -103,7 +127,7 @@ void testWater() {
assertFeatures(14, List.of(
Map.of("_layer", "poi"),
Map.of(
"class", "lake",
"class", "swimming_pool",

"_layer", "water",
"_type", "polygon",
Expand Down
2 changes: 1 addition & 1 deletion scripts/regenerate-openmaptiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -o errexit
set -o pipefail
set -o nounset

TAG="${1:-"v3.13"}"
TAG="${1:-"v3.13.1"}"
echo "tag=${TAG}"

BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}"
Expand Down