Browse Source

Also removing Ring and replacing it by LineStringBuilder

The Ring subclass is just a LineStringBuilder that has an additional
close() method and keeps a reference to a parent shape builder so
builders can be chained. This PR removes it and replaces it by
using LineStringBuilder instead. The close() method is moved there
and tests are adapted.
Christoph Büscher 10 years ago
parent
commit
b5b3ff5eb0

+ 4 - 9
core/src/main/java/org/elasticsearch/common/geo/builders/BaseLineStringBuilder.java

@@ -23,7 +23,6 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import com.spatial4j.core.shape.ShapeCollection;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import com.spatial4j.core.shape.Shape;
@@ -34,11 +33,7 @@ import com.vividsolutions.jts.geom.LineString;
 
 public abstract class BaseLineStringBuilder<E extends BaseLineStringBuilder<E>> extends PointCollection<E> {
 
-    protected BaseLineStringBuilder() {
-        this(new ArrayList<Coordinate>());
-    }
-
-    protected BaseLineStringBuilder(ArrayList<Coordinate> points) {
+    public BaseLineStringBuilder(ArrayList<Coordinate> points) {
         super(points);
     }
 
@@ -78,15 +73,15 @@ public abstract class BaseLineStringBuilder<E extends BaseLineStringBuilder<E>>
 
     /**
      * Decompose a linestring given as array of coordinates at a vertical line.
-     * 
+     *
      * @param dateline x-axis intercept of the vertical line
      * @param coordinates coordinates forming the linestring
-     * @return array of linestrings given as coordinate arrays 
+     * @return array of linestrings given as coordinate arrays
      */
     protected static Coordinate[][] decompose(double dateline, Coordinate[] coordinates) {
         int offset = 0;
         ArrayList<Coordinate[]> parts = new ArrayList<>();
-        
+
         double shift = coordinates[0].x > DATELINE ? DATELINE : (coordinates[0].x < -DATELINE ? -DATELINE : 0);
 
         for (int i = 1; i < coordinates.length; i++) {

+ 37 - 75
core/src/main/java/org/elasticsearch/common/geo/builders/BasePolygonBuilder.java

@@ -42,8 +42,8 @@ import java.util.Iterator;
  * The {@link BasePolygonBuilder} implements the groundwork to create polygons. This contains
  * Methods to wrap polygons at the dateline and building shapes from the data held by the
  * builder.
- * Since this Builder can be embedded to other builders (i.e. {@link MultiPolygonBuilder}) 
- * the class of the embedding builder is given by the generic argument <code>E</code>  
+ * Since this Builder can be embedded to other builders (i.e. {@link MultiPolygonBuilder})
+ * the class of the embedding builder is given by the generic argument <code>E</code>
 
  * @param <E> type of the embedding class
  */
@@ -51,11 +51,11 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
 
     public static final GeoShapeType TYPE = GeoShapeType.POLYGON;
 
-    // Linear ring defining the shell of the polygon
-    protected Ring<E> shell; 
+    // line string defining the shell of the polygon
+    protected LineStringBuilder shell;
 
-    // List of linear rings defining the holes of the polygon 
-    protected final ArrayList<BaseLineStringBuilder<?>> holes = new ArrayList<>();
+    // List of line strings defining the holes of the polygon
+    protected final ArrayList<LineStringBuilder> holes = new ArrayList<>();
 
     public BasePolygonBuilder(Orientation orientation) {
         super(orientation);
@@ -65,7 +65,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
     private E thisRef() {
         return (E)this;
     }
-    
+
     public E point(double longitude, double latitude) {
         shell.point(longitude, latitude);
         return thisRef();
@@ -96,27 +96,17 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
      * @param hole linear ring defining the hole
      * @return this
      */
-    public E hole(BaseLineStringBuilder<?> hole) {
+    public E hole(LineStringBuilder hole) {
         holes.add(hole);
         return thisRef();
     }
 
-    /**
-     * build new hole to the polygon
-     * @return this
-     */
-    public Ring<E> hole() {
-        Ring<E> hole = new Ring<>(thisRef());
-        this.holes.add(hole);
-        return hole;
-    }
-
     /**
      * Close the shell of the polygon
-     * @return parent
      */
-    public ShapeBuilder close() {
-        return shell.close();
+    public BasePolygonBuilder close() {
+        shell.close();
+        return this;
     }
 
     /**
@@ -138,11 +128,11 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
      * within the polygon.
      * This Method also wraps the polygons at the dateline. In order to this fact the result may
      * contains more polygons and less holes than defined in the builder it self.
-     * 
+     *
      * @return coordinates of the polygon
      */
     public Coordinate[][][] coordinates() {
-        int numEdges = shell.points.size()-1; // Last point is repeated 
+        int numEdges = shell.points.size()-1; // Last point is repeated
         for (int i = 0; i < holes.size(); i++) {
             numEdges += holes.get(i).points.size()-1;
             validateHole(shell, this.holes.get(i));
@@ -172,12 +162,12 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
 
     protected XContentBuilder coordinatesArray(XContentBuilder builder, Params params) throws IOException {
         shell.coordinatesToXcontent(builder, true);
-        for(BaseLineStringBuilder<?> hole : holes) {
+        for(BaseLineStringBuilder hole : holes) {
             hole.coordinatesToXcontent(builder, true);
         }
         return builder;
     }
-    
+
     @Override
     public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
         builder.startObject();
@@ -188,7 +178,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         builder.endObject();
         return builder;
     }
-    
+
     public Geometry buildGeometry(GeometryFactory factory, boolean fixDateline) {
         if(fixDateline) {
             Coordinate[][][] polygons = coordinates();
@@ -207,7 +197,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
     protected Polygon toPolygon(GeometryFactory factory) {
         final LinearRing shell = linearRing(factory, this.shell.points);
         final LinearRing[] holes = new LinearRing[this.holes.size()];
-        Iterator<BaseLineStringBuilder<?>> iterator = this.holes.iterator();
+        Iterator<LineStringBuilder> iterator = this.holes.iterator();
         for (int i = 0; iterator.hasNext(); i++) {
             holes[i] = linearRing(factory, iterator.next().points);
         }
@@ -226,7 +216,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
     protected static Polygon polygon(GeometryFactory factory, Coordinate[][] polygon) {
         LinearRing shell = factory.createLinearRing(polygon[0]);
         LinearRing[] holes;
-        
+
         if(polygon.length > 1) {
             holes = new LinearRing[polygon.length-1];
             for (int i = 0; i < holes.length; i++) {
@@ -243,7 +233,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
      * in turn contains an array of linestrings. These line Strings are represented as an array of
      * coordinates. The first linestring will be the shell of the polygon the others define holes
      * within the polygon.
-     *      
+     *
      * @param factory {@link GeometryFactory} to use
      * @param polygons definition of polygons
      * @return a new Multipolygon
@@ -258,19 +248,19 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
 
     /**
      * This method sets the component id of all edges in a ring to a given id and shifts the
-     * coordinates of this component according to the dateline 
-     * 
+     * coordinates of this component according to the dateline
+     *
      * @param edge An arbitrary edge of the component
      * @param id id to apply to the component
      * @param edges a list of edges to which all edges of the component will be added (could be <code>null</code>)
      * @return number of edges that belong to this component
      */
     private static int component(final Edge edge, final int id, final ArrayList<Edge> edges) {
-        // find a coordinate that is not part of the dateline 
+        // find a coordinate that is not part of the dateline
         Edge any = edge;
         while(any.coordinate.x == +DATELINE || any.coordinate.x == -DATELINE) {
             if((any = any.next) == edge) {
-                break;   
+                break;
             }
         }
 
@@ -362,7 +352,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         }
 
         return result;
-    } 
+    }
 
     private static final Coordinate[][] EMPTY = new Coordinate[0][];
 
@@ -378,7 +368,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         }
 
         return points;
-    } 
+    }
 
     private static Edge[] edges(Edge[] edges, int numHoles, ArrayList<ArrayList<Coordinate[]>> components) {
         ArrayList<Edge> mainEdges = new ArrayList<>(edges.length);
@@ -412,7 +402,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         }
         for (int i = 0; i < numHoles; i++) {
             final Edge current = new Edge(holes[i].coordinate, holes[i].next);
-            // the edge intersects with itself at its own coordinate.  We need intersect to be set this way so the binary search 
+            // the edge intersects with itself at its own coordinate.  We need intersect to be set this way so the binary search
             // will get the correct position in the edge list and therefore the correct component to add the hole
             current.intersect = current.coordinate;
             final int intersections = intersections(current.coordinate.x, edges);
@@ -457,20 +447,20 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
                 holes[e2.component-1] = holes[numHoles];
                 holes[numHoles] = null;
             }
-            // only connect edges if intersections are pairwise 
+            // only connect edges if intersections are pairwise
             // 1. per the comment above, the edge array is sorted by y-value of the intersection
-            // with the dateline.  Two edges have the same y intercept when they cross the 
+            // with the dateline.  Two edges have the same y intercept when they cross the
             // dateline thus they appear sequentially (pairwise) in the edge array. Two edges
             // do not have the same y intercept when we're forming a multi-poly from a poly
-            // that wraps the dateline (but there are 2 ordered intercepts).  
-            // The connect method creates a new edge for these paired edges in the linked list. 
-            // For boundary conditions (e.g., intersect but not crossing) there is no sibling edge 
+            // that wraps the dateline (but there are 2 ordered intercepts).
+            // The connect method creates a new edge for these paired edges in the linked list.
+            // For boundary conditions (e.g., intersect but not crossing) there is no sibling edge
             // to connect. Thus the first logic check enforces the pairwise rule
             // 2. the second logic check ensures the two candidate edges aren't already connected by an
             //    existing edge along the dateline - this is necessary due to a logic change in
-            //    ShapeBuilder.intersection that computes dateline edges as valid intersect points 
+            //    ShapeBuilder.intersection that computes dateline edges as valid intersect points
             //    in support of OGC standards
-            if (e1.intersect != Edge.MAX_COORDINATE && e2.intersect != Edge.MAX_COORDINATE 
+            if (e1.intersect != Edge.MAX_COORDINATE && e2.intersect != Edge.MAX_COORDINATE
                     && !(e1.next.next.coordinate.equals3D(e2.coordinate) && Math.abs(e1.next.coordinate.x) == DATELINE
                     && Math.abs(e2.coordinate.x) == DATELINE) ) {
                 connect(e1, e2);
@@ -489,7 +479,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
             // NOTE: the order of the object creation is crucial here! Don't change it!
             // first edge has no point on dateline
             Edge e1 = new Edge(in.intersect, in.next);
-            
+
             if(out.intersect != out.next.coordinate) {
                 // second edge has no point on dateline
                 Edge e2 = new Edge(out.intersect, out.next);
@@ -507,7 +497,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
                 // second edge has no point on dateline
                 Edge e1 = new Edge(out.intersect, out.next);
                 in.next = new Edge(in.intersect, e1, in.intersect);
-                
+
             } else {
                 // second edge intersects with dateline
                 in.next = new Edge(in.intersect, out.next, in.intersect);
@@ -516,8 +506,8 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         }
     }
 
-    private static int createEdges(int component, Orientation orientation, BaseLineStringBuilder<?> shell,
-                                   BaseLineStringBuilder<?> hole,
+    private static int createEdges(int component, Orientation orientation, BaseLineStringBuilder shell,
+                                   BaseLineStringBuilder hole,
                                    Edge[] edges, int offset) {
         // inner rings (holes) have an opposite direction than the outer rings
         // XOR will invert the orientation for outer ring cases (Truth Table:, T/T = F, T/F = T, F/T = T, F/F = F)
@@ -527,32 +517,4 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
         Edge.ring(component, direction, orientation == Orientation.LEFT, shell, points, 0, edges, offset, points.length-1);
         return points.length-1;
     }
-
-    public static class Ring<P extends ShapeBuilder> extends BaseLineStringBuilder<Ring<P>> {
-
-        private final P parent;
-
-        protected Ring(P parent) {
-            this(parent, new ArrayList<Coordinate>());
-        }
-
-        protected Ring(P parent, ArrayList<Coordinate> points) {
-            super(points);
-            this.parent = parent;
-        }
-
-        public P close() {
-            Coordinate start = points.get(0);
-            Coordinate end = points.get(points.size()-1);
-            if(start.x != end.x || start.y != end.y) {
-                points.add(start);
-            }
-            return parent;
-        }
-
-        @Override
-        public GeoShapeType type() {
-            return null;
-        }
-    }
 }

+ 12 - 12
core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java

@@ -29,7 +29,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class GeometryCollectionBuilder extends ShapeBuilder {
-    
+
     public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION;
 
     protected final ArrayList<ShapeBuilder> shapes = new ArrayList<>();
@@ -46,42 +46,42 @@ public class GeometryCollectionBuilder extends ShapeBuilder {
         this.shapes.add(shape);
         return this;
     }
-    
+
     public GeometryCollectionBuilder point(PointBuilder point) {
         this.shapes.add(point);
         return this;
     }
-    
+
     public GeometryCollectionBuilder multiPoint(MultiPointBuilder multiPoint) {
         this.shapes.add(multiPoint);
         return this;
     }
-    
-    public GeometryCollectionBuilder line(BaseLineStringBuilder<?> line) {
+
+    public GeometryCollectionBuilder line(BaseLineStringBuilder line) {
         this.shapes.add(line);
         return this;
     }
-    
+
     public GeometryCollectionBuilder multiLine(MultiLineStringBuilder multiLine) {
         this.shapes.add(multiLine);
         return this;
     }
-    
+
     public GeometryCollectionBuilder polygon(BasePolygonBuilder<?> polygon) {
         this.shapes.add(polygon);
         return this;
     }
-    
+
     public GeometryCollectionBuilder multiPolygon(MultiPolygonBuilder multiPolygon) {
         this.shapes.add(multiPolygon);
         return this;
     }
-    
+
     public GeometryCollectionBuilder envelope(EnvelopeBuilder envelope) {
         this.shapes.add(envelope);
         return this;
     }
-    
+
     public GeometryCollectionBuilder circle(CircleBuilder circle) {
         this.shapes.add(circle);
         return this;
@@ -120,11 +120,11 @@ public class GeometryCollectionBuilder extends ShapeBuilder {
     public Shape build() {
 
         List<Shape> shapes = new ArrayList<>(this.shapes.size());
-        
+
         for (ShapeBuilder shape : this.shapes) {
             shapes.add(shape.build());
         }
-            
+
         if (shapes.size() == 1)
             return shapes.get(0);
         else

+ 23 - 0
core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java

@@ -19,12 +19,23 @@
 
 package org.elasticsearch.common.geo.builders;
 
+import com.vividsolutions.jts.geom.Coordinate;
+
 import org.elasticsearch.common.xcontent.XContentBuilder;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 public class LineStringBuilder extends BaseLineStringBuilder<LineStringBuilder> {
 
+    public LineStringBuilder() {
+        this(new ArrayList<Coordinate>());
+    }
+
+    public LineStringBuilder(ArrayList<Coordinate> points) {
+        super(points);
+    }
+
     public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;
 
     @Override
@@ -42,4 +53,16 @@ public class LineStringBuilder extends BaseLineStringBuilder<LineStringBuilder>
         return TYPE;
     }
 
+    /**
+     * Closes the current lineString by adding the starting point as the end point
+     */
+    public LineStringBuilder close() {
+        Coordinate start = points.get(0);
+        Coordinate end = points.get(points.size()-1);
+        if(start.x != end.x || start.y != end.y) {
+            points.add(start);
+        }
+        return this;
+    }
+
 }

+ 5 - 5
core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java

@@ -34,9 +34,9 @@ public class MultiLineStringBuilder extends ShapeBuilder {
 
     public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;
 
-    private final ArrayList<BaseLineStringBuilder<?>> lines = new ArrayList<>();
+    private final ArrayList<LineStringBuilder> lines = new ArrayList<>();
 
-    public MultiLineStringBuilder linestring(BaseLineStringBuilder<?> line) {
+    public MultiLineStringBuilder linestring(LineStringBuilder line) {
         this.lines.add(line);
         return this;
     }
@@ -60,7 +60,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
         builder.field(FIELD_TYPE, TYPE.shapename);
         builder.field(FIELD_COORDINATES);
         builder.startArray();
-        for(BaseLineStringBuilder<?> line : lines) {
+        for(BaseLineStringBuilder line : lines) {
             line.coordinatesToXcontent(builder, false);
         }
         builder.endArray();
@@ -73,7 +73,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
         final Geometry geometry;
         if(wrapdateline) {
             ArrayList<LineString> parts = new ArrayList<>();
-            for (BaseLineStringBuilder<?> line : lines) {
+            for (BaseLineStringBuilder line : lines) {
                 BaseLineStringBuilder.decompose(FACTORY, line.coordinates(false), parts);
             }
             if(parts.size() == 1) {
@@ -84,7 +84,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
             }
         } else {
             LineString[] lineStrings = new LineString[lines.size()];
-            Iterator<BaseLineStringBuilder<?>> iterator = lines.iterator();
+            Iterator<LineStringBuilder> iterator = lines.iterator();
             for (int i = 0; iterator.hasNext(); i++) {
                 lineStrings[i] = FACTORY.createLineString(iterator.next().coordinates(false));
             }

+ 9 - 9
core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java

@@ -29,7 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import com.vividsolutions.jts.geom.Coordinate;
 
 /**
- * The {@link PointCollection} is an abstract base implementation for all GeoShapes. It simply handles a set of points. 
+ * The {@link PointCollection} is an abstract base implementation for all GeoShapes. It simply handles a set of points.
  */
 public abstract class PointCollection<E extends PointCollection<E>> extends ShapeBuilder {
 
@@ -43,7 +43,7 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
     protected PointCollection(ArrayList<Coordinate> points) {
         this.points = points;
     }
-    
+
     @SuppressWarnings("unchecked")
     private E thisRef() {
         return (E)this;
@@ -57,7 +57,7 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
      */
     public E point(double longitude, double latitude) {
         return this.point(coordinate(longitude, latitude));
-    } 
+    }
 
     /**
      * Add a new point to the collection
@@ -71,7 +71,7 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
 
     /**
      * Add a array of points to the collection
-     * 
+     *
      * @param coordinates array of {@link Coordinate}s to add
      * @return this
      */
@@ -81,7 +81,7 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
 
     /**
      * Add a collection of points to the collection
-     * 
+     *
      * @param coordinates array of {@link Coordinate}s to add
      * @return this
      */
@@ -92,7 +92,7 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
 
     /**
      * Copy all points 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
      */
@@ -106,9 +106,9 @@ public abstract class PointCollection<E extends PointCollection<E>> extends Shap
 
     /**
      * builds an array of coordinates to a {@link XContentBuilder}
-     * 
-     * @param builder builder to use 
-     * @param closed repeat the first point at the end of the array if it's not already defines as last element of the array  
+     *
+     * @param builder builder to use
+     * @param closed repeat the first point at the end of the array if it's not already defines as last element of the array
      * @return the builder
      */
     protected XContentBuilder coordinatesToXcontent(XContentBuilder builder, boolean closed) throws IOException {

+ 1 - 1
core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java

@@ -35,7 +35,7 @@ public class PolygonBuilder extends BasePolygonBuilder<PolygonBuilder> {
 
     protected PolygonBuilder(ArrayList<Coordinate> points, Orientation orientation) {
         super(orientation);
-        this.shell = new Ring<>(this, points);
+        this.shell = new LineStringBuilder(points);
     }
 
     @Override

+ 1 - 1
core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java

@@ -444,7 +444,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
          *            number of points
          * @return Array of edges
          */
-        protected static Edge[] ring(int component, boolean direction, boolean handedness, BaseLineStringBuilder<?> shell,
+        protected static Edge[] ring(int component, boolean direction, boolean handedness, BaseLineStringBuilder shell,
                                      Coordinate[] points, int offset, Edge[] edges, int toffset, int length) {
             // calculate the direction of the points:
             // find the point a the top of the set and check its

+ 0 - 2
core/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeQuery.java

@@ -29,14 +29,12 @@ import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TwoPhaseIterator;
 import org.apache.lucene.search.Weight;
-import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.NumericUtils;
 import org.elasticsearch.common.geo.GeoDistance;
 import org.elasticsearch.common.geo.GeoPoint;
 import org.elasticsearch.common.unit.DistanceUnit;
 import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
 import org.elasticsearch.index.fielddata.MultiGeoPointValues;
-import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
 import org.elasticsearch.index.mapper.geo.GeoPointFieldMapperLegacy;
 
 import java.io.IOException;

+ 35 - 35
core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java

@@ -29,6 +29,7 @@ import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.LineString;
 import com.vividsolutions.jts.geom.Polygon;
 
+import org.elasticsearch.common.geo.builders.LineStringBuilder;
 import org.elasticsearch.common.geo.builders.PolygonBuilder;
 import org.elasticsearch.common.geo.builders.ShapeBuilder;
 import org.elasticsearch.common.geo.builders.ShapeBuilders;
@@ -141,35 +142,34 @@ public class ShapeBuilderTests extends ESTestCase {
 
     public void testMultiLineString() {
         ShapeBuilders.newMultiLinestring()
-            .linestring()
+            .linestring(new LineStringBuilder()
                 .point(-100.0, 50.0)
                 .point(50.0, 50.0)
                 .point(50.0, 20.0)
                 .point(-100.0, 20.0)
-            .end()
-            .linestring()
+            )
+            .linestring(new LineStringBuilder()
                 .point(-100.0, 20.0)
                 .point(50.0, 20.0)
                 .point(50.0, 0.0)
                 .point(-100.0, 0.0)
-            .end()
+            )
             .build();
 
-
         // LineString that needs to be wrappped
         ShapeBuilders.newMultiLinestring()
-            .linestring()
+            .linestring(new LineStringBuilder()
                 .point(150.0, 60.0)
                 .point(200.0, 60.0)
                 .point(200.0, 40.0)
                 .point(150.0,  40.0)
-                .end()
-            .linestring()
+                )
+            .linestring(new LineStringBuilder()
                 .point(150.0, 20.0)
                 .point(200.0, 20.0)
                 .point(200.0, 0.0)
                 .point(150.0, 0.0)
-                .end()
+                )
             .build();
     }
 
@@ -251,7 +251,7 @@ public class ShapeBuilderTests extends ESTestCase {
             .point(174,0);
 
         // 3/4 of an embedded 'c', crossing dateline once
-        builder.hole()
+        builder.hole(new LineStringBuilder()
             .point(175, 1)
             .point(175, 7)
             .point(-178, 7)
@@ -260,15 +260,15 @@ public class ShapeBuilderTests extends ESTestCase {
             .point(176, 2)
             .point(179, 2)
             .point(179,1)
-            .point(175, 1);
+            .point(175, 1));
 
         // embedded hole right of the dateline
-        builder.hole()
+        builder.hole(new LineStringBuilder()
             .point(-179, 1)
             .point(-179, 2)
             .point(-177, 2)
             .point(-177,1)
-            .point(-179,1);
+            .point(-179,1));
 
         Shape shape = builder.close().build();
         assertMultiPolygon(shape);
@@ -292,7 +292,7 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(-186,0);
 
         // 3/4 of an embedded 'c', crossing dateline once
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-185,1)
                 .point(-181,1)
                 .point(-181,2)
@@ -301,15 +301,15 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(-178,6)
                 .point(-178,7)
                 .point(-185,7)
-                .point(-185,1);
+                .point(-185,1));
 
         // embedded hole right of the dateline
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-179,1)
                 .point(-177,1)
                 .point(-177,2)
                 .point(-179,2)
-                .point(-179,1);
+                .point(-179,1));
 
         Shape shape = builder.close().build();
         assertMultiPolygon(shape);
@@ -356,7 +356,7 @@ public class ShapeBuilderTests extends ESTestCase {
             .point(-85.0016455,37.1310491)
             .point(-85.0018514,37.1311314);
 
-        builder.hole()
+        builder.hole(new LineStringBuilder()
             .point(-85.0000002,37.1317672)
             .point(-85.0001983,37.1317538)
             .point(-85.0003378,37.1317582)
@@ -382,7 +382,7 @@ public class ShapeBuilderTests extends ESTestCase {
             .point(-84.9993527,37.1317788)
             .point(-84.9994931,37.1318061)
             .point(-84.9996815,37.1317979)
-            .point(-85.0000002,37.1317672);
+            .point(-85.0000002,37.1317672));
 
         Shape shape = builder.close().build();
         assertPolygon(shape);
@@ -398,12 +398,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(-6, 0)
                 .point(-4, 2);
 
-        builder.hole()
+        builder.hole(new LineStringBuilder()
             .point(4, 1)
             .point(4, -1)
             .point(-4, -1)
             .point(-4, 1)
-            .point(4, 1);
+            .point(4, 1));
 
         Shape shape = builder.close().build();
         assertPolygon(shape);
@@ -451,12 +451,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(176, -15)
                 .point(-177, -10)
                 .point(-177, 10);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(176, 10)
                 .point(180, 5)
                 .point(180, -5)
                 .point(176, -10)
-                .point(176, 10);
+                .point(176, 10));
         Shape shape = builder.close().build();
         assertMultiPolygon(shape);
 
@@ -467,12 +467,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(179, -10)
                 .point(-176, -15)
                 .point(-172, 0);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-176, 10)
                 .point(-176, -10)
                 .point(-180, -5)
                 .point(-180, 5)
-                .point(-176, 10);
+                .point(-176, 10));
         shape = builder.close().build();
         assertMultiPolygon(shape);
     }
@@ -486,12 +486,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(166, -15)
                 .point(179, -10)
                 .point(179, 10);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-177, 10)
                 .point(-178, -10)
                 .point(-180, -5)
                 .point(-180, 5)
-                .point(-177, 10);
+                .point(-177, 10));
         Shape shape = builder.close().build();
         assertMultiPolygon(shape);
     }
@@ -505,12 +505,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(166, -15)
                 .point(179, -10)
                 .point(179, 10);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(164, 0)
                 .point(175, 10)
                 .point(175, 5)
                 .point(179, -10)
-                .point(164, 0);
+                .point(164, 0));
         try {
             builder.close().build();
             fail("Expected InvalidShapeException");
@@ -528,17 +528,17 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(176, -15)
                 .point(-177, -10)
                 .point(-177, 10);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-177, 10)
                 .point(-178, -10)
                 .point(-180, -5)
                 .point(-180, 5)
-                .point(-177, 10);
-        builder.hole()
+                .point(-177, 10));
+        builder.hole(new LineStringBuilder()
                 .point(172, 0)
                 .point(176, 10)
                 .point(176, -5)
-                .point(172, 0);
+                .point(172, 0));
         Shape shape = builder.close().build();
         assertMultiPolygon(shape);
     }
@@ -552,12 +552,12 @@ public class ShapeBuilderTests extends ESTestCase {
                 .point(176, -15)
                 .point(-177, -10)
                 .point(-177, 10);
-        builder.hole()
+        builder.hole(new LineStringBuilder()
                 .point(-177, 10)
                 .point(172, 0)
                 .point(180, -5)
                 .point(176, -10)
-                .point(-177, 10);
+                .point(-177, 10));
         try {
             builder.close().build();
             fail("Expected InvalidShapeException");

+ 22 - 26
core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java

@@ -41,7 +41,7 @@ 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.GeoUtils;
+import org.elasticsearch.common.geo.builders.LineStringBuilder;
 import org.elasticsearch.common.geo.builders.MultiPolygonBuilder;
 import org.elasticsearch.common.geo.builders.PolygonBuilder;
 import org.elasticsearch.common.geo.builders.ShapeBuilders;
@@ -129,17 +129,17 @@ public class GeoFilterIT extends ESIntegTestCase {
         // polygon with hole
         ShapeBuilders.newPolygon()
                 .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
-                .hole()
+                .hole(new LineStringBuilder()
                 .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
-                .close().close().build();
+                .close()).close().build();
 
         try {
             // polygon with overlapping hole
             ShapeBuilders.newPolygon()
                     .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
-                    .hole()
+                    .hole(new LineStringBuilder()
                     .point(-5, -5).point(-5, 11).point(5, 11).point(5, -5)
-                    .close().close().build();
+                    .close()).close().build();
 
             fail("Self intersection not detected");
         } catch (InvalidShapeException e) {
@@ -149,12 +149,12 @@ public class GeoFilterIT extends ESIntegTestCase {
             // polygon with intersection holes
             ShapeBuilders.newPolygon()
                     .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
-                    .hole()
+                    .hole(new LineStringBuilder()
                     .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
-                    .close()
-                    .hole()
+                    .close())
+                    .hole(new LineStringBuilder()
                     .point(-5, -6).point(5, -6).point(5, -4).point(-5, -4)
-                    .close()
+                    .close())
                     .close().build();
             fail("Intersection of holes not detected");
         } catch (InvalidShapeException e) {
@@ -176,18 +176,18 @@ public class GeoFilterIT extends ESIntegTestCase {
         }
 
         // Multipolygon: polygon with hole and polygon within the whole
-        ShapeBuilder
+        ShapeBuilders
                 .newMultiPolygon()
                 .polygon(new PolygonBuilder()
                         .point(-10, -10)
                         .point(-10, 10)
                         .point(10, 10)
                         .point(10, -10)
-                        .hole().point(-5, -5)
+                        .hole(new LineStringBuilder().point(-5, -5)
                                .point(-5, 5)
                                .point(5, 5)
                                .point(5, -5)
-                               .close()
+                               .close())
                         .close())
                 .polygon(new PolygonBuilder()
                         .point(-4, -4)
@@ -222,16 +222,14 @@ public class GeoFilterIT extends ESIntegTestCase {
         // Create a multipolygon with two polygons. The first is an rectangle of size 10x10
         // with a hole of size 5x5 equidistant from all sides. This hole in turn contains
         // the second polygon of size 4x4 equidistant from all sites
-        MultiPolygonBuilder polygon = ShapeBuilder.newMultiPolygon()
+        MultiPolygonBuilder polygon = ShapeBuilders.newMultiPolygon()
                 .polygon(new PolygonBuilder()
-                .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
-                .hole()
-                .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
-                .close()
+                    .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
+                    .hole(new LineStringBuilder()
+                        .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close())
                 .close())
                 .polygon(new PolygonBuilder()
-                .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4)
-                .close());
+                    .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close());
 
         BytesReference data = jsonBuilder().startObject().field("area", polygon).endObject().bytes();
 
@@ -293,9 +291,8 @@ public class GeoFilterIT extends ESIntegTestCase {
         // Create a polygon that fills the empty area of the polygon defined above
         PolygonBuilder inverse = ShapeBuilders.newPolygon()
                 .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
-                .hole()
-                .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4)
-                .close()
+                .hole(new LineStringBuilder()
+                    .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close())
                 .close();
 
         data = jsonBuilder().startObject().field("area", inverse).endObject().bytes();
@@ -313,9 +310,8 @@ public class GeoFilterIT extends ESIntegTestCase {
         // Create Polygon with hole and common edge
         PolygonBuilder builder = ShapeBuilders.newPolygon()
                 .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
-                .hole()
-                .point(-5, -5).point(-5, 5).point(10, 5).point(10, -5)
-                .close()
+                .hole(new LineStringBuilder()
+                    .point(-5, -5).point(-5, 5).point(10, 5).point(10, -5).close())
                 .close();
 
         if (withinSupport) {
@@ -342,7 +338,7 @@ public class GeoFilterIT extends ESIntegTestCase {
         // Create a polygon crossing longitude 180 with hole.
         builder = ShapeBuilders.newPolygon()
                 .point(170, -10).point(190, -10).point(190, 10).point(170, 10)
-                .hole().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close()
+                    .hole(new LineStringBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close())
                 .close();
 
         data = jsonBuilder().startObject().field("area", builder).endObject().bytes();

+ 2 - 1
core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java

@@ -25,6 +25,7 @@ import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.geo.ShapeRelation;
 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.ShapeBuilder;
 import org.elasticsearch.common.geo.builders.ShapeBuilders;
 import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -193,7 +194,7 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
     public void testReusableBuilder() throws IOException {
         ShapeBuilder polygon = ShapeBuilders.newPolygon()
                 .point(170, -10).point(190, -10).point(190, 10).point(170, 10)
-                .hole().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close()
+                .hole(new LineStringBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close())
                 .close();
         assertUnmodified(polygon);
 

+ 1 - 2
core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java

@@ -31,7 +31,6 @@ import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Geometry;
 
 import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.geo.builders.BaseLineStringBuilder;
 import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder;
 import org.elasticsearch.common.geo.builders.LineStringBuilder;
 import org.elasticsearch.common.geo.builders.MultiLineStringBuilder;
@@ -198,7 +197,7 @@ public class RandomShapeGenerator extends RandomGeoGenerator {
             case MULTILINESTRING:
                 MultiLineStringBuilder mlsb = new MultiLineStringBuilder();
                 for (int i=0; i<RandomInts.randomIntBetween(r, 1, 10); ++i) {
-                    mlsb.linestring((BaseLineStringBuilder) createShape(r, nearPoint, within, ShapeType.LINESTRING, false));
+                    mlsb.linestring((LineStringBuilder) createShape(r, nearPoint, within, ShapeType.LINESTRING, false));
                 }
                 return mlsb;
             case POLYGON: