diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SimpleFeature.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SimpleFeature.java index 9b39ec8ef4..cc7eb32137 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SimpleFeature.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/SimpleFeature.java @@ -135,6 +135,11 @@ public int cost() { return 1; } + @Override + public Type type() { + return isPoint() ? Type.NODE : Type.WAY; + } + @Override public Map tags() { return tags(); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmElement.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmElement.java index 7bf59242fd..57c5e203ba 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmElement.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/reader/osm/OsmElement.java @@ -24,6 +24,8 @@ public interface OsmElement extends WithTags { int cost(); + Type type(); + enum Type { NODE, WAY, @@ -41,6 +43,11 @@ record Other( public int cost() { return 1 + tags.size() + (info == null ? 0 : Info.COST); } + + @Override + public Type type() { + return null; + } } /** A point on the earth's surface. */ @@ -117,6 +124,11 @@ public int cost() { return 1 + tags.size() + (info == null ? 0 : Info.COST); } + @Override + public Type type() { + return Type.NODE; + } + @Override public boolean equals(Object obj) { if (obj == this) { @@ -170,6 +182,11 @@ public Way(long id, Map tags, LongArrayList nodes) { public int cost() { return 1 + tags.size() + nodes.size() + (info == null ? 0 : Info.COST); } + + @Override + public Type type() { + return Type.WAY; + } } /** An ordered list of nodes, ways, and other relations. */ @@ -199,6 +216,11 @@ public int cost() { return 1 + tags.size() + members.size() * 3 + (info == null ? 0 : Info.COST); } + @Override + public Type type() { + return Type.RELATION; + } + /** * A node, way, or relation contained in a relation with an optional "role" to clarify the purpose of each member. */ diff --git a/planetiler-custommap/README.md b/planetiler-custommap/README.md index 41ba6e4ddc..c6da2a5fef 100644 --- a/planetiler-custommap/README.md +++ b/planetiler-custommap/README.md @@ -473,13 +473,16 @@ Scripts are parsed and evaluated inside a "context" that defines the variables a ##### 1. Root Context Available variables: -- `args` - a map from [argument](#arguments) name to value, see also [built-in arguments](#built-in-arguments) that are always available. + +- `args` - a map from [argument](#arguments) name to value, see also [built-in arguments](#built-in-arguments) that are + always available. ##### 2. Process Feature Context Context available when processing an input feature, for example testing whether to include it from `include_when`. Additional variables, on top of the root context: + - `feature.tags` - map with key/value tags from the input feature - `feature.id` - numeric ID of the input feature - `feature.source` - string source ID this feature came from @@ -489,12 +492,14 @@ Additional variables, on top of the root context: - `feature.osm_timestamp` - optional OSM last modified timestamp for this feature - `feature.osm_user_id` - optional ID of the OSM user that last modified this feature - `feature.osm_user_name` - optional name of the OSM user that last modified this feature +- `feature.osm_type` - type of the OSM element as a string: `"node"`, `"way"`, or `"relation"` ##### 3. Post-Match Context Context available after a feature has matched, for example computing an attribute value. Additional variables, on top of the process feature context: + - `match_key` - string tag that triggered a match to include the feature in this layer - `match_value` - the tag value associated with that key @@ -504,6 +509,7 @@ Context available after the value of an attribute has been computed, for example attribute. Additional variable, on top of the post-match context: + - `value` the value that was computed for this key For example: diff --git a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java index bd90ac8b84..5484ed0ab4 100644 --- a/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java +++ b/planetiler-custommap/src/main/java/com/onthegomap/planetiler/custommap/Contexts.java @@ -347,6 +347,7 @@ public record ProcessFeature( private static final String FEATURE_OSM_TIMESTAMP = "feature.osm_timestamp"; private static final String FEATURE_OSM_USER_ID = "feature.osm_user_id"; private static final String FEATURE_OSM_USER_NAME = "feature.osm_user_name"; + private static final String FEATURE_OSM_TYPE = "feature.osm_type"; public static ScriptEnvironment description(Root root) { return root.description() @@ -360,7 +361,8 @@ public static ScriptEnvironment description(Root root) { Decls.newVar(FEATURE_OSM_VERSION, Decls.Int), Decls.newVar(FEATURE_OSM_TIMESTAMP, Decls.Int), Decls.newVar(FEATURE_OSM_USER_ID, Decls.Int), - Decls.newVar(FEATURE_OSM_USER_NAME, Decls.String) + Decls.newVar(FEATURE_OSM_USER_NAME, Decls.String), + Decls.newVar(FEATURE_OSM_TYPE, Decls.String) ); } @@ -373,7 +375,11 @@ public Object apply(String key) { case FEATURE_SOURCE -> feature.getSource(); case FEATURE_SOURCE_LAYER -> wrapNullable(feature.getSourceLayer()); default -> { - OsmElement.Info info = feature instanceof OsmSourceFeature osm ? osm.originalElement().info() : null; + OsmElement elem = feature instanceof OsmSourceFeature osm ? osm.originalElement() : null; + if (FEATURE_OSM_TYPE.equals(key)) { + yield elem == null ? null : elem.type().name().toLowerCase(); + } + OsmElement.Info info = elem != null ? elem.info() : null; yield info == null ? null : switch (key) { case FEATURE_OSM_CHANGESET -> info.changeset(); case FEATURE_OSM_VERSION -> info.version(); diff --git a/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/ConfiguredFeatureTest.java b/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/ConfiguredFeatureTest.java index f17d253f1a..5cabed4330 100644 --- a/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/ConfiguredFeatureTest.java +++ b/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/ConfiguredFeatureTest.java @@ -556,6 +556,8 @@ void testCoerceAttributeValue() { "${feature.osm_user_id}|4", "${feature.osm_version}|5", "${feature.osm_user_name}|user", + "${feature.osm_type}|node", + "${feature.osm_type.charAt(0)}|n", "${coalesce(feature.source_layer, 'missing')}|missing", "{match: {test: {natural: water}}}|test", "{match: {test: {natural: not_water}}}|null",