Geo: replace intermediate geo objects with libs/geo (#37721)
Replaces intermediate geo objects built by ShapeBuilders with objects from the libs/geo hierarchy. This should allow us to build all geo functionality around a single hierarchy. Follow up for #35320
This commit is contained in:
parent
e88ae99340
commit
68149b6058
|
@ -212,6 +212,7 @@ allprojects {
|
|||
"org.elasticsearch:elasticsearch-core:${version}": ':libs:core',
|
||||
"org.elasticsearch:elasticsearch-nio:${version}": ':libs:nio',
|
||||
"org.elasticsearch:elasticsearch-x-content:${version}": ':libs:x-content',
|
||||
"org.elasticsearch:elasticsearch-geo:${version}": ':libs:elasticsearch-geo',
|
||||
"org.elasticsearch:elasticsearch-secure-sm:${version}": ':libs:secure-sm',
|
||||
"org.elasticsearch.client:elasticsearch-rest-client:${version}": ':client:rest',
|
||||
"org.elasticsearch.client:elasticsearch-rest-client-sniffer:${version}": ':client:sniffer',
|
||||
|
|
|
@ -67,6 +67,14 @@ public class Line implements Geometry {
|
|||
return lons[i];
|
||||
}
|
||||
|
||||
public double[] getLats() {
|
||||
return lats.clone();
|
||||
}
|
||||
|
||||
public double[] getLons() {
|
||||
return lons.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShapeType type() {
|
||||
return ShapeType.LINESTRING;
|
||||
|
|
|
@ -48,11 +48,11 @@ public class Point implements Geometry {
|
|||
return ShapeType.POINT;
|
||||
}
|
||||
|
||||
public double lat() {
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public double lon() {
|
||||
public double getLon() {
|
||||
return lon;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,12 +123,12 @@ public class WellKnownText {
|
|||
public Void visit(MultiPoint multiPoint) {
|
||||
// walk through coordinates:
|
||||
sb.append(LPAREN);
|
||||
visitPoint(multiPoint.get(0).lon(), multiPoint.get(0).lat());
|
||||
visitPoint(multiPoint.get(0).getLon(), multiPoint.get(0).getLat());
|
||||
for (int i = 1; i < multiPoint.size(); ++i) {
|
||||
sb.append(COMMA);
|
||||
sb.append(SPACE);
|
||||
Point point = multiPoint.get(i);
|
||||
visitPoint(point.lon(), point.lat());
|
||||
visitPoint(point.getLon(), point.getLat());
|
||||
}
|
||||
sb.append(RPAREN);
|
||||
return null;
|
||||
|
@ -146,7 +146,7 @@ public class WellKnownText {
|
|||
sb.append(EMPTY);
|
||||
} else {
|
||||
sb.append(LPAREN);
|
||||
visitPoint(point.lon(), point.lat());
|
||||
visitPoint(point.getLon(), point.getLat());
|
||||
sb.append(RPAREN);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -77,7 +77,8 @@ dependencies {
|
|||
compile "org.elasticsearch:elasticsearch-core:${version}"
|
||||
compile "org.elasticsearch:elasticsearch-secure-sm:${version}"
|
||||
compile "org.elasticsearch:elasticsearch-x-content:${version}"
|
||||
|
||||
compile "org.elasticsearch:elasticsearch-geo:${version}"
|
||||
|
||||
compileOnly project(':libs:plugin-classloader')
|
||||
testRuntime project(':libs:plugin-classloader')
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ public enum GeoShapeType {
|
|||
},
|
||||
GEOMETRYCOLLECTION("geometrycollection") {
|
||||
@Override
|
||||
public ShapeBuilder<?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
|
||||
public ShapeBuilder<?, ?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
|
||||
Orientation orientation, boolean coerce) {
|
||||
// noop, handled in parser
|
||||
return null;
|
||||
|
@ -298,7 +298,7 @@ public enum GeoShapeType {
|
|||
throw new IllegalArgumentException("unknown geo_shape ["+geoshapename+"]");
|
||||
}
|
||||
|
||||
public abstract ShapeBuilder<?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
|
||||
public abstract ShapeBuilder<?, ?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
|
||||
ShapeBuilder.Orientation orientation, boolean coerce);
|
||||
abstract CoordinateNode validate(CoordinateNode coordinates, boolean coerce);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CircleBuilder extends ShapeBuilder<Circle, CircleBuilder> {
|
||||
public class CircleBuilder extends ShapeBuilder<Circle, org.elasticsearch.geo.geometry.Circle, CircleBuilder> {
|
||||
|
||||
public static final ParseField FIELD_RADIUS = new ParseField("radius");
|
||||
public static final GeoShapeType TYPE = GeoShapeType.CIRCLE;
|
||||
|
@ -164,7 +164,7 @@ public class CircleBuilder extends ShapeBuilder<Circle, CircleBuilder> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
public org.elasticsearch.geo.geometry.Circle buildGeometry() {
|
||||
throw new UnsupportedOperationException("CIRCLE geometry is not supported");
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class EnvelopeBuilder extends ShapeBuilder<Rectangle, EnvelopeBuilder> {
|
||||
public class EnvelopeBuilder extends ShapeBuilder<Rectangle, org.elasticsearch.geo.geometry.Rectangle, EnvelopeBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE;
|
||||
|
||||
|
@ -113,8 +113,8 @@ public class EnvelopeBuilder extends ShapeBuilder<Rectangle, EnvelopeBuilder> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public org.apache.lucene.geo.Rectangle buildLucene() {
|
||||
return new org.apache.lucene.geo.Rectangle(bottomRight.y, topLeft.y, topLeft.x, bottomRight.x);
|
||||
public org.elasticsearch.geo.geometry.Rectangle buildGeometry() {
|
||||
return new org.elasticsearch.geo.geometry.Rectangle(bottomRight.y, topLeft.y, topLeft.x, bottomRight.x);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,11 +31,11 @@ import org.locationtech.spatial4j.shape.Shape;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class GeometryCollectionBuilder extends ShapeBuilder<Shape, GeometryCollectionBuilder> {
|
||||
public class GeometryCollectionBuilder extends ShapeBuilder<Shape,
|
||||
org.elasticsearch.geo.geometry.GeometryCollection<org.elasticsearch.geo.geometry.Geometry>, GeometryCollectionBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION;
|
||||
|
||||
|
@ -185,19 +185,14 @@ public class GeometryCollectionBuilder extends ShapeBuilder<Shape, GeometryColle
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
List<Object> shapes = new ArrayList<>(this.shapes.size());
|
||||
public org.elasticsearch.geo.geometry.GeometryCollection<org.elasticsearch.geo.geometry.Geometry> buildGeometry() {
|
||||
List<org.elasticsearch.geo.geometry.Geometry> shapes = new ArrayList<>(this.shapes.size());
|
||||
|
||||
for (ShapeBuilder shape : this.shapes) {
|
||||
Object o = shape.buildLucene();
|
||||
if (o.getClass().isArray()) {
|
||||
shapes.addAll(Arrays.asList((Object[])o));
|
||||
} else {
|
||||
shapes.add(o);
|
||||
}
|
||||
shapes.add(shape.buildGeometry());
|
||||
}
|
||||
|
||||
return shapes.toArray(new Object[shapes.size()]);
|
||||
return new org.elasticsearch.geo.geometry.GeometryCollection<>(shapes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
|
||||
package org.elasticsearch.common.geo.builders;
|
||||
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
|
||||
import org.elasticsearch.common.geo.GeoShapeType;
|
||||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.geo.geometry.Line;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.GeometryFactory;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
import org.locationtech.spatial4j.shape.jts.JtsGeometry;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -39,7 +39,7 @@ import java.util.List;
|
|||
import static org.elasticsearch.common.geo.GeoUtils.normalizeLat;
|
||||
import static org.elasticsearch.common.geo.GeoUtils.normalizeLon;
|
||||
|
||||
public class LineStringBuilder extends ShapeBuilder<JtsGeometry, LineStringBuilder> {
|
||||
public class LineStringBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.geo.geometry.Geometry, LineStringBuilder> {
|
||||
public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;
|
||||
|
||||
/**
|
||||
|
@ -125,15 +125,15 @@ public class LineStringBuilder extends ShapeBuilder<JtsGeometry, LineStringBuild
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
public org.elasticsearch.geo.geometry.Geometry buildGeometry() {
|
||||
// decompose linestrings crossing dateline into array of Lines
|
||||
Coordinate[] coordinates = this.coordinates.toArray(new Coordinate[this.coordinates.size()]);
|
||||
if (wrapdateline) {
|
||||
ArrayList<Line> linestrings = decomposeLucene(coordinates, new ArrayList<>());
|
||||
List<Line> linestrings = decomposeGeometry(coordinates, new ArrayList<>());
|
||||
if (linestrings.size() == 1) {
|
||||
return linestrings.get(0);
|
||||
} else {
|
||||
return linestrings.toArray(new Line[linestrings.size()]);
|
||||
return new MultiLine(linestrings);
|
||||
}
|
||||
}
|
||||
return new Line(Arrays.stream(coordinates).mapToDouble(i->normalizeLat(i.y)).toArray(),
|
||||
|
@ -149,7 +149,7 @@ public class LineStringBuilder extends ShapeBuilder<JtsGeometry, LineStringBuild
|
|||
return strings;
|
||||
}
|
||||
|
||||
static ArrayList<Line> decomposeLucene(Coordinate[] coordinates, ArrayList<Line> lines) {
|
||||
static List<Line> decomposeGeometry(Coordinate[] coordinates, List<Line> lines) {
|
||||
for (Coordinate[] part : decompose(+DATELINE, coordinates)) {
|
||||
for (Coordinate[] line : decompose(-DATELINE, part)) {
|
||||
lines.add(new Line(Arrays.stream(line).mapToDouble(i->normalizeLat(i.y)).toArray(),
|
||||
|
|
|
@ -19,25 +19,25 @@
|
|||
|
||||
package org.elasticsearch.common.geo.builders;
|
||||
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.elasticsearch.common.geo.GeoShapeType;
|
||||
import org.elasticsearch.common.geo.parsers.GeoWKTParser;
|
||||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.geom.LineString;
|
||||
import org.locationtech.spatial4j.shape.jts.JtsGeometry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MultiLineStringBuilder extends ShapeBuilder<JtsGeometry, MultiLineStringBuilder> {
|
||||
public class MultiLineStringBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.geo.geometry.Geometry, MultiLineStringBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;
|
||||
|
||||
|
@ -150,24 +150,24 @@ public class MultiLineStringBuilder extends ShapeBuilder<JtsGeometry, MultiLineS
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
public org.elasticsearch.geo.geometry.Geometry buildGeometry() {
|
||||
if (wrapdateline) {
|
||||
ArrayList<Line> parts = new ArrayList<>();
|
||||
List<org.elasticsearch.geo.geometry.Line> parts = new ArrayList<>();
|
||||
for (LineStringBuilder line : lines) {
|
||||
LineStringBuilder.decomposeLucene(line.coordinates(false), parts);
|
||||
LineStringBuilder.decomposeGeometry(line.coordinates(false), parts);
|
||||
}
|
||||
if (parts.size() == 1) {
|
||||
return parts.get(0);
|
||||
}
|
||||
return parts.toArray(new Line[parts.size()]);
|
||||
return new MultiLine(parts);
|
||||
}
|
||||
Line[] linestrings = new Line[lines.size()];
|
||||
List<org.elasticsearch.geo.geometry.Line> linestrings = new ArrayList<>(lines.size());
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
LineStringBuilder lsb = lines.get(i);
|
||||
linestrings[i] = new Line(lsb.coordinates.stream().mapToDouble(c->c.y).toArray(),
|
||||
lsb.coordinates.stream().mapToDouble(c->c.x).toArray());
|
||||
linestrings.add(new org.elasticsearch.geo.geometry.Line(lsb.coordinates.stream().mapToDouble(c->c.y).toArray(),
|
||||
lsb.coordinates.stream().mapToDouble(c->c.x).toArray()));
|
||||
}
|
||||
return linestrings;
|
||||
return new MultiLine(linestrings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,14 +24,16 @@ import org.elasticsearch.common.geo.XShapeCollection;
|
|||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.geo.geometry.MultiPoint;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.spatial4j.shape.Point;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MultiPointBuilder extends ShapeBuilder<XShapeCollection<Point>, MultiPointBuilder> {
|
||||
public class MultiPointBuilder extends ShapeBuilder<XShapeCollection<Point>, MultiPoint, MultiPointBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT;
|
||||
|
||||
|
@ -74,14 +76,9 @@ public class MultiPointBuilder extends ShapeBuilder<XShapeCollection<Point>, Mul
|
|||
}
|
||||
|
||||
@Override
|
||||
public double[][] buildLucene() {
|
||||
double[][] points = new double[coordinates.size()][];
|
||||
Coordinate coord;
|
||||
for (int i = 0; i < coordinates.size(); ++i) {
|
||||
coord = coordinates.get(i);
|
||||
points[i] = new double[] {coord.x, coord.y};
|
||||
}
|
||||
return points;
|
||||
public MultiPoint buildGeometry() {
|
||||
return new MultiPoint(coordinates.stream().map(coord -> new org.elasticsearch.geo.geometry.Point(coord.y, coord.x))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,17 +26,17 @@ import org.elasticsearch.common.geo.parsers.ShapeParser;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.geo.geometry.MultiPolygon;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.spatial4j.shape.Shape;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MultiPolygonBuilder extends ShapeBuilder<Shape, MultiPolygonBuilder> {
|
||||
public class MultiPolygonBuilder extends ShapeBuilder<Shape, MultiPolygon, MultiPolygonBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.MULTIPOLYGON;
|
||||
|
||||
|
@ -185,31 +185,20 @@ public class MultiPolygonBuilder extends ShapeBuilder<Shape, MultiPolygonBuilder
|
|||
//note: ShapeCollection is probably faster than a Multi* geom.
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
List<org.apache.lucene.geo.Polygon> shapes = new ArrayList<>(this.polygons.size());
|
||||
public MultiPolygon buildGeometry() {
|
||||
List<org.elasticsearch.geo.geometry.Polygon> shapes = new ArrayList<>(this.polygons.size());
|
||||
Object poly;
|
||||
if (wrapdateline) {
|
||||
for (PolygonBuilder polygon : this.polygons) {
|
||||
poly = polygon.buildLucene();
|
||||
if (poly instanceof org.apache.lucene.geo.Polygon[]) {
|
||||
shapes.addAll(Arrays.asList((org.apache.lucene.geo.Polygon[])poly));
|
||||
} else {
|
||||
shapes.add((org.apache.lucene.geo.Polygon)poly);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < this.polygons.size(); ++i) {
|
||||
PolygonBuilder pb = this.polygons.get(i);
|
||||
poly = pb.buildLucene();
|
||||
if (poly instanceof org.apache.lucene.geo.Polygon[]) {
|
||||
shapes.addAll(Arrays.asList((org.apache.lucene.geo.Polygon[])poly));
|
||||
} else {
|
||||
shapes.add((org.apache.lucene.geo.Polygon)poly);
|
||||
}
|
||||
for (PolygonBuilder polygon : this.polygons) {
|
||||
poly = polygon.buildGeometry();
|
||||
if (poly instanceof List) {
|
||||
shapes.addAll((List<org.elasticsearch.geo.geometry.Polygon>) poly);
|
||||
} else {
|
||||
shapes.add((org.elasticsearch.geo.geometry.Polygon)poly);
|
||||
}
|
||||
}
|
||||
return shapes.stream().toArray(org.apache.lucene.geo.Polygon[]::new);
|
||||
return new MultiPolygon(shapes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
package org.elasticsearch.common.geo.builders;
|
||||
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoShapeType;
|
||||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.locationtech.spatial4j.shape.Point;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
import org.locationtech.spatial4j.shape.Point;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PointBuilder extends ShapeBuilder<Point, PointBuilder> {
|
||||
public class PointBuilder extends ShapeBuilder<Point, org.elasticsearch.geo.geometry.Point, PointBuilder> {
|
||||
public static final GeoShapeType TYPE = GeoShapeType.POINT;
|
||||
|
||||
/**
|
||||
|
@ -90,8 +88,8 @@ public class PointBuilder extends ShapeBuilder<Point, PointBuilder> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GeoPoint buildLucene() {
|
||||
return new GeoPoint(coordinates.get(0).y, coordinates.get(0).x);
|
||||
public org.elasticsearch.geo.geometry.Point buildGeometry() {
|
||||
return new org.elasticsearch.geo.geometry.Point(coordinates.get(0).y, coordinates.get(0).x);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.locationtech.spatial4j.shape.jts.JtsGeometry;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -55,7 +56,7 @@ import static org.apache.lucene.geo.GeoUtils.orient;
|
|||
* Methods to wrap polygons at the dateline and building shapes from the data held by the
|
||||
* builder.
|
||||
*/
|
||||
public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
||||
public class PolygonBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.geo.geometry.Geometry, PolygonBuilder> {
|
||||
|
||||
public static final GeoShapeType TYPE = GeoShapeType.POLYGON;
|
||||
|
||||
|
@ -233,14 +234,14 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object buildLucene() {
|
||||
public org.elasticsearch.geo.geometry.Geometry buildGeometry() {
|
||||
if (wrapdateline) {
|
||||
Coordinate[][][] polygons = coordinates();
|
||||
return polygons.length == 1
|
||||
? polygonLucene(polygons[0])
|
||||
: multipolygonLucene(polygons);
|
||||
? polygonGeometry(polygons[0])
|
||||
: multipolygon(polygons);
|
||||
}
|
||||
return toPolygonLucene();
|
||||
return toPolygonGeometry();
|
||||
}
|
||||
|
||||
protected XContentBuilder coordinatesArray(XContentBuilder builder, Params params) throws IOException {
|
||||
|
@ -288,17 +289,19 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
return factory.createPolygon(shell, holes);
|
||||
}
|
||||
|
||||
public Object toPolygonLucene() {
|
||||
final org.apache.lucene.geo.Polygon[] holes = new org.apache.lucene.geo.Polygon[this.holes.size()];
|
||||
for (int i = 0; i < holes.length; ++i) {
|
||||
holes[i] = linearRing(this.holes.get(i).coordinates);
|
||||
public org.elasticsearch.geo.geometry.Polygon toPolygonGeometry() {
|
||||
final List<org.elasticsearch.geo.geometry.LinearRing> holes = new ArrayList<>(this.holes.size());
|
||||
for (int i = 0; i < this.holes.size(); ++i) {
|
||||
holes.add(linearRing(this.holes.get(i).coordinates));
|
||||
}
|
||||
return new org.apache.lucene.geo.Polygon(this.shell.coordinates.stream().mapToDouble(i -> normalizeLat(i.y)).toArray(),
|
||||
this.shell.coordinates.stream().mapToDouble(i -> normalizeLon(i.x)).toArray(), holes);
|
||||
return new org.elasticsearch.geo.geometry.Polygon(
|
||||
new org.elasticsearch.geo.geometry.LinearRing(
|
||||
this.shell.coordinates.stream().mapToDouble(i -> normalizeLat(i.y)).toArray(),
|
||||
this.shell.coordinates.stream().mapToDouble(i -> normalizeLon(i.x)).toArray()), holes);
|
||||
}
|
||||
|
||||
protected static org.apache.lucene.geo.Polygon linearRing(List<Coordinate> coordinates) {
|
||||
return new org.apache.lucene.geo.Polygon(coordinates.stream().mapToDouble(i -> normalizeLat(i.y)).toArray(),
|
||||
protected static org.elasticsearch.geo.geometry.LinearRing linearRing(List<Coordinate> coordinates) {
|
||||
return new org.elasticsearch.geo.geometry.LinearRing(coordinates.stream().mapToDouble(i -> normalizeLat(i.y)).toArray(),
|
||||
coordinates.stream().mapToDouble(i -> normalizeLon(i.x)).toArray());
|
||||
}
|
||||
|
||||
|
@ -335,13 +338,13 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
return factory.createPolygon(shell, holes);
|
||||
}
|
||||
|
||||
protected static org.apache.lucene.geo.Polygon polygonLucene(Coordinate[][] polygon) {
|
||||
org.apache.lucene.geo.Polygon[] holes;
|
||||
protected static org.elasticsearch.geo.geometry.Polygon polygonGeometry(Coordinate[][] polygon) {
|
||||
List<org.elasticsearch.geo.geometry.LinearRing> holes;
|
||||
Coordinate[] shell = polygon[0];
|
||||
if (polygon.length > 1) {
|
||||
holes = new org.apache.lucene.geo.Polygon[polygon.length - 1];
|
||||
for (int i = 0; i < holes.length; ++i) {
|
||||
Coordinate[] coords = polygon[i+1];
|
||||
holes = new ArrayList<>(polygon.length - 1);
|
||||
for (int i = 1; i < polygon.length; ++i) {
|
||||
Coordinate[] coords = polygon[i];
|
||||
//We do not have holes on the dateline as they get eliminated
|
||||
//when breaking the polygon around it.
|
||||
double[] x = new double[coords.length];
|
||||
|
@ -350,10 +353,10 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
x[c] = normalizeLon(coords[c].x);
|
||||
y[c] = normalizeLat(coords[c].y);
|
||||
}
|
||||
holes[i] = new org.apache.lucene.geo.Polygon(y, x);
|
||||
holes.add(new org.elasticsearch.geo.geometry.LinearRing(y, x));
|
||||
}
|
||||
} else {
|
||||
holes = new org.apache.lucene.geo.Polygon[0];
|
||||
holes = Collections.emptyList();
|
||||
}
|
||||
|
||||
double[] x = new double[shell.length];
|
||||
|
@ -365,7 +368,7 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
y[i] = normalizeLat(shell[i].y);
|
||||
}
|
||||
|
||||
return new org.apache.lucene.geo.Polygon(y, x, holes);
|
||||
return new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(y, x), holes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,12 +389,12 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, PolygonBuilder> {
|
|||
return factory.createMultiPolygon(polygonSet);
|
||||
}
|
||||
|
||||
protected static org.apache.lucene.geo.Polygon[] multipolygonLucene(Coordinate[][][] polygons) {
|
||||
org.apache.lucene.geo.Polygon[] polygonSet = new org.apache.lucene.geo.Polygon[polygons.length];
|
||||
for (int i = 0; i < polygonSet.length; ++i) {
|
||||
polygonSet[i] = polygonLucene(polygons[i]);
|
||||
protected static org.elasticsearch.geo.geometry.MultiPolygon multipolygon(Coordinate[][][] polygons) {
|
||||
List<org.elasticsearch.geo.geometry.Polygon> polygonSet = new ArrayList<>(polygons.length);
|
||||
for (int i = 0; i < polygons.length; ++i) {
|
||||
polygonSet.add(polygonGeometry(polygons[i]));
|
||||
}
|
||||
return polygonSet;
|
||||
return new org.elasticsearch.geo.geometry.MultiPolygon(polygonSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,8 @@ import java.util.Objects;
|
|||
/**
|
||||
* Basic class for building GeoJSON shapes like Polygons, Linestrings, etc
|
||||
*/
|
||||
public abstract class ShapeBuilder<T extends Shape, E extends ShapeBuilder<T,E>> implements NamedWriteable, ToXContentObject {
|
||||
public abstract class ShapeBuilder<T extends Shape, G extends org.elasticsearch.geo.geometry.Geometry,
|
||||
E extends ShapeBuilder<T, G, E>> implements NamedWriteable, ToXContentObject {
|
||||
|
||||
protected static final Logger LOGGER = LogManager.getLogger(ShapeBuilder.class);
|
||||
|
||||
|
@ -218,7 +219,7 @@ public abstract class ShapeBuilder<T extends Shape, E extends ShapeBuilder<T,E>>
|
|||
*
|
||||
* @return GeoPoint, double[][], Line, Line[], Polygon, Polygon[], Rectangle, Object[]
|
||||
*/
|
||||
public abstract Object buildLucene();
|
||||
public abstract G buildGeometry();
|
||||
|
||||
protected static Coordinate shift(Coordinate coordinate, double dateline) {
|
||||
if (dateline == 0) {
|
||||
|
@ -484,7 +485,7 @@ public abstract class ShapeBuilder<T extends Shape, E extends ShapeBuilder<T,E>>
|
|||
if (this == o) return true;
|
||||
if (!(o instanceof ShapeBuilder)) return false;
|
||||
|
||||
ShapeBuilder<?,?> that = (ShapeBuilder<?,?>) o;
|
||||
ShapeBuilder<?,?,?> that = (ShapeBuilder<?,?,?>) o;
|
||||
|
||||
return Objects.equals(coordinates, that.coordinates);
|
||||
}
|
||||
|
|
|
@ -22,13 +22,20 @@ import org.apache.lucene.document.Field;
|
|||
import org.apache.lucene.document.LatLonShape;
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.apache.lucene.geo.Polygon;
|
||||
import org.apache.lucene.geo.Rectangle;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.elasticsearch.common.Explicit;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.builders.ShapeBuilder;
|
||||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.geo.geometry.Circle;
|
||||
import org.elasticsearch.geo.geometry.Geometry;
|
||||
import org.elasticsearch.geo.geometry.GeometryCollection;
|
||||
import org.elasticsearch.geo.geometry.GeometryVisitor;
|
||||
import org.elasticsearch.geo.geometry.LinearRing;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.elasticsearch.geo.geometry.MultiPoint;
|
||||
import org.elasticsearch.geo.geometry.MultiPolygon;
|
||||
import org.elasticsearch.geo.geometry.Point;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -107,7 +114,7 @@ public class GeoShapeFieldMapper extends BaseGeoShapeFieldMapper {
|
|||
if (shapeBuilder == null) {
|
||||
return;
|
||||
}
|
||||
shape = shapeBuilder.buildLucene();
|
||||
shape = shapeBuilder.buildGeometry();
|
||||
}
|
||||
indexShape(context, shape);
|
||||
} catch (Exception e) {
|
||||
|
@ -120,47 +127,97 @@ public class GeoShapeFieldMapper extends BaseGeoShapeFieldMapper {
|
|||
}
|
||||
|
||||
private void indexShape(ParseContext context, Object luceneShape) {
|
||||
if (luceneShape instanceof GeoPoint) {
|
||||
GeoPoint pt = (GeoPoint) luceneShape;
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), pt.lat(), pt.lon()));
|
||||
} else if (luceneShape instanceof double[]) {
|
||||
double[] pt = (double[]) luceneShape;
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), pt[1], pt[0]));
|
||||
} else if (luceneShape instanceof Line) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), (Line)luceneShape));
|
||||
} else if (luceneShape instanceof Polygon) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), (Polygon) luceneShape));
|
||||
} else if (luceneShape instanceof double[][]) {
|
||||
double[][] pts = (double[][])luceneShape;
|
||||
for (int i = 0; i < pts.length; ++i) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), pts[i][1], pts[i][0]));
|
||||
}
|
||||
} else if (luceneShape instanceof Line[]) {
|
||||
Line[] lines = (Line[]) luceneShape;
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), lines[i]));
|
||||
}
|
||||
} else if (luceneShape instanceof Polygon[]) {
|
||||
Polygon[] polys = (Polygon[]) luceneShape;
|
||||
for (int i = 0; i < polys.length; ++i) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), polys[i]));
|
||||
}
|
||||
} else if (luceneShape instanceof Rectangle) {
|
||||
// index rectangle as a polygon
|
||||
Rectangle r = (Rectangle) luceneShape;
|
||||
Polygon p = new Polygon(new double[]{r.minLat, r.minLat, r.maxLat, r.maxLat, r.minLat},
|
||||
new double[]{r.minLon, r.maxLon, r.maxLon, r.minLon, r.minLon});
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), p));
|
||||
} else if (luceneShape instanceof Object[]) {
|
||||
// recurse to index geometry collection
|
||||
for (Object o : (Object[])luceneShape) {
|
||||
indexShape(context, o);
|
||||
}
|
||||
if (luceneShape instanceof Geometry) {
|
||||
((Geometry) luceneShape).visit(new LuceneGeometryIndexer(context));
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid shape type found [" + luceneShape.getClass() + "] while indexing shape");
|
||||
}
|
||||
}
|
||||
|
||||
private class LuceneGeometryIndexer implements GeometryVisitor<Void> {
|
||||
private ParseContext context;
|
||||
|
||||
private LuceneGeometryIndexer(ParseContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(Circle circle) {
|
||||
throw new IllegalArgumentException("invalid shape type found [Circle] while indexing shape");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GeometryCollection<?> collection) {
|
||||
for (Geometry geometry : collection) {
|
||||
geometry.visit(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(org.elasticsearch.geo.geometry.Line line) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), new Line(line.getLats(), line.getLons())));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(LinearRing ring) {
|
||||
throw new IllegalArgumentException("invalid shape type found [LinearRing] while indexing shape");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(MultiLine multiLine) {
|
||||
for (org.elasticsearch.geo.geometry.Line line : multiLine) {
|
||||
visit(line);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(MultiPoint multiPoint) {
|
||||
for(Point point : multiPoint) {
|
||||
visit(point);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(MultiPolygon multiPolygon) {
|
||||
for(org.elasticsearch.geo.geometry.Polygon polygon : multiPolygon) {
|
||||
visit(polygon);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(Point point) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), point.getLat(), point.getLon()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(org.elasticsearch.geo.geometry.Polygon polygon) {
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), toLucenePolygon(polygon)));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(org.elasticsearch.geo.geometry.Rectangle r) {
|
||||
Polygon p = new Polygon(new double[]{r.getMinLat(), r.getMinLat(), r.getMaxLat(), r.getMaxLat(), r.getMinLat()},
|
||||
new double[]{r.getMinLon(), r.getMaxLon(), r.getMaxLon(), r.getMinLon(), r.getMinLon()});
|
||||
indexFields(context, LatLonShape.createIndexableFields(name(), p));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Polygon toLucenePolygon(org.elasticsearch.geo.geometry.Polygon polygon) {
|
||||
Polygon[] holes = new Polygon[polygon.getNumberOfHoles()];
|
||||
for(int i = 0; i<holes.length; i++) {
|
||||
holes[i] = new Polygon(polygon.getHole(i).getLats(), polygon.getHole(i).getLons());
|
||||
}
|
||||
return new Polygon(polygon.getPolygon().getLats(), polygon.getPolygon().getLons(), holes);
|
||||
}
|
||||
|
||||
private void indexFields(ParseContext context, Field[] fields) {
|
||||
ArrayList<IndexableField> flist = new ArrayList<>(Arrays.asList(fields));
|
||||
createFieldNamesField(context, flist);
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.lucene.document.LatLonShape;
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.apache.lucene.geo.Polygon;
|
||||
import org.apache.lucene.geo.Rectangle;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
|
@ -42,7 +41,6 @@ import org.elasticsearch.client.Client;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoShapeType;
|
||||
import org.elasticsearch.common.geo.ShapeRelation;
|
||||
import org.elasticsearch.common.geo.SpatialStrategy;
|
||||
|
@ -56,6 +54,15 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.geo.geometry.Circle;
|
||||
import org.elasticsearch.geo.geometry.Geometry;
|
||||
import org.elasticsearch.geo.geometry.GeometryCollection;
|
||||
import org.elasticsearch.geo.geometry.GeometryVisitor;
|
||||
import org.elasticsearch.geo.geometry.LinearRing;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.elasticsearch.geo.geometry.MultiPoint;
|
||||
import org.elasticsearch.geo.geometry.MultiPolygon;
|
||||
import org.elasticsearch.geo.geometry.Point;
|
||||
import org.elasticsearch.index.mapper.BaseGeoShapeFieldMapper;
|
||||
import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
|
@ -64,6 +71,8 @@ import java.io.IOException;
|
|||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.elasticsearch.index.mapper.GeoShapeFieldMapper.toLucenePolygon;
|
||||
|
||||
/**
|
||||
* {@link QueryBuilder} that builds a GeoShape Query
|
||||
*/
|
||||
|
@ -446,55 +455,85 @@ public class GeoShapeQueryBuilder extends AbstractQueryBuilder<GeoShapeQueryBuil
|
|||
}
|
||||
|
||||
// wrap geoQuery as a ConstantScoreQuery
|
||||
return getVectorQueryFromShape(context, queryShapeBuilder.buildLucene());
|
||||
return getVectorQueryFromShape(context, queryShapeBuilder.buildGeometry());
|
||||
}
|
||||
|
||||
private Query getVectorQueryFromShape(QueryShardContext context, Object queryShape) {
|
||||
Query geoQuery;
|
||||
if (queryShape instanceof Line[]) {
|
||||
geoQuery = LatLonShape.newLineQuery(fieldName(), relation.getLuceneRelation(), (Line[]) queryShape);
|
||||
} else if (queryShape instanceof Polygon[]) {
|
||||
geoQuery = LatLonShape.newPolygonQuery(fieldName(), relation.getLuceneRelation(), (Polygon[]) queryShape);
|
||||
} else if (queryShape instanceof Line) {
|
||||
geoQuery = LatLonShape.newLineQuery(fieldName(), relation.getLuceneRelation(), (Line) queryShape);
|
||||
} else if (queryShape instanceof Polygon) {
|
||||
geoQuery = LatLonShape.newPolygonQuery(fieldName(), relation.getLuceneRelation(), (Polygon) queryShape);
|
||||
} else if (queryShape instanceof Rectangle) {
|
||||
Rectangle r = (Rectangle) queryShape;
|
||||
geoQuery = LatLonShape.newBoxQuery(fieldName(), relation.getLuceneRelation(),
|
||||
r.minLat, r.maxLat, r.minLon, r.maxLon);
|
||||
} else if (queryShape instanceof double[][]) {
|
||||
// note: we decompose point queries into a bounding box query with min values == max values
|
||||
// to do this for multipoint we would have to create a BooleanQuery for each point
|
||||
// this is *way* too costly. So we do not allow multipoint queries
|
||||
throw new QueryShardException(context, "Field [" + fieldName + "] does not support " + GeoShapeType.MULTIPOINT + " queries");
|
||||
} else if (queryShape instanceof double[] || queryShape instanceof GeoPoint) {
|
||||
// for now just create a single bounding box query with min values == max values
|
||||
double[] pt;
|
||||
if (queryShape instanceof GeoPoint) {
|
||||
pt = new double[] {((GeoPoint)queryShape).lon(), ((GeoPoint)queryShape).lat()};
|
||||
} else {
|
||||
pt = (double[])queryShape;
|
||||
if (pt.length != 2) {
|
||||
throw new QueryShardException(context, "Expected double array of length 2. "
|
||||
+ "But found length " + pt.length + " for field [" + fieldName + "]");
|
||||
private Query getVectorQueryFromShape(QueryShardContext context, Geometry queryShape) {
|
||||
return queryShape.visit(new GeometryVisitor<Query>() {
|
||||
@Override
|
||||
public Query visit(Circle circle) {
|
||||
throw new QueryShardException(context, "Field [" + fieldName + "] found and unknown shape Circle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(GeometryCollection<?> collection) {
|
||||
BooleanQuery.Builder bqb = new BooleanQuery.Builder();
|
||||
visit(bqb, collection);
|
||||
return bqb.build();
|
||||
}
|
||||
|
||||
private void visit(BooleanQuery.Builder bqb, GeometryCollection<?> collection) {
|
||||
for (Geometry shape : collection) {
|
||||
if (shape instanceof MultiPoint) {
|
||||
// Flatten multipoints
|
||||
visit(bqb, (GeometryCollection<?>) shape);
|
||||
} else {
|
||||
bqb.add(shape.visit(this), BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
}
|
||||
}
|
||||
return LatLonShape.newBoxQuery(fieldName, relation.getLuceneRelation(), pt[1], pt[1], pt[0], pt[0]);
|
||||
} else if (queryShape instanceof Object[]) {
|
||||
geoQuery = createGeometryCollectionQuery(context, (Object[]) queryShape);
|
||||
} else {
|
||||
throw new QueryShardException(context, "Field [" + fieldName + "] found and unknown shape");
|
||||
}
|
||||
return geoQuery;
|
||||
}
|
||||
|
||||
private Query createGeometryCollectionQuery(QueryShardContext context, Object... shapes) {
|
||||
BooleanQuery.Builder bqb = new BooleanQuery.Builder();
|
||||
for (Object shape : shapes) {
|
||||
bqb.add(getVectorQueryFromShape(context, shape), BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
return bqb.build();
|
||||
@Override
|
||||
public Query visit(org.elasticsearch.geo.geometry.Line line) {
|
||||
return LatLonShape.newLineQuery(fieldName(), relation.getLuceneRelation(), new Line(line.getLats(), line.getLons()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(LinearRing ring) {
|
||||
throw new QueryShardException(context, "Field [" + fieldName + "] found and unsupported shape LinearRing");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(MultiLine multiLine) {
|
||||
Line[] lines = new Line[multiLine.size()];
|
||||
for (int i=0; i<multiLine.size(); i++) {
|
||||
lines[i] = new Line(multiLine.get(i).getLats(), multiLine.get(i).getLons());
|
||||
}
|
||||
return LatLonShape.newLineQuery(fieldName(), relation.getLuceneRelation(), lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(MultiPoint multiPoint) {
|
||||
throw new QueryShardException(context, "Field [" + fieldName + "] does not support " + GeoShapeType.MULTIPOINT +
|
||||
" queries");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(MultiPolygon multiPolygon) {
|
||||
Polygon[] polygons = new Polygon[multiPolygon.size()];
|
||||
for (int i=0; i<multiPolygon.size(); i++) {
|
||||
polygons[i] = toLucenePolygon(multiPolygon.get(i));
|
||||
}
|
||||
return LatLonShape.newPolygonQuery(fieldName(), relation.getLuceneRelation(), polygons);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(Point point) {
|
||||
return LatLonShape.newBoxQuery(fieldName, relation.getLuceneRelation(),
|
||||
point.getLat(), point.getLat(), point.getLon(), point.getLon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(org.elasticsearch.geo.geometry.Polygon polygon) {
|
||||
return LatLonShape.newPolygonQuery(fieldName(), relation.getLuceneRelation(), toLucenePolygon(polygon));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query visit(org.elasticsearch.geo.geometry.Rectangle r) {
|
||||
return LatLonShape.newBoxQuery(fieldName(), relation.getLuceneRelation(),
|
||||
r.getMinLat(), r.getMaxLat(), r.getMinLon(), r.getMaxLon());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,7 +62,7 @@ abstract class BaseGeoParsingTestCase extends ESTestCase {
|
|||
if (useJTS) {
|
||||
ElasticsearchGeoAssertions.assertEquals(expected, ShapeParser.parse(parser).buildS4J());
|
||||
} else {
|
||||
ElasticsearchGeoAssertions.assertEquals(expected, ShapeParser.parse(parser).buildLucene());
|
||||
ElasticsearchGeoAssertions.assertEquals(expected, ShapeParser.parse(parser).buildGeometry());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.common.geo;
|
||||
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
|
@ -31,6 +30,10 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.geo.geometry.Geometry;
|
||||
import org.elasticsearch.geo.geometry.GeometryCollection;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.elasticsearch.geo.geometry.MultiPoint;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
|
||||
import org.elasticsearch.index.mapper.Mapper;
|
||||
|
@ -53,6 +56,7 @@ import org.locationtech.spatial4j.shape.jts.JtsPoint;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.geo.builders.ShapeBuilder.SPATIAL_CONTEXT;
|
||||
|
@ -72,7 +76,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
.endObject();
|
||||
Point expected = GEOMETRY_FACTORY.createPoint(new Coordinate(100.0, 0.0));
|
||||
assertGeometryEquals(new JtsPoint(expected, SPATIAL_CONTEXT), pointGeoJson, true);
|
||||
assertGeometryEquals(new GeoPoint(0d, 100d), pointGeoJson, false);
|
||||
assertGeometryEquals(new org.elasticsearch.geo.geometry.Point(0d, 100d), pointGeoJson, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +102,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(lineGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertLineString(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertLineString(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,9 +134,9 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
}),
|
||||
});
|
||||
assertGeometryEquals(jtsGeom(expected), multilinesGeoJson, true);
|
||||
assertGeometryEquals(new Line[] {
|
||||
new Line(new double[] {0d, 1d}, new double[] {100d, 101d}),
|
||||
new Line(new double[] {2d, 3d}, new double[] {102d, 103d})},
|
||||
assertGeometryEquals(new MultiLine(Arrays.asList(
|
||||
new org.elasticsearch.geo.geometry.Line(new double[] {0d, 1d}, new double[] {100d, 101d}),
|
||||
new org.elasticsearch.geo.geometry.Line(new double[] {2d, 3d}, new double[] {102d, 103d}))),
|
||||
multilinesGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -188,7 +192,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
.endObject();
|
||||
Rectangle expected = SPATIAL_CONTEXT.makeRectangle(-50, 50, -30, 30);
|
||||
assertGeometryEquals(expected, multilinesGeoJson, true);
|
||||
assertGeometryEquals(new org.apache.lucene.geo.Rectangle(-30, 30, -50, 50),
|
||||
assertGeometryEquals(new org.elasticsearch.geo.geometry.Rectangle(-30, 30, -50, 50),
|
||||
multilinesGeoJson, false);
|
||||
|
||||
// test #2: envelope that spans dateline
|
||||
|
@ -201,7 +205,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
expected = SPATIAL_CONTEXT.makeRectangle(50, -50, -30, 30);
|
||||
assertGeometryEquals(expected, multilinesGeoJson, true);
|
||||
assertGeometryEquals(new org.apache.lucene.geo.Rectangle(-30, 30, 50, -50),
|
||||
assertGeometryEquals(new org.elasticsearch.geo.geometry.Rectangle(-30, 30, 50, -50),
|
||||
multilinesGeoJson, false);
|
||||
|
||||
// test #3: "envelope" (actually a triangle) with invalid number of coordinates (TopRight, BottomLeft, BottomRight)
|
||||
|
@ -257,9 +261,10 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, null);
|
||||
assertGeometryEquals(jtsGeom(expected), polygonGeoJson, true);
|
||||
|
||||
org.apache.lucene.geo.Polygon p = new org.apache.lucene.geo.Polygon(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d},
|
||||
new double[] {100d, 101d, 101d, 100d, 100d});
|
||||
org.elasticsearch.geo.geometry.Polygon p = new org.elasticsearch.geo.geometry.Polygon(
|
||||
new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d},
|
||||
new double[] {100d, 101d, 101d, 100d, 100d}));
|
||||
assertGeometryEquals(p, polygonGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -303,9 +308,10 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
ElasticsearchGeoAssertions.assertEquals(jtsGeom(expected), ShapeParser.parse(parser, mapperBuilder).buildS4J());
|
||||
}
|
||||
|
||||
org.apache.lucene.geo.Polygon p = new org.apache.lucene.geo.Polygon(
|
||||
org.elasticsearch.geo.geometry.Polygon p = new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
Arrays.stream(coordinates).mapToDouble(i->i.y).toArray(),
|
||||
Arrays.stream(coordinates).mapToDouble(i->i.x).toArray());
|
||||
Arrays.stream(coordinates).mapToDouble(i->i.x).toArray()
|
||||
));
|
||||
assertGeometryEquals(p, polygonGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -502,7 +508,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 2: ccw poly crossing dateline
|
||||
|
@ -527,7 +533,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 3: cw poly not crossing dateline
|
||||
|
@ -552,7 +558,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 4: cw poly crossing dateline
|
||||
|
@ -577,7 +583,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -610,7 +616,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 2: ccw poly crossing dateline
|
||||
|
@ -641,7 +647,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 3: cw poly not crossing dateline
|
||||
|
@ -672,7 +678,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 4: cw poly crossing dateline
|
||||
|
@ -703,7 +709,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,12 +861,12 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, holes);
|
||||
assertGeometryEquals(jtsGeom(expected), polygonGeoJson, true);
|
||||
|
||||
org.apache.lucene.geo.Polygon hole =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
org.elasticsearch.geo.geometry.LinearRing hole =
|
||||
new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0.8d, 0.2d, 0.2d, 0.8d, 0.8d}, new double[] {100.8d, 100.8d, 100.2d, 100.2d, 100.8d});
|
||||
org.apache.lucene.geo.Polygon p =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d}, new double[] {100d, 101d, 101d, 100d, 100d}, hole);
|
||||
org.elasticsearch.geo.geometry.Polygon p =
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d}, new double[] {100d, 101d, 101d, 100d, 100d}), Collections.singletonList(hole));
|
||||
assertGeometryEquals(p, polygonGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -902,9 +908,9 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
SPATIAL_CONTEXT.makePoint(101, 1.0));
|
||||
assertGeometryEquals(expected, multiPointGeoJson, true);
|
||||
|
||||
assertGeometryEquals(new double[][]{
|
||||
new double[] {100d, 0d},
|
||||
new double[] {101d, 1d}}, multiPointGeoJson, false);
|
||||
assertGeometryEquals(new MultiPoint(Arrays.asList(
|
||||
new org.elasticsearch.geo.geometry.Point(0, 100),
|
||||
new org.elasticsearch.geo.geometry.Point(1, 101))), multiPointGeoJson, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -975,16 +981,15 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
assertGeometryEquals(expected, multiPolygonGeoJson, true);
|
||||
|
||||
org.apache.lucene.geo.Polygon hole =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
org.elasticsearch.geo.geometry.LinearRing hole = new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0.8d, 0.2d, 0.2d, 0.8d, 0.8d}, new double[] {100.8d, 100.8d, 100.2d, 100.2d, 100.8d});
|
||||
|
||||
org.apache.lucene.geo.Polygon[] polygons = new org.apache.lucene.geo.Polygon[] {
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {2d, 3d, 3d, 2d, 2d}, new double[] {103d, 103d, 102d, 102d, 103d}),
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {0d, 1d, 1d, 0d, 0d}, new double[] {101d, 101d, 100d, 100d, 101d}, hole)
|
||||
};
|
||||
org.elasticsearch.geo.geometry.MultiPolygon polygons = new org.elasticsearch.geo.geometry.MultiPolygon(Arrays.asList(
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {2d, 3d, 3d, 2d, 2d}, new double[] {103d, 103d, 102d, 102d, 103d})),
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0d, 1d, 1d, 0d, 0d}, new double[] {101d, 101d, 100d, 100d, 101d}), Collections.singletonList(hole))));
|
||||
|
||||
assertGeometryEquals(polygons, multiPolygonGeoJson, false);
|
||||
|
||||
// test #2: multipolygon; one polygon with one hole
|
||||
|
@ -1034,14 +1039,13 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
assertGeometryEquals(jtsGeom(withHoles), multiPolygonGeoJson, true);
|
||||
|
||||
org.apache.lucene.geo.Polygon luceneHole =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
org.elasticsearch.geo.geometry.LinearRing luceneHole =
|
||||
new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0.8d, 0.2d, 0.2d, 0.8d, 0.8d}, new double[] {100.8d, 100.8d, 100.2d, 100.2d, 100.8d});
|
||||
|
||||
org.apache.lucene.geo.Polygon[] lucenePolygons = new org.apache.lucene.geo.Polygon[] {
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d}, new double[] {100d, 101d, 101d, 100d, 100d}, luceneHole)
|
||||
};
|
||||
org.elasticsearch.geo.geometry.MultiPolygon lucenePolygons = new org.elasticsearch.geo.geometry.MultiPolygon(
|
||||
Collections.singletonList(new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0d, 0d, 1d, 1d, 0d}, new double[] {100d, 101d, 101d, 100d, 100d}), Collections.singletonList(luceneHole))));
|
||||
assertGeometryEquals(lucenePolygons, multiPolygonGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -1117,19 +1121,21 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
//equals returns true only if geometries are in the same order
|
||||
assertGeometryEquals(shapeCollection(expected), geometryCollectionGeoJson, true);
|
||||
|
||||
Object[] luceneExpected = new Object[] {
|
||||
new Line(new double[] {0d, 1d}, new double[] {100d, 101d}),
|
||||
new GeoPoint(2d, 102d),
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {-12.142857142857142d, 12.142857142857142d, 15d, 0d, -15d, -12.142857142857142d},
|
||||
new double[] {180d, 180d, 176d, 172d, 176d, 180d}
|
||||
),
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {12.142857142857142d, -12.142857142857142d, -10d, 10d, 12.142857142857142d},
|
||||
new double[] {-180d, -180d, -177d, -177d, -180d}
|
||||
)
|
||||
};
|
||||
assertGeometryEquals(luceneExpected, geometryCollectionGeoJson, false);
|
||||
GeometryCollection<Geometry> geometryExpected = new GeometryCollection<> (Arrays.asList(
|
||||
new org.elasticsearch.geo.geometry.Line(new double[] {0d, 1d}, new double[] {100d, 101d}),
|
||||
new org.elasticsearch.geo.geometry.Point(2d, 102d),
|
||||
new org.elasticsearch.geo.geometry.MultiPolygon(Arrays.asList(
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {-12.142857142857142d, 12.142857142857142d, 15d, 0d, -15d, -12.142857142857142d},
|
||||
new double[] {180d, 180d, 176d, 172d, 176d, 180d}
|
||||
)),
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {12.142857142857142d, -12.142857142857142d, -10d, 10d, 12.142857142857142d},
|
||||
new double[] {-180d, -180d, -177d, -177d, -180d}
|
||||
))
|
||||
))
|
||||
));
|
||||
assertGeometryEquals(geometryExpected, geometryCollectionGeoJson, false);
|
||||
}
|
||||
|
||||
public void testThatParserExtractsCorrectTypeAndCoordinatesFromArbitraryJson() throws IOException {
|
||||
|
@ -1151,7 +1157,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
Point expected = GEOMETRY_FACTORY.createPoint(new Coordinate(100.0, 0.0));
|
||||
assertGeometryEquals(new JtsPoint(expected, SPATIAL_CONTEXT), pointGeoJson, true);
|
||||
|
||||
GeoPoint expectedPt = new GeoPoint(0, 100);
|
||||
org.elasticsearch.geo.geometry.Point expectedPt = new org.elasticsearch.geo.geometry.Point(0, 100);
|
||||
assertGeometryEquals(expectedPt, pointGeoJson, false);
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1193,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 2: valid ccw (right handed system) poly not crossing dateline (with 'ccw' field)
|
||||
|
@ -1221,7 +1227,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 3: valid ccw (right handed system) poly not crossing dateline (with 'counterclockwise' field)
|
||||
|
@ -1255,7 +1261,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 4: valid cw (left handed system) poly crossing dateline (with 'left' field)
|
||||
|
@ -1289,7 +1295,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 5: valid cw multipoly (left handed system) poly crossing dateline (with 'cw' field)
|
||||
|
@ -1323,7 +1329,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
|
||||
// test 6: valid cw multipoly (left handed system) poly crossing dateline (with 'clockwise' field)
|
||||
|
@ -1357,7 +1363,7 @@ public class GeoJsonShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
try (XContentParser parser = createParser(polygonGeoJson)) {
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildLucene(), false);
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(ShapeParser.parse(parser).buildGeometry(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.elasticsearch.common.geo;
|
||||
|
||||
import org.apache.lucene.geo.GeoTestUtil;
|
||||
import org.apache.lucene.geo.Line;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.Version;
|
||||
|
@ -41,6 +40,9 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.geo.geometry.Line;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.elasticsearch.geo.geometry.MultiPoint;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
|
||||
import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
|
||||
|
@ -61,6 +63,7 @@ import org.locationtech.spatial4j.shape.jts.JtsPoint;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.geo.builders.ShapeBuilder.SPATIAL_CONTEXT;
|
||||
|
@ -72,7 +75,7 @@ import static org.hamcrest.Matchers.hasToString;
|
|||
*/
|
||||
public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
||||
|
||||
private static XContentBuilder toWKTContent(ShapeBuilder<?, ?> builder, boolean generateMalformed)
|
||||
private static XContentBuilder toWKTContent(ShapeBuilder<?, ?, ?> builder, boolean generateMalformed)
|
||||
throws IOException {
|
||||
String wkt = builder.toWKT();
|
||||
if (generateMalformed) {
|
||||
|
@ -87,12 +90,12 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
return XContentFactory.jsonBuilder().value(wkt);
|
||||
}
|
||||
|
||||
private void assertExpected(Object expected, ShapeBuilder<?, ?> builder, boolean useJTS) throws IOException {
|
||||
private void assertExpected(Object expected, ShapeBuilder<?, ?, ?> builder, boolean useJTS) throws IOException {
|
||||
XContentBuilder xContentBuilder = toWKTContent(builder, false);
|
||||
assertGeometryEquals(expected, xContentBuilder, useJTS);
|
||||
}
|
||||
|
||||
private void assertMalformed(ShapeBuilder<?, ?> builder) throws IOException {
|
||||
private void assertMalformed(ShapeBuilder<?, ?, ?> builder) throws IOException {
|
||||
XContentBuilder xContentBuilder = toWKTContent(builder, true);
|
||||
assertValidException(xContentBuilder, ElasticsearchParseException.class);
|
||||
}
|
||||
|
@ -103,7 +106,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
Coordinate c = new Coordinate(p.lon(), p.lat());
|
||||
Point expected = GEOMETRY_FACTORY.createPoint(c);
|
||||
assertExpected(new JtsPoint(expected, SPATIAL_CONTEXT), new PointBuilder().coordinate(c), true);
|
||||
assertExpected(new GeoPoint(p.lat(), p.lon()), new PointBuilder().coordinate(c), false);
|
||||
assertExpected(new org.elasticsearch.geo.geometry.Point(p.lat(), p.lon()), new PointBuilder().coordinate(c), false);
|
||||
assertMalformed(new PointBuilder().coordinate(c));
|
||||
}
|
||||
|
||||
|
@ -123,13 +126,12 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
ShapeCollection<?> expected = shapeCollection(shapes);
|
||||
assertExpected(expected, new MultiPointBuilder(coordinates), true);
|
||||
|
||||
double[][] luceneShapes = new double[numPoints][2];
|
||||
List<org.elasticsearch.geo.geometry.Point> points = new ArrayList<>(numPoints);
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
Coordinate c = coordinates.get(i);
|
||||
luceneShapes[i][0] = c.x;
|
||||
luceneShapes[i][1] = c.y;
|
||||
points.add(new org.elasticsearch.geo.geometry.Point(c.y, c.x));
|
||||
}
|
||||
assertExpected(luceneShapes, new MultiPointBuilder(coordinates), false);
|
||||
assertExpected(new MultiPoint(points), new MultiPointBuilder(coordinates), false);
|
||||
assertMalformed(new MultiPointBuilder(coordinates));
|
||||
}
|
||||
|
||||
|
@ -175,13 +177,13 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
lineStrings.toArray(new LineString[lineStrings.size()]));
|
||||
assertExpected(jtsGeom(expected), builder, true);
|
||||
|
||||
Line[] lines = new Line[lineStrings.size()];
|
||||
List<Line> lines = new ArrayList<>(lineStrings.size());
|
||||
for (int j = 0; j < lineStrings.size(); ++j) {
|
||||
Coordinate[] c = lineStrings.get(j).getCoordinates();
|
||||
lines[j] = new Line(Arrays.stream(c).mapToDouble(i->i.y).toArray(),
|
||||
Arrays.stream(c).mapToDouble(i->i.x).toArray());
|
||||
lines.add(new Line(Arrays.stream(c).mapToDouble(i->i.y).toArray(),
|
||||
Arrays.stream(c).mapToDouble(i->i.x).toArray()));
|
||||
}
|
||||
assertExpected(lines, builder, false);
|
||||
assertExpected(new MultiLine(lines), builder, false);
|
||||
assertMalformed(builder);
|
||||
}
|
||||
|
||||
|
@ -245,12 +247,12 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, holes);
|
||||
assertExpected(jtsGeom(expected), polygonWithHole, true);
|
||||
|
||||
org.apache.lucene.geo.Polygon hole =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
org.elasticsearch.geo.geometry.LinearRing hole =
|
||||
new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0.8d, 0.8d, 0.2d, 0.2d, 0.8d}, new double[] {100.2d, 100.8d, 100.8d, 100.2d, 100.2d});
|
||||
org.apache.lucene.geo.Polygon p =
|
||||
new org.apache.lucene.geo.Polygon(
|
||||
new double[] {0d, 1d, 1d, 0d, 0d}, new double[] {101d, 101d, 100d, 100d, 101d}, hole);
|
||||
org.elasticsearch.geo.geometry.Polygon p =
|
||||
new org.elasticsearch.geo.geometry.Polygon(new org.elasticsearch.geo.geometry.LinearRing(
|
||||
new double[] {0d, 1d, 1d, 0d, 0d}, new double[] {101d, 101d, 100d, 100d, 101d}), Collections.singletonList(hole));
|
||||
assertExpected(p, polygonWithHole, false);
|
||||
assertMalformed(polygonWithHole);
|
||||
}
|
||||
|
@ -357,7 +359,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
final LegacyGeoShapeFieldMapper mapperBuilder =
|
||||
(LegacyGeoShapeFieldMapper)(new LegacyGeoShapeFieldMapper.Builder("test").ignoreZValue(true).build(mockBuilderContext));
|
||||
|
||||
ShapeBuilder<?, ?> shapeBuilder = ShapeParser.parse(parser, mapperBuilder);
|
||||
ShapeBuilder<?, ?, ?> shapeBuilder = ShapeParser.parse(parser, mapperBuilder);
|
||||
assertEquals(shapeBuilder.numDimensions(), 3);
|
||||
}
|
||||
|
||||
|
@ -383,7 +385,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
final LegacyGeoShapeFieldMapper coercingMapperBuilder =
|
||||
(LegacyGeoShapeFieldMapper)(new LegacyGeoShapeFieldMapper.Builder("test").coerce(true).build(mockBuilderContext));
|
||||
ShapeBuilder<?, ?> shapeBuilder = ShapeParser.parse(parser, coercingMapperBuilder);
|
||||
ShapeBuilder<?, ?, ?> shapeBuilder = ShapeParser.parse(parser, coercingMapperBuilder);
|
||||
assertNotNull(shapeBuilder);
|
||||
assertEquals("polygon ((100.0 5.0, 100.0 10.0, 90.0 10.0, 90.0 5.0, 100.0 5.0))", shapeBuilder.toWKT());
|
||||
}
|
||||
|
@ -418,7 +420,7 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
|
||||
Rectangle expected = SPATIAL_CONTEXT.makeRectangle(r.minLon, r.maxLon, r.minLat, r.maxLat);
|
||||
assertExpected(expected, builder, true);
|
||||
assertExpected(r, builder, false);
|
||||
assertExpected(new org.elasticsearch.geo.geometry.Rectangle(r.minLat, r.maxLat, r.minLon, r.maxLon), builder, false);
|
||||
assertMalformed(builder);
|
||||
}
|
||||
|
||||
|
@ -436,12 +438,12 @@ public class GeoWKTShapeParserTests extends BaseGeoParsingTestCase {
|
|||
if (randomBoolean()) {
|
||||
assertEquals(shapeCollection(expected).isEmpty(), builder.buildS4J().isEmpty());
|
||||
} else {
|
||||
assertEquals(shapeCollection(expected).isEmpty(), ((Object[])builder.buildLucene()).length == 0);
|
||||
assertEquals(shapeCollection(expected).isEmpty(), builder.buildGeometry().size() == 0);
|
||||
}
|
||||
} else {
|
||||
GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(random());
|
||||
assertExpected(gcb.buildS4J(), gcb, true);
|
||||
assertExpected(gcb.buildLucene(), gcb, false);
|
||||
assertExpected(gcb.buildGeometry(), gcb, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
Point point = pb.buildS4J();
|
||||
assertEquals(-100D, point.getX(), 0.0d);
|
||||
assertEquals(45D, point.getY(), 0.0d);
|
||||
GeoPoint geoPoint = pb.buildLucene();
|
||||
org.elasticsearch.geo.geometry.Point geoPoint = pb.buildGeometry();
|
||||
assertEquals(-100D, geoPoint.getLon(), 0.0d);
|
||||
assertEquals(45D, geoPoint.getLat(), 0.0d);
|
||||
}
|
||||
|
@ -65,11 +65,11 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
assertEquals(45D, rectangle.getMaxX(), 0.0d);
|
||||
assertEquals(30D, rectangle.getMaxY(), 0.0d);
|
||||
|
||||
org.apache.lucene.geo.Rectangle luceneRectangle = eb.buildLucene();
|
||||
assertEquals(-45D, luceneRectangle.minLon, 0.0d);
|
||||
assertEquals(-30D, luceneRectangle.minLat, 0.0d);
|
||||
assertEquals(45D, luceneRectangle.maxLon, 0.0d);
|
||||
assertEquals(30D, luceneRectangle.maxLat, 0.0d);
|
||||
org.elasticsearch.geo.geometry.Rectangle luceneRectangle = eb.buildGeometry();
|
||||
assertEquals(-45D, luceneRectangle.getMinLon(), 0.0d);
|
||||
assertEquals(-30D, luceneRectangle.getMinLat(), 0.0d);
|
||||
assertEquals(45D, luceneRectangle.getMaxLon(), 0.0d);
|
||||
assertEquals(30D, luceneRectangle.getMaxLat(), 0.0d);
|
||||
}
|
||||
|
||||
public void testNewPolygon() {
|
||||
|
@ -87,15 +87,15 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
assertEquals(exterior.getCoordinateN(2), new Coordinate(45, -30));
|
||||
assertEquals(exterior.getCoordinateN(3), new Coordinate(-45, -30));
|
||||
|
||||
org.apache.lucene.geo.Polygon lucenePoly = (org.apache.lucene.geo.Polygon)(pb.toPolygonLucene());
|
||||
assertEquals(lucenePoly.getPolyLat(0), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(0), -45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(1), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(1), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(2), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(2), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(3), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(3), -45, 0d);
|
||||
org.elasticsearch.geo.geometry.LinearRing polygon = pb.toPolygonGeometry().getPolygon();
|
||||
assertEquals(polygon.getLat(0), 30, 0d);
|
||||
assertEquals(polygon.getLon(0), -45, 0d);
|
||||
assertEquals(polygon.getLat(1), 30, 0d);
|
||||
assertEquals(polygon.getLon(1), 45, 0d);
|
||||
assertEquals(polygon.getLat(2), -30, 0d);
|
||||
assertEquals(polygon.getLon(2), 45, 0d);
|
||||
assertEquals(polygon.getLat(3), -30, 0d);
|
||||
assertEquals(polygon.getLon(3), -45, 0d);
|
||||
}
|
||||
|
||||
public void testNewPolygon_coordinate() {
|
||||
|
@ -113,15 +113,15 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
assertEquals(exterior.getCoordinateN(2), new Coordinate(45, -30));
|
||||
assertEquals(exterior.getCoordinateN(3), new Coordinate(-45, -30));
|
||||
|
||||
org.apache.lucene.geo.Polygon lucenePoly = (org.apache.lucene.geo.Polygon)(pb.toPolygonLucene());
|
||||
assertEquals(lucenePoly.getPolyLat(0), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(0), -45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(1), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(1), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(2), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(2), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(3), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(3), -45, 0d);
|
||||
org.elasticsearch.geo.geometry.LinearRing polygon = pb.toPolygonGeometry().getPolygon();
|
||||
assertEquals(polygon.getLat(0), 30, 0d);
|
||||
assertEquals(polygon.getLon(0), -45, 0d);
|
||||
assertEquals(polygon.getLat(1), 30, 0d);
|
||||
assertEquals(polygon.getLon(1), 45, 0d);
|
||||
assertEquals(polygon.getLat(2), -30, 0d);
|
||||
assertEquals(polygon.getLon(2), 45, 0d);
|
||||
assertEquals(polygon.getLat(3), -30, 0d);
|
||||
assertEquals(polygon.getLon(3), -45, 0d);
|
||||
}
|
||||
|
||||
public void testNewPolygon_coordinates() {
|
||||
|
@ -137,15 +137,15 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
assertEquals(exterior.getCoordinateN(2), new Coordinate(45, -30));
|
||||
assertEquals(exterior.getCoordinateN(3), new Coordinate(-45, -30));
|
||||
|
||||
org.apache.lucene.geo.Polygon lucenePoly = (org.apache.lucene.geo.Polygon)(pb.toPolygonLucene());
|
||||
assertEquals(lucenePoly.getPolyLat(0), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(0), -45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(1), 30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(1), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(2), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(2), 45, 0d);
|
||||
assertEquals(lucenePoly.getPolyLat(3), -30, 0d);
|
||||
assertEquals(lucenePoly.getPolyLon(3), -45, 0d);
|
||||
org.elasticsearch.geo.geometry.LinearRing polygon = pb.toPolygonGeometry().getPolygon();
|
||||
assertEquals(polygon.getLat(0), 30, 0d);
|
||||
assertEquals(polygon.getLon(0), -45, 0d);
|
||||
assertEquals(polygon.getLat(1), 30, 0d);
|
||||
assertEquals(polygon.getLon(1), 45, 0d);
|
||||
assertEquals(polygon.getLat(2), -30, 0d);
|
||||
assertEquals(polygon.getLon(2), 45, 0d);
|
||||
assertEquals(polygon.getLat(3), -30, 0d);
|
||||
assertEquals(polygon.getLon(3), -45, 0d);
|
||||
}
|
||||
|
||||
public void testLineStringBuilder() {
|
||||
|
@ -161,7 +161,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(-110.0, 55.0));
|
||||
|
||||
lsb.buildS4J();
|
||||
lsb.buildLucene();
|
||||
lsb.buildGeometry();
|
||||
|
||||
// Building a linestring that needs to be wrapped
|
||||
lsb = new LineStringBuilder(new CoordinatesBuilder()
|
||||
|
@ -175,7 +175,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(130.0, 60.0));
|
||||
|
||||
lsb.buildS4J();
|
||||
lsb.buildLucene();
|
||||
lsb.buildGeometry();
|
||||
|
||||
// Building a lineString on the dateline
|
||||
lsb = new LineStringBuilder(new CoordinatesBuilder()
|
||||
|
@ -185,7 +185,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(-180.0, -80.0));
|
||||
|
||||
lsb.buildS4J();
|
||||
lsb.buildLucene();
|
||||
lsb.buildGeometry();
|
||||
|
||||
// Building a lineString on the dateline
|
||||
lsb = new LineStringBuilder(new CoordinatesBuilder()
|
||||
|
@ -195,7 +195,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(180.0, -80.0));
|
||||
|
||||
lsb.buildS4J();
|
||||
lsb.buildLucene();
|
||||
lsb.buildGeometry();
|
||||
}
|
||||
|
||||
public void testMultiLineString() {
|
||||
|
@ -215,7 +215,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
)
|
||||
);
|
||||
mlsb.buildS4J();
|
||||
mlsb.buildLucene();
|
||||
mlsb.buildGeometry();
|
||||
|
||||
// LineString that needs to be wrapped
|
||||
new MultiLineStringBuilder()
|
||||
|
@ -235,7 +235,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
mlsb.buildS4J();
|
||||
mlsb.buildLucene();
|
||||
mlsb.buildGeometry();
|
||||
}
|
||||
|
||||
public void testPolygonSelfIntersection() {
|
||||
|
@ -283,7 +283,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.close());
|
||||
|
||||
assertMultiPolygon(pb.buildS4J(), true);
|
||||
assertMultiPolygon(pb.buildLucene(), false);
|
||||
assertMultiPolygon(pb.buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testLineStringWrapping() {
|
||||
|
@ -295,7 +295,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.close());
|
||||
|
||||
assertMultiLineString(lsb.buildS4J(), true);
|
||||
assertMultiLineString(lsb.buildLucene(), false);
|
||||
assertMultiLineString(lsb.buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testDatelineOGC() {
|
||||
|
@ -339,7 +339,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
));
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testDateline() {
|
||||
|
@ -383,7 +383,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
));
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testComplexShapeWithHole() {
|
||||
|
@ -458,7 +458,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
)
|
||||
);
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithHoleAtEdgeEndPoints() {
|
||||
|
@ -480,7 +480,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(4, 1)
|
||||
));
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithPointOnDateline() {
|
||||
|
@ -491,7 +491,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(180, 0)
|
||||
);
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithEdgeAlongDateline() {
|
||||
|
@ -504,7 +504,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
|
||||
// test case 2: test the negative side of the dateline
|
||||
builder = new PolygonBuilder(new CoordinatesBuilder()
|
||||
|
@ -515,7 +515,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithBoundaryHoles() {
|
||||
|
@ -537,7 +537,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
));
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
|
||||
// test case 2: test the negative side of the dateline
|
||||
builder = new PolygonBuilder(
|
||||
|
@ -560,7 +560,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
));
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithTangentialHole() {
|
||||
|
@ -582,7 +582,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
));
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithInvalidTangentialHole() {
|
||||
|
@ -606,7 +606,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildS4J());
|
||||
assertThat(e.getMessage(), containsString("interior cannot share more than one point with the exterior"));
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildLucene());
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildGeometry());
|
||||
assertThat(e.getMessage(), containsString("interior cannot share more than one point with the exterior"));
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
.coordinate(172, 0)
|
||||
));
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testBoundaryShapeWithInvalidTangentialHole() {
|
||||
|
@ -657,7 +657,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
Exception e;
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildS4J());
|
||||
assertThat(e.getMessage(), containsString("interior cannot share more than one point with the exterior"));
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildLucene());
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildGeometry());
|
||||
assertThat(e.getMessage(), containsString("interior cannot share more than one point with the exterior"));
|
||||
}
|
||||
|
||||
|
@ -673,7 +673,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testShapeWithAlternateOrientation() {
|
||||
|
@ -686,7 +686,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
assertPolygon(builder.close().buildS4J(), true);
|
||||
assertPolygon(builder.close().buildLucene(), false);
|
||||
assertPolygon(builder.close().buildGeometry(), false);
|
||||
|
||||
// cw: geo core will convert to ccw across the dateline
|
||||
builder = new PolygonBuilder(new CoordinatesBuilder()
|
||||
|
@ -697,7 +697,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
);
|
||||
|
||||
assertMultiPolygon(builder.close().buildS4J(), true);
|
||||
assertMultiPolygon(builder.close().buildLucene(), false);
|
||||
assertMultiPolygon(builder.close().buildGeometry(), false);
|
||||
}
|
||||
|
||||
public void testInvalidShapeWithConsecutiveDuplicatePoints() {
|
||||
|
@ -711,7 +711,7 @@ public class ShapeBuilderTests extends ESTestCase {
|
|||
|
||||
Exception e = expectThrows(InvalidShapeException.class, () -> builder.close().buildS4J());
|
||||
assertThat(e.getMessage(), containsString("duplicate consecutive coordinates at: ("));
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildLucene());
|
||||
e = expectThrows(InvalidShapeException.class, () -> builder.close().buildGeometry());
|
||||
assertThat(e.getMessage(), containsString("duplicate consecutive coordinates at: ("));
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ import java.io.IOException;
|
|||
|
||||
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
||||
|
||||
public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder<?,?>> extends ESTestCase {
|
||||
public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder<?,?,?>> extends ESTestCase {
|
||||
|
||||
private static final int NUMBER_OF_TESTBUILDERS = 20;
|
||||
private static NamedWriteableRegistry namedWriteableRegistry;
|
||||
|
@ -81,7 +81,7 @@ public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder<?,?>>
|
|||
XContentBuilder shuffled = shuffleXContent(builder);
|
||||
try (XContentParser shapeContentParser = createParser(shuffled)) {
|
||||
shapeContentParser.nextToken();
|
||||
ShapeBuilder<?, ?> parsedShape = ShapeParser.parse(shapeContentParser);
|
||||
ShapeBuilder<?, ?, ?> parsedShape = ShapeParser.parse(shapeContentParser);
|
||||
assertNotSame(testShape, parsedShape);
|
||||
assertEquals(testShape, parsedShape);
|
||||
assertEquals(testShape.hashCode(), parsedShape.hashCode());
|
||||
|
|
|
@ -69,7 +69,7 @@ public class GeometryCollectionBuilderTests extends AbstractShapeBuilderTestCase
|
|||
GeometryCollectionBuilder mutation = copyShape(original);
|
||||
if (mutation.shapes.size() > 0) {
|
||||
int shapePosition = randomIntBetween(0, mutation.shapes.size() - 1);
|
||||
ShapeBuilder<?, ?> shapeToChange = mutation.shapes.get(shapePosition);
|
||||
ShapeBuilder<?, ?, ?> shapeToChange = mutation.shapes.get(shapePosition);
|
||||
switch (shapeToChange.type()) {
|
||||
case POINT:
|
||||
shapeToChange = PointBuilderTests.mutate((PointBuilder) shapeToChange);
|
||||
|
|
|
@ -187,7 +187,7 @@ public class ExternalMapper extends FieldMapper {
|
|||
// Let's add a Dummy Shape
|
||||
PointBuilder pb = new PointBuilder(-100, 45);
|
||||
if (shapeMapper instanceof GeoShapeFieldMapper) {
|
||||
shapeMapper.parse(context.createExternalValueContext(pb.buildLucene()));
|
||||
shapeMapper.parse(context.createExternalValueContext(pb.buildGeometry()));
|
||||
} else {
|
||||
shapeMapper.parse(context.createExternalValueContext(pb.buildS4J()));
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
|
|||
}
|
||||
|
||||
private static List<GeoPoint> randomPolygon() {
|
||||
ShapeBuilder<?, ?> shapeBuilder = null;
|
||||
ShapeBuilder<?, ?, ?> shapeBuilder = null;
|
||||
// This is a temporary fix because sometimes the RandomShapeGenerator
|
||||
// returns null. This is if there is an error generating the polygon. So
|
||||
// in this case keep trying until we successfully generate one
|
||||
|
|
|
@ -63,7 +63,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
protected static String indexedShapePath;
|
||||
protected static String indexedShapeIndex;
|
||||
protected static String indexedShapeRouting;
|
||||
protected static ShapeBuilder<?, ?> indexedShapeToReturn;
|
||||
protected static ShapeBuilder<?, ?, ?> indexedShapeToReturn;
|
||||
|
||||
protected String fieldName() {
|
||||
return GEO_SHAPE_FIELD_NAME;
|
||||
|
@ -88,7 +88,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
// LatLonShape does not support MultiPoint queries
|
||||
RandomShapeGenerator.ShapeType shapeType =
|
||||
randomFrom(ShapeType.POINT, ShapeType.LINESTRING, ShapeType.MULTILINESTRING, ShapeType.POLYGON);
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
GeoShapeQueryBuilder builder;
|
||||
clearShapeFields();
|
||||
if (indexedShape == false) {
|
||||
|
@ -174,7 +174,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
}
|
||||
|
||||
public void testNoFieldName() throws Exception {
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new GeoShapeQueryBuilder(null, shape));
|
||||
assertEquals("fieldName is required", e.getMessage());
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
}
|
||||
|
||||
public void testNoRelation() throws IOException {
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
GeoShapeQueryBuilder builder = new GeoShapeQueryBuilder(fieldName(), shape);
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> builder.relation(null));
|
||||
assertEquals("No Shape Relation defined", e.getMessage());
|
||||
|
@ -255,7 +255,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
|
||||
public void testIgnoreUnmapped() throws IOException {
|
||||
ShapeType shapeType = ShapeType.randomType(random());
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
final GeoShapeQueryBuilder queryBuilder = new GeoShapeQueryBuilder("unmapped", shape);
|
||||
queryBuilder.ignoreUnmapped(true);
|
||||
Query query = queryBuilder.toQuery(createShardContext());
|
||||
|
@ -270,7 +270,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
|
|||
|
||||
public void testWrongFieldType() throws IOException {
|
||||
ShapeType shapeType = ShapeType.randomType(random());
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
final GeoShapeQueryBuilder queryBuilder = new GeoShapeQueryBuilder(STRING_FIELD_NAME, shape);
|
||||
QueryShardException e = expectThrows(QueryShardException.class, () -> queryBuilder.toQuery(createShardContext()));
|
||||
assertThat(e.getMessage(), containsString("Field [mapped_string] is not of type [geo_shape] but of type [text]"));
|
||||
|
|
|
@ -51,7 +51,7 @@ public class LegacyGeoShapeFieldQueryTests extends GeoShapeQueryBuilderTests {
|
|||
@Override
|
||||
protected GeoShapeQueryBuilder doCreateTestQueryBuilder(boolean indexedShape) {
|
||||
ShapeType shapeType = ShapeType.randomType(random());
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
|
||||
GeoShapeQueryBuilder builder;
|
||||
clearShapeFields();
|
||||
if (indexedShape == false) {
|
||||
|
@ -93,7 +93,7 @@ public class LegacyGeoShapeFieldQueryTests extends GeoShapeQueryBuilderTests {
|
|||
}
|
||||
|
||||
public void testInvalidRelation() throws IOException {
|
||||
ShapeBuilder<?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null);
|
||||
GeoShapeQueryBuilder builder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, shape);
|
||||
builder.strategy(SpatialStrategy.TERM);
|
||||
expectThrows(IllegalArgumentException.class, () -> builder.relation(randomFrom(ShapeRelation.DISJOINT, ShapeRelation.WITHIN)));
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.geo.GeoPoint;
|
|||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.geo.geometry.MultiLine;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Assert;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
@ -221,7 +222,9 @@ public class ElasticsearchGeoAssertions {
|
|||
|| (s1 instanceof GeoPoint && s2 instanceof GeoPoint)) {
|
||||
Assert.assertEquals(s1, s2);
|
||||
} else if (s1 instanceof Object[] && s2 instanceof Object[]) {
|
||||
Assert.assertArrayEquals((Object[])s1, (Object[])s2);
|
||||
Assert.assertArrayEquals((Object[]) s1, (Object[]) s2);
|
||||
} else if (s1 instanceof org.elasticsearch.geo.geometry.Geometry && s2 instanceof org.elasticsearch.geo.geometry.Geometry) {
|
||||
Assert.assertEquals(s1, s2);
|
||||
} else {
|
||||
//We want to know the type of the shape because we test shape equality in a special way...
|
||||
//... in particular we test that one ring is equivalent to another ring even if the points are rotated or reversed.
|
||||
|
@ -242,7 +245,7 @@ public class ElasticsearchGeoAssertions {
|
|||
unwrapJTS(shape) instanceof MultiPolygon);
|
||||
} else {
|
||||
assertTrue("expected Polygon[] but found " + shape.getClass().getName(),
|
||||
shape instanceof org.apache.lucene.geo.Polygon[]);
|
||||
shape instanceof org.elasticsearch.geo.geometry.MultiPolygon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +255,7 @@ public class ElasticsearchGeoAssertions {
|
|||
+ unwrapJTS(shape).getClass().getName(), unwrapJTS(shape) instanceof Polygon);
|
||||
} else {
|
||||
assertTrue("expected Polygon but found " + shape.getClass().getName(),
|
||||
shape instanceof org.apache.lucene.geo.Polygon);
|
||||
shape instanceof org.elasticsearch.geo.geometry.Polygon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +265,7 @@ public class ElasticsearchGeoAssertions {
|
|||
+ unwrapJTS(shape).getClass().getName(), unwrapJTS(shape) instanceof LineString);
|
||||
} else {
|
||||
assertTrue("expected Line but found " + shape.getClass().getName(),
|
||||
shape instanceof org.apache.lucene.geo.Line);
|
||||
shape instanceof org.elasticsearch.geo.geometry.Line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +275,7 @@ public class ElasticsearchGeoAssertions {
|
|||
+ unwrapJTS(shape).getClass().getName(), unwrapJTS(shape) instanceof MultiLineString);
|
||||
} else {
|
||||
assertTrue("expected Line[] but found " + shape.getClass().getName(),
|
||||
shape instanceof org.apache.lucene.geo.Line[]);
|
||||
shape instanceof MultiLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue