Browse Source

remove dependency on legacy geo code from test (#74609)

ShapeBuilders are moved to use Geometry classes.
Ignacio Vera 4 years ago
parent
commit
21794f82e0

+ 4 - 3
server/src/test/java/org/elasticsearch/index/fielddata/AbstractGeoFieldDataTestCase.java

@@ -13,10 +13,11 @@ import org.apache.lucene.document.LatLonDocValuesField;
 import org.apache.lucene.document.StringField;
 import org.elasticsearch.common.geo.GeoPoint;
 import org.elasticsearch.common.geo.GeoUtils;
+import org.elasticsearch.geo.GeometryTestUtils;
+import org.elasticsearch.geometry.Point;
 
 import java.io.IOException;
 
-import static org.elasticsearch.test.geo.RandomShapeGenerator.randomPoint;
 import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.lessThanOrEqualTo;
@@ -26,8 +27,8 @@ public abstract class AbstractGeoFieldDataTestCase extends AbstractFieldDataImpl
     protected abstract String getFieldDataType();
 
     protected Field randomGeoPointField(String fieldName, Field.Store store) {
-        GeoPoint point = randomPoint(random());
-        return new LatLonDocValuesField(fieldName, point.lat(), point.lon());
+        Point point = GeometryTestUtils.randomPoint();
+        return new LatLonDocValuesField(fieldName, point.getLat(), point.getLon());
     }
 
     @Override

+ 9 - 8
server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java

@@ -16,13 +16,13 @@ import org.apache.lucene.search.Query;
 import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.common.geo.GeoPoint;
 import org.elasticsearch.common.geo.GeoUtils;
+import org.elasticsearch.geo.GeometryTestUtils;
+import org.elasticsearch.geometry.Rectangle;
+import org.elasticsearch.geometry.utils.Geohash;
 import org.elasticsearch.index.mapper.GeoPointFieldMapper;
 import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.test.AbstractQueryTestCase;
-import org.elasticsearch.test.geo.RandomShapeGenerator;
-import org.locationtech.spatial4j.io.GeohashUtils;
-import org.locationtech.spatial4j.shape.Rectangle;
 
 import java.io.IOException;
 
@@ -38,7 +38,8 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
     protected GeoBoundingBoxQueryBuilder doCreateTestQueryBuilder() {
         String fieldName = randomFrom(GEO_POINT_FIELD_NAME, GEO_POINT_ALIAS_FIELD_NAME, GEO_SHAPE_FIELD_NAME);
         GeoBoundingBoxQueryBuilder builder = new GeoBoundingBoxQueryBuilder(fieldName);
-        Rectangle box = RandomShapeGenerator.xRandomRectangle(random(), RandomShapeGenerator.xRandomPoint(random()));
+        // make sure that minX != maxX after geohash encoding
+        Rectangle box = randomValueOtherThanMany((r) -> Math.abs(r.getMaxX() - r.getMinX()) < 0.1, GeometryTestUtils::randomRectangle);
 
         if (randomBoolean()) {
             // check the top-left/bottom-right combination of setters
@@ -51,8 +52,8 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
                 break;
             case 1:
                 builder.setCorners(
-                        GeohashUtils.encodeLatLon(box.getMaxY(), box.getMinX()),
-                        GeohashUtils.encodeLatLon(box.getMinY(), box.getMaxX()));
+                        Geohash.stringEncode(box.getMinX(), box.getMaxY()),
+                        Geohash.stringEncode(box.getMaxX(), box.getMinY()));
                 break;
             default:
                 builder.setCorners(box.getMaxY(), box.getMinX(), box.getMinY(), box.getMaxX());
@@ -65,8 +66,8 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
                         new GeoPoint(box.getMaxY(), box.getMaxX()));
             } else {
                 builder.setCornersOGC(
-                        GeohashUtils.encodeLatLon(box.getMinY(), box.getMinX()),
-                        GeohashUtils.encodeLatLon(box.getMaxY(), box.getMaxX()));
+                        Geohash.stringEncode(box.getMinX(), box.getMinY()),
+                        Geohash.stringEncode(box.getMaxX(), box.getMaxY()));
             }
         }
 

+ 2 - 4
server/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java

@@ -17,12 +17,11 @@ import org.elasticsearch.common.ParsingException;
 import org.elasticsearch.common.geo.GeoDistance;
 import org.elasticsearch.common.geo.GeoPoint;
 import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.geo.GeometryTestUtils;
 import org.elasticsearch.index.mapper.GeoPointFieldMapper;
 import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.test.AbstractQueryTestCase;
-import org.elasticsearch.test.geo.RandomShapeGenerator;
-import org.locationtech.spatial4j.shape.Point;
 
 import java.io.IOException;
 
@@ -54,8 +53,7 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase<GeoDista
                 break;
         }
 
-        Point p = RandomShapeGenerator.xRandomPoint(random());
-        qb.point(new GeoPoint(p.getY(), p.getX()));
+        qb.point(new GeoPoint(GeometryTestUtils.randomLat(), GeometryTestUtils.randomLon()));
 
         if (randomBoolean()) {
             qb.setValidationMethod(randomFrom(GeoValidationMethod.values()));

+ 6 - 17
server/src/test/java/org/elasticsearch/index/query/GeoPolygonQueryBuilderTests.java

@@ -15,13 +15,10 @@ import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
 import org.elasticsearch.common.ParsingException;
 import org.elasticsearch.common.geo.GeoPoint;
-import org.elasticsearch.common.geo.builders.ShapeBuilder;
+import org.elasticsearch.geo.GeometryTestUtils;
+import org.elasticsearch.geometry.LinearRing;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.test.AbstractQueryTestCase;
-import org.elasticsearch.test.geo.RandomShapeGenerator;
-import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.spatial4j.shape.jts.JtsGeometry;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -102,18 +99,10 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase<GeoPolygo
     }
 
     private static List<GeoPoint> randomPolygon() {
-        ShapeBuilder<?, ?, ?> shapeBuilder = null;
-        // This is a temporary fix because sometimes the RandomShapeGenerator
-        // returns null. This is if there is an error generating the polygon. So
-        // in this case keep trying until we successfully generate one
-        while (shapeBuilder == null) {
-            shapeBuilder = RandomShapeGenerator.createShapeWithin(random(), null, ShapeType.POLYGON);
-        }
-        JtsGeometry shape = (JtsGeometry) shapeBuilder.buildS4J();
-        Coordinate[] coordinates = shape.getGeom().getCoordinates();
-        ArrayList<GeoPoint> polygonPoints = new ArrayList<>();
-        for (Coordinate coord : coordinates) {
-            polygonPoints.add(new GeoPoint(coord.y, coord.x));
+        LinearRing linearRing = GeometryTestUtils.randomPolygon(false).getPolygon();
+        List<GeoPoint> polygonPoints = new ArrayList<>(linearRing.length());
+        for (int i = 0; i < linearRing.length(); i++) {
+            polygonPoints.add(new GeoPoint(linearRing.getLat(i), linearRing.getLon(i)));
         }
         return polygonPoints;
     }

+ 5 - 3
server/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceRangeTests.java

@@ -14,10 +14,11 @@ import org.elasticsearch.common.unit.DistanceUnit;
 import org.elasticsearch.common.xcontent.XContentParseException;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.json.JsonXContent;
+import org.elasticsearch.geo.GeometryTestUtils;
+import org.elasticsearch.geometry.Point;
 import org.elasticsearch.search.aggregations.BaseAggregationTestCase;
 import org.elasticsearch.search.aggregations.bucket.range.GeoDistanceAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.range.GeoDistanceAggregationBuilder.Range;
-import org.elasticsearch.test.geo.RandomShapeGenerator;
 
 import java.io.IOException;
 
@@ -29,8 +30,9 @@ public class GeoDistanceRangeTests extends BaseAggregationTestCase<GeoDistanceAg
     @Override
     protected GeoDistanceAggregationBuilder createTestAggregatorBuilder() {
         int numRanges = randomIntBetween(1, 10);
-        GeoPoint origin = RandomShapeGenerator.randomPoint(random());
-        GeoDistanceAggregationBuilder factory = new GeoDistanceAggregationBuilder(randomAlphaOfLengthBetween(3, 10), origin);
+        Point origin = GeometryTestUtils.randomPoint();
+        GeoDistanceAggregationBuilder factory =
+            new GeoDistanceAggregationBuilder(randomAlphaOfLengthBetween(3, 10), new GeoPoint(origin.getLat(), origin.getLon()));
         for (int i = 0; i < numRanges; i++) {
             String key = null;
             if (randomBoolean()) {

+ 67 - 94
server/src/test/java/org/elasticsearch/search/geo/GeoQueryTests.java

@@ -14,38 +14,31 @@ import org.elasticsearch.action.search.SearchPhaseExecutionException;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.geo.GeoShapeType;
 import org.elasticsearch.common.geo.ShapeRelation;
-import org.elasticsearch.common.geo.builders.CircleBuilder;
-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.MultiLineStringBuilder;
-import org.elasticsearch.common.geo.builders.MultiPointBuilder;
-import org.elasticsearch.common.geo.builders.MultiPolygonBuilder;
-import org.elasticsearch.common.geo.builders.PointBuilder;
-import org.elasticsearch.common.geo.builders.PolygonBuilder;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.geometry.Circle;
 import org.elasticsearch.geometry.Geometry;
 import org.elasticsearch.geometry.Line;
 import org.elasticsearch.geometry.LinearRing;
 import org.elasticsearch.geometry.MultiLine;
 import org.elasticsearch.geometry.MultiPoint;
+import org.elasticsearch.geometry.MultiPolygon;
 import org.elasticsearch.geometry.Point;
+import org.elasticsearch.geometry.Polygon;
 import org.elasticsearch.geometry.Rectangle;
+import org.elasticsearch.geometry.ShapeType;
 import org.elasticsearch.index.query.GeoShapeQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.search.SearchHits;
 import org.elasticsearch.test.ESSingleNodeTestCase;
 import org.elasticsearch.test.TestGeoShapeFieldMapperPlugin;
-import org.locationtech.jts.geom.Coordinate;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@@ -96,9 +89,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
               .field(defaultGeoFieldName, "POINT(-45 -50)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        EnvelopeBuilder shape = new EnvelopeBuilder(new Coordinate(-45, 45), new Coordinate(45, -45));
-        GeometryCollectionBuilder builder = new GeometryCollectionBuilder().shape(shape);
-        Geometry geometry = builder.buildGeometry().get(0);
+        Geometry geometry = new Rectangle(-45, 45, 45, -45);
         SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
             .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
                 .relation(ShapeRelation.INTERSECTS))
@@ -137,9 +128,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(-45 -50)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        CircleBuilder shape = new CircleBuilder().center(new Coordinate(-30, -30)).radius("100m");
-        GeometryCollectionBuilder builder = new GeometryCollectionBuilder().shape(shape);
-        Geometry geometry = builder.buildGeometry().get(0);
+        Geometry geometry = new Circle(-30, -30, 100);
 
         try {
             client().prepareSearch(defaultIndexName)
@@ -150,7 +139,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             Exception e) {
             assertThat(e.getCause().getMessage(),
                 containsString("failed to create query: "
-                    + GeoShapeType.CIRCLE + " geometry is not supported"));
+                    + ShapeType.CIRCLE + " geometry is not supported"));
         }
     }
 
@@ -169,17 +158,15 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(-45 -50)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        CoordinatesBuilder cb = new CoordinatesBuilder();
-        cb.coordinate(new Coordinate(-35, -35))
-            .coordinate(new Coordinate(-35, -25))
-            .coordinate(new Coordinate(-25, -25))
-            .coordinate(new Coordinate(-25, -35))
-            .coordinate(new Coordinate(-35, -35));
-        PolygonBuilder shape = new PolygonBuilder(cb);
-        GeometryCollectionBuilder builder = new GeometryCollectionBuilder().shape(shape);
-        Geometry geometry = builder.buildGeometry();
+        Polygon polygon = new Polygon(
+            new LinearRing(
+                new double[] {-35, -35, -25, -25, -35},
+                new double[] {-35, -25, -25, -35, -35}
+            )
+        );
+
         SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
-            .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
+            .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, polygon)
                 .relation(ShapeRelation.INTERSECTS))
             .get();
 
