diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java index 16641aede20..c15e0d9130e 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Circle; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.unit.DistanceUnit; @@ -35,7 +36,7 @@ public class CircleBuilder extends ShapeBuilder { public static final String FIELD_RADIUS = "radius"; public static final GeoShapeType TYPE = GeoShapeType.CIRCLE; - public static final CircleBuilder PROTOTYPE = new CircleBuilder(); + static final CircleBuilder PROTOTYPE = new CircleBuilder(); private DistanceUnit unit = DistanceUnit.DEFAULT; private double radius; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java similarity index 59% rename from core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java rename to core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java index 58b85fff760..72ac7be8114 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java @@ -29,22 +29,23 @@ import java.util.Collection; import java.util.List; /** - * The {@link PointCollection} is an abstract base implementation for all GeoShapes. It simply handles a set of points. + * The {@link CoordinateCollection} is an abstract base implementation for {@link LineStringBuilder} and {@link MultiPointBuilder}. + * It holds a common list of {@link Coordinate}, provides setters for adding elements to the list and can render this to XContent. */ -public abstract class PointCollection> extends ShapeBuilder { +public abstract class CoordinateCollection> extends ShapeBuilder { - protected final List points; + protected final List coordinates; /** - * Construct a new collection of points. - * @param points an initial list of points - * @throws IllegalArgumentException if points is null or empty + * Construct a new collection of coordinates. + * @param coordinates an initial list of coordinates + * @throws IllegalArgumentException if coordinates is null or empty */ - protected PointCollection(List points) { - if (points == null || points.size() == 0) { + protected CoordinateCollection(List coordinates) { + if (coordinates == null || coordinates.size() == 0) { throw new IllegalArgumentException("cannot create point collection with empty set of points"); } - this.points = points; + this.coordinates = coordinates; } @SuppressWarnings("unchecked") @@ -53,54 +54,54 @@ public abstract class PointCollection> extends Shap } /** - * Add a new point to the collection + * Add a new coordinate to the collection * @param longitude longitude of the coordinate * @param latitude latitude of the coordinate * @return this */ - public E point(double longitude, double latitude) { - return this.point(coordinate(longitude, latitude)); + public E coordinate(double longitude, double latitude) { + return this.coordinate(new Coordinate(longitude, latitude)); } /** - * Add a new point to the collection + * Add a new coordinate to the collection * @param coordinate coordinate of the point * @return this */ - public E point(Coordinate coordinate) { - this.points.add(coordinate); + public E coordinate(Coordinate coordinate) { + this.coordinates.add(coordinate); return thisRef(); } /** - * Add a array of points to the collection + * Add a array of coordinates to the collection * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public E points(Coordinate...coordinates) { - return this.points(Arrays.asList(coordinates)); + public E coordinates(Coordinate...coordinates) { + return this.coordinates(Arrays.asList(coordinates)); } /** - * Add a collection of points to the collection + * Add a collection of coordinates to the collection * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public E points(Collection coordinates) { - this.points.addAll(coordinates); + public E coordinates(Collection coordinates) { + this.coordinates.addAll(coordinates); return thisRef(); } /** - * Copy all points to a new Array + * Copy all coordinate to a new Array * * @param closed if set to true the first point of the array is repeated as last element * @return Array of coordinates */ protected Coordinate[] coordinates(boolean closed) { - Coordinate[] result = points.toArray(new Coordinate[points.size() + (closed?1:0)]); + Coordinate[] result = coordinates.toArray(new Coordinate[coordinates.size() + (closed?1:0)]); if(closed) { result[result.length-1] = result[0]; } @@ -116,14 +117,14 @@ public abstract class PointCollection> extends Shap */ protected XContentBuilder coordinatesToXcontent(XContentBuilder builder, boolean closed) throws IOException { builder.startArray(); - for(Coordinate point : points) { - toXContent(builder, point); + for(Coordinate coord : coordinates) { + toXContent(builder, coord); } if(closed) { - Coordinate start = points.get(0); - Coordinate end = points.get(points.size()-1); + Coordinate start = coordinates.get(0); + Coordinate end = coordinates.get(coordinates.size()-1); if(start.x != end.x || start.y != end.y) { - toXContent(builder, points.get(0)); + toXContent(builder, coordinates.get(0)); } } builder.endArray(); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java similarity index 60% rename from core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java rename to core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java index febb3dcb5ba..43393d5e086 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java @@ -27,60 +27,60 @@ import java.util.Collection; import java.util.List; /** - * A builder for a list of points (of {@link Coordinate} type). - * Enables chaining of individual points either as long/lat pairs + * A builder for a list of coordinates. + * Enables chaining of individual coordinates either as long/lat pairs * or as {@link Coordinate} elements, arrays or collections. */ -public class PointListBuilder { +public class CoordinatesBuilder { private final List points = new ArrayList<>(); /** - * Add a new point to the collection - * @param longitude longitude of the coordinate - * @param latitude latitude of the coordinate + * Add a new coordinate to the collection + * @param coordinate the coordinate to add * @return this */ - public PointListBuilder point(double longitude, double latitude) { - return this.point(new Coordinate(longitude, latitude)); - } - - /** - * Add a new point to the collection - * @param coordinate coordinate of the point - * @return this - */ - public PointListBuilder point(Coordinate coordinate) { + public CoordinatesBuilder coordinate(Coordinate coordinate) { this.points.add(coordinate); return this; } /** - * Add a array of points to the collection - * - * @param coordinates array of {@link Coordinate}s to add + * Add a new coordinate to the collection + * @param longitude longitude of the coordinate + * @param latitude latitude of the coordinate * @return this */ - public PointListBuilder points(Coordinate...coordinates) { - return this.points(Arrays.asList(coordinates)); + public CoordinatesBuilder coordinate(double longitude, double latitude) { + return this.coordinate(new Coordinate(longitude, latitude)); } /** - * Add a collection of points to the collection + * Add an array of coordinates to the current coordinates * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public PointListBuilder points(Collection coordinates) { + public CoordinatesBuilder coordinates(Coordinate...coordinates) { + return this.coordinates(Arrays.asList(coordinates)); + } + + /** + * Add a collection of coordinates to the current coordinates + * + * @param coordinates collection of {@link Coordinate}s to add + * @return this + */ + public CoordinatesBuilder coordinates(Collection coordinates) { this.points.addAll(coordinates); return this; } /** - * Closes the current list of points by adding the starting point as the end point - * if they are not already the same + * Makes a closed ring out of the current coordinates by adding the starting point as the end point. + * Will have no effect of starting and end point are already the same coordinate. */ - public PointListBuilder close() { + public CoordinatesBuilder close() { Coordinate start = points.get(0); Coordinate end = points.get(points.size()-1); if(start.x != end.x || start.y != end.y) { @@ -90,9 +90,9 @@ public class PointListBuilder { } /** - * @return the current list of points + * @return a list containing the current coordinates */ - public List list() { + public List build() { return new ArrayList<>(this.points); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java index 708241c6666..9ad51292977 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Rectangle; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -32,7 +33,7 @@ public class EnvelopeBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE; - public static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0)); + static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0)); private Coordinate topLeft; private Coordinate bottomRight; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java index 5fc6b58e176..6e0094f7165 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java @@ -20,6 +20,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Shape; + import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.geo.XShapeCollection; import org.elasticsearch.common.io.stream.StreamInput; @@ -35,7 +36,7 @@ public class GeometryCollectionBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION; - public static final GeometryCollectionBuilder PROTOTYPE = new GeometryCollectionBuilder(); + static final GeometryCollectionBuilder PROTOTYPE = new GeometryCollectionBuilder(); protected final ArrayList shapes = new ArrayList<>(); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java index 48752d013ae..1f16037cd0d 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java @@ -24,14 +24,6 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -43,25 +35,29 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -public class LineStringBuilder extends PointCollection { +public class LineStringBuilder extends CoordinateCollection { /** * Construct a new LineString. * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) - * a LineString must contain two or more positions - * @param points the initial list of points - * @throw {@link IllegalArgumentException} if there are less then two points defined + * a LineString must contain two or more coordinates + * @param coordinates the initial list of coordinates + * @throw {@link IllegalArgumentException} if there are less then two coordinates defined */ - public LineStringBuilder(List points) { - super(points); - if (points.size() < 2) { - throw new IllegalArgumentException("invalid number of points in LineString (found [" + points.size()+ "] - must be >= 2)"); + public LineStringBuilder(List coordinates) { + super(coordinates); + if (coordinates.size() < 2) { + throw new IllegalArgumentException("invalid number of points in LineString (found [" + coordinates.size()+ "] - must be >= 2)"); } } + public LineStringBuilder(CoordinatesBuilder coordinates) { + this(coordinates.build()); + } + public static final GeoShapeType TYPE = GeoShapeType.LINESTRING; - public static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).point(1.0, 1.0).list()); + static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(1.0, 1.0)); @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { @@ -74,13 +70,14 @@ public class LineStringBuilder extends PointCollection { } /** - * Closes the current lineString by adding the starting point as the end point + * Closes the current lineString by adding the starting point as the end point. + * This will have no effect if starting and end point are already the same. */ public LineStringBuilder close() { - Coordinate start = points.get(0); - Coordinate end = points.get(points.size()-1); + Coordinate start = coordinates.get(0); + Coordinate end = coordinates.get(coordinates.size() - 1); if(start.x != end.x || start.y != end.y) { - points.add(start); + coordinates.add(start); } return this; } @@ -92,7 +89,7 @@ public class LineStringBuilder extends PointCollection { @Override public Shape build() { - Coordinate[] coordinates = points.toArray(new Coordinate[points.size()]); + Coordinate[] coordinates = this.coordinates.toArray(new Coordinate[this.coordinates.size()]); Geometry geometry; if(wrapdateline) { ArrayList strings = decompose(FACTORY, coordinates, new ArrayList()); @@ -171,7 +168,7 @@ public class LineStringBuilder extends PointCollection { @Override public int hashCode() { - return Objects.hash(points); + return Objects.hash(coordinates); } @Override @@ -183,25 +180,25 @@ public class LineStringBuilder extends PointCollection { return false; } LineStringBuilder other = (LineStringBuilder) obj; - return Objects.equals(points, other.points); + return Objects.equals(coordinates, other.coordinates); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(points.size()); - for (Coordinate point : points) { + out.writeVInt(coordinates.size()); + for (Coordinate point : coordinates) { writeCoordinateTo(point, out); } } @Override public LineStringBuilder readFrom(StreamInput in) throws IOException { - PointListBuilder pl = new PointListBuilder(); + CoordinatesBuilder coordinates = new CoordinatesBuilder(); int size = in.readVInt(); for (int i=0; i < size; i++) { - pl.point(readCoordinateFrom(in)); + coordinates.coordinate(readCoordinateFrom(in)); } - LineStringBuilder lineStringBuilder = new LineStringBuilder(pl.list()); + LineStringBuilder lineStringBuilder = new LineStringBuilder(coordinates); return lineStringBuilder; } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java index 4dc13454216..0de79ac8fe8 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java @@ -23,9 +23,6 @@ import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.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.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -40,7 +37,7 @@ public class MultiLineStringBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING; - public static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder(); + static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder(); private final ArrayList lines = new ArrayList<>(); @@ -49,10 +46,6 @@ public class MultiLineStringBuilder extends ShapeBuilder { return this; } - public MultiLineStringBuilder linestring(Coordinate[] coordinates) { - return this.linestring(new LineStringBuilder(new PointListBuilder().points(coordinates).list())); - } - public Coordinate[][] coordinates() { Coordinate[][] result = new Coordinate[lines.size()][]; for (int i = 0; i < result.length; i++) { diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java index ebc5d822d3b..1ed976f43ee 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java @@ -22,6 +22,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Point; import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.geo.XShapeCollection; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -29,22 +30,21 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; -public class MultiPointBuilder extends PointCollection { +public class MultiPointBuilder extends CoordinateCollection { public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT; - public final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(Arrays.asList(new Coordinate[]{new Coordinate(0.0, 0.0)})); + final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).build()); /** * Create a new {@link MultiPointBuilder}. - * @param points needs at least two points to be valid, otherwise will throw an exception + * @param coordinates needs at least two coordinates to be valid, otherwise will throw an exception */ - public MultiPointBuilder(List points) { - super(points); + public MultiPointBuilder(List coordinates) { + super(coordinates); } @Override @@ -61,8 +61,8 @@ public class MultiPointBuilder extends PointCollection { public Shape build() { //Could wrap JtsGeometry but probably slower due to conversions to/from JTS in relate() //MultiPoint geometry = FACTORY.createMultiPoint(points.toArray(new Coordinate[points.size()])); - List shapes = new ArrayList<>(points.size()); - for (Coordinate coord : points) { + List shapes = new ArrayList<>(coordinates.size()); + for (Coordinate coord : coordinates) { shapes.add(SPATIAL_CONTEXT.makePoint(coord.x, coord.y)); } XShapeCollection multiPoints = new XShapeCollection<>(shapes, SPATIAL_CONTEXT); @@ -77,7 +77,7 @@ public class MultiPointBuilder extends PointCollection { @Override public int hashCode() { - return Objects.hash(points); + return Objects.hash(coordinates); } @Override @@ -89,13 +89,13 @@ public class MultiPointBuilder extends PointCollection { return false; } MultiPointBuilder other = (MultiPointBuilder) obj; - return Objects.equals(points, other.points); + return Objects.equals(coordinates, other.coordinates); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(points.size()); - for (Coordinate point : points) { + out.writeVInt(coordinates.size()); + for (Coordinate point : coordinates) { writeCoordinateTo(point, out); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java index 37eafb57e9c..8d77d395155 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java @@ -29,7 +29,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -37,7 +36,7 @@ import java.util.Objects; public class MultiPolygonBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.MULTIPOLYGON; - public static final MultiPolygonBuilder PROTOTYPE = new MultiPolygonBuilder(); + static final MultiPolygonBuilder PROTOTYPE = new MultiPolygonBuilder(); private final ArrayList polygons = new ArrayList<>(); @@ -60,7 +59,7 @@ public class MultiPolygonBuilder extends ShapeBuilder { * {@link MultiPolygonBuilder} to the polygon if polygon has different orientation. */ public MultiPolygonBuilder polygon(PolygonBuilder polygon) { - PolygonBuilder pb = new PolygonBuilder(Arrays.asList(polygon.shell().coordinates(false)), this.orientation); + PolygonBuilder pb = new PolygonBuilder(new CoordinatesBuilder().coordinates(polygon.shell().coordinates(false)), this.orientation); for (LineStringBuilder hole : polygon.holes()) { pb.hole(hole); } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java index 1cee6525e7a..40e57566d48 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java @@ -32,7 +32,7 @@ import java.util.Objects; public class PointBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.POINT; - public static final PointBuilder PROTOTYPE = new PointBuilder(); + static final PointBuilder PROTOTYPE = new PointBuilder(); private Coordinate coordinate; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java index 189b2c9ce86..36589a4a4a7 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java @@ -27,6 +27,7 @@ import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; + import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -52,8 +53,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public class PolygonBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.POLYGON; - public static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new PointListBuilder().point(0.0, 0.0).point(0.0, 1.0) - .point(1.0, 0.0).point(0.0, 0.0).list()); + static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(0.0, 1.0) + .coordinate(1.0, 0.0).coordinate(0.0, 0.0)); private static final Coordinate[][] EMPTY = new Coordinate[0][]; @@ -65,17 +66,25 @@ public class PolygonBuilder extends ShapeBuilder { // List of line strings defining the holes of the polygon private final ArrayList holes = new ArrayList<>(); - public PolygonBuilder(List points, Orientation orientation) { - this(points, orientation, false); - } - - public PolygonBuilder(List points, Orientation orientation, boolean coerce) { + public PolygonBuilder(LineStringBuilder lineString, Orientation orientation, boolean coerce) { this.orientation = orientation; - this.shell = validateLinearRing(new LineStringBuilder(points), coerce); + if (coerce) { + lineString.close(); + } + validateLinearRing(lineString); + this.shell = lineString; } - public PolygonBuilder(List points) { - this(points, Orientation.RIGHT); + public PolygonBuilder(LineStringBuilder lineString, Orientation orientation) { + this(lineString, orientation, false); + } + + public PolygonBuilder(CoordinatesBuilder coordinates, Orientation orientation) { + this(new LineStringBuilder(coordinates), orientation, false); + } + + public PolygonBuilder(CoordinatesBuilder coordinates) { + this(coordinates, Orientation.RIGHT); } public Orientation orientation() { @@ -94,11 +103,15 @@ public class PolygonBuilder extends ShapeBuilder { /** * Add a new hole to the polygon * @param hole linear ring defining the hole - * @param coerce if set to true, will close the hole by adding starting point as end point + * @param coerce if set to true, it will try to close the hole by adding starting point as end point * @return this */ public PolygonBuilder hole(LineStringBuilder hole, boolean coerce) { - holes.add(validateLinearRing(hole, coerce)); + if (coerce) { + hole.close(); + } + validateLinearRing(hole); + holes.add(hole); return this; } @@ -124,36 +137,30 @@ public class PolygonBuilder extends ShapeBuilder { return this; } - private static LineStringBuilder validateLinearRing(LineStringBuilder linestring, boolean coerce) { + private static void validateLinearRing(LineStringBuilder lineString) { /** * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) * A LinearRing is closed LineString with 4 or more positions. The first and last positions * are equivalent (they represent equivalent points). Though a LinearRing is not explicitly * represented as a GeoJSON geometry type, it is referred to in the Polygon geometry type definition. */ - int numValidPts; - List points = linestring.points; - if (points.size() < (numValidPts = (coerce) ? 3 : 4)) { + List points = lineString.coordinates; + if (points.size() < 4) { throw new IllegalArgumentException( - "invalid number of points in LinearRing (found [" + points.size() + "] - must be >= " + numValidPts + ")"); + "invalid number of points in LinearRing (found [" + points.size() + "] - must be >= 4)"); } if (!points.get(0).equals(points.get(points.size() - 1))) { - if (coerce) { - points.add(points.get(0)); - } else { throw new IllegalArgumentException("invalid LinearRing found (coordinates are not closed)"); - } } - return linestring; } /** * Validates only 1 vertex is tangential (shared) between the interior and exterior of a polygon */ protected void validateHole(LineStringBuilder shell, LineStringBuilder hole) { - HashSet exterior = Sets.newHashSet(shell.points); - HashSet interior = Sets.newHashSet(hole.points); + HashSet exterior = Sets.newHashSet(shell.coordinates); + HashSet interior = Sets.newHashSet(hole.coordinates); exterior.retainAll(interior); if (exterior.size() >= 2) { throw new InvalidShapeException("Invalid polygon, interior cannot share more than one point with the exterior"); @@ -171,9 +178,9 @@ public class PolygonBuilder extends ShapeBuilder { * @return coordinates of the polygon */ public Coordinate[][][] coordinates() { - int numEdges = shell.points.size()-1; // Last point is repeated + int numEdges = shell.coordinates.size()-1; // Last point is repeated for (int i = 0; i < holes.size(); i++) { - numEdges += holes.get(i).points.size()-1; + numEdges += holes.get(i).coordinates.size()-1; validateHole(shell, this.holes.get(i)); } @@ -236,11 +243,11 @@ public class PolygonBuilder extends ShapeBuilder { } protected Polygon toPolygon(GeometryFactory factory) { - final LinearRing shell = linearRing(factory, this.shell.points); + final LinearRing shell = linearRing(factory, this.shell.coordinates); final LinearRing[] holes = new LinearRing[this.holes.size()]; Iterator iterator = this.holes.iterator(); for (int i = 0; iterator.hasNext(); i++) { - holes[i] = linearRing(factory, iterator.next().points); + holes[i] = linearRing(factory, iterator.next().coordinates); } return factory.createPolygon(shell, holes); } @@ -731,9 +738,9 @@ public class PolygonBuilder extends ShapeBuilder { @Override public PolygonBuilder readFrom(StreamInput in) throws IOException { - LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in); + LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in); Orientation orientation = Orientation.readFrom(in); - PolygonBuilder polyBuilder = new PolygonBuilder(shell.points, orientation); + PolygonBuilder polyBuilder = new PolygonBuilder(shell, orientation); int holes = in.readVInt(); for (int i = 0; i < holes; i++) { polyBuilder.hole(LineStringBuilder.PROTOTYPE.readFrom(in)); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java index e080ee4e201..8c3ea3f3261 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java @@ -26,6 +26,7 @@ import com.spatial4j.core.shape.jts.JtsGeometry; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; + import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.io.stream.NamedWriteable; @@ -86,11 +87,6 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri protected final boolean autoIndexJtsGeometry = true;//may want to turn off once SpatialStrategy impls do it. protected ShapeBuilder() { - - } - - protected static Coordinate coordinate(double longitude, double latitude) { - return new Coordinate(longitude, latitude); } protected JtsGeometry jtsGeometry(Geometry geom) { @@ -594,11 +590,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri protected static MultiPointBuilder parseMultiPoint(CoordinateNode coordinates) { validateMultiPointNode(coordinates); - PointListBuilder points = new PointListBuilder(); + CoordinatesBuilder points = new CoordinatesBuilder(); for (CoordinateNode node : coordinates.children) { - points.point(node.coordinate); + points.coordinate(node.coordinate); } - return new MultiPointBuilder(points.list()); + return new MultiPointBuilder(points.build()); } protected static LineStringBuilder parseLineString(CoordinateNode coordinates) { @@ -611,11 +607,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)", coordinates.children.size()); } - PointListBuilder line = new PointListBuilder(); + CoordinatesBuilder line = new CoordinatesBuilder(); for (CoordinateNode node : coordinates.children) { - line.point(node.coordinate); + line.coordinate(node.coordinate); } - return ShapeBuilders.newLineString(line.list()); + return ShapeBuilders.newLineString(line); } protected static MultiLineStringBuilder parseMultiLine(CoordinateNode coordinates) { @@ -663,7 +659,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri } LineStringBuilder shell = parseLinearRing(coordinates.children.get(0), coerce); - PolygonBuilder polygon = new PolygonBuilder(shell.points, orientation); + PolygonBuilder polygon = new PolygonBuilder(shell, orientation); for (int i = 1; i < coordinates.children.size(); i++) { polygon.hole(parseLinearRing(coordinates.children.get(i), coerce)); } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java index 1fb36fe21e1..1c828814431 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java @@ -64,6 +64,14 @@ public class ShapeBuilders { return new LineStringBuilder(list); } + /** + * Create a new lineString + * @return a new {@link LineStringBuilder} + */ + public static LineStringBuilder newLineString(CoordinatesBuilder coordinates) { + return new LineStringBuilder(coordinates); + } + /** * Create a new Collection of lineStrings * @return a new {@link MultiLineStringBuilder} @@ -73,10 +81,18 @@ public class ShapeBuilders { } /** - * Create a new Polygon - * @return a new {@link PointBuilder} + * Create a new PolygonBuilder + * @return a new {@link PolygonBuilder} */ public static PolygonBuilder newPolygon(List shell) { + return new PolygonBuilder(new CoordinatesBuilder().coordinates(shell)); + } + + /** + * Create a new PolygonBuilder + * @return a new {@link PolygonBuilder} + */ + public static PolygonBuilder newPolygon(CoordinatesBuilder shell) { return new PolygonBuilder(shell); } diff --git a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java index 0837361ab15..d0e03ceddad 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java @@ -28,8 +28,9 @@ import com.spatial4j.core.shape.impl.PointImpl; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Polygon; + +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; @@ -59,12 +60,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-45, 30) - .point(45, 30) - .point(45, -30) - .point(-45, -30) - .point(-45, 30).list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-45, 30) + .coordinate(45, 30) + .coordinate(45, -30) + .coordinate(-45, -30) + .coordinate(-45, 30)).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -74,12 +75,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinate() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(new Coordinate(-45, 30)) - .point(new Coordinate(45, 30)) - .point(new Coordinate(45, -30)) - .point(new Coordinate(-45, -30)) - .point(new Coordinate(-45, 30)).list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(new Coordinate(-45, 30)) + .coordinate(new Coordinate(45, 30)) + .coordinate(new Coordinate(45, -30)) + .coordinate(new Coordinate(-45, -30)) + .coordinate(new Coordinate(-45, 30))).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -89,9 +90,9 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinates() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .points(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)) - .list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinates(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)) + ).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -102,92 +103,92 @@ public class ShapeBuilderTests extends ESTestCase { public void testLineStringBuilder() { // Building a simple LineString - ShapeBuilders.newLineString(new PointListBuilder() - .point(-130.0, 55.0) - .point(-130.0, -40.0) - .point(-15.0, -40.0) - .point(-20.0, 50.0) - .point(-45.0, 50.0) - .point(-45.0, -15.0) - .point(-110.0, -15.0) - .point(-110.0, 55.0).list()).build(); + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-130.0, 55.0) + .coordinate(-130.0, -40.0) + .coordinate(-15.0, -40.0) + .coordinate(-20.0, 50.0) + .coordinate(-45.0, 50.0) + .coordinate(-45.0, -15.0) + .coordinate(-110.0, -15.0) + .coordinate(-110.0, 55.0)).build(); // Building a linestring that needs to be wrapped - ShapeBuilders.newLineString(new PointListBuilder() - .point(100.0, 50.0) - .point(110.0, -40.0) - .point(240.0, -40.0) - .point(230.0, 60.0) - .point(200.0, 60.0) - .point(200.0, -30.0) - .point(130.0, -30.0) - .point(130.0, 60.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(100.0, 50.0) + .coordinate(110.0, -40.0) + .coordinate(240.0, -40.0) + .coordinate(230.0, 60.0) + .coordinate(200.0, 60.0) + .coordinate(200.0, -30.0) + .coordinate(130.0, -30.0) + .coordinate(130.0, 60.0) + ) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString(new PointListBuilder() - .point(-180.0, 80.0) - .point(-180.0, 40.0) - .point(-180.0, -40.0) - .point(-180.0, -80.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-180.0, 80.0) + .coordinate(-180.0, 40.0) + .coordinate(-180.0, -40.0) + .coordinate(-180.0, -80.0) + ) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString(new PointListBuilder() - .point(180.0, 80.0) - .point(180.0, 40.0) - .point(180.0, -40.0) - .point(180.0, -80.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(180.0, 80.0) + .coordinate(180.0, 40.0) + .coordinate(180.0, -40.0) + .coordinate(180.0, -80.0) + ) .build(); } public void testMultiLineString() { ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder(new PointListBuilder() - .point(-100.0, 50.0) - .point(50.0, 50.0) - .point(50.0, 20.0) - .point(-100.0, 20.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-100.0, 50.0) + .coordinate(50.0, 50.0) + .coordinate(50.0, 20.0) + .coordinate(-100.0, 20.0) + ) ) - .linestring(new LineStringBuilder(new PointListBuilder() - .point(-100.0, 20.0) - .point(50.0, 20.0) - .point(50.0, 0.0) - .point(-100.0, 0.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-100.0, 20.0) + .coordinate(50.0, 20.0) + .coordinate(50.0, 0.0) + .coordinate(-100.0, 0.0) + ) ) .build(); // LineString that needs to be wrappped ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder(new PointListBuilder() - .point(150.0, 60.0) - .point(200.0, 60.0) - .point(200.0, 40.0) - .point(150.0, 40.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(150.0, 60.0) + .coordinate(200.0, 60.0) + .coordinate(200.0, 40.0) + .coordinate(150.0, 40.0) + ) + ) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(150.0, 20.0) + .coordinate(200.0, 20.0) + .coordinate(200.0, 0.0) + .coordinate(150.0, 0.0) ) - .linestring(new LineStringBuilder(new PointListBuilder() - .point(150.0, 20.0) - .point(200.0, 20.0) - .point(200.0, 0.0) - .point(150.0, 0.0) - .list()) ) .build(); } public void testPolygonSelfIntersection() { try { - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-40.0, 50.0) - .point(40.0, 50.0) - .point(-40.0, -50.0) - .point(40.0, -50.0).close().list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-40.0, 50.0) + .coordinate(40.0, 50.0) + .coordinate(-40.0, -50.0) + .coordinate(40.0, -50.0).close()) .build(); fail("Expected InvalidShapeException"); } catch (InvalidShapeException e) { @@ -221,26 +222,26 @@ public class ShapeBuilderTests extends ESTestCase { } public void testPolygonWrapping() { - Shape shape = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-150.0, 65.0) - .point(-250.0, 65.0) - .point(-250.0, -65.0) - .point(-150.0, -65.0) + Shape shape = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-150.0, 65.0) + .coordinate(-250.0, 65.0) + .coordinate(-250.0, -65.0) + .coordinate(-150.0, -65.0) .close() - .list()) + ) .build(); assertMultiPolygon(shape); } public void testLineStringWrapping() { - Shape shape = ShapeBuilders.newLineString(new PointListBuilder() - .point(-150.0, 65.0) - .point(-250.0, 65.0) - .point(-250.0, -65.0) - .point(-150.0, -65.0) + Shape shape = ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-150.0, 65.0) + .coordinate(-250.0, 65.0) + .coordinate(-250.0, -65.0) + .coordinate(-150.0, -65.0) .close() - .list()) + ) .build(); assertMultiLineString(shape); } @@ -251,39 +252,39 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(174,0) - .point(-176,0) - .point(-176,3) - .point(177,3) - .point(177,5) - .point(-176,5) - .point(-176,8) - .point(174,8) - .point(174,0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(174,0) + .coordinate(-176,0) + .coordinate(-176,3) + .coordinate(177,3) + .coordinate(177,5) + .coordinate(-176,5) + .coordinate(-176,8) + .coordinate(174,8) + .coordinate(174,0) + ); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(175, 1) - .point(175, 7) - .point(-178, 7) - .point(-178, 6) - .point(176, 6) - .point(176, 2) - .point(179, 2) - .point(179,1) - .point(175, 1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(175, 1) + .coordinate(175, 7) + .coordinate(-178, 7) + .coordinate(-178, 6) + .coordinate(176, 6) + .coordinate(176, 2) + .coordinate(179, 2) + .coordinate(179,1) + .coordinate(175, 1) + )); // embedded hole right of the dateline - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-179, 1) - .point(-179, 2) - .point(-177, 2) - .point(-177,1) - .point(-179,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-179, 1) + .coordinate(-179, 2) + .coordinate(-177, 2) + .coordinate(-177,1) + .coordinate(-179,1) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); @@ -295,114 +296,114 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-186,0) - .point(-176,0) - .point(-176,3) - .point(-183,3) - .point(-183,5) - .point(-176,5) - .point(-176,8) - .point(-186,8) - .point(-186,0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-186,0) + .coordinate(-176,0) + .coordinate(-176,3) + .coordinate(-183,3) + .coordinate(-183,5) + .coordinate(-176,5) + .coordinate(-176,8) + .coordinate(-186,8) + .coordinate(-186,0) + ); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-185,1) - .point(-181,1) - .point(-181,2) - .point(-184,2) - .point(-184,6) - .point(-178,6) - .point(-178,7) - .point(-185,7) - .point(-185,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-185,1) + .coordinate(-181,1) + .coordinate(-181,2) + .coordinate(-184,2) + .coordinate(-184,6) + .coordinate(-178,6) + .coordinate(-178,7) + .coordinate(-185,7) + .coordinate(-185,1) + )); // embedded hole right of the dateline - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-179,1) - .point(-177,1) - .point(-177,2) - .point(-179,2) - .point(-179,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-179,1) + .coordinate(-177,1) + .coordinate(-177,2) + .coordinate(-179,2) + .coordinate(-179,1) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testComplexShapeWithHole() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-85.0018514,37.1311314) - .point(-85.0016645,37.1315293) - .point(-85.0016246,37.1317069) - .point(-85.0016526,37.1318183) - .point(-85.0017119,37.1319196) - .point(-85.0019371,37.1321182) - .point(-85.0019972,37.1322115) - .point(-85.0019942,37.1323234) - .point(-85.0019543,37.1324336) - .point(-85.001906,37.1324985) - .point(-85.001834,37.1325497) - .point(-85.0016965,37.1325907) - .point(-85.0016011,37.1325873) - .point(-85.0014816,37.1325353) - .point(-85.0011755,37.1323509) - .point(-85.000955,37.1322802) - .point(-85.0006241,37.1322529) - .point(-85.0000002,37.1322307) - .point(-84.9994,37.1323001) - .point(-84.999109,37.1322864) - .point(-84.998934,37.1322415) - .point(-84.9988639,37.1321888) - .point(-84.9987841,37.1320944) - .point(-84.9987208,37.131954) - .point(-84.998736,37.1316611) - .point(-84.9988091,37.131334) - .point(-84.9989283,37.1311337) - .point(-84.9991943,37.1309198) - .point(-84.9993573,37.1308459) - .point(-84.9995888,37.1307924) - .point(-84.9998746,37.130806) - .point(-85.0000002,37.1308358) - .point(-85.0004984,37.1310658) - .point(-85.0008008,37.1311625) - .point(-85.0009461,37.1311684) - .point(-85.0011373,37.1311515) - .point(-85.0016455,37.1310491) - .point(-85.0018514,37.1311314) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-85.0018514,37.1311314) + .coordinate(-85.0016645,37.1315293) + .coordinate(-85.0016246,37.1317069) + .coordinate(-85.0016526,37.1318183) + .coordinate(-85.0017119,37.1319196) + .coordinate(-85.0019371,37.1321182) + .coordinate(-85.0019972,37.1322115) + .coordinate(-85.0019942,37.1323234) + .coordinate(-85.0019543,37.1324336) + .coordinate(-85.001906,37.1324985) + .coordinate(-85.001834,37.1325497) + .coordinate(-85.0016965,37.1325907) + .coordinate(-85.0016011,37.1325873) + .coordinate(-85.0014816,37.1325353) + .coordinate(-85.0011755,37.1323509) + .coordinate(-85.000955,37.1322802) + .coordinate(-85.0006241,37.1322529) + .coordinate(-85.0000002,37.1322307) + .coordinate(-84.9994,37.1323001) + .coordinate(-84.999109,37.1322864) + .coordinate(-84.998934,37.1322415) + .coordinate(-84.9988639,37.1321888) + .coordinate(-84.9987841,37.1320944) + .coordinate(-84.9987208,37.131954) + .coordinate(-84.998736,37.1316611) + .coordinate(-84.9988091,37.131334) + .coordinate(-84.9989283,37.1311337) + .coordinate(-84.9991943,37.1309198) + .coordinate(-84.9993573,37.1308459) + .coordinate(-84.9995888,37.1307924) + .coordinate(-84.9998746,37.130806) + .coordinate(-85.0000002,37.1308358) + .coordinate(-85.0004984,37.1310658) + .coordinate(-85.0008008,37.1311625) + .coordinate(-85.0009461,37.1311684) + .coordinate(-85.0011373,37.1311515) + .coordinate(-85.0016455,37.1310491) + .coordinate(-85.0018514,37.1311314) + ); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-85.0000002,37.1317672) - .point(-85.0001983,37.1317538) - .point(-85.0003378,37.1317582) - .point(-85.0004697,37.131792) - .point(-85.0008048,37.1319439) - .point(-85.0009342,37.1319838) - .point(-85.0010184,37.1319463) - .point(-85.0010618,37.13184) - .point(-85.0010057,37.1315102) - .point(-85.000977,37.1314403) - .point(-85.0009182,37.1313793) - .point(-85.0005366,37.1312209) - .point(-85.000224,37.1311466) - .point(-85.000087,37.1311356) - .point(-85.0000002,37.1311433) - .point(-84.9995021,37.1312336) - .point(-84.9993308,37.1312859) - .point(-84.9992567,37.1313252) - .point(-84.9991868,37.1314277) - .point(-84.9991593,37.1315381) - .point(-84.9991841,37.1316527) - .point(-84.9992329,37.1317117) - .point(-84.9993527,37.1317788) - .point(-84.9994931,37.1318061) - .point(-84.9996815,37.1317979) - .point(-85.0000002,37.1317672) - .list()) + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-85.0000002,37.1317672) + .coordinate(-85.0001983,37.1317538) + .coordinate(-85.0003378,37.1317582) + .coordinate(-85.0004697,37.131792) + .coordinate(-85.0008048,37.1319439) + .coordinate(-85.0009342,37.1319838) + .coordinate(-85.0010184,37.1319463) + .coordinate(-85.0010618,37.13184) + .coordinate(-85.0010057,37.1315102) + .coordinate(-85.000977,37.1314403) + .coordinate(-85.0009182,37.1313793) + .coordinate(-85.0005366,37.1312209) + .coordinate(-85.000224,37.1311466) + .coordinate(-85.000087,37.1311356) + .coordinate(-85.0000002,37.1311433) + .coordinate(-84.9995021,37.1312336) + .coordinate(-84.9993308,37.1312859) + .coordinate(-84.9992567,37.1313252) + .coordinate(-84.9991868,37.1314277) + .coordinate(-84.9991593,37.1315381) + .coordinate(-84.9991841,37.1316527) + .coordinate(-84.9992329,37.1317117) + .coordinate(-84.9993527,37.1317788) + .coordinate(-84.9994931,37.1318061) + .coordinate(-84.9996815,37.1317979) + .coordinate(-85.0000002,37.1317672) + ) ); Shape shape = builder.close().build(); @@ -410,35 +411,35 @@ public class ShapeBuilderTests extends ESTestCase { } public void testShapeWithHoleAtEdgeEndPoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-4, 2) - .point(4, 2) - .point(6, 0) - .point(4, -2) - .point(-4, -2) - .point(-6, 0) - .point(-4, 2) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-4, 2) + .coordinate(4, 2) + .coordinate(6, 0) + .coordinate(4, -2) + .coordinate(-4, -2) + .coordinate(-6, 0) + .coordinate(-4, 2) + ); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(4, 1) - .point(4, -1) - .point(-4, -1) - .point(-4, 1) - .point(4, 1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(4, 1) + .coordinate(4, -1) + .coordinate(-4, -1) + .coordinate(-4, 1) + .coordinate(4, 1) + )); Shape shape = builder.close().build(); assertPolygon(shape); } public void testShapeWithPointOnDateline() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(176, -4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(176, -4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); @@ -446,23 +447,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithEdgeAlongDateline() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(180, -4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(180, -4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); // test case 2: test the negative side of the dateline - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-176, 4) - .point(-180, 0) - .point(-180, -4) - .point(-176, 4) - .list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-176, 4) + .coordinate(-180, 0) + .coordinate(-180, -4) + .coordinate(-176, 4) + ); shape = builder.close().build(); assertPolygon(shape); @@ -470,85 +471,85 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithBoundaryHoles() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(176, 10) - .point(180, 5) - .point(180, -5) - .point(176, -10) - .point(176, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(176, 10) + .coordinate(180, 5) + .coordinate(180, -5) + .coordinate(176, -10) + .coordinate(176, 10) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); // test case 2: test the negative side of the dateline builder = ShapeBuilders.newPolygon( - new PointListBuilder() - .point(-176, 15) - .point(179, 10) - .point(179, -10) - .point(-176, -15) - .point(-172, 0) + new CoordinatesBuilder() + .coordinate(-176, 15) + .coordinate(179, 10) + .coordinate(179, -10) + .coordinate(-176, -15) + .coordinate(-172, 0) .close() - .list()); + ); builder.hole(new LineStringBuilder( - new PointListBuilder() - .point(-176, 10) - .point(-176, -10) - .point(-180, -5) - .point(-180, 5) - .point(-176, 10) + new CoordinatesBuilder() + .coordinate(-176, 10) + .coordinate(-176, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-176, 10) .close() - .list())); + )); shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(179, 10) - .point(168, 15) - .point(164, 0) - .point(166, -15) - .point(179, -10) - .point(179, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(-178, -10) - .point(-180, -5) - .point(-180, 5) - .point(-177, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(179, 10) + .coordinate(168, 15) + .coordinate(164, 0) + .coordinate(166, -15) + .coordinate(179, -10) + .coordinate(179, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(-178, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-177, 10) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithInvalidTangentialHole() { // test a shape with one invalid tangential (shared) vertex (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(179, 10) - .point(168, 15) - .point(164, 0) - .point(166, -15) - .point(179, -10) - .point(179, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(164, 0) - .point(175, 10) - .point(175, 5) - .point(179, -10) - .point(164, 0) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(179, 10) + .coordinate(168, 15) + .coordinate(164, 0) + .coordinate(166, -15) + .coordinate(179, -10) + .coordinate(179, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(164, 0) + .coordinate(175, 10) + .coordinate(175, 5) + .coordinate(179, -10) + .coordinate(164, 0) + )); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -559,48 +560,48 @@ public class ShapeBuilderTests extends ESTestCase { public void testBoundaryShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex for each hole (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(-178, -10) - .point(-180, -5) - .point(-180, 5) - .point(-177, 10) - .list())); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(172, 0) - .point(176, 10) - .point(176, -5) - .point(172, 0) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(-178, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-177, 10) + )); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(172, 0) + .coordinate(176, 10) + .coordinate(176, -5) + .coordinate(172, 0) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testBoundaryShapeWithInvalidTangentialHole() { // test shape with two tangential (shared) vertices (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(172, 0) - .point(180, -5) - .point(176, -10) - .point(-177, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(172, 0) + .coordinate(180, -5) + .coordinate(176, -10) + .coordinate(-177, 10) + )); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -613,12 +614,12 @@ public class ShapeBuilderTests extends ESTestCase { * Test an enveloping polygon around the max mercator bounds */ public void testBoundaryShape() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-180, 90) - .point(180, 90) - .point(180, -90) - .point(-180, 90) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-180, 90) + .coordinate(180, 90) + .coordinate(180, -90) + .coordinate(-180, 90) + ); Shape shape = builder.close().build(); @@ -627,23 +628,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithAlternateOrientation() { // cw: should produce a multi polygon spanning hemispheres - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(-176, 4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(-176, 4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); // cw: geo core will convert to ccw across the dateline - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(-176, 4) - .point(176, 4) - .point(180, 0) - .list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(-176, 4) + .coordinate(176, 4) + .coordinate(180, 0) + ); shape = builder.close().build(); @@ -651,13 +652,13 @@ public class ShapeBuilderTests extends ESTestCase { } public void testInvalidShapeWithConsecutiveDuplicatePoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(176, 4) - .point(-176, 4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(176, 4) + .coordinate(-176, 4) + .coordinate(180, 0) + ); try { builder.close().build(); fail("Expected InvalidShapeException"); diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java index 8562ad6adf5..f6fcf8449d3 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java @@ -20,10 +20,12 @@ package org.elasticsearch.common.geo.builders; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.test.geo.RandomShapeGenerator; import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType; import java.io.IOException; +import java.util.List; import static org.hamcrest.Matchers.equalTo; @@ -31,21 +33,21 @@ public class LineStringBuilderTests extends AbstractShapeBuilderTestCase) null); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); } try { - new LineStringBuilder(new PointListBuilder().list()); + new LineStringBuilder(new CoordinatesBuilder()); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); } try { - new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).list()); + new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0)); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("invalid number of points in LineString (found [1] - must be >= 2)", equalTo(e.getMessage())); @@ -79,7 +81,7 @@ public class LineStringBuilderTests extends AbstractShapeBuilderTestCase { @Override @@ -77,7 +80,7 @@ public class PolygonBuilderTests extends AbstractShapeBuilderTestCase= 4)", e.getMessage()); + } + + PolygonBuilder pb = new PolygonBuilder(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0) + .coordinate(1.0, 0.0).coordinate(1.0, 1.0).build()), Orientation.RIGHT, true); + assertThat("Shell should have been closed via coerce", pb.shell().coordinates(false).length, equalTo(4)); + } + + public void testCoerceHole() { + PolygonBuilder pb = new PolygonBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0) + .coordinate(2.0, 0.0).coordinate(2.0, 2.0).coordinate(0.0, 0.0)); + try{ + pb.hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0,0.0).coordinate(1.0,0.0).coordinate(1.0,1.0).build())); + fail("should raise validation exception"); + } catch (IllegalArgumentException e) { + assertEquals("invalid number of points in LinearRing (found [3] - must be >= 4)", e.getMessage()); + } + + pb.hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0,0.0).coordinate(1.0,0.0).coordinate(1.0,1.0).build()), true); + assertThat("hole should have been closed via coerce", pb.holes().get(0).coordinates(false).length, equalTo(4)); + } + } diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java index d93bcc2fe41..61f7865fa13 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java @@ -23,7 +23,7 @@ import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.ShapeRelation; -import org.elasticsearch.common.geo.builders.PointListBuilder; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item; @@ -176,13 +176,13 @@ public class QueryDSLDocumentationTests extends ESTestCase { GeoShapeQueryBuilder qb = geoShapeQuery( "pin.location", ShapeBuilders.newMultiPoint( - new PointListBuilder() - .point(0, 0) - .point(0, 10) - .point(10, 10) - .point(10, 0) - .point(0, 0) - .list())); + new CoordinatesBuilder() + .coordinate(0, 0) + .coordinate(0, 10) + .coordinate(10, 10) + .coordinate(10, 0) + .coordinate(0, 0) + .build())); qb.relation(ShapeRelation.WITHIN); qb = geoShapeQuery( diff --git a/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java b/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java index 00aee4f039e..e96c53fe943 100644 --- a/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java +++ b/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java @@ -23,6 +23,7 @@ import com.spatial4j.core.context.SpatialContext; import com.spatial4j.core.distance.DistanceUtils; import com.spatial4j.core.exception.InvalidShapeException; import com.spatial4j.core.shape.Shape; + import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy; import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree; import org.apache.lucene.spatial.query.SpatialArgs; @@ -40,9 +41,9 @@ import org.elasticsearch.common.Priority; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; import org.elasticsearch.common.geo.builders.MultiPolygonBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.io.Streams; @@ -120,29 +121,28 @@ public class GeoFilterIT extends ESIntegTestCase { public void testShapeBuilders() { try { // self intersection polygon - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10) - .point(10, 10) - .point(-10, 10) - .point(10, -10) - .close() - .list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10) + .coordinate(10, 10) + .coordinate(-10, 10) + .coordinate(10, -10) + .close()) .build(); fail("Self intersection not detected"); } catch (InvalidShapeException e) { } // polygon with hole - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())) .build(); try { // polygon with overlapping hole - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 11).point(5, 11).point(5, -5).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 11).coordinate(5, 11).coordinate(5, -5).close())) .build(); fail("Self intersection not detected"); @@ -151,10 +151,10 @@ public class GeoFilterIT extends ESIntegTestCase { try { // polygon with intersection holes - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list())) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -6).point(5, -6).point(5, -4).point(-5, -4).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -6).coordinate(5, -6).coordinate(5, -4).coordinate(-5, -4).close())) .build(); fail("Intersection of holes not detected"); } catch (InvalidShapeException e) { @@ -162,16 +162,15 @@ public class GeoFilterIT extends ESIntegTestCase { try { // Common line in polygon - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10) - .point(-10, 10) - .point(-5, 10) - .point(-5, -5) - .point(-5, 20) - .point(10, 20) - .point(10, -10) - .close() - .list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10) + .coordinate(-10, 10) + .coordinate(-5, 10) + .coordinate(-5, -5) + .coordinate(-5, 20) + .coordinate(10, 20) + .coordinate(10, -10) + .close()) .build(); fail("Self intersection not detected"); } catch (InvalidShapeException e) { @@ -181,21 +180,21 @@ public class GeoFilterIT extends ESIntegTestCase { ShapeBuilders .newMultiPolygon() .polygon(new PolygonBuilder( - new PointListBuilder().point(-10, -10) - .point(-10, 10) - .point(10, 10) - .point(10, -10).close().list()) + new CoordinatesBuilder().coordinate(-10, -10) + .coordinate(-10, 10) + .coordinate(10, 10) + .coordinate(10, -10).close()) .hole(new LineStringBuilder( - new PointListBuilder().point(-5, -5) - .point(-5, 5) - .point(5, 5) - .point(5, -5).close().list()))) + new CoordinatesBuilder().coordinate(-5, -5) + .coordinate(-5, 5) + .coordinate(5, 5) + .coordinate(5, -5).close()))) .polygon(new PolygonBuilder( - new PointListBuilder() - .point(-4, -4) - .point(-4, 4) - .point(4, 4) - .point(4, -4).close().list())) + new CoordinatesBuilder() + .coordinate(-4, -4) + .coordinate(-4, 4) + .coordinate(4, 4) + .coordinate(4, -4).close())) .build(); } @@ -225,11 +224,11 @@ public class GeoFilterIT extends ESIntegTestCase { // the second polygon of size 4x4 equidistant from all sites MultiPolygonBuilder polygon = ShapeBuilders.newMultiPolygon() .polygon(new PolygonBuilder( - new PointListBuilder().point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list()))) + new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close()))) .polygon(new PolygonBuilder( - new PointListBuilder().point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close().list())); + new CoordinatesBuilder().coordinate(-4, -4).coordinate(-4, 4).coordinate(4, 4).coordinate(4, -4).close())); BytesReference data = jsonBuilder().startObject().field("area", polygon).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); @@ -288,10 +287,10 @@ public class GeoFilterIT extends ESIntegTestCase { } // Create a polygon that fills the empty area of the polygon defined above - PolygonBuilder inverse = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list()) + PolygonBuilder inverse = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close()) .hole(new LineStringBuilder( - new PointListBuilder().point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close().list())); + new CoordinatesBuilder().coordinate(-4, -4).coordinate(-4, 4).coordinate(4, 4).coordinate(4, -4).close())); data = jsonBuilder().startObject().field("area", inverse).endObject().bytes(); client().prepareIndex("shapes", "polygon", "2").setSource(data).execute().actionGet(); @@ -306,15 +305,15 @@ public class GeoFilterIT extends ESIntegTestCase { assertFirstHit(result, hasId("2")); // Create Polygon with hole and common edge - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(10, 5).point(10, -5).close().list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(10, 5).coordinate(10, -5).close())); if (withinSupport) { // Polygon WithIn Polygon - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-30, -30).point(-30, 30).point(30, 30).point(30, -30).close().list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-30, -30).coordinate(-30, 30).coordinate(30, 30).coordinate(30, -30).close()); result = client().prepareSearch() .setQuery(matchAllQuery()) @@ -324,17 +323,17 @@ public class GeoFilterIT extends ESIntegTestCase { } // Create a polygon crossing longitude 180. - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()); data = jsonBuilder().startObject().field("area", builder).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); client().admin().indices().prepareRefresh().execute().actionGet(); // Create a polygon crossing longitude 180 with hole. - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close().list())); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(175, -5).coordinate(185, -5).coordinate(185, 5).coordinate(175, 5).close())); data = jsonBuilder().startObject().field("area", builder).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java b/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java index 5813e028583..c6f05ee23a2 100644 --- a/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java +++ b/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java @@ -25,10 +25,10 @@ import com.vividsolutions.jts.geom.Coordinate; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.geo.ShapeRelation; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.EnvelopeBuilder; import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -198,13 +198,13 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { } public void testReusableBuilder() throws IOException { - ShapeBuilder polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close().list())); + ShapeBuilder polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(175, -5).coordinate(185, -5).coordinate(185, 5).coordinate(175, 5).close())); assertUnmodified(polygon); - ShapeBuilder linestring = ShapeBuilders.newLineString(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()); + ShapeBuilder linestring = ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()); assertUnmodified(linestring); } @@ -377,8 +377,8 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { "location", ShapeBuilders.newGeometryCollection() .polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0) - .point(99.0, -1.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(99.0, -1.0).coordinate(99.0, 3.0).coordinate(103.0, 3.0).coordinate(103.0, -1.0) + .coordinate(99.0, -1.0)))).relation(ShapeRelation.INTERSECTS); SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); @@ -386,17 +386,17 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { filter = QueryBuilders.geoShapeQuery( "location", ShapeBuilders.newGeometryCollection().polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0) - .point(199.0, -11.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0).coordinate(193.0, 13.0).coordinate(193.0, -11.0) + .coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS); result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); assertHitCount(result, 0); filter = QueryBuilders.geoShapeQuery("location", ShapeBuilders.newGeometryCollection() - .polygon(ShapeBuilders.newPolygon(new PointListBuilder().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0).point(99.0, -1.0).list())) + .polygon(ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(99.0, -1.0).coordinate(99.0, 3.0).coordinate(103.0, 3.0).coordinate(103.0, -1.0).coordinate(99.0, -1.0))) .polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0) - .point(199.0, -11.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0).coordinate(193.0, 13.0).coordinate(193.0, -11.0) + .coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS); result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); diff --git a/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java b/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java index 01f7c8f66ee..4cc7f8f8487 100644 --- a/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java +++ b/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java @@ -31,13 +31,13 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.geo.builders.CoordinateCollection; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; import org.elasticsearch.common.geo.builders.MultiLineStringBuilder; import org.elasticsearch.common.geo.builders.MultiPointBuilder; import org.elasticsearch.common.geo.builders.PointBuilder; -import org.elasticsearch.common.geo.builders.PointCollection; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.search.geo.GeoShapeQueryTests; @@ -189,12 +189,12 @@ public class RandomShapeGenerator extends RandomGeoGenerator { // if this number gets out of hand, the number of self intersections for a linestring can become // (n^2-n)/2 and computing the relation intersection matrix will become NP-Hard int numPoints = RandomInts.randomIntBetween(r, 3, 10); - PointListBuilder pl = new PointListBuilder(); + CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder(); for (int i=0; i