From 25de29acda7cf265b73f59e3bd0179d635d85969 Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Wed, 21 May 2025 16:14:57 +0200 Subject: [PATCH] Deserialize geojson coordinate arrays to double arrays instead of List of Doubles. --- .../org/elasticsearch/common/geo/GeoJson.java | 40 +++------ .../common/geo/GeoJsonSerializationTests.java | 4 +- .../index/mapper/GeoPointFieldTypeTests.java | 21 +++-- .../mapper/GeoPointScriptFieldTypeTests.java | 11 ++- .../geo/GeometryFieldTypeTestCase.java | 49 +++++++++++ .../mapper/GeoShapeFieldBlockLoaderTests.java | 12 +-- .../mapper/GeoShapeScriptFieldTypeTests.java | 13 ++- .../GeoShapeWithDocValuesFieldTypeTests.java | 84 +++++++++++-------- .../index/mapper/PointFieldTypeTests.java | 20 ++--- .../mapper/ShapeFieldBlockLoaderTests.java | 12 +-- .../index/mapper/ShapeFieldTypeTests.java | 23 +++-- 11 files changed, 172 insertions(+), 117 deletions(-) create mode 100644 test/framework/src/main/java/org/elasticsearch/geo/GeometryFieldTypeTestCase.java diff --git a/server/src/main/java/org/elasticsearch/common/geo/GeoJson.java b/server/src/main/java/org/elasticsearch/common/geo/GeoJson.java index cb269e107f726..1d9648e3b1a92 100644 --- a/server/src/main/java/org/elasticsearch/common/geo/GeoJson.java +++ b/server/src/main/java/org/elasticsearch/common/geo/GeoJson.java @@ -223,7 +223,7 @@ public static Map toMap(Geometry geometry) { @Override public Void visit(Circle circle) { root.put(FIELD_RADIUS.getPreferredName(), DistanceUnit.METERS.toString(circle.getRadiusMeters())); - root.put(FIELD_COORDINATES.getPreferredName(), coordinatesToList(circle.getY(), circle.getX(), circle.getZ())); + root.put(FIELD_COORDINATES.getPreferredName(), coordinatesToArray(circle.getX(), circle.getY(), circle.getZ())); return null; } @@ -264,13 +264,7 @@ public Void visit(MultiPoint multiPoint) { List points = new ArrayList<>(multiPoint.size()); for (int i = 0; i < multiPoint.size(); i++) { Point p = multiPoint.get(i); - List point = new ArrayList<>(); - point.add(p.getX()); - point.add(p.getY()); - if (p.hasZ()) { - point.add(p.getZ()); - } - points.add(point); + points.add(coordinatesToArray(p.getX(), p.getY(), p.getZ())); } root.put(FIELD_COORDINATES.getPreferredName(), points); return null; @@ -288,7 +282,7 @@ public Void visit(MultiPolygon multiPolygon) { @Override public Void visit(Point point) { - root.put(FIELD_COORDINATES.getPreferredName(), coordinatesToList(point.getY(), point.getX(), point.getZ())); + root.put(FIELD_COORDINATES.getPreferredName(), coordinatesToArray(point.getX(), point.getY(), point.getZ())); return null; } @@ -306,34 +300,26 @@ public Void visit(Polygon polygon) { @Override public Void visit(Rectangle rectangle) { List coords = new ArrayList<>(2); - coords.add(coordinatesToList(rectangle.getMaxY(), rectangle.getMinX(), rectangle.getMinZ())); // top left - coords.add(coordinatesToList(rectangle.getMinY(), rectangle.getMaxX(), rectangle.getMaxZ())); // bottom right + coords.add(coordinatesToArray(rectangle.getMinX(), rectangle.getMaxY(), rectangle.getMinZ())); // top left + coords.add(coordinatesToArray(rectangle.getMaxX(), rectangle.getMinY(), rectangle.getMaxZ())); // bottom right root.put(FIELD_COORDINATES.getPreferredName(), coords); return null; } - private static List coordinatesToList(double lat, double lon, double alt) { - List coords = new ArrayList<>(3); - coords.add(lon); - coords.add(lat); - if (Double.isNaN(alt) == false) { - coords.add(alt); + private static double[] coordinatesToArray(double lon, double lat, double alt) { + if (Double.isNaN(alt)) { + return new double[] { lon, lat }; + } else { + return new double[] { lon, lat, alt }; } - return coords; } private static List coordinatesToList(Line line) { - List lines = new ArrayList<>(line.length()); + List coords = new ArrayList<>(line.length()); for (int i = 0; i < line.length(); i++) { - List coords = new ArrayList<>(3); - coords.add(line.getX(i)); - coords.add(line.getY(i)); - if (line.hasZ()) { - coords.add(line.getZ(i)); - } - lines.add(coords); + coords.add(coordinatesToArray(line.getX(i), line.getY(i), line.getZ(i))); } - return lines; + return coords; } private static List coordinatesToList(Polygon polygon) { diff --git a/server/src/test/java/org/elasticsearch/common/geo/GeoJsonSerializationTests.java b/server/src/test/java/org/elasticsearch/common/geo/GeoJsonSerializationTests.java index b6055e65c21a9..f84cfe24cbdee 100644 --- a/server/src/test/java/org/elasticsearch/common/geo/GeoJsonSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/common/geo/GeoJsonSerializationTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.geometry.utils.GeographyValidator; @@ -23,6 +24,7 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import java.io.IOException; @@ -133,7 +135,7 @@ public void testToMap() throws IOException { .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, input) ) { Map map = GeoJson.toMap(geometry); - assertThat(parser.map(), equalTo(map)); + assertThat(parser.map(), equalTo(XContentHelper.mapToXContentParser(XContentParserConfiguration.EMPTY, map).map())); } } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java index 93f1b2b977b0f..a887fc435897c 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java @@ -12,6 +12,7 @@ import org.apache.lucene.tests.geo.GeoTestUtil; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.SimpleFeatureFactory; +import org.elasticsearch.geo.GeometryFieldTypeTestCase; import org.elasticsearch.geometry.Point; import org.elasticsearch.geometry.utils.WellKnownBinary; import org.elasticsearch.index.IndexVersion; @@ -25,7 +26,7 @@ import static org.hamcrest.Matchers.equalTo; -public class GeoPointFieldTypeTests extends FieldTypeTestCase { +public class GeoPointFieldTypeTests extends GeometryFieldTypeTestCase { public void testFetchSourceValue() throws IOException { boolean ignoreMalformed = randomBoolean(); @@ -38,7 +39,9 @@ public void testFetchSourceValue() throws IOException { ).build(MapperBuilderContext.root(false, false)).fieldType(); Map jsonPoint = Map.of("type", "Point", "coordinates", List.of(42.0, 27.1)); + Map mapPoint = Map.of("type", "Point", "coordinates", new double[] { 42.0, 27.1 }); Map otherJsonPoint = Map.of("type", "Point", "coordinates", List.of(30.0, 50.0)); + Map otherMapPoint = Map.of("type", "Point", "coordinates", new double[] { 30.0, 50.0 }); String wktPoint = "POINT (42.0 27.1)"; String otherWktPoint = "POINT (30.0 50.0)"; byte[] wkbPoint = WellKnownBinary.toWKB(new Point(42.0, 27.1), ByteOrder.LITTLE_ENDIAN); @@ -46,7 +49,7 @@ public void testFetchSourceValue() throws IOException { // Test a single point in [lon, lat] array format. Object sourceValue = List.of(42.0, 27.1); - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); List wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -54,7 +57,7 @@ public void testFetchSourceValue() throws IOException { // Test a single point in "lat, lon" string format. sourceValue = "27.1,42.0"; - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -62,7 +65,7 @@ public void testFetchSourceValue() throws IOException { // Test a list of points in [lon, lat] array format. sourceValue = List.of(List.of(42.0, 27.1), List.of(30.0, 50.0)); - assertEquals(List.of(jsonPoint, otherJsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint, otherMapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint, otherWktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -71,7 +74,7 @@ public void testFetchSourceValue() throws IOException { // Test a list of points in [lat,lon] array format with one malformed sourceValue = List.of(List.of(42.0, 27.1), List.of("a", "b"), List.of(30.0, 50.0)); - assertEquals(List.of(jsonPoint, otherJsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint, otherMapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint, otherWktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -80,7 +83,7 @@ public void testFetchSourceValue() throws IOException { // Test a single point in well-known text format. sourceValue = "POINT (42.0 27.1)"; - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -93,7 +96,7 @@ public void testFetchSourceValue() throws IOException { // test normalize sourceValue = "27.1,402.0"; if (ignoreMalformed) { - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -106,12 +109,12 @@ public void testFetchSourceValue() throws IOException { // test single point in GeoJSON format sourceValue = jsonPoint; - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a list of points in GeoJSON format sourceValue = List.of(jsonPoint, otherJsonPoint); - assertEquals(List.of(jsonPoint, otherJsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint, otherMapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint, otherWktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointScriptFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointScriptFieldTypeTests.java index 086fd84cfb9ab..67b2394bec342 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointScriptFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointScriptFieldTypeTests.java @@ -117,6 +117,7 @@ public void testSort() throws IOException { assertThat(e.getMessage(), equalTo("can't sort on geo_point field without using specific sorting feature, like geo_distance")); } + @SuppressWarnings("unchecked") public void testFetch() throws IOException { try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) { addDocument(iw, List.of(new StoredField("_source", new BytesRef(""" @@ -126,10 +127,12 @@ public void testFetch() throws IOException { Source source = searchContext.lookup().getSource(reader.leaves().get(0), 0); ValueFetcher fetcher = simpleMappedFieldType().valueFetcher(searchContext, randomBoolean() ? null : "geojson"); fetcher.setNextReader(reader.leaves().get(0)); - assertThat( - fetcher.fetchValues(source, 0, null), - equalTo(List.of(Map.of("type", "Point", "coordinates", List.of(45.0, 45.0)))) - ); + // we need to check manually the map as the assertion methods do not like arrays inside the map + Map fetchValue = (Map) fetcher.fetchValues(source, 0, null).get(0); + assertThat(fetchValue.size(), equalTo(2)); + assertThat(fetchValue.get("type"), equalTo("Point")); + double[] coordinates = (double[]) fetchValue.get("coordinates"); + assertThat(coordinates, equalTo(new double[] { 45.0, 45.0 })); fetcher = simpleMappedFieldType().valueFetcher(searchContext, "wkt"); fetcher.setNextReader(reader.leaves().get(0)); assertThat(fetcher.fetchValues(source, 0, null), equalTo(List.of("POINT (45.0 45.0)"))); diff --git a/test/framework/src/main/java/org/elasticsearch/geo/GeometryFieldTypeTestCase.java b/test/framework/src/main/java/org/elasticsearch/geo/GeometryFieldTypeTestCase.java new file mode 100644 index 0000000000000..5a14ed7357382 --- /dev/null +++ b/test/framework/src/main/java/org/elasticsearch/geo/GeometryFieldTypeTestCase.java @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.geo; + +import org.elasticsearch.index.mapper.FieldTypeTestCase; + +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.equalTo; + +public abstract class GeometryFieldTypeTestCase extends FieldTypeTestCase { + + @SuppressWarnings("unchecked") + public static void assertGeoJsonFetch(List expected, List actual) { + assertThat(actual.size(), equalTo(expected.size())); + for (int i = 0; i < expected.size(); i++) { + Object o = expected.get(i); + if (o instanceof Map m) { + assertGeoJsonFetch(m, (Map) actual.get(i)); + } else if (o instanceof List l) { + assertGeoJsonFetch(l, (List) actual.get(i)); + } else { + assertThat(o, equalTo(actual.get(i))); + } + } + } + + @SuppressWarnings("unchecked") + public static void assertGeoJsonFetch(Map expected, Map actual) { + assertThat(actual.size(), equalTo(expected.size())); + for (Map.Entry e : expected.entrySet()) { + assertTrue(actual.containsKey(e.getKey())); + Object o = e.getValue(); + if (o instanceof Map m) { + assertGeoJsonFetch(m, (Map) actual.get(e.getKey())); + } else if (o instanceof List l) { + assertGeoJsonFetch(l, (List) actual.get(e.getKey())); + } else { + assertThat(o, equalTo(actual.get(e.getKey()))); + } + } + } +} diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeFieldBlockLoaderTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeFieldBlockLoaderTests.java index 394ce2da7d167..088cc396f6463 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeFieldBlockLoaderTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeFieldBlockLoaderTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.common.geo.GeoJson; import org.elasticsearch.common.geo.GeometryNormalizer; import org.elasticsearch.common.geo.Orientation; -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.geometry.utils.GeographyValidator; import org.elasticsearch.geometry.utils.WellKnownBinary; @@ -19,8 +19,7 @@ import org.elasticsearch.index.mapper.BlockLoaderTestCase; import org.elasticsearch.plugins.ExtensiblePlugin; import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.MapXContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xpack.spatial.LocalStateSpatialPlugin; import org.elasticsearch.xpack.spatial.datageneration.GeoShapeDataSourceHandler; @@ -80,12 +79,7 @@ private Geometry fromWKT(String s) { @SuppressWarnings("unchecked") private Geometry fromGeoJson(Map map) { try { - var parser = new MapXContentParser( - xContentRegistry(), - LoggingDeprecationHandler.INSTANCE, - (Map) map, - XContentType.JSON - ); + var parser = XContentHelper.mapToXContentParser(XContentParserConfiguration.EMPTY, (Map) map); parser.nextToken(); var geometry = GeoJson.fromXContent(GeographyValidator.instance(true), false, true, parser); diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeScriptFieldTypeTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeScriptFieldTypeTests.java index 5d6f68f8e06a9..60fdc078afe29 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeScriptFieldTypeTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeScriptFieldTypeTests.java @@ -140,6 +140,7 @@ public void testSort() throws IOException { assertThat(e.getMessage(), equalTo("can't sort on geo_shape field")); } + @SuppressWarnings("unchecked") public void testFetch() throws IOException { try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) { addDocument(iw, List.of(new StoredField("_source", new BytesRef(""" @@ -149,10 +150,14 @@ public void testFetch() throws IOException { Source source = searchContext.lookup().getSource(reader.leaves().get(0), 0); ValueFetcher fetcher = simpleMappedFieldType().valueFetcher(searchContext, randomBoolean() ? null : "geojson"); fetcher.setNextReader(reader.leaves().get(0)); - assertThat( - fetcher.fetchValues(source, 0, null), - equalTo(List.of(Map.of("type", "LineString", "coordinates", List.of(List.of(45.0, 45.0), List.of(0.0, 0.0))))) - ); + // we need to check manually the map as the assertion methods do not like arrays inside the map + Map fetchValue = (Map) fetcher.fetchValues(source, 0, null).get(0); + assertThat(fetchValue.size(), equalTo(2)); + assertThat(fetchValue.get("type"), equalTo("LineString")); + List coordinates = (List) fetchValue.get("coordinates"); + assertThat(coordinates.size(), equalTo(2)); + assertThat(coordinates.get(0), equalTo(new double[] { 45.0, 45.0 })); + assertThat(coordinates.get(1), equalTo(new double[] { 0.0, 0.0 })); fetcher = simpleMappedFieldType().valueFetcher(searchContext, "wkt"); fetcher.setNextReader(reader.leaves().get(0)); assertThat(fetcher.fetchValues(source, 0, null), equalTo(List.of("LINESTRING (45.0 45.0, 0.0 0.0)"))); diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldTypeTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldTypeTests.java index 7c5fa5053222b..09c922c25bd6e 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldTypeTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldTypeTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.geo.GeometryNormalizer; import org.elasticsearch.common.geo.Orientation; import org.elasticsearch.common.geo.SimpleVectorTileFormatter; +import org.elasticsearch.geo.GeometryFieldTypeTestCase; import org.elasticsearch.geo.GeometryTestUtils; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.geometry.Line; @@ -20,7 +21,6 @@ import org.elasticsearch.geometry.utils.WellKnownBinary; import org.elasticsearch.geometry.utils.WellKnownText; import org.elasticsearch.index.IndexVersion; -import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperBuilderContext; import org.elasticsearch.xpack.vectortile.SpatialGeometryFormatterExtension; @@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; -public class GeoShapeWithDocValuesFieldTypeTests extends FieldTypeTestCase { +public class GeoShapeWithDocValuesFieldTypeTests extends GeometryFieldTypeTestCase { public void testFetchSourceValue() throws Exception { final GeoFormatterFactory geoFormatterFactory = new GeoFormatterFactory<>( @@ -49,6 +49,13 @@ public void testFetchSourceValue() throws Exception { geoFormatterFactory ).build(MapperBuilderContext.root(false, false)).fieldType(); + Map mapLineString = Map.of( + "type", + "LineString", + "coordinates", + List.of(new double[] { 42.0, 27.1 }, new double[] { 30.0, 50.0 }) + ); + Map mapPoint = Map.of("type", "Point", "coordinates", new double[] { 14.0, 15.0 }); Map jsonLineString = Map.of("type", "LineString", "coordinates", List.of(List.of(42.0, 27.1), List.of(30.0, 50.0))); Map jsonPoint = Map.of("type", "Point", "coordinates", List.of(14.0, 15.0)); Map jsonMalformed = Map.of("type", "Point", "coordinates", "foo"); @@ -63,7 +70,7 @@ public void testFetchSourceValue() throws Exception { // Test a single shape in geojson format. Object sourceValue = jsonLineString; - assertEquals(List.of(jsonLineString), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString), fetchSourceValue(mapper, sourceValue, "wkt")); List wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -77,7 +84,7 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes in geojson format. sourceValue = List.of(jsonLineString, jsonPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -86,7 +93,7 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes including one malformed in geojson format sourceValue = List.of(jsonLineString, jsonMalformed, jsonPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -95,7 +102,7 @@ public void testFetchSourceValue() throws Exception { // Test a single shape in wkt format. sourceValue = wktLineString; - assertEquals(List.of(jsonLineString), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a single malformed shape in wkt format @@ -105,12 +112,12 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes in wkt format. sourceValue = List.of(wktLineString, wktPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a list of shapes including one malformed in wkt format sourceValue = List.of(wktLineString, wktMalformed, wktPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); } @@ -128,8 +135,13 @@ public void testFetchStoredValue() throws IOException { geoFormatterFactory ).setStored(true).build(MapperBuilderContext.root(randomBoolean(), false)).fieldType(); - Map jsonLineString = Map.of("type", "LineString", "coordinates", List.of(List.of(42.0, 27.1), List.of(30.0, 50.0))); - Map jsonPoint = Map.of("type", "Point", "coordinates", List.of(14.0, 15.0)); + Map mapLineString = Map.of( + "type", + "LineString", + "coordinates", + List.of(new double[] { 42.0, 27.1 }, new double[] { 30.0, 50.0 }) + ); + Map mapPoint = Map.of("type", "Point", "coordinates", new double[] { 14.0, 15.0 }); String wktLineString = "LINESTRING (42.0 27.1, 30.0 50.0)"; String wktPoint = "POINT (14.0 15.0)"; @@ -139,7 +151,7 @@ public void testFetchStoredValue() throws IOException { BytesRef wkbPoint = new BytesRef(WellKnownBinary.toWKB(new Point(14.0, 15.0), ByteOrder.LITTLE_ENDIAN)); // Test a single shape in wkb format. List storedValues = List.of(wkbLineString); - assertEquals(List.of(jsonLineString), fetchStoredValue(mapper, storedValues, null)); + assertGeoJsonFetch(List.of(mapLineString), fetchStoredValue(mapper, storedValues, null)); assertEquals(List.of(wktLineString), fetchStoredValue(mapper, storedValues, "wkt")); List wkb = fetchStoredValue(mapper, storedValues, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -147,7 +159,7 @@ public void testFetchStoredValue() throws IOException { // Test a list of shapes in wkb format. storedValues = List.of(wkbLineString, wkbPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchStoredValue(mapper, storedValues, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchStoredValue(mapper, storedValues, null)); assertEquals(List.of(wktLineString, wktPoint), fetchStoredValue(mapper, storedValues, "wkt")); wkb = fetchStoredValue(mapper, storedValues, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -219,7 +231,7 @@ private Geometry normalize(Geometry geometry) { } public void testFetchSourcePolygonDateLine() throws Exception { - assertFetchGeometry( + assertGeoJsonFetchGeometry( "POLYGON((170 -10, -170 -10, -170 10, 170 10, 170 -10))", "MULTIPOLYGON (((180.0 -10.0, 180.0 10.0, 170.0 10.0, 170.0 -10.0, 180.0 -10.0))," + "((-180.0 10.0, -180.0 -10.0, -170.0 -10.0, -170.0 10.0, -180.0 10.0)))", @@ -230,20 +242,20 @@ public void testFetchSourcePolygonDateLine() throws Exception { List.of( List.of( List.of( - List.of(180.0, -10.0), - List.of(180.0, 10.0), - List.of(170.0, 10.0), - List.of(170.0, -10.0), - List.of(180.0, -10.0) + new double[] { 180.0, -10.0 }, + new double[] { 180.0, 10.0 }, + new double[] { 170.0, 10.0 }, + new double[] { 170.0, -10.0 }, + new double[] { 180.0, -10.0 } ) ), List.of( List.of( - List.of(-180.0, 10.0), - List.of(-180.0, -10.0), - List.of(-170.0, -10.0), - List.of(-170.0, 10.0), - List.of(-180.0, 10.0) + new double[] { -180.0, 10.0 }, + new double[] { -180.0, -10.0 }, + new double[] { -170.0, -10.0 }, + new double[] { -170.0, 10.0 }, + new double[] { -180.0, 10.0 } ) ) ) @@ -254,31 +266,31 @@ public void testFetchSourcePolygonDateLine() throws Exception { } public void testFetchSourceEnvelope() throws Exception { - assertFetchGeometry( + assertGeoJsonFetchGeometry( "BBOX(-10, 10, 10, -10)", "BBOX (-10.0, 10.0, 10.0, -10.0)", - Map.of("type", "Envelope", "coordinates", List.of(List.of(-10.0, 10.0), List.of(10.0, -10.0))), + Map.of("type", "Envelope", "coordinates", List.of(new double[] { -10.0, 10.0 }, new double[] { 10.0, -10.0 })), "POLYGON ((-10 -10, 10 -10, 10 10, -10 10, -10 -10)))" ); } public void testFetchSourceEnvelopeDateLine() throws Exception { - assertFetchGeometry( + assertGeoJsonFetchGeometry( "BBOX(10, -10, 10, -10)", "BBOX (10.0, -10.0, 10.0, -10.0)", - Map.of("type", "Envelope", "coordinates", List.of(List.of(10.0, 10.0), List.of(-10.0, -10.0))), + Map.of("type", "Envelope", "coordinates", List.of(new double[] { 10.0, 10.0 }, new double[] { -10.0, -10.0 })), "MULTIPOLYGON (((-180 -10, -10 -10, -10 10, -180 10, -180 -10)), ((10 -10, 180 -10, 180 10, 10 10, 10 -10)))" ); } - private void assertFetchGeometry(Object sourceValue, String wktValue, Map jsonValue, String mvtEquivalentAsWKT) + private void assertGeoJsonFetchGeometry(Object sourceValue, String wktValue, Map jsonValue, String mvtEquivalentAsWKT) throws Exception { - assertFetchSourceGeometry(sourceValue, wktValue, jsonValue); - assertFetchSourceMVT(sourceValue, mvtEquivalentAsWKT); - assertFetchStoredGeometry(wktValue, jsonValue); + assertGeoJsonFetchSourceGeometry(sourceValue, wktValue, jsonValue); + assertGeoJsonFetchSourceMVT(sourceValue, mvtEquivalentAsWKT); + assertGeoJsonFetchStoredGeometry(wktValue, jsonValue); } - private void assertFetchSourceGeometry(Object sourceValue, String wktValue, Map jsonValue) throws IOException { + private void assertGeoJsonFetchSourceGeometry(Object sourceValue, String wktValue, Map jsonValue) throws IOException { final GeoFormatterFactory geoFormatterFactory = new GeoFormatterFactory<>( new SpatialGeometryFormatterExtension().getGeometryFormatterFactories() ); @@ -291,11 +303,11 @@ private void assertFetchSourceGeometry(Object sourceValue, String wktValue, Map< geoFormatterFactory ).build(MapperBuilderContext.root(false, false)).fieldType(); - assertEquals(List.of(jsonValue), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(jsonValue), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktValue), fetchSourceValue(mapper, sourceValue, "wkt")); } - private void assertFetchStoredGeometry(String wktValue, Map jsonValue) throws Exception { + private void assertGeoJsonFetchStoredGeometry(String wktValue, Map jsonValue) throws Exception { final GeoFormatterFactory geoFormatterFactory = new GeoFormatterFactory<>( new SpatialGeometryFormatterExtension().getGeometryFormatterFactories() ); @@ -312,11 +324,11 @@ private void assertFetchStoredGeometry(String wktValue, Map json BytesRef wkb = new BytesRef(WellKnownBinary.toWKB(geometry, randomBoolean() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN)); - assertEquals(List.of(jsonValue), fetchStoredValue(mapper, List.of(wkb), null)); + assertGeoJsonFetch(List.of(jsonValue), fetchStoredValue(mapper, List.of(wkb), null)); assertEquals(List.of(wktValue), fetchStoredValue(mapper, List.of(wkb), "wkt")); } - private void assertFetchSourceMVT(Object sourceValue, String mvtEquivalentAsWKT) throws IOException { + private void assertGeoJsonFetchSourceMVT(Object sourceValue, String mvtEquivalentAsWKT) throws IOException { final GeoFormatterFactory geoFormatterFactory = new GeoFormatterFactory<>( new SpatialGeometryFormatterExtension().getGeometryFormatterFactories() ); diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldTypeTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldTypeTests.java index 6524860e9438c..d01d13d8aceb9 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldTypeTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/PointFieldTypeTests.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.spatial.index.mapper; +import org.elasticsearch.geo.GeometryFieldTypeTestCase; import org.elasticsearch.geometry.Point; import org.elasticsearch.geometry.utils.WellKnownBinary; -import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperBuilderContext; @@ -20,29 +20,29 @@ import static org.hamcrest.Matchers.equalTo; -public class PointFieldTypeTests extends FieldTypeTestCase { +public class PointFieldTypeTests extends GeometryFieldTypeTestCase { public void testFetchSourceValue() throws IOException { MappedFieldType mapper = new PointFieldMapper.Builder("field", false).build(MapperBuilderContext.root(false, false)).fieldType(); - Map jsonPoint = Map.of("type", "Point", "coordinates", List.of(42.0, 27.1)); + Map mapPoint = Map.of("type", "Point", "coordinates", new double[] { 42.0, 27.1 }); String wktPoint = "POINT (42.0 27.1)"; - Map otherJsonPoint = Map.of("type", "Point", "coordinates", List.of(30.0, 50.0)); + Map otherMapPoint = Map.of("type", "Point", "coordinates", new double[] { 30.0, 50.0 }); String otherWktPoint = "POINT (30.0 50.0)"; byte[] wkbPoint = WellKnownBinary.toWKB(new Point(42.0, 27.1), ByteOrder.LITTLE_ENDIAN); byte[] otherWkbPoint = WellKnownBinary.toWKB(new Point(30.0, 50.0), ByteOrder.LITTLE_ENDIAN); // Test a single point in [x, y] array format. Object sourceValue = List.of(42.0, 27.1); - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); - assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); List wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); assertThat(wkb.get(0), equalTo(wkbPoint)); // Test a single point in "x, y" string format. sourceValue = "42.0,27.1"; - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -56,7 +56,7 @@ public void testFetchSourceValue() throws IOException { // Test a list of points in [x, y] array format. sourceValue = List.of(List.of(42.0, 27.1), List.of(30.0, 50.0)); - assertEquals(List.of(jsonPoint, otherJsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint, otherMapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint, otherWktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -65,12 +65,12 @@ public void testFetchSourceValue() throws IOException { // Test a single point in well-known text format. sourceValue = "POINT (42.0 27.1)"; - assertEquals(List.of(jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a list of points in [x, y] array format with a malformed entry sourceValue = List.of(List.of(42.0, 27.1), List.of("a", "b"), List.of(30.0, 50.0)); - assertEquals(List.of(jsonPoint, otherJsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapPoint, otherMapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktPoint, otherWktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); } diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldBlockLoaderTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldBlockLoaderTests.java index 9fd0b05c249b7..962e4230ad6c3 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldBlockLoaderTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldBlockLoaderTests.java @@ -9,7 +9,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.geo.GeoJson; -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.geometry.utils.StandardValidator; import org.elasticsearch.geometry.utils.WellKnownBinary; @@ -17,8 +17,7 @@ import org.elasticsearch.index.mapper.BlockLoaderTestCase; import org.elasticsearch.plugins.ExtensiblePlugin; import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.xcontent.XContentType; -import org.elasticsearch.xcontent.support.MapXContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xpack.spatial.LocalStateSpatialPlugin; import org.elasticsearch.xpack.spatial.datageneration.ShapeDataSourceHandler; @@ -77,12 +76,7 @@ private Geometry fromWKT(String s) { @SuppressWarnings("unchecked") private Geometry fromGeoJson(Map map) { try { - var parser = new MapXContentParser( - xContentRegistry(), - LoggingDeprecationHandler.INSTANCE, - (Map) map, - XContentType.JSON - ); + var parser = XContentHelper.mapToXContentParser(XContentParserConfiguration.EMPTY, (Map) map); parser.nextToken(); return GeoJson.fromXContent(StandardValidator.instance(true), false, true, parser); diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldTypeTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldTypeTests.java index c7d87a6c6e8f5..8b058cd9176de 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldTypeTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/index/mapper/ShapeFieldTypeTests.java @@ -7,11 +7,11 @@ package org.elasticsearch.xpack.spatial.index.mapper; +import org.elasticsearch.geo.GeometryFieldTypeTestCase; import org.elasticsearch.geometry.utils.StandardValidator; import org.elasticsearch.geometry.utils.WellKnownBinary; import org.elasticsearch.geometry.utils.WellKnownText; import org.elasticsearch.index.IndexVersion; -import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperBuilderContext; @@ -21,13 +21,20 @@ import static org.hamcrest.Matchers.equalTo; -public class ShapeFieldTypeTests extends FieldTypeTestCase { +public class ShapeFieldTypeTests extends GeometryFieldTypeTestCase { public void testFetchSourceValue() throws Exception { MappedFieldType mapper = new ShapeFieldMapper.Builder("field", IndexVersion.current(), false, true).build( MapperBuilderContext.root(false, false) ).fieldType(); + Map mapLineString = Map.of( + "type", + "LineString", + "coordinates", + List.of(new double[] { 42.0, 27.1 }, new double[] { 30.0, 50.0 }) + ); + Map mapPoint = Map.of("type", "Point", "coordinates", new double[] { 14.3, 15.0 }); Map jsonLineString = Map.of("type", "LineString", "coordinates", List.of(List.of(42.0, 27.1), List.of(30.0, 50.0))); Map jsonPoint = Map.of("type", "Point", "coordinates", List.of(14.3, 15.0)); Map jsonMalformed = Map.of("type", "Point", "coordinates", "foo"); @@ -42,7 +49,7 @@ public void testFetchSourceValue() throws Exception { // Test a single shape in geojson format. Object sourceValue = jsonLineString; - assertEquals(List.of(jsonLineString), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString), fetchSourceValue(mapper, sourceValue, "wkt")); List wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(1)); @@ -56,7 +63,7 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes in geojson format. sourceValue = List.of(jsonLineString, jsonPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -65,7 +72,7 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes including one malformed in geojson format sourceValue = List.of(jsonLineString, jsonMalformed, jsonPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); wkb = fetchSourceValue(mapper, sourceValue, "wkb"); assertThat(wkb.size(), equalTo(2)); @@ -74,7 +81,7 @@ public void testFetchSourceValue() throws Exception { // Test a single shape in wkt format. sourceValue = wktLineString; - assertEquals(List.of(jsonLineString), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a single malformed shape in wkt format @@ -84,12 +91,12 @@ public void testFetchSourceValue() throws Exception { // Test a list of shapes in wkt format. sourceValue = List.of(wktLineString, wktPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); // Test a list of shapes including one malformed in wkt format sourceValue = List.of(wktLineString, wktMalformed, wktPoint); - assertEquals(List.of(jsonLineString, jsonPoint), fetchSourceValue(mapper, sourceValue, null)); + assertGeoJsonFetch(List.of(mapLineString, mapPoint), fetchSourceValue(mapper, sourceValue, null)); assertEquals(List.of(wktLineString, wktPoint), fetchSourceValue(mapper, sourceValue, "wkt")); }