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

Make projection configurable for yaml sources #1066

Merged
merged 2 commits into from
Oct 13, 2024
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
4 changes: 4 additions & 0 deletions planetiler-custommap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ A description that tells planetiler how to read geospatial objects with tags fro
For [geofabrik](https://download.geofabrik.de/) named areas, use `geofabrik:` prefixes, for
example `geofabrik:rhode-island`. Can be a string or [expression](#expression) that can
reference [argument values](#arguments).
- `projection` - Planetiler will try to determine the projection automatically for shapefile/geopackage sources, but if
that is not correct you can override the projection by specifying a coordinate reference system authority code
like `EPSG:3857` or `EPSG:4326` here. Can be a string or [expression](#expression) that can
reference [argument values](#arguments).

For example:

Expand Down
14 changes: 14 additions & 0 deletions planetiler-custommap/planetiler.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@
"local_path": {
"description": "Local path to the file to use, inferred from `url` if missing",
"$ref": "#/$defs/expression"
},
"projection": {
"description": "Override the coordinate reference system authority code for a shapefile or geopackage source if it can not be determined automatically",
"anyOf": [
{
"enum": [
"EPSG:3857",
"EPSG:4326"
]
},
{
"type": "#/$defs/expression"
}
]
}
},
"anyOf": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ private static void configureSource(Planetiler planetiler, Path sourcesDir, Sour

DataSourceType sourceType = source.type();
Path localPath = source.localPath();
String projection = source.projection();
if (localPath == null) {
if (source.url() == null) {
throw new ParseException("Must provide either a url or path for " + source.id());
Expand All @@ -71,8 +72,8 @@ private static void configureSource(Planetiler planetiler, Path sourcesDir, Sour

switch (sourceType) {
case OSM -> planetiler.addOsmSource(source.id(), localPath, source.url());
case SHAPEFILE -> planetiler.addShapefileSource(source.id(), localPath, source.url());
case GEOPACKAGE -> planetiler.addGeoPackageSource(source.id(), localPath, source.url());
case SHAPEFILE -> planetiler.addShapefileSource(projection, source.id(), localPath, source.url());
case GEOPACKAGE -> planetiler.addGeoPackageSource(projection, source.id(), localPath, source.url());
default -> throw new IllegalArgumentException("Unhandled source type for " + source.id() + ": " + sourceType);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,18 @@ public String description() {
public List<Source> sources() {
List<Source> sources = new ArrayList<>();
schema.sources().forEach((key, value) -> {
var url = ConfigExpressionParser.tryStaticEvaluate(rootContext, value.url(), String.class).get();
var path = ConfigExpressionParser.tryStaticEvaluate(rootContext, value.localPath(), String.class).get();
sources.add(new Source(key, value.type(), url, path == null ? null : Path.of(path)));
var url = evaluate(value.url(), String.class);
var path = evaluate(value.localPath(), String.class);
var projection = evaluate(value.projection(), String.class);
sources.add(new Source(key, value.type(), url, path == null ? null : Path.of(path), projection));
});
return sources;
}

private <T> T evaluate(Object expression, Class<T> returnType) {
return ConfigExpressionParser.tryStaticEvaluate(rootContext, expression, returnType).get();
}

public FeatureLayer findFeatureLayer(String layerId) {
return layersById.get(layerId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ public record Source(
String id,
DataSourceType type,
String url,
Path localPath
Path localPath,
String projection
) {

public String defaultFileUrl() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
public record DataSource(
DataSourceType type,
Object url,
@JsonProperty("local_path") Object localPath
@JsonProperty("local_path") Object localPath,
Object projection
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ sources:
water_polygons:
type: shapefile
url: https://osmdata.openstreetmap.de/download/water-polygons-split-3857.zip
projection: EPSG:3857
osm:
type: osm
url: geofabrik:monaco
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,7 @@ void testUseArgumentInSourceUrlPath() {
"osm",
DataSourceType.OSM,
"geofabrik:boston",
null,
null
)), loadConfig(config).sources());

Expand All @@ -1125,6 +1126,7 @@ void testUseArgumentInSourceUrlPath() {
"osm",
DataSourceType.OSM,
"geofabrik:rhode-island",
null,
null
)), loadConfig(config).sources());

Expand All @@ -1137,6 +1139,35 @@ void testUseArgumentInSourceUrlPath() {
assertEquals("example.com_file.osm.pbf", loadConfig(config).sources().get(0).defaultFileUrl());
}

@ParameterizedTest
@CsvSource({
"EPSG:3875, EPSG:3875",
"${'EPSG:' + '3875'}, EPSG:3875",
})
void testSetProjection(String in, String out) {
var config = """
sources:
osm:
type: osm
url: geofabrik:rhode-island
projection: %s
layers:
- id: testLayer
features:
- source: osm
geometry: point
""".formatted(in);

this.planetilerConfig = PlanetilerConfig.from(Arguments.of(Map.of()));
assertEquals(List.of(new Source(
"osm",
DataSourceType.OSM,
"geofabrik:rhode-island",
null,
out
)), loadConfig(config).sources());
}

@ParameterizedTest
@CsvSource("""
10,10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ void ensureValidGeometries() throws Exception {
}
}

// @Test --TODO FIX after adding water layer
@Test
void testContainsOceanPolyons() {
assertMinFeatures("water", Map.of(
"natural", "water"
), 0, 1, Polygon.class);
), 6, 1, Polygon.class);
}

@Test
Expand Down
Loading