Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 13 additions & 27 deletions server/src/main/java/org/elasticsearch/common/geo/GeoJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public static Map<String, Object> 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;
}

Expand Down Expand Up @@ -264,13 +264,7 @@ public Void visit(MultiPoint multiPoint) {
List<Object> points = new ArrayList<>(multiPoint.size());
for (int i = 0; i < multiPoint.size(); i++) {
Point p = multiPoint.get(i);
List<Object> 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;
Expand All @@ -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;
}

Expand All @@ -306,34 +300,26 @@ public Void visit(Polygon polygon) {
@Override
public Void visit(Rectangle rectangle) {
List<Object> 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<Object> coordinatesToList(double lat, double lon, double alt) {
List<Object> 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<Object> coordinatesToList(Line line) {
List<Object> lines = new ArrayList<>(line.length());
List<Object> coords = new ArrayList<>(line.length());
for (int i = 0; i < line.length(); i++) {
List<Object> 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<Object> coordinatesToList(Polygon polygon) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -133,7 +135,7 @@ public void testToMap() throws IOException {
.createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, input)
) {
Map<String, Object> map = GeoJson.toMap(geometry);
assertThat(parser.map(), equalTo(map));
assertThat(parser.map(), equalTo(XContentHelper.mapToXContentParser(XContentParserConfiguration.EMPTY, map).map()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand All @@ -38,31 +39,33 @@ public void testFetchSourceValue() throws IOException {
).build(MapperBuilderContext.root(false, false)).fieldType();

Map<String, Object> jsonPoint = Map.of("type", "Point", "coordinates", List.of(42.0, 27.1));
Map<String, Object> mapPoint = Map.of("type", "Point", "coordinates", new double[] { 42.0, 27.1 });
Map<String, Object> otherJsonPoint = Map.of("type", "Point", "coordinates", List.of(30.0, 50.0));
Map<String, Object> 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);
byte[] otherWkbPoint = WellKnownBinary.toWKB(new Point(30.0, 50.0), ByteOrder.LITTLE_ENDIAN);

// 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));
assertThat(wkb.get(0), equalTo(wkbPoint));

// 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));
assertThat(wkb.get(0), equalTo(wkbPoint));

// 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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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("""
Expand All @@ -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<String, Object> fetchValue = (Map<String, Object>) 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)")));
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, Object>) 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())));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
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;
import org.elasticsearch.geometry.utils.WellKnownText;
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;

Expand Down Expand Up @@ -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<String, Object>) map,
XContentType.JSON
);
var parser = XContentHelper.mapToXContentParser(XContentParserConfiguration.EMPTY, (Map<String, ?>) map);
parser.nextToken();

var geometry = GeoJson.fromXContent(GeographyValidator.instance(true), false, true, parser);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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("""
Expand All @@ -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<String, Object> fetchValue = (Map<String, Object>) fetcher.fetchValues(source, 0, null).get(0);
assertThat(fetchValue.size(), equalTo(2));
assertThat(fetchValue.get("type"), equalTo("LineString"));
List<double[]> coordinates = (List<double[]>) 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)")));
Expand Down
Loading