@@ -212,30 +199,24 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(-50 -50)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        CoordinatesBuilder encloseDocument1Cb = new CoordinatesBuilder();
-        encloseDocument1Cb.coordinate(new Coordinate(-35, -35))
-            .coordinate(new Coordinate(-35, -25))
-            .coordinate(new Coordinate(-25, -25))
-            .coordinate(new Coordinate(-25, -35))
-            .coordinate(new Coordinate(-35, -35));
-        PolygonBuilder encloseDocument1Shape = new PolygonBuilder(encloseDocument1Cb);
-
-        CoordinatesBuilder encloseDocument2Cb = new CoordinatesBuilder();
-        encloseDocument2Cb.coordinate(new Coordinate(-55, -55))
-            .coordinate(new Coordinate(-55, -45))
-            .coordinate(new Coordinate(-45, -45))
-            .coordinate(new Coordinate(-45, -55))
-            .coordinate(new Coordinate(-55, -55));
-        PolygonBuilder encloseDocument2Shape = new PolygonBuilder(encloseDocument2Cb);
-
-        MultiPolygonBuilder mp = new MultiPolygonBuilder();
-        mp.polygon(encloseDocument1Shape).polygon(encloseDocument2Shape);
-
-        GeometryCollectionBuilder builder = new GeometryCollectionBuilder().shape(mp);
-        Geometry geometry = builder.buildGeometry();
+        Polygon encloseDocument1Cb = new Polygon(
+            new LinearRing(
+                new double[] {-35, -35, -25, -25, -35},
+                new double[] {-35, -25, -25, -35, -35}
+            )
+        );
+
+        Polygon encloseDocument2Cb = new Polygon(
+            new LinearRing(
+                new double[] {-55, -55, -45, -45, -55},
+                new double[] {-55, -45, -45, -55, -55}
+            )
+        );
+
+        MultiPolygon multiPolygon = new MultiPolygon(List.of(encloseDocument1Cb, encloseDocument2Cb));
         {
             SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
-                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
+                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, multiPolygon)
                     .relation(ShapeRelation.INTERSECTS))
                 .get();
 
@@ -247,7 +228,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
         }
         {
             SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
-                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
+                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, multiPolygon)
                     .relation(ShapeRelation.WITHIN))
                 .get();
 
@@ -259,7 +240,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
         }
         {
             SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
-                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
+                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, multiPolygon)
                     .relation(ShapeRelation.DISJOINT))
                 .get();
 
@@ -270,7 +251,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
         }
         {
             SearchResponse searchResponse = client().prepareSearch(defaultIndexName)
-                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, geometry)
+                .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, multiPolygon)
                     .relation(ShapeRelation.CONTAINS))
                 .get();
 
@@ -388,8 +369,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(171 0)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        Rectangle rectangle = new Rectangle(
-            169, -178, 1, -1);
+        Rectangle rectangle = new Rectangle(169, -178, 1, -1);
 
         GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", rectangle);
         SearchResponse response = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
@@ -424,14 +404,14 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(171 7)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        PolygonBuilder polygon = new PolygonBuilder(new CoordinatesBuilder()
-                    .coordinate(-177, 10)
-                    .coordinate(177, 10)
-                    .coordinate(177, 5)
-                    .coordinate(-177, 5)
-                    .coordinate(-177, 10));
+        Polygon polygon = new Polygon(
+            new LinearRing(
+                new double[] {-177, 177, 177, -177, -177},
+                new double[] {10, 10, 5, 5, 10}
+            )
+        );
 
-        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", polygon.buildGeometry());
+        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", polygon);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
         SearchResponse response = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
         SearchHits searchHits = response.getHits();
@@ -462,23 +442,24 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(171 7)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        MultiPolygonBuilder multiPolygon = new MultiPolygonBuilder()
-            .polygon(new PolygonBuilder(new CoordinatesBuilder()
-                .coordinate(-167, 10)
-                .coordinate(-171, 10)
-                .coordinate(171, 5)
-                .coordinate(-167, 5)
-                .coordinate(-167, 10)))
-            .polygon(new PolygonBuilder(new CoordinatesBuilder()
-                .coordinate(-177, 10)
-                .coordinate(177, 10)
-                .coordinate(177, 5)
-                .coordinate(-177, 5)
-                .coordinate(-177, 10)));
-
-        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery(
-            "geo",
-            multiPolygon.buildGeometry());
+
+        Polygon polygon1 = new Polygon(
+            new LinearRing(
+                new double[] {-167, -171, 171, -167, -167},
+                new double[] {10, 10, 5, 5, 10}
+            )
+        );
+
+        Polygon polygon2 = new Polygon(
+            new LinearRing(
+                new double[] {-177, 177, 177, -177, -177},
+                new double[] {10, 10, 5, 5, 10}
+            )
+        );
+
+        MultiPolygon multiPolygon = new MultiPolygon(List.of(polygon1, polygon2));
+
+        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", multiPolygon);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
         SearchResponse response = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
         SearchHits searchHits = response.getHits();
@@ -509,16 +490,10 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
         client().admin().indices().prepareCreate("test").setMapping(mapping).get();
         ensureGreen();
 
-        CoordinatesBuilder coords1 = new CoordinatesBuilder()
-            .coordinate(-35,-35)
-            .coordinate(-25,-25);
-        CoordinatesBuilder coords2 = new CoordinatesBuilder()
-            .coordinate(-15,-15)
-            .coordinate(-5,-5);
-        LineStringBuilder lsb1 = new LineStringBuilder(coords1);
-        LineStringBuilder lsb2 = new LineStringBuilder(coords2);
-        MultiLineStringBuilder mlb = new MultiLineStringBuilder().linestring(lsb1).linestring(lsb2);
-        MultiLine multiline = (MultiLine) mlb.buildGeometry();
+        Line lsb1 = new Line(new double[]{-35, -25}, new double[] {-35, -25});
+        Line lsb2 = new Line(new double[]{-15, -5}, new double[] {-15, -5});
+
+        MultiLine multiline = new MultiLine(List.of(lsb1, lsb2));
 
         GeoShapeQueryBuilder builder = QueryBuilders.geoShapeQuery(defaultGeoFieldName, multiline).relation(ShapeRelation.WITHIN);
         SearchRequestBuilder searchRequestBuilder = client().prepareSearch("test").setQuery(builder);
