Merge pull request #14529 from cbuescher/introduce-shapebuilders

Geo: Moving static factory methods to ShapeBuilders
This commit is contained in:
Christoph Büscher 2015-11-17 11:08:35 +01:00
commit d6a756fbe2
9 changed files with 260 additions and 220 deletions

View File

@ -41,7 +41,7 @@ import java.io.IOException;
import java.util.*;
/**
* Basic class for building GeoJSON shapes like Polygons, Linestrings, etc
* Basic class for building GeoJSON shapes like Polygons, Linestrings, etc
*/
public abstract class ShapeBuilder extends ToXContentToBytes {
@ -97,122 +97,10 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
return jtsGeometry;
}
/**
* Create a new point
*
* @param longitude longitude of the point
* @param latitude latitude of the point
* @return a new {@link PointBuilder}
*/
public static PointBuilder newPoint(double longitude, double latitude) {
return newPoint(new Coordinate(longitude, latitude));
}
/**
* Create a new {@link PointBuilder} from a {@link Coordinate}
* @param coordinate coordinate defining the position of the point
* @return a new {@link PointBuilder}
*/
public static PointBuilder newPoint(Coordinate coordinate) {
return new PointBuilder().coordinate(coordinate);
}
/**
* Create a new set of points
* @return new {@link MultiPointBuilder}
*/
public static MultiPointBuilder newMultiPoint() {
return new MultiPointBuilder();
}
/**
* Create a new lineString
* @return a new {@link LineStringBuilder}
*/
public static LineStringBuilder newLineString() {
return new LineStringBuilder();
}
/**
* Create a new Collection of lineStrings
* @return a new {@link MultiLineStringBuilder}
*/
public static MultiLineStringBuilder newMultiLinestring() {
return new MultiLineStringBuilder();
}
/**
* Create a new Polygon
* @return a new {@link PointBuilder}
*/
public static PolygonBuilder newPolygon() {
return new PolygonBuilder();
}
/**
* Create a new Polygon
* @return a new {@link PointBuilder}
*/
public static PolygonBuilder newPolygon(Orientation orientation) {
return new PolygonBuilder(orientation);
}
/**
* Create a new Collection of polygons
* @return a new {@link MultiPolygonBuilder}
*/
public static MultiPolygonBuilder newMultiPolygon() {
return new MultiPolygonBuilder();
}
/**
* Create a new Collection of polygons
* @return a new {@link MultiPolygonBuilder}
*/
public static MultiPolygonBuilder newMultiPolygon(Orientation orientation) {
return new MultiPolygonBuilder(orientation);
}
/**
* Create a new GeometryCollection
* @return a new {@link GeometryCollectionBuilder}
*/
public static GeometryCollectionBuilder newGeometryCollection() {
return new GeometryCollectionBuilder();
}
/**
* Create a new GeometryCollection
* @return a new {@link GeometryCollectionBuilder}
*/
public static GeometryCollectionBuilder newGeometryCollection(Orientation orientation) {
return new GeometryCollectionBuilder(orientation);
}
/**
* create a new Circle
* @return a new {@link CircleBuilder}
*/
public static CircleBuilder newCircleBuilder() {
return new CircleBuilder();
}
/**
* create a new rectangle
* @return a new {@link EnvelopeBuilder}
*/
public static EnvelopeBuilder newEnvelope() { return new EnvelopeBuilder(); }
/**
* create a new rectangle
* @return a new {@link EnvelopeBuilder}
*/
public static EnvelopeBuilder newEnvelope(Orientation orientation) { return new EnvelopeBuilder(orientation); }
/**
* Create a new Shape from this builder. Since calling this method could change the
* defined shape. (by inserting new coordinates or change the position of points)
* the builder looses its validity. So this method should only be called once on a builder
* the builder looses its validity. So this method should only be called once on a builder
* @return new {@link Shape} defined by the builder
*/
public abstract Shape build();
@ -220,7 +108,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Recursive method which parses the arrays of coordinates used to define
* Shapes
*
*
* @param parser
* Parser that will be read from
* @return CoordinateNode representing the start of the coordinate tree
@ -232,8 +120,8 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
XContentParser.Token token = parser.nextToken();
// Base cases
if (token != XContentParser.Token.START_ARRAY &&
token != XContentParser.Token.END_ARRAY &&
if (token != XContentParser.Token.START_ARRAY &&
token != XContentParser.Token.END_ARRAY &&
token != XContentParser.Token.VALUE_NULL) {
double lon = parser.doubleValue();
token = parser.nextToken();
@ -317,7 +205,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Calculate the intersection of a line segment and a vertical dateline.
*
*
* @param p1
* start-point of the line segment
* @param p2
@ -347,7 +235,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
* Calculate all intersections of line segments and a vertical line. The
* Array of edges will be ordered asc by the y-coordinate of the
* intersections of edges.
*
*
* @param dateline
* x-coordinate of the dateline
* @param edges
@ -360,7 +248,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
for (int i = 0; i < edges.length; i++) {
Coordinate p1 = edges[i].coordinate;
Coordinate p2 = edges[i].next.coordinate;
assert !Double.isNaN(p2.x) && !Double.isNaN(p1.x);
assert !Double.isNaN(p2.x) && !Double.isNaN(p1.x);
edges[i].intersect = Edge.MAX_COORDINATE;
double position = intersection(p1, p2, dateline);
@ -386,7 +274,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Creates a new leaf CoordinateNode
*
*
* @param coordinate
* Coordinate for the Node
*/
@ -397,7 +285,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Creates a new parent CoordinateNode
*
*
* @param children
* Children of the Node
*/
@ -427,7 +315,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* This helper class implements a linked list for {@link Coordinate}. It contains
* fields for a dateline intersection and component id
* fields for a dateline intersection and component id
*/
protected static final class Edge {
Coordinate coordinate; // coordinate of the start point
@ -500,7 +388,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Concatenate a set of points to a polygon
*
*
* @param component
* component id of the polygon
* @param direction
@ -547,7 +435,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Create a connected list of a list of coordinates
*
*
* @param points
* array of point
* @param offset
@ -567,7 +455,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
final int next = (offset + ((top + 1) % length));
boolean orientation = points[offset + prev].x > points[offset + next].x;
// OGC requires shell as ccw (Right-Handedness) and holes as cw (Left-Handedness)
// OGC requires shell as ccw (Right-Handedness) and holes as cw (Left-Handedness)
// since GeoJSON doesn't specify (and doesn't need to) GEO core will assume OGC standards
// thus if orientation is computed as cw, the logic will translate points across dateline
// and convert to a right handed system
@ -576,7 +464,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
double[] range = range(points, offset, length);
final double rng = range[1] - range[0];
// translate the points if the following is true
// 1. shell orientation is cw and range is greater than a hemisphere (180 degrees) but not spanning 2 hemispheres
// 1. shell orientation is cw and range is greater than a hemisphere (180 degrees) but not spanning 2 hemispheres
// (translation would result in a collapsed poly)
// 2. the shell of the candidate hole has been translated (to preserve the coordinate system)
boolean incorrectOrientation = component == 0 && handedness != orientation;
@ -595,7 +483,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
}
/**
* Transforms coordinates in the eastern hemisphere (-180:0) to a (180:360) range
* Transforms coordinates in the eastern hemisphere (-180:0) to a (180:360) range
*/
protected static void translate(Coordinate[] points) {
for (Coordinate c : points) {
@ -607,7 +495,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
/**
* Set the intersection of this line segment to the given position
*
*
* @param position
* position of the intersection [0..1]
* @return the {@link Coordinate} of the intersection
@ -770,7 +658,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
throw new ElasticsearchParseException("shape type [{}] not included", shapeType);
}
}
protected static void validatePointNode(CoordinateNode node) {
if (node.isEmpty()) {
throw new ElasticsearchParseException("invalid number of points (0) provided when expecting a single coordinate ([lat, lng])");
@ -783,11 +671,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
protected static PointBuilder parsePoint(CoordinateNode node) {
validatePointNode(node);
return newPoint(node.coordinate);
return ShapeBuilders.newPoint(node.coordinate);
}
protected static CircleBuilder parseCircle(CoordinateNode coordinates, Distance radius) {
return newCircleBuilder().center(coordinates.coordinate).radius(radius);
return ShapeBuilders.newCircleBuilder().center(coordinates.coordinate).radius(radius);
}
protected static EnvelopeBuilder parseEnvelope(CoordinateNode coordinates, final Orientation orientation) {
@ -804,7 +692,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
uL = new Coordinate(Math.min(uL.x, lR.x), Math.max(uL.y, lR.y));
lR = new Coordinate(Math.max(uLtmp.x, lR.x), Math.min(uLtmp.y, lR.y));
}
return newEnvelope(orientation).topLeft(uL).bottomRight(lR);
return ShapeBuilders.newEnvelope(orientation).topLeft(uL).bottomRight(lR);
}
protected static void validateMultiPointNode(CoordinateNode coordinates) {
@ -842,7 +730,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)", coordinates.children.size());
}
LineStringBuilder line = newLineString();
LineStringBuilder line = ShapeBuilders.newLineString();
for (CoordinateNode node : coordinates.children) {
line.point(node.coordinate);
}
@ -850,7 +738,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
}
protected static MultiLineStringBuilder parseMultiLine(CoordinateNode coordinates) {
MultiLineStringBuilder multiline = newMultiLinestring();
MultiLineStringBuilder multiline = ShapeBuilders.newMultiLinestring();
for (CoordinateNode node : coordinates.children) {
multiline.linestring(parseLineString(node));
}
@ -903,13 +791,13 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
protected static MultiPolygonBuilder parseMultiPolygon(CoordinateNode coordinates, final Orientation orientation,
final boolean coerce) {
MultiPolygonBuilder polygons = newMultiPolygon(orientation);
MultiPolygonBuilder polygons = ShapeBuilders.newMultiPolygon(orientation);
for (CoordinateNode node : coordinates.children) {
polygons.polygon(parsePolygon(node, orientation, coerce));
}
return polygons;
}
/**
* Parse the geometries array of a GeometryCollection
*
@ -922,16 +810,16 @@ public abstract class ShapeBuilder extends ToXContentToBytes {
if (parser.currentToken() != XContentParser.Token.START_ARRAY) {
throw new ElasticsearchParseException("geometries must be an array of geojson objects");
}
XContentParser.Token token = parser.nextToken();
GeometryCollectionBuilder geometryCollection = newGeometryCollection( (mapper == null) ? Orientation.RIGHT : mapper
GeometryCollectionBuilder geometryCollection = ShapeBuilders.newGeometryCollection( (mapper == null) ? Orientation.RIGHT : mapper
.fieldType().orientation());
while (token != XContentParser.Token.END_ARRAY) {
ShapeBuilder shapeBuilder = GeoShapeType.parse(parser);
geometryCollection.shape(shapeBuilder);
token = parser.nextToken();
}
return geometryCollection;
}
}

View File

@ -0,0 +1,148 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.geo.builders;
import com.vividsolutions.jts.geom.Coordinate;
/**
* A collection of static methods for creating ShapeBuilders.
*/
public class ShapeBuilders {
/**
* Create a new point
*
* @param longitude longitude of the point
* @param latitude latitude of the point
* @return a new {@link PointBuilder}
*/
public static PointBuilder newPoint(double longitude, double latitude) {
return ShapeBuilders.newPoint(new Coordinate(longitude, latitude));
}
/**
* Create a new {@link PointBuilder} from a {@link Coordinate}
* @param coordinate coordinate defining the position of the point
* @return a new {@link PointBuilder}
*/
public static PointBuilder newPoint(Coordinate coordinate) {
return new PointBuilder().coordinate(coordinate);
}
/**
* Create a new set of points
* @return new {@link MultiPointBuilder}
*/
public static MultiPointBuilder newMultiPoint() {
return new MultiPointBuilder();
}
/**
* Create a new lineString
* @return a new {@link LineStringBuilder}
*/
public static LineStringBuilder newLineString() {
return new LineStringBuilder();
}
/**
* Create a new Collection of lineStrings
* @return a new {@link MultiLineStringBuilder}
*/
public static MultiLineStringBuilder newMultiLinestring() {
return new MultiLineStringBuilder();
}
/**
* Create a new Polygon
* @return a new {@link PointBuilder}
*/
public static PolygonBuilder newPolygon() {
return new PolygonBuilder();
}
/**
* Create a new Polygon
* @return a new {@link PointBuilder}
*/
public static PolygonBuilder newPolygon(ShapeBuilder.Orientation orientation) {
return new PolygonBuilder(orientation);
}
/**
* Create a new Collection of polygons
* @return a new {@link MultiPolygonBuilder}
*/
public static MultiPolygonBuilder newMultiPolygon() {
return new MultiPolygonBuilder();
}
/**
* Create a new Collection of polygons
* @return a new {@link MultiPolygonBuilder}
*/
public static MultiPolygonBuilder newMultiPolygon(ShapeBuilder.Orientation orientation) {
return new MultiPolygonBuilder(orientation);
}
/**
* Create a new GeometryCollection
* @return a new {@link GeometryCollectionBuilder}
*/
public static GeometryCollectionBuilder newGeometryCollection() {
return new GeometryCollectionBuilder();
}
/**
* Create a new GeometryCollection
*
* @return a new {@link GeometryCollectionBuilder}
*/
public static GeometryCollectionBuilder newGeometryCollection(ShapeBuilder.Orientation orientation) {
return new GeometryCollectionBuilder(orientation);
}
/**
* create a new Circle
*
* @return a new {@link CircleBuilder}
*/
public static CircleBuilder newCircleBuilder() {
return new CircleBuilder();
}
/**
* create a new rectangle
*
* @return a new {@link EnvelopeBuilder}
*/
public static EnvelopeBuilder newEnvelope() {
return new EnvelopeBuilder();
}
/**
* create a new rectangle
*
* @return a new {@link EnvelopeBuilder}
*/
public static EnvelopeBuilder newEnvelope(ShapeBuilder.Orientation orientation) {
return new EnvelopeBuilder(orientation);
}
}

View File

@ -31,6 +31,7 @@ import com.vividsolutions.jts.geom.Polygon;
import org.elasticsearch.common.geo.builders.PolygonBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.test.ESTestCase;
import static org.elasticsearch.test.hamcrest.ElasticsearchGeoAssertions.assertMultiLineString;
@ -43,13 +44,13 @@ import static org.hamcrest.Matchers.containsString;
public class ShapeBuilderTests extends ESTestCase {
public void testNewPoint() {
Point point = ShapeBuilder.newPoint(-100, 45).build();
Point point = ShapeBuilders.newPoint(-100, 45).build();
assertEquals(-100D, point.getX(), 0.0d);
assertEquals(45D, point.getY(), 0.0d);
}
public void testNewRectangle() {
Rectangle rectangle = ShapeBuilder.newEnvelope().topLeft(-45, 30).bottomRight(45, -30).build();
Rectangle rectangle = ShapeBuilders.newEnvelope().topLeft(-45, 30).bottomRight(45, -30).build();
assertEquals(-45D, rectangle.getMinX(), 0.0d);
assertEquals(-30D, rectangle.getMinY(), 0.0d);
assertEquals(45D, rectangle.getMaxX(), 0.0d);
@ -57,7 +58,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testNewPolygon() {
Polygon polygon = ShapeBuilder.newPolygon()
Polygon polygon = ShapeBuilders.newPolygon()
.point(-45, 30)
.point(45, 30)
.point(45, -30)
@ -72,7 +73,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testNewPolygon_coordinate() {
Polygon polygon = ShapeBuilder.newPolygon()
Polygon polygon = ShapeBuilders.newPolygon()
.point(new Coordinate(-45, 30))
.point(new Coordinate(45, 30))
.point(new Coordinate(45, -30))
@ -87,7 +88,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testNewPolygon_coordinates() {
Polygon polygon = ShapeBuilder.newPolygon()
Polygon polygon = ShapeBuilders.newPolygon()
.points(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)).toPolygon();
LineString exterior = polygon.getExteriorRing();
@ -99,7 +100,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testLineStringBuilder() {
// Building a simple LineString
ShapeBuilder.newLineString()
ShapeBuilders.newLineString()
.point(-130.0, 55.0)
.point(-130.0, -40.0)
.point(-15.0, -40.0)
@ -110,7 +111,7 @@ public class ShapeBuilderTests extends ESTestCase {
.point(-110.0, 55.0).build();
// Building a linestring that needs to be wrapped
ShapeBuilder.newLineString()
ShapeBuilders.newLineString()
.point(100.0, 50.0)
.point(110.0, -40.0)
.point(240.0, -40.0)
@ -122,7 +123,7 @@ public class ShapeBuilderTests extends ESTestCase {
.build();
// Building a lineString on the dateline
ShapeBuilder.newLineString()
ShapeBuilders.newLineString()
.point(-180.0, 80.0)
.point(-180.0, 40.0)
.point(-180.0, -40.0)
@ -130,7 +131,7 @@ public class ShapeBuilderTests extends ESTestCase {
.build();
// Building a lineString on the dateline
ShapeBuilder.newLineString()
ShapeBuilders.newLineString()
.point(180.0, 80.0)
.point(180.0, 40.0)
.point(180.0, -40.0)
@ -139,7 +140,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testMultiLineString() {
ShapeBuilder.newMultiLinestring()
ShapeBuilders.newMultiLinestring()
.linestring()
.point(-100.0, 50.0)
.point(50.0, 50.0)
@ -156,7 +157,7 @@ public class ShapeBuilderTests extends ESTestCase {
// LineString that needs to be wrappped
ShapeBuilder.newMultiLinestring()
ShapeBuilders.newMultiLinestring()
.linestring()
.point(150.0, 60.0)
.point(200.0, 60.0)
@ -174,7 +175,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testPolygonSelfIntersection() {
try {
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.point(-40.0, 50.0)
.point(40.0, 50.0)
.point(-40.0, -50.0)
@ -188,31 +189,31 @@ public class ShapeBuilderTests extends ESTestCase {
public void testGeoCircle() {
double earthCircumference = 40075016.69;
Circle circle = ShapeBuilder.newCircleBuilder().center(0, 0).radius("100m").build();
Circle circle = ShapeBuilders.newCircleBuilder().center(0, 0).radius("100m").build();
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(0, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
circle = ShapeBuilder.newCircleBuilder().center(+180, 0).radius("100m").build();
circle = ShapeBuilders.newCircleBuilder().center(+180, 0).radius("100m").build();
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(180, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
circle = ShapeBuilder.newCircleBuilder().center(-180, 0).radius("100m").build();
circle = ShapeBuilders.newCircleBuilder().center(-180, 0).radius("100m").build();
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(-180, 0, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
circle = ShapeBuilder.newCircleBuilder().center(0, 90).radius("100m").build();
circle = ShapeBuilders.newCircleBuilder().center(0, 90).radius("100m").build();
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(0, 90, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
circle = ShapeBuilder.newCircleBuilder().center(0, -90).radius("100m").build();
circle = ShapeBuilders.newCircleBuilder().center(0, -90).radius("100m").build();
assertEquals((360 * 100) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(0, -90, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
double randomLat = (randomDouble() * 180) - 90;
double randomLon = (randomDouble() * 360) - 180;
double randomRadius = randomIntBetween(1, (int) earthCircumference / 4);
circle = ShapeBuilder.newCircleBuilder().center(randomLon, randomLat).radius(randomRadius + "m").build();
circle = ShapeBuilders.newCircleBuilder().center(randomLon, randomLat).radius(randomRadius + "m").build();
assertEquals((360 * randomRadius) / earthCircumference, circle.getRadius(), 0.00000001);
assertEquals(new PointImpl(randomLon, randomLat, ShapeBuilder.SPATIAL_CONTEXT), circle.getCenter());
}
public void testPolygonWrapping() {
Shape shape = ShapeBuilder.newPolygon()
Shape shape = ShapeBuilders.newPolygon()
.point(-150.0, 65.0)
.point(-250.0, 65.0)
.point(-250.0, -65.0)
@ -223,7 +224,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testLineStringWrapping() {
Shape shape = ShapeBuilder.newLineString()
Shape shape = ShapeBuilders.newLineString()
.point(-150.0, 65.0)
.point(-250.0, 65.0)
.point(-250.0, -65.0)
@ -238,7 +239,7 @@ public class ShapeBuilderTests extends ESTestCase {
// expected results: 3 polygons, 1 with a hole
// a giant c shape
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(174,0)
.point(-176,0)
.point(-176,3)
@ -279,7 +280,7 @@ public class ShapeBuilderTests extends ESTestCase {
// expected results: 3 polygons, 1 with a hole
// a giant c shape
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-186,0)
.point(-176,0)
.point(-176,3)
@ -315,7 +316,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testComplexShapeWithHole() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-85.0018514,37.1311314)
.point(-85.0016645,37.1315293)
.point(-85.0016246,37.1317069)
@ -388,7 +389,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testShapeWithHoleAtEdgeEndPoints() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-4, 2)
.point(4, 2)
.point(6, 0)
@ -409,7 +410,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testShapeWithPointOnDateline() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(180, 0)
.point(176, 4)
.point(176, -4)
@ -421,7 +422,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testShapeWithEdgeAlongDateline() {
// test case 1: test the positive side of the dateline
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(180, 0)
.point(176, 4)
.point(180, -4)
@ -431,7 +432,7 @@ public class ShapeBuilderTests extends ESTestCase {
assertPolygon(shape);
// test case 2: test the negative side of the dateline
builder = ShapeBuilder.newPolygon()
builder = ShapeBuilders.newPolygon()
.point(-176, 4)
.point(-180, 0)
.point(-180, -4)
@ -443,7 +444,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testShapeWithBoundaryHoles() {
// test case 1: test the positive side of the dateline
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-177, 10)
.point(176, 15)
.point(172, 0)
@ -460,7 +461,7 @@ public class ShapeBuilderTests extends ESTestCase {
assertMultiPolygon(shape);
// test case 2: test the negative side of the dateline
builder = ShapeBuilder.newPolygon()
builder = ShapeBuilders.newPolygon()
.point(-176, 15)
.point(179, 10)
.point(179, -10)
@ -478,7 +479,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testShapeWithTangentialHole() {
// test a shape with one tangential (shared) vertex (should pass)
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(179, 10)
.point(168, 15)
.point(164, 0)
@ -497,7 +498,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testShapeWithInvalidTangentialHole() {
// test a shape with one invalid tangential (shared) vertex (should throw exception)
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(179, 10)
.point(168, 15)
.point(164, 0)
@ -520,7 +521,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testBoundaryShapeWithTangentialHole() {
// test a shape with one tangential (shared) vertex for each hole (should pass)
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-177, 10)
.point(176, 15)
.point(172, 0)
@ -544,7 +545,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testBoundaryShapeWithInvalidTangentialHole() {
// test shape with two tangential (shared) vertices (should throw exception)
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-177, 10)
.point(176, 15)
.point(172, 0)
@ -569,7 +570,7 @@ public class ShapeBuilderTests extends ESTestCase {
* Test an enveloping polygon around the max mercator bounds
*/
public void testBoundaryShape() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-180, 90)
.point(180, 90)
.point(180, -90)
@ -582,7 +583,7 @@ public class ShapeBuilderTests extends ESTestCase {
public void testShapeWithAlternateOrientation() {
// cw: should produce a multi polygon spanning hemispheres
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(180, 0)
.point(176, 4)
.point(-176, 4)
@ -592,7 +593,7 @@ public class ShapeBuilderTests extends ESTestCase {
assertPolygon(shape);
// cw: geo core will convert to ccw across the dateline
builder = ShapeBuilder.newPolygon()
builder = ShapeBuilders.newPolygon()
.point(180, 0)
.point(-176, 4)
.point(176, 4)
@ -604,7 +605,7 @@ public class ShapeBuilderTests extends ESTestCase {
}
public void testInvalidShapeWithConsecutiveDuplicatePoints() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(180, 0)
.point(176, 4)
.point(176, 4)

View File

@ -20,12 +20,13 @@
package org.elasticsearch.index.mapper.externalvalues;
import com.spatial4j.core.shape.Point;
import org.apache.lucene.document.Field;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Iterators;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.ContentPath;
@ -201,7 +202,7 @@ public class ExternalMapper extends FieldMapper {
pointMapper.parse(context.createExternalValueContext(point));
// Let's add a Dummy Shape
Point shape = ShapeBuilder.newPoint(-100, 45).build();
Point shape = ShapeBuilders.newPoint(-100, 45).build();
shapeMapper.parse(context.createExternalValueContext(shape));
context = context.createExternalValueContext(generatedValue);

View File

@ -21,7 +21,7 @@ package org.elasticsearch.index.mapper.externalvalues;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.plugins.Plugin;
@ -69,7 +69,7 @@ public class ExternalValuesMapperIntegrationIT extends ESIntegTestCase {
assertThat(response.getHits().totalHits(), equalTo((long) 1));
response = client().prepareSearch("test-idx")
.setPostFilter(QueryBuilders.geoShapeQuery("field.shape", ShapeBuilder.newPoint(-100, 45)).relation(ShapeRelation.WITHIN))
.setPostFilter(QueryBuilders.geoShapeQuery("field.shape", ShapeBuilders.newPoint(-100, 45)).relation(ShapeRelation.WITHIN))
.execute().actionGet();
assertThat(response.getHits().totalHits(), equalTo((long) 1));

View File

@ -30,6 +30,7 @@ import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.SpatialStrategy;
import org.elasticsearch.common.geo.builders.EnvelopeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.json.JsonXContent;
@ -217,7 +218,7 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
// see #3878
public void testThatXContentSerializationInsideOfArrayWorks() throws Exception {
EnvelopeBuilder envelopeBuilder = ShapeBuilder.newEnvelope().topLeft(0, 0).bottomRight(10, 10);
EnvelopeBuilder envelopeBuilder = ShapeBuilders.newEnvelope().topLeft(0, 0).bottomRight(10, 10);
GeoShapeQueryBuilder geoQuery = QueryBuilders.geoShapeQuery("searchGeometry", envelopeBuilder);
JsonXContent.contentBuilder().startArray().value(geoQuery).endArray();
}

View File

@ -23,7 +23,7 @@ import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
@ -175,7 +175,7 @@ public class QueryDSLDocumentationTests extends ESTestCase {
public void testGeoShape() throws IOException {
GeoShapeQueryBuilder qb = geoShapeQuery(
"pin.location",
ShapeBuilder.newMultiPoint()
ShapeBuilders.newMultiPoint()
.point(0, 0)
.point(0, 10)
.point(10, 10)

View File

@ -44,7 +44,7 @@ import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.geo.builders.MultiPolygonBuilder;
import org.elasticsearch.common.geo.builders.PolygonBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -116,7 +116,7 @@ public class GeoFilterIT extends ESIntegTestCase {
public void testShapeBuilders() {
try {
// self intersection polygon
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.point(-10, -10)
.point(10, 10)
.point(-10, 10)
@ -127,7 +127,7 @@ public class GeoFilterIT extends ESIntegTestCase {
}
// polygon with hole
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.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)
@ -135,7 +135,7 @@ public class GeoFilterIT extends ESIntegTestCase {
try {
// polygon with overlapping hole
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole()
.point(-5, -5).point(-5, 11).point(5, 11).point(5, -5)
@ -147,7 +147,7 @@ public class GeoFilterIT extends ESIntegTestCase {
try {
// polygon with intersection holes
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.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)
@ -162,7 +162,7 @@ public class GeoFilterIT extends ESIntegTestCase {
try {
// Common line in polygon
ShapeBuilder.newPolygon()
ShapeBuilders.newPolygon()
.point(-10, -10)
.point(-10, 10)
.point(-5, 10)
@ -192,7 +192,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// } catch (InvalidShapeException e) {}
// Multipolygon: polygon with hole and polygon within the whole
ShapeBuilder.newMultiPolygon()
ShapeBuilders.newMultiPolygon()
.polygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole()
@ -247,7 +247,7 @@ 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()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole()
@ -266,7 +266,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// Point in polygon
SearchResponse result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(3, 3)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(3, 3)))
.execute().actionGet();
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
@ -274,7 +274,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// Point in polygon hole
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(4.5, 4.5)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(4.5, 4.5)))
.execute().actionGet();
assertHitCount(result, 0);
@ -285,7 +285,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// Point on polygon border
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(10.0, 5.0)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(10.0, 5.0)))
.execute().actionGet();
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
@ -293,7 +293,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// Point on hole border
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(5.0, 2.0)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(5.0, 2.0)))
.execute().actionGet();
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
@ -302,21 +302,21 @@ public class GeoFilterIT extends ESIntegTestCase {
// Point not in polygon
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoDisjointQuery("area", ShapeBuilder.newPoint(3, 3)))
.setPostFilter(QueryBuilders.geoDisjointQuery("area", ShapeBuilders.newPoint(3, 3)))
.execute().actionGet();
assertHitCount(result, 0);
// Point in polygon hole
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoDisjointQuery("area", ShapeBuilder.newPoint(4.5, 4.5)))
.setPostFilter(QueryBuilders.geoDisjointQuery("area", ShapeBuilders.newPoint(4.5, 4.5)))
.execute().actionGet();
assertHitCount(result, 1);
assertFirstHit(result, hasId("1"));
}
// Create a polygon that fills the empty area of the polygon defined above
PolygonBuilder inverse = ShapeBuilder.newPolygon()
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)
@ -330,13 +330,13 @@ public class GeoFilterIT extends ESIntegTestCase {
// re-check point on polygon hole
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(4.5, 4.5)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(4.5, 4.5)))
.execute().actionGet();
assertHitCount(result, 1);
assertFirstHit(result, hasId("2"));
// Create Polygon with hole and common edge
PolygonBuilder builder = ShapeBuilder.newPolygon()
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)
@ -345,7 +345,7 @@ public class GeoFilterIT extends ESIntegTestCase {
if (withinSupport) {
// Polygon WithIn Polygon
builder = ShapeBuilder.newPolygon()
builder = ShapeBuilders.newPolygon()
.point(-30, -30).point(-30, 30).point(30, 30).point(30, -30).close();
result = client().prepareSearch()
@ -356,7 +356,7 @@ public class GeoFilterIT extends ESIntegTestCase {
}
// Create a polygon crossing longitude 180.
builder = ShapeBuilder.newPolygon()
builder = ShapeBuilders.newPolygon()
.point(170, -10).point(190, -10).point(190, 10).point(170, 10)
.close();
@ -365,7 +365,7 @@ public class GeoFilterIT extends ESIntegTestCase {
client().admin().indices().prepareRefresh().execute().actionGet();
// Create a polygon crossing longitude 180 with hole.
builder = ShapeBuilder.newPolygon()
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()
.close();
@ -376,25 +376,25 @@ public class GeoFilterIT extends ESIntegTestCase {
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(174, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(174, -4)))
.execute().actionGet();
assertHitCount(result, 1);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(-174, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(-174, -4)))
.execute().actionGet();
assertHitCount(result, 1);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(180, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(180, -4)))
.execute().actionGet();
assertHitCount(result, 0);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilder.newPoint(180, -6)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", ShapeBuilders.newPoint(180, -6)))
.execute().actionGet();
assertHitCount(result, 1);
}

View File

@ -27,6 +27,7 @@ import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
@ -96,7 +97,7 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
.endObject()
.endObject()));
ShapeBuilder shape = ShapeBuilder.newEnvelope().topLeft(-45, 45).bottomRight(45, -45);
ShapeBuilder shape = ShapeBuilders.newEnvelope().topLeft(-45, 45).bottomRight(45, -45);
SearchResponse searchResponse = client().prepareSearch()
.setQuery(geoIntersectionQuery("location", shape))
@ -141,7 +142,7 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
.endObject()));
ShapeBuilder query = ShapeBuilder.newEnvelope().topLeft(-122.88, 48.62).bottomRight(-122.82, 48.54);
ShapeBuilder query = ShapeBuilders.newEnvelope().topLeft(-122.88, 48.62).bottomRight(-122.82, 48.54);
// This search would fail if both geoshape indexing and geoshape filtering
// used the bottom-level optimization in SpatialPrefixTree#recursiveGetNodes.
@ -166,7 +167,7 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
createIndex("shapes");
ensureGreen();
ShapeBuilder shape = ShapeBuilder.newEnvelope().topLeft(-45, 45).bottomRight(45, -45);
ShapeBuilder shape = ShapeBuilders.newEnvelope().topLeft(-45, 45).bottomRight(45, -45);
indexRandom(true,
client().prepareIndex("shapes", "shape_type", "Big_Rectangle").setSource(jsonBuilder().startObject()
@ -199,13 +200,13 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
}
public void testReusableBuilder() throws IOException {
ShapeBuilder polygon = ShapeBuilder.newPolygon()
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()
.close();
assertUnmodified(polygon);
ShapeBuilder linestring = ShapeBuilder.newLineString()
ShapeBuilder linestring = ShapeBuilders.newLineString()
.point(170, -10).point(190, -10).point(190, 10).point(170, 10);
assertUnmodified(linestring);
}
@ -355,9 +356,9 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
GeoShapeQueryBuilder filter = QueryBuilders.geoShapeQuery(
"location",
ShapeBuilder.newGeometryCollection()
ShapeBuilders.newGeometryCollection()
.polygon(
ShapeBuilder.newPolygon().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0)
ShapeBuilders.newPolygon().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0)
.point(99.0, -1.0))).relation(ShapeRelation.INTERSECTS);
SearchResponse result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
@ -365,17 +366,17 @@ public class GeoShapeIntegrationIT extends ESIntegTestCase {
assertHitCount(result, 1);
filter = QueryBuilders.geoShapeQuery(
"location",
ShapeBuilder.newGeometryCollection().polygon(
ShapeBuilder.newPolygon().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0)
ShapeBuilders.newGeometryCollection().polygon(
ShapeBuilders.newPolygon().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0)
.point(199.0, -11.0))).relation(ShapeRelation.INTERSECTS);
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();
assertSearchResponse(result);
assertHitCount(result, 0);
filter = QueryBuilders.geoShapeQuery("location", ShapeBuilder.newGeometryCollection()
.polygon(ShapeBuilder.newPolygon().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0).point(99.0, -1.0))
filter = QueryBuilders.geoShapeQuery("location", ShapeBuilders.newGeometryCollection()
.polygon(ShapeBuilders.newPolygon().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0).point(99.0, -1.0))
.polygon(
ShapeBuilder.newPolygon().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0)
ShapeBuilders.newPolygon().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0)
.point(199.0, -11.0))).relation(ShapeRelation.INTERSECTS);
result = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(filter).get();