Merge pull request #14482 from cbuescher/remove-internal-linestring-builder

Remove InternalLineStringBuilder and InternalPolygonBuilder
This commit is contained in:
Christoph Büscher 2015-11-20 00:06:04 +01:00
commit aa1507d349
14 changed files with 171 additions and 277 deletions

View File

@ -23,7 +23,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import com.spatial4j.core.shape.ShapeCollection;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.Shape;
@ -34,11 +33,7 @@ import com.vividsolutions.jts.geom.LineString;
public abstract class BaseLineStringBuilder<E extends BaseLineStringBuilder<E>> extends PointCollection<E> { public abstract class BaseLineStringBuilder<E extends BaseLineStringBuilder<E>> extends PointCollection<E> {
protected BaseLineStringBuilder() { public BaseLineStringBuilder(ArrayList<Coordinate> points) {
this(new ArrayList<Coordinate>());
}
protected BaseLineStringBuilder(ArrayList<Coordinate> points) {
super(points); super(points);
} }

View File

@ -51,11 +51,11 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
public static final GeoShapeType TYPE = GeoShapeType.POLYGON; public static final GeoShapeType TYPE = GeoShapeType.POLYGON;
// Linear ring defining the shell of the polygon // line string defining the shell of the polygon
protected Ring<E> shell; protected LineStringBuilder shell;
// List of linear rings defining the holes of the polygon // List of line strings defining the holes of the polygon
protected final ArrayList<BaseLineStringBuilder<?>> holes = new ArrayList<>(); protected final ArrayList<LineStringBuilder> holes = new ArrayList<>();
public BasePolygonBuilder(Orientation orientation) { public BasePolygonBuilder(Orientation orientation) {
super(orientation); super(orientation);
@ -96,27 +96,17 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
* @param hole linear ring defining the hole * @param hole linear ring defining the hole
* @return this * @return this
*/ */
public E hole(BaseLineStringBuilder<?> hole) { public E hole(LineStringBuilder hole) {
holes.add(hole); holes.add(hole);
return thisRef(); return thisRef();
} }
/**
* build new hole to the polygon
* @return this
*/
public Ring<E> hole() {
Ring<E> hole = new Ring<>(thisRef());
this.holes.add(hole);
return hole;
}
/** /**
* Close the shell of the polygon * Close the shell of the polygon
* @return parent
*/ */
public ShapeBuilder close() { public BasePolygonBuilder close() {
return shell.close(); shell.close();
return this;
} }
/** /**
@ -172,7 +162,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
protected XContentBuilder coordinatesArray(XContentBuilder builder, Params params) throws IOException { protected XContentBuilder coordinatesArray(XContentBuilder builder, Params params) throws IOException {
shell.coordinatesToXcontent(builder, true); shell.coordinatesToXcontent(builder, true);
for(BaseLineStringBuilder<?> hole : holes) { for(BaseLineStringBuilder hole : holes) {
hole.coordinatesToXcontent(builder, true); hole.coordinatesToXcontent(builder, true);
} }
return builder; return builder;
@ -207,7 +197,7 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
protected Polygon toPolygon(GeometryFactory factory) { protected Polygon toPolygon(GeometryFactory factory) {
final LinearRing shell = linearRing(factory, this.shell.points); final LinearRing shell = linearRing(factory, this.shell.points);
final LinearRing[] holes = new LinearRing[this.holes.size()]; final LinearRing[] holes = new LinearRing[this.holes.size()];
Iterator<BaseLineStringBuilder<?>> iterator = this.holes.iterator(); Iterator<LineStringBuilder> iterator = this.holes.iterator();
for (int i = 0; iterator.hasNext(); i++) { for (int i = 0; iterator.hasNext(); i++) {
holes[i] = linearRing(factory, iterator.next().points); holes[i] = linearRing(factory, iterator.next().points);
} }
@ -516,8 +506,8 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
} }
} }
private static int createEdges(int component, Orientation orientation, BaseLineStringBuilder<?> shell, private static int createEdges(int component, Orientation orientation, BaseLineStringBuilder shell,
BaseLineStringBuilder<?> hole, BaseLineStringBuilder hole,
Edge[] edges, int offset) { Edge[] edges, int offset) {
// inner rings (holes) have an opposite direction than the outer rings // inner rings (holes) have an opposite direction than the outer rings
// XOR will invert the orientation for outer ring cases (Truth Table:, T/T = F, T/F = T, F/T = T, F/F = F) // XOR will invert the orientation for outer ring cases (Truth Table:, T/T = F, T/F = T, F/T = T, F/F = F)
@ -527,32 +517,4 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
Edge.ring(component, direction, orientation == Orientation.LEFT, shell, points, 0, edges, offset, points.length-1); Edge.ring(component, direction, orientation == Orientation.LEFT, shell, points, 0, edges, offset, points.length-1);
return points.length-1; return points.length-1;
} }
public static class Ring<P extends ShapeBuilder> extends BaseLineStringBuilder<Ring<P>> {
private final P parent;
protected Ring(P parent) {
this(parent, new ArrayList<Coordinate>());
}
protected Ring(P parent, ArrayList<Coordinate> points) {
super(points);
this.parent = parent;
}
public P close() {
Coordinate start = points.get(0);
Coordinate end = points.get(points.size()-1);
if(start.x != end.x || start.y != end.y) {
points.add(start);
}
return parent;
}
@Override
public GeoShapeType type() {
return null;
}
}
} }

View File

@ -57,7 +57,7 @@ public class GeometryCollectionBuilder extends ShapeBuilder {
return this; return this;
} }
public GeometryCollectionBuilder line(BaseLineStringBuilder<?> line) { public GeometryCollectionBuilder line(BaseLineStringBuilder line) {
this.shapes.add(line); this.shapes.add(line);
return this; return this;
} }

View File

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

View File

@ -22,7 +22,6 @@ package org.elasticsearch.common.geo.builders;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.Shape;
import com.spatial4j.core.shape.jts.JtsGeometry;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.LineString;
@ -35,15 +34,9 @@ public class MultiLineStringBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING; public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;
private final ArrayList<BaseLineStringBuilder<?>> lines = new ArrayList<>(); private final ArrayList<LineStringBuilder> lines = new ArrayList<>();
public InternalLineStringBuilder linestring() { public MultiLineStringBuilder linestring(LineStringBuilder line) {
InternalLineStringBuilder line = new InternalLineStringBuilder(this);
this.lines.add(line);
return line;
}
public MultiLineStringBuilder linestring(BaseLineStringBuilder<?> line) {
this.lines.add(line); this.lines.add(line);
return this; return this;
} }
@ -67,7 +60,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
builder.field(FIELD_TYPE, TYPE.shapename); builder.field(FIELD_TYPE, TYPE.shapename);
builder.field(FIELD_COORDINATES); builder.field(FIELD_COORDINATES);
builder.startArray(); builder.startArray();
for(BaseLineStringBuilder<?> line : lines) { for(BaseLineStringBuilder line : lines) {
line.coordinatesToXcontent(builder, false); line.coordinatesToXcontent(builder, false);
} }
builder.endArray(); builder.endArray();
@ -80,7 +73,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
final Geometry geometry; final Geometry geometry;
if(wrapdateline) { if(wrapdateline) {
ArrayList<LineString> parts = new ArrayList<>(); ArrayList<LineString> parts = new ArrayList<>();
for (BaseLineStringBuilder<?> line : lines) { for (BaseLineStringBuilder line : lines) {
BaseLineStringBuilder.decompose(FACTORY, line.coordinates(false), parts); BaseLineStringBuilder.decompose(FACTORY, line.coordinates(false), parts);
} }
if(parts.size() == 1) { if(parts.size() == 1) {
@ -91,7 +84,7 @@ public class MultiLineStringBuilder extends ShapeBuilder {
} }
} else { } else {
LineString[] lineStrings = new LineString[lines.size()]; LineString[] lineStrings = new LineString[lines.size()];
Iterator<BaseLineStringBuilder<?>> iterator = lines.iterator(); Iterator<LineStringBuilder> iterator = lines.iterator();
for (int i = 0; iterator.hasNext(); i++) { for (int i = 0; iterator.hasNext(); i++) {
lineStrings[i] = FACTORY.createLineString(iterator.next().coordinates(false)); lineStrings[i] = FACTORY.createLineString(iterator.next().coordinates(false));
} }
@ -99,27 +92,4 @@ public class MultiLineStringBuilder extends ShapeBuilder {
} }
return jtsGeometry(geometry); return jtsGeometry(geometry);
} }
public static class InternalLineStringBuilder extends BaseLineStringBuilder<InternalLineStringBuilder> {
private final MultiLineStringBuilder collection;
public InternalLineStringBuilder(MultiLineStringBuilder collection) {
super();
this.collection = collection;
}
public MultiLineStringBuilder end() {
return collection;
}
public Coordinate[] coordinates() {
return super.coordinates(false);
}
@Override
public GeoShapeType type() {
return null;
}
}
} }

View File

@ -48,16 +48,6 @@ public class MultiPolygonBuilder extends ShapeBuilder {
return this; return this;
} }
public InternalPolygonBuilder polygon() {
return polygon(Orientation.RIGHT);
}
public InternalPolygonBuilder polygon(Orientation orientation) {
InternalPolygonBuilder polygon = new InternalPolygonBuilder(this, orientation);
this.polygon(polygon);
return polygon;
}
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
@ -100,20 +90,5 @@ public class MultiPolygonBuilder extends ShapeBuilder {
//note: ShapeCollection is probably faster than a Multi* geom. //note: ShapeCollection is probably faster than a Multi* geom.
} }
public static class InternalPolygonBuilder extends BasePolygonBuilder<InternalPolygonBuilder> {
private final MultiPolygonBuilder collection;
private InternalPolygonBuilder(MultiPolygonBuilder collection, Orientation orientation) {
super(orientation);
this.collection = collection;
this.shell = new Ring<>(this);
}
@Override
public MultiPolygonBuilder close() {
super.close();
return collection;
}
}
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -41,7 +41,7 @@ import org.elasticsearch.common.Priority;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.geo.builders.LineStringBuilder;
import org.elasticsearch.common.geo.builders.MultiPolygonBuilder; import org.elasticsearch.common.geo.builders.MultiPolygonBuilder;
import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.geo.builders.ShapeBuilders;
@ -129,17 +129,17 @@ public class GeoFilterIT extends ESIntegTestCase {
// polygon with hole // polygon with hole
ShapeBuilders.newPolygon() ShapeBuilders.newPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole() .hole(new LineStringBuilder()
.point(-5, -5).point(-5, 5).point(5, 5).point(5, -5) .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
.close().close().build(); .close()).close().build();
try { try {
// polygon with overlapping hole // polygon with overlapping hole
ShapeBuilders.newPolygon() ShapeBuilders.newPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole() .hole(new LineStringBuilder()
.point(-5, -5).point(-5, 11).point(5, 11).point(5, -5) .point(-5, -5).point(-5, 11).point(5, 11).point(5, -5)
.close().close().build(); .close()).close().build();
fail("Self intersection not detected"); fail("Self intersection not detected");
} catch (InvalidShapeException e) { } catch (InvalidShapeException e) {
@ -149,12 +149,12 @@ public class GeoFilterIT extends ESIntegTestCase {
// polygon with intersection holes // polygon with intersection holes
ShapeBuilders.newPolygon() ShapeBuilders.newPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole() .hole(new LineStringBuilder()
.point(-5, -5).point(-5, 5).point(5, 5).point(5, -5) .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
.close() .close())
.hole() .hole(new LineStringBuilder()
.point(-5, -6).point(5, -6).point(5, -4).point(-5, -4) .point(-5, -6).point(5, -6).point(5, -4).point(-5, -4)
.close() .close())
.close().build(); .close().build();
fail("Intersection of holes not detected"); fail("Intersection of holes not detected");
} catch (InvalidShapeException e) { } catch (InvalidShapeException e) {
@ -175,52 +175,27 @@ public class GeoFilterIT extends ESIntegTestCase {
} catch (InvalidShapeException e) { } catch (InvalidShapeException e) {
} }
// Not specified
// try {
// // two overlapping polygons within a multipolygon
// ShapeBuilder.newMultiPolygon()
// .polygon()
// .point(-10, -10)
// .point(-10, 10)
// .point(10, 10)
// .point(10, -10)
// .close()
// .polygon()
// .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
// .close().build();
// fail("Polygon intersection not detected";
// } catch (InvalidShapeException e) {}
// Multipolygon: polygon with hole and polygon within the whole // Multipolygon: polygon with hole and polygon within the whole
ShapeBuilders.newMultiPolygon() ShapeBuilders
.polygon() .newMultiPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .polygon(new PolygonBuilder()
.hole() .point(-10, -10)
.point(-5, -5).point(-5, 5).point(5, 5).point(5, -5) .point(-10, 10)
.close() .point(10, 10)
.close() .point(10, -10)
.polygon() .hole(new LineStringBuilder().point(-5, -5)
.point(-4, -4).point(-4, 4).point(4, 4).point(4, -4) .point(-5, 5)
.close() .point(5, 5)
.point(5, -5)
.close())
.close())
.polygon(new PolygonBuilder()
.point(-4, -4)
.point(-4, 4)
.point(4, 4)
.point(4, -4)
.close())
.build(); .build();
// Not supported
// try {
// // Multipolygon: polygon with hole and polygon within the hole but overlapping
// ShapeBuilder.newMultiPolygon()
// .polygon()
// .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
// .hole()
// .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
// .close()
// .close()
// .polygon()
// .point(-4, -4).point(-4, 6).point(4, 6).point(4, -4)
// .close()
// .build();
// fail("Polygon intersection not detected";
// } catch (InvalidShapeException e) {}
} }
public void testShapeRelations() throws Exception { public void testShapeRelations() throws Exception {
@ -248,15 +223,13 @@ public class GeoFilterIT extends ESIntegTestCase {
// with a hole of size 5x5 equidistant from all sides. This hole in turn contains // 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 // the second polygon of size 4x4 equidistant from all sites
MultiPolygonBuilder polygon = ShapeBuilders.newMultiPolygon() MultiPolygonBuilder polygon = ShapeBuilders.newMultiPolygon()
.polygon() .polygon(new PolygonBuilder()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole() .hole(new LineStringBuilder()
.point(-5, -5).point(-5, 5).point(5, 5).point(5, -5) .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close())
.close() .close())
.close() .polygon(new PolygonBuilder()
.polygon() .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close());
.point(-4, -4).point(-4, 4).point(4, 4).point(4, -4)
.close();
BytesReference data = jsonBuilder().startObject().field("area", polygon).endObject().bytes(); BytesReference data = jsonBuilder().startObject().field("area", polygon).endObject().bytes();
@ -318,9 +291,8 @@ public class GeoFilterIT extends ESIntegTestCase {
// Create a polygon that fills the empty area of the polygon defined above // Create a polygon that fills the empty area of the polygon defined above
PolygonBuilder inverse = ShapeBuilders.newPolygon() PolygonBuilder inverse = ShapeBuilders.newPolygon()
.point(-5, -5).point(-5, 5).point(5, 5).point(5, -5) .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5)
.hole() .hole(new LineStringBuilder()
.point(-4, -4).point(-4, 4).point(4, 4).point(4, -4) .point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close())
.close()
.close(); .close();
data = jsonBuilder().startObject().field("area", inverse).endObject().bytes(); data = jsonBuilder().startObject().field("area", inverse).endObject().bytes();
@ -338,9 +310,8 @@ public class GeoFilterIT extends ESIntegTestCase {
// Create Polygon with hole and common edge // Create Polygon with hole and common edge
PolygonBuilder builder = ShapeBuilders.newPolygon() PolygonBuilder builder = ShapeBuilders.newPolygon()
.point(-10, -10).point(-10, 10).point(10, 10).point(10, -10) .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10)
.hole() .hole(new LineStringBuilder()
.point(-5, -5).point(-5, 5).point(10, 5).point(10, -5) .point(-5, -5).point(-5, 5).point(10, 5).point(10, -5).close())
.close()
.close(); .close();
if (withinSupport) { if (withinSupport) {
@ -367,7 +338,7 @@ public class GeoFilterIT extends ESIntegTestCase {
// Create a polygon crossing longitude 180 with hole. // Create a polygon crossing longitude 180 with hole.
builder = ShapeBuilders.newPolygon() builder = ShapeBuilders.newPolygon()
.point(170, -10).point(190, -10).point(190, 10).point(170, 10) .point(170, -10).point(190, -10).point(190, 10).point(170, 10)
.hole().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close() .hole(new LineStringBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close())
.close(); .close();
data = jsonBuilder().startObject().field("area", builder).endObject().bytes(); data = jsonBuilder().startObject().field("area", builder).endObject().bytes();

View File

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

View File

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