@@ -554,8 +529,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(-35 -25)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        PointBuilder pb = new PointBuilder().coordinate(-35, -25);
-        Point point = pb.buildGeometry();
+        Point point = new Point(-35, -25);
         {
             SearchResponse response = client().prepareSearch("test")
                 .setQuery(QueryBuilders.geoShapeQuery(defaultGeoFieldName, point)).get();
@@ -592,8 +566,7 @@ public abstract class GeoQueryTests extends ESSingleNodeTestCase {
             .field(defaultGeoFieldName, "POINT(-35 -25)")
             .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        MultiPointBuilder mpb = new MultiPointBuilder().coordinate(-35,-25).coordinate(-15,-5);
-        MultiPoint multiPoint = mpb.buildGeometry();
+        MultiPoint multiPoint = new MultiPoint(List.of(new Point(-35,-25), new Point(-15,-5)));
 
         {
             SearchResponse response = client().prepareSearch("test")

+ 169 - 210
server/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java

@@ -8,40 +8,40 @@
 
 package org.elasticsearch.search.geo;
 
-import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
 import org.apache.lucene.geo.GeoTestUtil;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.index.IndexRequest;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.CheckedSupplier;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.geo.GeoJson;
 import org.elasticsearch.common.geo.ShapeRelation;
-import org.elasticsearch.common.geo.builders.CircleBuilder;
-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.MultiPointBuilder;
-import org.elasticsearch.common.geo.builders.PointBuilder;
-import org.elasticsearch.common.geo.builders.PolygonBuilder;
-import org.elasticsearch.common.geo.builders.ShapeBuilder;
 import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.geo.GeometryTestUtils;
+import org.elasticsearch.geometry.Circle;
+import org.elasticsearch.geometry.Geometry;
+import org.elasticsearch.geometry.GeometryCollection;
+import org.elasticsearch.geometry.LinearRing;
+import org.elasticsearch.geometry.MultiPoint;
+import org.elasticsearch.geometry.Point;
+import org.elasticsearch.geometry.Polygon;
+import org.elasticsearch.geometry.Rectangle;
+import org.elasticsearch.geometry.utils.WellKnownText;
 import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
 import org.elasticsearch.index.mapper.MapperParsingException;
 import org.elasticsearch.index.query.ExistsQueryBuilder;
 import org.elasticsearch.index.query.GeoShapeQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.test.VersionUtils;
-import org.elasticsearch.test.geo.RandomShapeGenerator;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.spatial4j.shape.Rectangle;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
@@ -49,14 +49,10 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 import static org.elasticsearch.index.query.QueryBuilders.geoIntersectionQuery;
 import static org.elasticsearch.index.query.QueryBuilders.geoShapeQuery;
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.elasticsearch.test.geo.RandomShapeGenerator.createGeometryCollectionWithin;
-import static org.elasticsearch.test.geo.RandomShapeGenerator.xRandomPoint;
-import static org.elasticsearch.test.geo.RandomShapeGenerator.xRandomRectangle;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.greaterThan;
 
 public class GeoShapeQueryTests extends GeoQueryTests {
     protected static final String[] PREFIX_TREES = new String[] {
@@ -195,28 +191,36 @@ public class GeoShapeQueryTests extends GeoQueryTests {
 
     public void testRandomGeoCollectionQuery() throws Exception {
         // Create a random geometry collection to index.
-        GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(random());;
+        GeometryCollection<Geometry> randomIndexCollection = GeometryTestUtils.randomGeometryCollectionWithoutCircle(false);
         org.apache.lucene.geo.Polygon randomPoly = GeoTestUtil.nextPolygon();
 
         assumeTrue("Skipping the check for the polygon with a degenerated dimension",
             randomPoly.maxLat - randomPoly.minLat > 8.4e-8 &&  randomPoly.maxLon - randomPoly.minLon > 8.4e-8);
 
-        CoordinatesBuilder cb = new CoordinatesBuilder();
-        for (int i = 0; i < randomPoly.numPoints(); ++i) {
-            cb.coordinate(randomPoly.getPolyLon(i), randomPoly.getPolyLat(i));
+        Polygon polygon = new Polygon(new LinearRing(randomPoly.getPolyLons(), randomPoly.getPolyLats()));
+        List<Geometry> indexGeometries = new ArrayList<>();
+        for (Geometry geometry : randomIndexCollection) {
+            indexGeometries.add(geometry);
         }
-        gcb.shape(new PolygonBuilder(cb));
+        indexGeometries.add(polygon);
+        GeometryCollection<Geometry> gcb = new GeometryCollection<>(indexGeometries);
 
-        logger.info("Created Random GeometryCollection containing {} shapes", gcb.numShapes());
+        logger.info("Created Random GeometryCollection containing {} shapes", gcb.size());
 
         createRandomMapping("test", Settings.builder().put("index.number_of_shards", 1).build());
 
-        XContentBuilder docSource = gcb.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(gcb, jsonBuilder().startObject().field("geo"), null).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
         // Create a random geometry collection to query
-        GeometryCollectionBuilder queryCollection = RandomShapeGenerator.createGeometryCollection(random());
-        queryCollection.shape(new PolygonBuilder(cb));
+        GeometryCollection<Geometry> randomQueryCollection = GeometryTestUtils.randomGeometryCollection(false);
+
+        List<Geometry> queryGeometries = new ArrayList<>();
+        for (Geometry geometry : randomQueryCollection) {
+            queryGeometries.add(geometry);
+        }
+        queryGeometries.add(polygon);
+        GeometryCollection<Geometry> queryCollection = new GeometryCollection<>(queryGeometries);
 
         GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", queryCollection);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
@@ -247,7 +251,7 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         @SuppressWarnings("unchecked") CheckedSupplier<GeoShapeQueryBuilder, IOException> querySupplier = randomFrom(
             () -> QueryBuilders.geoShapeQuery(
                 "geo",
-                new EnvelopeBuilder(new Coordinate(-21, 44), new Coordinate(-39, 9))
+                new Rectangle(-21, -39, 44, 9)
             ).relation(ShapeRelation.WITHIN),
             () -> {
                 XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
@@ -295,63 +299,66 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         client().admin().indices().prepareCreate("test").setMapping(mapping).setSettings(settings).get();
         ensureGreen();
 
-        EnvelopeBuilder envelopeBuilder = new EnvelopeBuilder(new Coordinate(-10, 10), new Coordinate(10, -10));
+        Rectangle envelope = new Rectangle(-10, 10, 10, -10);
 
         client().index(new IndexRequest("test")
-            .source(jsonBuilder().startObject().field("geo", envelopeBuilder).endObject())
+            .source(jsonBuilder().startObject().field("geo", WellKnownText.toWKT(envelope)).endObject())
             .setRefreshPolicy(IMMEDIATE)).actionGet();
 
         {
             // A geometry collection that is fully within the indexed shape
-            GeometryCollectionBuilder builder = new GeometryCollectionBuilder();
-            builder.shape(new PointBuilder(1, 2));
-            builder.shape(new PointBuilder(-2, -1));
+            List<Geometry> geometries = new ArrayList<>();
+            geometries.add(new Point(1, 2));
+            geometries.add(new Point(-2, -1));
+            GeometryCollection<Geometry> collection = new GeometryCollection<>(geometries);
             SearchResponse response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.CONTAINS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.CONTAINS))
                 .get();
             assertEquals(1, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.INTERSECTS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.INTERSECTS))
                 .get();
             assertEquals(1, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.DISJOINT))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.DISJOINT))
                 .get();
             assertEquals(0, response.getHits().getTotalHits().value);
         }
-        // A geometry collection that is partially within the indexed shape
         {
-            GeometryCollectionBuilder builder = new GeometryCollectionBuilder();
-            builder.shape(new PointBuilder(1, 2));
-            builder.shape(new PointBuilder(20, 30));
+            // A geometry collection that is partially within the indexed shape
+            List<Geometry> geometries = new ArrayList<>();
+            geometries.add(new Point(1, 2));
+            geometries.add(new Point(20, 30));
+            GeometryCollection<Geometry> collection = new GeometryCollection<>(geometries);
             SearchResponse response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.CONTAINS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.CONTAINS))
                 .get();
             assertEquals(0, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.INTERSECTS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.INTERSECTS))
                 .get();
             assertEquals(1, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.DISJOINT))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.DISJOINT))
                 .get();
             assertEquals(0, response.getHits().getTotalHits().value);
         }
         {
             // A geometry collection that is disjoint with the indexed shape
-            GeometryCollectionBuilder builder = new GeometryCollectionBuilder();
-            builder.shape(new PointBuilder(-20, -30));
-            builder.shape(new PointBuilder(20, 30));
+            List<Geometry> geometries = new ArrayList<>();
+            geometries.add(new Point(-20, -30));
+            geometries.add(new Point(20, 30));
+            GeometryCollection<Geometry> collection = new GeometryCollection<>(geometries);
             SearchResponse response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.CONTAINS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.CONTAINS))
                 .get();
             assertEquals(0, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.INTERSECTS))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.INTERSECTS))
                 .get();
             assertEquals(0, response.getHits().getTotalHits().value);
             response = client().prepareSearch("test")
-                .setQuery(geoShapeQuery("geo", builder.buildGeometry()).relation(ShapeRelation.DISJOINT))
+                .setQuery(geoShapeQuery("geo", collection).relation(ShapeRelation.DISJOINT))
                 .get();
             assertEquals(1, response.getHits().getTotalHits().value);
         }
@@ -379,7 +386,7 @@ public class GeoShapeQueryTests extends GeoQueryTests {
                 .endObject()
                 .endObject()).setRefreshPolicy(IMMEDIATE).get();
 
-        EnvelopeBuilder query = new EnvelopeBuilder(new Coordinate(-122.88, 48.62), new Coordinate(-122.82, 48.54));
+        Rectangle query = new Rectangle(-122.88, -122.82, 48.62, 48.54);
 
         // This search would fail if both geoshape indexing and geoshape filtering
         // used the bottom-level optimization in SpatialPrefixTree#recursiveGetNodes.
@@ -398,50 +405,35 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         createIndex("shapes", Settings.EMPTY, "shape_type", "_source", "enabled=false");
         ensureGreen();
 
-        EnvelopeBuilder shape = new EnvelopeBuilder(new Coordinate(-45, 45), new Coordinate(45, -45));
+        Rectangle shape = new Rectangle(-45, 45, 45, -45);
 
         client().prepareIndex("shapes").setId("Big_Rectangle").setSource(jsonBuilder().startObject()
-            .field("shape", shape).endObject()).setRefreshPolicy(IMMEDIATE).get();
+            .field("shape", WellKnownText.toWKT(shape)).endObject()).setRefreshPolicy(IMMEDIATE).get();
 
         IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> client().prepareSearch("test")
             .setQuery(geoIntersectionQuery("geo", "Big_Rectangle")).get());
         assertThat(e.getMessage(), containsString("source disabled"));
     }
 
