Make projection configurable for yaml sources (#1066)

pull/1067/head
Michael Barry 2024-10-13 13:35:07 -04:00 zatwierdzone przez GitHub
rodzic c757f1ee3f
commit f259a9fbf2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
9 zmienionych plików z 67 dodań i 9 usunięć

Wyświetl plik

@ -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:

Wyświetl plik

@ -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": [

Wyświetl plik

@ -62,6 +62,7 @@ public class ConfiguredMapMain {
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());
@ -71,8 +72,8 @@ public class ConfiguredMapMain {
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);
}
}

Wyświetl plik

@ -117,13 +117,18 @@ public class ConfiguredProfile implements Profile {
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);
}

Wyświetl plik

@ -8,7 +8,8 @@ public record Source(
String id,
DataSourceType type,
String url,
Path localPath
Path localPath,
String projection
) {
public String defaultFileUrl() {

Wyświetl plik

@ -5,5 +5,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
public record DataSource(
DataSourceType type,
Object url,
@JsonProperty("local_path") Object localPath
@JsonProperty("local_path") Object localPath,
Object projection
) {}

Wyświetl plik

@ -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

Wyświetl plik

@ -1117,6 +1117,7 @@ class ConfiguredFeatureTest {
"osm",
DataSourceType.OSM,
"geofabrik:boston",
null,
null
)), loadConfig(config).sources());
@ -1125,6 +1126,7 @@ class ConfiguredFeatureTest {
"osm",
DataSourceType.OSM,
"geofabrik:rhode-island",
null,
null
)), loadConfig(config).sources());
@ -1137,6 +1139,35 @@ class ConfiguredFeatureTest {
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

Wyświetl plik

@ -81,11 +81,11 @@ class ConfiguredMapTest {
}
}
// @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