diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/Config.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/Config.java index 2d0b2f32..eee9bc2c 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/Config.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/Config.java @@ -30,8 +30,13 @@ public void initConstructUtils(ObjectMapper mapper) { public void init() { // register modudle for json serializing mapper.registerModule(new JsonNullableModule()); - // configure ObjectMapper to exclude null fields while serializing - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + // Configure ObjectMapper to exclude null fields while serializing + mapper.setDefaultPropertyInclusion( + JsonInclude.Value.construct( + JsonInclude.Include.NON_NULL, + JsonInclude.Include.USE_DEFAULTS + ) + ); } @Bean diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunction.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunction.java index 9631ad6b..cee940e6 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunction.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunction.java @@ -34,7 +34,12 @@ private static Map loadStaticMap(String path, String keyField) if (properties != null) { JsonNode objectId = properties.get(keyField); if (objectId != null) { - String key = objectId.asText(); + // This is used to avoid the trailing zeros in the number, for example 123.0 in key, + // where the React frontend with javascript number type will parse the number to 123 + // and cause the key mismatch with the map. + final String key = objectId.isNumber() + ? objectId.decimalValue().stripTrailingZeros().toPlainString() + : objectId.asText(); JsonNode geometry = feature.get("geometry"); if (geometry != null) { String geoJson = mapper.writeValueAsString(geometry); @@ -82,8 +87,11 @@ public IBoundaryFunction(List parameters, Literal fallback) { public Object evaluate(Object feature) { String name = getParameters().get(0).evaluate(feature, String.class); String id = getParameters().get(1).evaluate(feature, String.class); - - return getGeoJsonFromMap(name, id); + Geometry geometry = getGeoJsonFromMap(name, id); + if(geometry == null) { + log.warn("IBoundaryFunction lookup failed: name={}, id={}", name, id); + } + return geometry; } @Override diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunctionTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunctionTest.java index 8291daff..42b0a562 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunctionTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/parser/elastic/IBoundaryFunctionTest.java @@ -31,6 +31,15 @@ public void testIBoundaryFunction() { assertInstanceOf(Geometry.class, geom); } + @Test + public void testMeowKeyNormalization() { + // Meow.json has ECO_CODE like 20192.0 (as JSON number), React/JS does String(20192.0) === '20192' + // so loadStaticMap must store keys without trailing .0 to avoid lookup mismatch + assertNotNull(IBoundaryFunction.MEOW.get("20192"), "Expected key '20192' for MEOW (from 20192.0)"); + assertNotNull(IBoundaryFunction.MEOW.get("20053")); + assertNull(IBoundaryFunction.MEOW.get("20192.0"), "Should not have .0 suffixed key"); + } + @Test public void testIBoundaryWithCQL() throws Exception { // Parse full CQL2 string