-    public void testReusableBuilder() throws IOException {
-        PolygonBuilder polygon = new PolygonBuilder(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);
-
-        LineStringBuilder linestring = new LineStringBuilder(new CoordinatesBuilder()
-                .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close());
-        assertUnmodified(linestring);
-    }
-
-    private void assertUnmodified(ShapeBuilder builder) throws IOException {
-        String before = Strings.toString(jsonBuilder().startObject().field("area", builder).endObject());
-        builder.buildS4J();
-        String after = Strings.toString(jsonBuilder().startObject().field("area", builder).endObject());
-        assertThat(before, equalTo(after));
-    }
-
     /** tests querying a random geometry collection with a point */
     public void testPointQuery() throws Exception {
         // Create a random geometry collection to index.
-        GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(random());
-        double[] pt = new double[] {GeoTestUtil.nextLongitude(), GeoTestUtil.nextLatitude()};
-        PointBuilder pb = new PointBuilder(pt[0], pt[1]);
-        gcb.shape(pb);
+        GeometryCollection<Geometry> randomCollection = GeometryTestUtils.randomGeometryCollectionWithoutCircle(false);
+        Point point = GeometryTestUtils.randomPoint(false);
+        List<Geometry> geometries = new ArrayList<>();
+        for (Geometry geometry : randomCollection) {
+            geometries.add(geometry);
+        }
+        geometries.add(point);
+        GeometryCollection<Geometry> gcb = new GeometryCollection<>(geometries);
 
-        // create mapping
+            // create mapping
         createRandomMapping("test", Settings.EMPTY);
 
-        XContentBuilder docSource = gcb.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(gcb, jsonBuilder().startObject().field("geo"), ToXContent.EMPTY_PARAMS).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
-        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", pb);
+        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", point);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
         SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
         assertSearchResponse(result);
@@ -449,71 +441,36 @@ public class GeoShapeQueryTests extends GeoQueryTests {
     }
 
     public void testContainsShapeQuery() throws Exception {
-        // Create a random geometry collection.
-        Rectangle mbr = xRandomRectangle(random(), xRandomPoint(random()), true);
-        boolean usePrefixTrees = randomBoolean();
-        GeometryCollectionBuilder gcb;
-        if (usePrefixTrees) {
-            gcb = createGeometryCollectionWithin(random(), mbr);
-        } else {
-            // vector strategy does not yet support multipoint queries
-            gcb = new GeometryCollectionBuilder();
-            int numShapes = RandomNumbers.randomIntBetween(random(), 1, 4);
-            for (int i = 0; i < numShapes; ++i) {
-                ShapeBuilder shape;
-                do {
-                    shape = RandomShapeGenerator.createShapeWithin(random(), mbr);
-                } while (shape instanceof MultiPointBuilder);
-                gcb.shape(shape);
-            }
-        }
-
-        // don't use random mapping as permits quadtree
-        String mapping = Strings.toString(
-            usePrefixTrees ?
-                createPrefixTreeMapping(LegacyGeoShapeFieldMapper.PrefixTrees.QUADTREE) :
-                createDefaultMapping());
-
-        if (usePrefixTrees) {
-            MapperParsingException ex =
-                expectThrows(MapperParsingException.class,
-                    () -> client().admin().indices().prepareCreate("test").setMapping(mapping).get());
-            assertThat(ex.getMessage(),
-                containsString("using deprecated parameters [tree] in mapper [geo] of type [geo_shape] is no longer allowed"));
-        }
-
-        Version version = VersionUtils.randomPreviousCompatibleVersion(random(), Version.V_8_0_0);
-        Settings settings = usePrefixTrees ? settings(version).build() : Settings.EMPTY;
-        client().admin().indices().prepareCreate("test").setMapping(mapping).setSettings(settings).get();
-        ensureGreen();
+        Polygon polygon = new Polygon(
+            new LinearRing(
+                new double[] {-30, 30, 30, -30, -30},
+                new double[] {-30, -30, 30, 30, -30}
+            )
+        );
+        Polygon innerPolygon = new Polygon(
+            new LinearRing(
+                new double[] {-5, 5, 5, -5, -5},
+                new double[] {-5, -5, 5, 5, -5}
+            )
+        );
+        createRandomMapping("test", Settings.EMPTY);
 
-        XContentBuilder docSource = gcb.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(polygon, jsonBuilder().startObject().field("geo"), null).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
-
-        // index the mbr of the collection
-        EnvelopeBuilder env = new EnvelopeBuilder(new Coordinate(mbr.getMinX(), mbr.getMaxY()),
-                new Coordinate(mbr.getMaxX(), mbr.getMinY()));
-        docSource = env.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
-        client().prepareIndex("test").setId("2").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
-
-        ShapeBuilder filterShape = (gcb.getShapeAt(randomIntBetween(0, gcb.numShapes() - 1)));
-        GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("geo", filterShape)
-                .relation(ShapeRelation.CONTAINS);
-        SearchResponse response = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
-                .setPostFilter(filter).get();
+        GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("geo", innerPolygon).relation(ShapeRelation.CONTAINS);
+        SearchResponse response = client().prepareSearch("test").setQuery(filter).get();
         assertSearchResponse(response);
-
-        assertThat(response.getHits().getTotalHits().value, greaterThan(0L));
+        assertThat(response.getHits().getTotalHits().value, equalTo(1L));
     }
 
     public void testExistsQuery() throws Exception {
         // Create a random geometry collection.
-        GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(random());
-        logger.info("Created Random GeometryCollection containing {} shapes", gcb.numShapes());
+        GeometryCollection<Geometry> gcb = GeometryTestUtils.randomGeometryCollectionWithoutCircle(false);
+        logger.info("Created Random GeometryCollection containing {} shapes", gcb.size());
 
         createRandomMapping("test", Settings.EMPTY);
 
-        XContentBuilder docSource = gcb.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(gcb, jsonBuilder().startObject().field("geo"), null).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
         ExistsQueryBuilder eqb = QueryBuilders.existsQuery("geo");
@@ -545,22 +502,19 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         client().admin().indices().prepareCreate("geo_points_only").setMapping(mapping).setSettings(settings).get();
         ensureGreen();
 
-        ShapeBuilder shape = RandomShapeGenerator.createShape(random());
+        Geometry geometry = GeometryTestUtils.randomGeometry(false);
         try {
             client().prepareIndex("geo_points_only").setId("1")
-                    .setSource(jsonBuilder().startObject().field("geo", shape).endObject())
+                    .setSource(GeoJson.toXContent(geometry, jsonBuilder().startObject().field("geo"), null).endObject())
                     .setRefreshPolicy(IMMEDIATE).get();
         } catch (MapperParsingException e) {
-            // RandomShapeGenerator created something other than a POINT type, verify the correct exception is thrown
+            // Random geometry generator created something other than a POINT type, verify the correct exception is thrown
             assertThat(e.getMessage(), containsString("is configured for points only"));
             return;
         }
 
         // test that point was inserted
-        SearchResponse response = client().prepareSearch("geo_points_only")
-                .setQuery(geoIntersectionQuery("geo", shape))
-                .get();
-
+        SearchResponse response = client().prepareSearch("geo_points_only").setQuery(geoIntersectionQuery("geo", geometry)).get();
         assertEquals(1, response.getHits().getTotalHits().value);
     }
 
@@ -588,15 +542,15 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         ensureGreen();
 
         // MULTIPOINT
-        ShapeBuilder shape = RandomShapeGenerator.createShape(random(), RandomShapeGenerator.ShapeType.MULTIPOINT);
+        MultiPoint multiPoint = GeometryTestUtils.randomMultiPoint(false);
         client().prepareIndex("geo_points_only").setId("1")
-            .setSource(jsonBuilder().startObject().field("geo", shape).endObject())
+            .setSource(GeoJson.toXContent(multiPoint, jsonBuilder().startObject().field("geo"), null).endObject())
             .setRefreshPolicy(IMMEDIATE).get();
 
         // POINT
-        shape = RandomShapeGenerator.createShape(random(), RandomShapeGenerator.ShapeType.POINT);
+        Point point =  GeometryTestUtils.randomPoint(false);
         client().prepareIndex("geo_points_only").setId("2")
-            .setSource(jsonBuilder().startObject().field("geo", shape).endObject())
+            .setSource(GeoJson.toXContent(point, jsonBuilder().startObject().field("geo"), null).endObject())
             .setRefreshPolicy(IMMEDIATE).get();
 
         // test that point was inserted
@@ -611,10 +565,10 @@ public class GeoShapeQueryTests extends GeoQueryTests {
 
         createRandomMapping("test", Settings.EMPTY);
 
-        EnvelopeBuilder shape = new EnvelopeBuilder(new Coordinate(-45, 45), new Coordinate(45, -45));
+        Rectangle shape = new Rectangle(-45, 45, 45, -45);
 
-        client().prepareIndex("shapes").setId("Big_Rectangle").setSource(jsonBuilder().startObject()
-            .field("shape", shape).endObject()).setRefreshPolicy(IMMEDIATE).get();
+        client().prepareIndex("shapes").setId("Big_Rectangle").setSource(
+            GeoJson.toXContent(shape, jsonBuilder().startObject().field("shape"), null).endObject()).setRefreshPolicy(IMMEDIATE).get();
         client().prepareIndex("test").setId("1").setSource(jsonBuilder().startObject()
             .field("name", "Document 1")
             .startObject("geo")
@@ -669,37 +623,38 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         client().admin().indices().prepareCreate("test").setMapping(mapping).setSettings(settings).get();
         ensureGreen();
 
-        ShapeBuilder shape = RandomShapeGenerator.createShape(random(), RandomShapeGenerator.ShapeType.MULTIPOINT);
+        MultiPoint multiPoint = GeometryTestUtils.randomMultiPoint(false);
         client().prepareIndex("test").setId("1")
-            .setSource(jsonBuilder().startObject().field("geo", shape).endObject())
+            .setSource(GeoJson.toXContent(multiPoint, jsonBuilder().startObject().field("geo"), null).endObject())
             .setRefreshPolicy(IMMEDIATE).get();
 
         SearchResponse response = client().prepareSearch("test")
-            .setQuery(geoShapeQuery("alias", shape))
+            .setQuery(geoShapeQuery("alias", multiPoint))
             .get();
         assertEquals(1, response.getHits().getTotalHits().value);
     }
 
     public void testQueryRandomGeoCollection() throws Exception {
         // Create a random geometry collection.
-        GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(random());
+        GeometryCollection<Geometry> randomCollection = GeometryTestUtils.randomGeometryCollectionWithoutCircle(false);
         org.apache.lucene.geo.Polygon randomPoly = GeoTestUtil.nextPolygon();
-        CoordinatesBuilder cb = new CoordinatesBuilder();
-        for (int i = 0; i < randomPoly.numPoints(); ++i) {
-            cb.coordinate(randomPoly.getPolyLon(i), randomPoly.getPolyLat(i));
+        Polygon polygon = new Polygon(new LinearRing(randomPoly.getPolyLons(), randomPoly.getPolyLats()));
+
+        List<Geometry> geometries = new ArrayList<>();
+        for(Geometry geometry : randomCollection) {
+            geometries.add(geometry);
         }
-        gcb.shape(new PolygonBuilder(cb));
+        geometries.add(polygon);
+        GeometryCollection<Geometry> gcb = new GeometryCollection<>(geometries);
 
-        logger.info("Created Random GeometryCollection containing {} shapes", gcb.numShapes());
+        logger.info("Created Random GeometryCollection containing {} shapes", gcb.size());
 
         createRandomMapping("test", Settings.EMPTY);
 
-        XContentBuilder docSource = gcb.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(gcb, jsonBuilder().startObject().field("geo"), null).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
-        ShapeBuilder filterShape = (gcb.getShapeAt(gcb.numShapes() - 1));
-
-        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", filterShape);
+        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", polygon);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
         SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
         assertSearchResponse(result);
@@ -737,78 +692,82 @@ public class GeoShapeQueryTests extends GeoQueryTests {
         client().prepareIndex("test").setId("1")
             .setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
-        GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery(
-            "geo",
-            new GeometryCollectionBuilder()
-                .polygon(
-                    new PolygonBuilder(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").setQuery(QueryBuilders.matchAllQuery())
-            .setPostFilter(filter).get();
-        assertSearchResponse(result);
-        assertHitCount(result, 1);
-        filter = QueryBuilders.geoShapeQuery(
-            "geo",
-            new GeometryCollectionBuilder().polygon(
-                new PolygonBuilder(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").setQuery(QueryBuilders.matchAllQuery())
-            .setPostFilter(filter).get();
-        assertSearchResponse(result);
-        assertHitCount(result, 0);
-        filter = QueryBuilders.geoShapeQuery("geo", new GeometryCollectionBuilder()
-            .polygon(new PolygonBuilder(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(
-                new PolygonBuilder(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").setQuery(QueryBuilders.matchAllQuery())
-            .setPostFilter(filter).get();
-        assertSearchResponse(result);
-        assertHitCount(result, 1);
-        // no shape
-        filter = QueryBuilders.geoShapeQuery("geo", new GeometryCollectionBuilder());
-        result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
-            .setPostFilter(filter).get();
-        assertSearchResponse(result);
-        assertHitCount(result, 0);
+        Polygon polygon1 = new Polygon(
+            new LinearRing(
+                new double[] {99.0, 99.0, 103.0, 103.0, 99.0},
+                new double[] {-1.0, 3.0, 3.0, -1.0, -1.0}
+            )
+        );
+        Polygon polygon2 = new Polygon(
+            new LinearRing(
+                new double[] {199.0, 199.0, 193.0, 193.0, 199.0},
+                new double[] {-11.0, 13.0, 13.0, -11.0, -11.0}
+            )
+        );
+
+        {
+            GeoShapeQueryBuilder filter =
+                QueryBuilders.geoShapeQuery("geo", new GeometryCollection<>(List.of(polygon1))).relation(ShapeRelation.INTERSECTS);
+            SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).setPostFilter(filter).get();
+            assertSearchResponse(result);
+            assertHitCount(result, 1);
+        }
+        {
+            GeoShapeQueryBuilder filter =
+                QueryBuilders.geoShapeQuery("geo", new GeometryCollection<>(List.of(polygon2))).relation(ShapeRelation.INTERSECTS);
+            SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).setPostFilter(filter).get();
+            assertSearchResponse(result);
+            assertHitCount(result, 0);
+        }
+        {
+            GeoShapeQueryBuilder filter =
+                QueryBuilders.geoShapeQuery("geo",
+                    new GeometryCollection<>(List.of(polygon1, polygon2))).relation(ShapeRelation.INTERSECTS);
+            SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).setPostFilter(filter).get();
+            assertSearchResponse(result);
+            assertHitCount(result, 1);
+        }
+        {
+            // no shape
+            GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery("geo", GeometryCollection.EMPTY);
+            SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).setPostFilter(filter).get();
+            assertSearchResponse(result);
+            assertHitCount(result, 0);
+        }
     }
 
     public void testDistanceQuery() throws Exception {
         createRandomMapping("test_distance", Settings.EMPTY);
 
-        CircleBuilder circleBuilder = new CircleBuilder().center(new Coordinate(1, 0)).radius(350, DistanceUnit.KILOMETERS);
+        Circle circle = new Circle(1, 0, 350000);
 
         client().index(new IndexRequest("test_distance")
-            .source(jsonBuilder().startObject().field("geo", new PointBuilder(2, 2)).endObject())
+            .source(jsonBuilder().startObject().field("geo", WellKnownText.toWKT(new Point(2, 2))).endObject())
             .setRefreshPolicy(IMMEDIATE)).actionGet();
         client().index(new IndexRequest("test_distance")
-            .source(jsonBuilder().startObject().field("geo", new PointBuilder(3, 1)).endObject())
+            .source(jsonBuilder().startObject().field("geo", WellKnownText.toWKT(new Point(3, 1))).endObject())
             .setRefreshPolicy(IMMEDIATE)).actionGet();
         client().index(new IndexRequest("test_distance")
-            .source(jsonBuilder().startObject().field("geo", new PointBuilder(-20, -30)).endObject())
+            .source(jsonBuilder().startObject().field("geo", WellKnownText.toWKT(new Point(-20, -30))).endObject())
             .setRefreshPolicy(IMMEDIATE)).actionGet();
         client().index(new IndexRequest("test_distance")
-            .source(jsonBuilder().startObject().field("geo", new PointBuilder(20, 30)).endObject())
+            .source(jsonBuilder().startObject().field("geo", WellKnownText.toWKT(new Point(20, 30))).endObject())
             .setRefreshPolicy(IMMEDIATE)).actionGet();
 
         SearchResponse response = client().prepareSearch("test_distance")
-            .setQuery(QueryBuilders.geoShapeQuery("geo", circleBuilder.buildGeometry()).relation(ShapeRelation.WITHIN))
+            .setQuery(QueryBuilders.geoShapeQuery("geo", circle).relation(ShapeRelation.WITHIN))
             .get();
         assertEquals(2, response.getHits().getTotalHits().value);
         response = client().prepareSearch("test_distance")
-            .setQuery(QueryBuilders.geoShapeQuery("geo", circleBuilder.buildGeometry()).relation(ShapeRelation.INTERSECTS))
+            .setQuery(QueryBuilders.geoShapeQuery("geo", circle).relation(ShapeRelation.INTERSECTS))
             .get();
         assertEquals(2, response.getHits().getTotalHits().value);
         response = client().prepareSearch("test_distance")
-            .setQuery(QueryBuilders.geoShapeQuery("geo", circleBuilder.buildGeometry()).relation(ShapeRelation.DISJOINT))
+            .setQuery(QueryBuilders.geoShapeQuery("geo", circle).relation(ShapeRelation.DISJOINT))
             .get();
         assertEquals(2, response.getHits().getTotalHits().value);
         response = client().prepareSearch("test_distance")
-            .setQuery(QueryBuilders.geoShapeQuery("geo", circleBuilder.buildGeometry()).relation(ShapeRelation.CONTAINS))
+            .setQuery(QueryBuilders.geoShapeQuery("geo", circle).relation(ShapeRelation.CONTAINS))
             .get();
         assertEquals(0, response.getHits().getTotalHits().value);
     }
@@ -816,12 +775,12 @@ public class GeoShapeQueryTests extends GeoQueryTests {
     public void testIndexRectangleSpanningDateLine() throws Exception {
         createRandomMapping("test", Settings.EMPTY);
 
-        EnvelopeBuilder envelopeBuilder = new EnvelopeBuilder(new Coordinate(178, 10), new Coordinate(-178, -10));
+        Rectangle envelope = new Rectangle(178, -178, 10, -10);
 
-        XContentBuilder docSource = envelopeBuilder.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        XContentBuilder docSource = GeoJson.toXContent(envelope, jsonBuilder().startObject().field("geo"), null).endObject();
         client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
 
-        ShapeBuilder filterShape = new PointBuilder(179, 0);
+        Point filterShape = new Point(179, 0);
 
         GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", filterShape);
         geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);

+ 14 - 1
test/framework/src/main/java/org/elasticsearch/geo/GeometryTestUtils.java

@@ -165,6 +165,10 @@ public class GeometryTestUtils {
         return randomGeometryCollection(0, hasAlt);
     }
 
+    public static GeometryCollection<Geometry> randomGeometryCollectionWithoutCircle(boolean hasAlt) {
+        return randomGeometryCollectionWithoutCircle(0, hasAlt);
+    }
+
     private static GeometryCollection<Geometry> randomGeometryCollection(int level, boolean hasAlt) {
         int size = ESTestCase.randomIntBetween(1, 10);
         List<Geometry> shapes = new ArrayList<>();
@@ -174,6 +178,15 @@ public class GeometryTestUtils {
         return new GeometryCollection<>(shapes);
     }
 
+    private static GeometryCollection<Geometry> randomGeometryCollectionWithoutCircle(int level, boolean hasAlt) {
+        int size = ESTestCase.randomIntBetween(1, 10);
+        List<Geometry> shapes = new ArrayList<>();
+        for (int i = 0; i < size; i++) {
+            shapes.add(randomGeometryWithoutCircle(level, hasAlt));
+        }
+        return new GeometryCollection<>(shapes);
+    }
+
     public static Geometry randomGeometry(boolean hasAlt) {
         return randomGeometry(0, hasAlt);
     }
@@ -203,7 +216,7 @@ public class GeometryTestUtils {
             GeometryTestUtils::randomMultiPolygon,
             hasAlt ? GeometryTestUtils::randomPoint : (b) -> randomRectangle(),
             level < 3 ? (b) ->
-                randomGeometryWithoutCircleCollection(level + 1, hasAlt) : GeometryTestUtils::randomPoint // don't build too deep
+                randomGeometryCollectionWithoutCircle(level + 1, hasAlt) : GeometryTestUtils::randomPoint // don't build too deep
         );
         return geometry.apply(hasAlt);
     }