diff --git a/planetiler-core/pom.xml b/planetiler-core/pom.xml
index f4621268f3..eef160c5d5 100644
--- a/planetiler-core/pom.xml
+++ b/planetiler-core/pom.xml
@@ -19,7 +19,8 @@
32.0
2.24.0
0.16.0
- 4.28.2
+
+ 4.28.1
6.6.5
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 7063a9c829..f4977bfaaa 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
@@ -3,6 +3,7 @@
import com.google.api.expr.v1alpha1.Constant;
import com.google.api.expr.v1alpha1.Decl;
import com.google.api.expr.v1alpha1.Type;
+import com.google.common.collect.ForwardingMap;
import com.google.protobuf.NullValue;
import com.onthegomap.planetiler.config.Arguments;
import com.onthegomap.planetiler.config.PlanetilerConfig;
@@ -370,7 +371,7 @@ public static ScriptEnvironment description(Root root) {
public Object apply(String key) {
if (key != null) {
return switch (key) {
- case FEATURE_TAGS -> tagValueProducer.mapTags(feature);
+ case FEATURE_TAGS -> mapWithDefault(tagValueProducer.mapTags(feature), NullValue.NULL_VALUE);
case FEATURE_ID -> feature.id();
case FEATURE_SOURCE -> feature.getSource();
case FEATURE_SOURCE_LAYER -> wrapNullable(feature.getSourceLayer());
@@ -395,6 +396,20 @@ public Object apply(String key) {
}
}
+ private static Map mapWithDefault(Map map, Object nullValue) {
+ return new ForwardingMap<>() {
+ @Override
+ protected Map delegate() {
+ return map;
+ }
+
+ @Override
+ public V get(Object key) {
+ return map.getOrDefault(key, (V) nullValue);
+ }
+ };
+ }
+
public FeaturePostMatch createPostMatchContext(List matchKeys) {
return new FeaturePostMatch(this, matchKeys);
}
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 64bdc0056d..f38397f440 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
@@ -1287,4 +1287,38 @@ void testLineCentroid(String type) {
assertInstanceOf(Puntal.class, feature.getGeometry());
}, 1);
}
+
+ @Test
+ void testWikidataParse() {
+ var config = """
+ sources:
+ osm:
+ type: osm
+ url: geofabrik:rhode-island
+ local_path: data/rhode-island.osm.pbf
+ layers:
+ - id: testLayer
+ features:
+ - source: osm
+ geometry: point
+ attributes:
+ - key: wikidata
+ value: "${feature.tags.wikidata != null ? int(feature.tags.wikidata.replace('Q', '')) : 0}"
+ """;
+ this.planetilerConfig = PlanetilerConfig.from(Arguments.of(Map.of()));
+ testPoint(config, Map.of(
+ "wikidata", "Q235"
+ ), feature -> {
+ assertEquals(Map.of("wikidata", 235L), feature.getAttrsAtZoom(14));
+ }, 1);
+ testPoint(config, Map.of(
+ "wikidata", "235"
+ ), feature -> {
+ assertEquals(Map.of("wikidata", 235L), feature.getAttrsAtZoom(14));
+ }, 1);
+ testPoint(config, Map.of(
+ ), feature -> {
+ assertEquals(Map.of("wikidata", 0L), feature.getAttrsAtZoom(14));
+ }, 1);
+ }
}
diff --git a/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/expression/ExpressionTests.java b/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/expression/ExpressionTests.java
index 92c9e4af57..3f25abef0b 100644
--- a/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/expression/ExpressionTests.java
+++ b/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/expression/ExpressionTests.java
@@ -43,6 +43,7 @@ class ExpressionTests {
"{'a': 2}.has('a', 1, 2)|true|boolean",
"{'a': 2}.has('a', 3)|false|boolean",
"{'a': 1}.has('b')|false|boolean",
+ "int({'tags': {'wikidata': 'Q1'}}.tags.wikidata.replace('Q', ''))|1|long",
"coalesce({'a': 1}.get('a'), 2)|1|long",
"coalesce({'a': 1}.get('b'), 2)|2|long",