Remove PROTOTYPE from ShapeBuilders

Also cuts lots of tests over to expectThrows and fixes DistanceUnit's
serialization.
This commit is contained in:
Nik Everett 2016-03-24 13:19:19 -04:00
parent ee49081bc7
commit 9402251eaf
24 changed files with 281 additions and 341 deletions

View File

@ -349,9 +349,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]cli[/\\]CheckFileCommand.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]collect[/\\]ImmutableOpenIntMap.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]GeoDistance.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]LineStringBuilder.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]PolygonBuilder.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]ShapeBuilder.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]inject[/\\]DefaultConstructionProxyFactory.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]inject[/\\]InjectorImpl.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]inject[/\\]internal[/\\]ConstructionContext.java" checks="LineLength" />
@ -1064,9 +1061,6 @@
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]blobstore[/\\]FsBlobStoreTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]breaker[/\\]MemoryCircuitBreakerTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]ShapeBuilderTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]AbstractShapeBuilderTestCase.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]EnvelopeBuilderTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]geo[/\\]builders[/\\]PolygonBuilderTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]hash[/\\]MessageDigestsTests.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]inject[/\\]ModuleTestCase.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]io[/\\]stream[/\\]BytesStreamsTests.java" checks="LineLength" />

View File

@ -36,8 +36,6 @@ public class CircleBuilder extends ShapeBuilder {
public static final String FIELD_RADIUS = "radius";
public static final GeoShapeType TYPE = GeoShapeType.CIRCLE;
public static final CircleBuilder PROTOTYPE = new CircleBuilder();
private DistanceUnit unit = DistanceUnit.DEFAULT;
private double radius;
private Coordinate center;
@ -50,6 +48,21 @@ public class CircleBuilder extends ShapeBuilder {
this.center = ZERO_ZERO;
}
/**
* Read from a stream.
*/
public CircleBuilder(StreamInput in) throws IOException {
center(readFromStream(in));
radius(in.readDouble(), DistanceUnit.readFromStream(in));;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(center, out);
out.writeDouble(radius);
unit.writeTo(out);
}
/**
* Set the center of the circle
*
@ -170,18 +183,4 @@ public class CircleBuilder extends ShapeBuilder {
Objects.equals(radius, other.radius) &&
Objects.equals(unit.ordinal(), other.unit.ordinal());
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(center, out);
out.writeDouble(radius);
DistanceUnit.writeDistanceUnit(out, unit);
}
@Override
public CircleBuilder readFrom(StreamInput in) throws IOException {
return new CircleBuilder()
.center(readCoordinateFrom(in))
.radius(in.readDouble(), DistanceUnit.readDistanceUnit(in));
}
}

View File

@ -21,9 +21,12 @@ package org.elasticsearch.common.geo.builders;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -48,6 +51,25 @@ public abstract class CoordinateCollection<E extends CoordinateCollection<E>> ex
this.coordinates = coordinates;
}
/**
* Read from a stream.
*/
protected CoordinateCollection(StreamInput in) throws IOException {
int size = in.readVInt();
coordinates = new ArrayList<>(size);
for (int i=0; i < size; i++) {
coordinates.add(readFromStream(in));
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(coordinates.size());
for (Coordinate point : coordinates) {
writeCoordinateTo(point, out);
}
}
@SuppressWarnings("unchecked")
private E thisRef() {
return (E)this;

View File

@ -33,11 +33,12 @@ public class EnvelopeBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE;
public static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0));
private Coordinate topLeft;
private Coordinate bottomRight;
private final Coordinate topLeft;
private final Coordinate bottomRight;
/**
* Build an envelope from the top left and bottom right coordinates.
*/
public EnvelopeBuilder(Coordinate topLeft, Coordinate bottomRight) {
Objects.requireNonNull(topLeft, "topLeft of envelope cannot be null");
Objects.requireNonNull(bottomRight, "bottomRight of envelope cannot be null");
@ -45,6 +46,20 @@ public class EnvelopeBuilder extends ShapeBuilder {
this.bottomRight = bottomRight;
}
/**
* Read from a stream.
*/
public EnvelopeBuilder(StreamInput in) throws IOException {
topLeft = readFromStream(in);
bottomRight = readFromStream(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(topLeft, out);
writeCoordinateTo(bottomRight, out);
}
public Coordinate topLeft() {
return this.topLeft;
}
@ -91,15 +106,4 @@ public class EnvelopeBuilder extends ShapeBuilder {
return Objects.equals(topLeft, other.topLeft) &&
Objects.equals(bottomRight, other.bottomRight);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(topLeft, out);
writeCoordinateTo(bottomRight, out);
}
@Override
public EnvelopeBuilder readFrom(StreamInput in) throws IOException {
return new EnvelopeBuilder(readCoordinateFrom(in), readCoordinateFrom(in));
}
}

View File

@ -36,9 +36,34 @@ public class GeometryCollectionBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION;
public static final GeometryCollectionBuilder PROTOTYPE = new GeometryCollectionBuilder();
/**
* List of shapes. Package scope for testing.
*/
final List<ShapeBuilder> shapes = new ArrayList<>();
protected final ArrayList<ShapeBuilder> shapes = new ArrayList<>();
/**
* Build and empty GeometryCollectionBuilder.
*/
public GeometryCollectionBuilder() {
}
/**
* Read from a stream.
*/
public GeometryCollectionBuilder(StreamInput in) throws IOException {
int shapes = in.readVInt();
for (int i = 0; i < shapes; i++) {
shape(in.readShape());
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(shapes.size());
for (ShapeBuilder shape : shapes) {
out.writeShape(shape);
}
}
public GeometryCollectionBuilder shape(ShapeBuilder shape) {
this.shapes.add(shape);
@ -146,23 +171,4 @@ public class GeometryCollectionBuilder extends ShapeBuilder {
GeometryCollectionBuilder other = (GeometryCollectionBuilder) obj;
return Objects.equals(shapes, other.shapes);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(shapes.size());
for (ShapeBuilder shape : shapes) {
out.writeShape(shape);
}
}
@Override
public GeometryCollectionBuilder readFrom(StreamInput in) throws IOException {
GeometryCollectionBuilder geometryCollectionBuilder = new GeometryCollectionBuilder();
int shapes = in.readVInt();
for (int i = 0; i < shapes; i++) {
geometryCollectionBuilder.shape(in.readShape());
}
return geometryCollectionBuilder;
}
}

View File

@ -19,15 +19,14 @@
package org.elasticsearch.common.geo.builders;
import org.locationtech.spatial4j.shape.Shape;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.locationtech.spatial4j.shape.Shape;
import java.io.IOException;
import java.util.ArrayList;
@ -36,6 +35,7 @@ import java.util.List;
import java.util.Objects;
public class LineStringBuilder extends CoordinateCollection<LineStringBuilder> {
public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;
/**
* Construct a new LineString.
@ -55,9 +55,12 @@ public class LineStringBuilder extends CoordinateCollection<LineStringBuilder> {
this(coordinates.build());
}
public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;
public static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(1.0, 1.0));
/**
* Read from a stream.
*/
public LineStringBuilder(StreamInput in) throws IOException {
super(in);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
@ -182,23 +185,4 @@ public class LineStringBuilder extends CoordinateCollection<LineStringBuilder> {
LineStringBuilder other = (LineStringBuilder) obj;
return Objects.equals(coordinates, other.coordinates);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(coordinates.size());
for (Coordinate point : coordinates) {
writeCoordinateTo(point, out);
}
}
@Override
public LineStringBuilder readFrom(StreamInput in) throws IOException {
CoordinatesBuilder coordinates = new CoordinatesBuilder();
int size = in.readVInt();
for (int i=0; i < size; i++) {
coordinates.coordinate(readCoordinateFrom(in));
}
LineStringBuilder lineStringBuilder = new LineStringBuilder(coordinates);
return lineStringBuilder;
}
}

View File

@ -37,10 +37,29 @@ public class MultiLineStringBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;
public static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder();
private final ArrayList<LineStringBuilder> lines = new ArrayList<>();
public MultiLineStringBuilder() {
}
/**
* Read from a stream.
*/
public MultiLineStringBuilder(StreamInput in) throws IOException {
int size = in.readVInt();
for (int i = 0; i < size; i++) {
linestring(new LineStringBuilder(in));
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(lines.size());
for (LineStringBuilder line : lines) {
line.writeTo(out);
}
}
public MultiLineStringBuilder linestring(LineStringBuilder line) {
this.lines.add(line);
return this;
@ -114,22 +133,4 @@ public class MultiLineStringBuilder extends ShapeBuilder {
MultiLineStringBuilder other = (MultiLineStringBuilder) obj;
return Objects.equals(lines, other.lines);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(lines.size());
for (LineStringBuilder line : lines) {
line.writeTo(out);
}
}
@Override
public MultiLineStringBuilder readFrom(StreamInput in) throws IOException {
MultiLineStringBuilder multiLineStringBuilder = new MultiLineStringBuilder();
int size = in.readVInt();
for (int i = 0; i < size; i++) {
multiLineStringBuilder.linestring(LineStringBuilder.PROTOTYPE.readFrom(in));
}
return multiLineStringBuilder;
}
}

View File

@ -19,14 +19,13 @@
package org.elasticsearch.common.geo.builders;
import org.locationtech.spatial4j.shape.Point;
import org.locationtech.spatial4j.shape.Shape;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.common.geo.XShapeCollection;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.locationtech.spatial4j.shape.Point;
import org.locationtech.spatial4j.shape.Shape;
import java.io.IOException;
import java.util.ArrayList;
@ -37,8 +36,6 @@ public class MultiPointBuilder extends CoordinateCollection<MultiPointBuilder> {
public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT;
public static final MultiPointBuilder PROTOTYPE = new MultiPointBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).build());
/**
* Create a new {@link MultiPointBuilder}.
* @param coordinates needs at least two coordinates to be valid, otherwise will throw an exception
@ -47,6 +44,13 @@ public class MultiPointBuilder extends CoordinateCollection<MultiPointBuilder> {
super(coordinates);
}
/**
* Read from a stream.
*/
public MultiPointBuilder(StreamInput in) throws IOException {
super(in);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
@ -91,24 +95,4 @@ public class MultiPointBuilder extends CoordinateCollection<MultiPointBuilder> {
MultiPointBuilder other = (MultiPointBuilder) obj;
return Objects.equals(coordinates, other.coordinates);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(coordinates.size());
for (Coordinate point : coordinates) {
writeCoordinateTo(point, out);
}
}
@Override
public MultiPointBuilder readFrom(StreamInput in) throws IOException {
int size = in.readVInt();
List<Coordinate> points = new ArrayList<Coordinate>(size);
for (int i=0; i < size; i++) {
points.add(readCoordinateFrom(in));
}
MultiPointBuilder multiPointBuilder = new MultiPointBuilder(points);
return multiPointBuilder;
}
}

View File

@ -36,20 +36,45 @@ import java.util.Objects;
public class MultiPolygonBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.MULTIPOLYGON;
public static final MultiPolygonBuilder PROTOTYPE = new MultiPolygonBuilder();
private final ArrayList<PolygonBuilder> polygons = new ArrayList<>();
private final List<PolygonBuilder> polygons = new ArrayList<>();
private Orientation orientation = Orientation.RIGHT;
private final Orientation orientation;
/**
* Build a MultiPolygonBuilder with RIGHT orientation.
*/
public MultiPolygonBuilder() {
this(Orientation.RIGHT);
}
/**
* Build a MultiPolygonBuilder with an arbitrary orientation.
*/
public MultiPolygonBuilder(Orientation orientation) {
this.orientation = orientation;
}
/**
* Read from a stream.
*/
public MultiPolygonBuilder(StreamInput in) throws IOException {
orientation = Orientation.readFrom(in);
int holes = in.readVInt();
for (int i = 0; i < holes; i++) {
polygon(new PolygonBuilder(in));
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
orientation.writeTo(out);
out.writeVInt(polygons.size());
for (PolygonBuilder polygon : polygons) {
polygon.writeTo(out);
}
}
public Orientation orientation() {
return this.orientation;
}
@ -70,7 +95,7 @@ public class MultiPolygonBuilder extends ShapeBuilder {
/**
* get the list of polygons
*/
public ArrayList<PolygonBuilder> polygons() {
public List<PolygonBuilder> polygons() {
return polygons;
}
@ -134,23 +159,4 @@ public class MultiPolygonBuilder extends ShapeBuilder {
return Objects.equals(polygons, other.polygons) &&
Objects.equals(orientation, other.orientation);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
orientation.writeTo(out);
out.writeVInt(polygons.size());
for (PolygonBuilder polygon : polygons) {
polygon.writeTo(out);
}
}
@Override
public MultiPolygonBuilder readFrom(StreamInput in) throws IOException {
MultiPolygonBuilder polyBuilder = new MultiPolygonBuilder(Orientation.readFrom(in));
int holes = in.readVInt();
for (int i = 0; i < holes; i++) {
polyBuilder.polygon(PolygonBuilder.PROTOTYPE.readFrom(in));
}
return polyBuilder;
}
}

View File

@ -30,9 +30,7 @@ import java.io.IOException;
import java.util.Objects;
public class PointBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.POINT;
public static final PointBuilder PROTOTYPE = new PointBuilder();
private Coordinate coordinate;
@ -43,6 +41,18 @@ public class PointBuilder extends ShapeBuilder {
this.coordinate = ZERO_ZERO;
}
/**
* Read from a stream.
*/
public PointBuilder(StreamInput in) throws IOException {
coordinate = readFromStream(in);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(coordinate, out);
}
public PointBuilder coordinate(Coordinate coordinate) {
this.coordinate = coordinate;
return this;
@ -91,14 +101,4 @@ public class PointBuilder extends ShapeBuilder {
PointBuilder other = (PointBuilder) obj;
return Objects.equals(coordinate, other.coordinate);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeCoordinateTo(coordinate, out);
}
@Override
public PointBuilder readFrom(StreamInput in) throws IOException {
return new PointBuilder().coordinate(readCoordinateFrom(in));
}
}

View File

@ -53,8 +53,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class PolygonBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.POLYGON;
public static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(0.0, 1.0)
.coordinate(1.0, 0.0).coordinate(0.0, 0.0));
private static final Coordinate[][] EMPTY = new Coordinate[0][];
@ -64,7 +62,7 @@ public class PolygonBuilder extends ShapeBuilder {
private LineStringBuilder shell;
// List of line strings defining the holes of the polygon
private final ArrayList<LineStringBuilder> holes = new ArrayList<>();
private final List<LineStringBuilder> holes = new ArrayList<>();
public PolygonBuilder(LineStringBuilder lineString, Orientation orientation, boolean coerce) {
this.orientation = orientation;
@ -87,6 +85,28 @@ public class PolygonBuilder extends ShapeBuilder {
this(coordinates, Orientation.RIGHT);
}
/**
* Read from a stream.
*/
public PolygonBuilder(StreamInput in) throws IOException {
shell = new LineStringBuilder(in);
orientation = Orientation.readFrom(in);
int holes = in.readVInt();
for (int i = 0; i < holes; i++) {
hole(new LineStringBuilder(in));
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
shell.writeTo(out);
orientation.writeTo(out);
out.writeVInt(holes.size());
for (LineStringBuilder hole : holes) {
hole.writeTo(out);
}
}
public Orientation orientation() {
return this.orientation;
}
@ -383,10 +403,10 @@ public class PolygonBuilder extends ShapeBuilder {
return coordinates;
}
private static Coordinate[][][] buildCoordinates(ArrayList<ArrayList<Coordinate[]>> components) {
private static Coordinate[][][] buildCoordinates(List<List<Coordinate[]>> components) {
Coordinate[][][] result = new Coordinate[components.size()][][];
for (int i = 0; i < result.length; i++) {
ArrayList<Coordinate[]> component = components.get(i);
List<Coordinate[]> component = components.get(i);
result[i] = component.toArray(new Coordinate[component.size()][]);
}
@ -416,13 +436,13 @@ public class PolygonBuilder extends ShapeBuilder {
return points;
}
private static Edge[] edges(Edge[] edges, int numHoles, ArrayList<ArrayList<Coordinate[]>> components) {
private static Edge[] edges(Edge[] edges, int numHoles, List<List<Coordinate[]>> components) {
ArrayList<Edge> mainEdges = new ArrayList<>(edges.length);
for (int i = 0; i < edges.length; i++) {
if (edges[i].component >= 0) {
int length = component(edges[i], -(components.size()+numHoles+1), mainEdges);
ArrayList<Coordinate[]> component = new ArrayList<>();
List<Coordinate[]> component = new ArrayList<>();
component.add(coordinates(edges[i], new Coordinate[length+1]));
components.add(component);
}
@ -432,12 +452,12 @@ public class PolygonBuilder extends ShapeBuilder {
}
private static Coordinate[][][] compose(Edge[] edges, Edge[] holes, int numHoles) {
final ArrayList<ArrayList<Coordinate[]>> components = new ArrayList<>();
final List<List<Coordinate[]>> components = new ArrayList<>();
assign(holes, holes(holes, numHoles), numHoles, edges(edges, numHoles, components), components);
return buildCoordinates(components);
}
private static void assign(Edge[] holes, Coordinate[][] points, int numHoles, Edge[] edges, ArrayList<ArrayList<Coordinate[]>> components) {
private static void assign(Edge[] holes, Coordinate[][] points, int numHoles, Edge[] edges, List<List<Coordinate[]>> components) {
// Assign Hole to related components
// To find the new component the hole belongs to all intersections of the
// polygon edges with a vertical line are calculated. This vertical line
@ -668,8 +688,8 @@ public class PolygonBuilder extends ShapeBuilder {
* number of points to use
* @return the edges creates
*/
private static Edge[] concat(int component, boolean direction, Coordinate[] points, final int pointOffset, Edge[] edges, final int edgeOffset,
int length) {
private static Edge[] concat(int component, boolean direction, Coordinate[] points, final int pointOffset, Edge[] edges,
final int edgeOffset, int length) {
assert edges.length >= length+edgeOffset;
assert points.length >= length+pointOffset;
edges[edgeOffset] = new Edge(points[pointOffset], null);
@ -725,26 +745,4 @@ public class PolygonBuilder extends ShapeBuilder {
Objects.equals(holes, other.holes) &&
Objects.equals(orientation, other.orientation);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
shell.writeTo(out);
orientation.writeTo(out);
out.writeVInt(holes.size());
for (LineStringBuilder hole : holes) {
hole.writeTo(out);
}
}
@Override
public PolygonBuilder readFrom(StreamInput in) throws IOException {
LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in);
Orientation orientation = Orientation.readFrom(in);
PolygonBuilder polyBuilder = new PolygonBuilder(shell, orientation);
int holes = in.readVInt();
for (int i = 0; i < holes; i++) {
polyBuilder.hole(LineStringBuilder.PROTOTYPE.readFrom(in));
}
return polyBuilder;
}
}

View File

@ -180,7 +180,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
out.writeDouble(coordinate.y);
}
protected Coordinate readCoordinateFrom(StreamInput in) throws IOException {
protected static Coordinate readFromStream(StreamInput in) throws IOException {
return new Coordinate(in.readDouble(), in.readDouble());
}
@ -519,7 +519,8 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
} else if (geometryCollections == null && GeoShapeType.GEOMETRYCOLLECTION == shapeType) {
throw new ElasticsearchParseException("geometries not included");
} else if (radius != null && GeoShapeType.CIRCLE != shapeType) {
throw new ElasticsearchParseException("field [{}] is supported for [{}] only", CircleBuilder.FIELD_RADIUS, CircleBuilder.TYPE);
throw new ElasticsearchParseException("field [{}] is supported for [{}] only", CircleBuilder.FIELD_RADIUS,
CircleBuilder.TYPE);
}
switch (shapeType) {
@ -539,7 +540,8 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
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])");
throw new ElasticsearchParseException(
"invalid number of points (0) provided when expecting a single coordinate ([lat, lng])");
} else if (node.coordinate == null) {
if (node.children.isEmpty() == false) {
throw new ElasticsearchParseException("multipoint data provided when single point data expected.");
@ -559,8 +561,9 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
protected static EnvelopeBuilder parseEnvelope(CoordinateNode coordinates) {
// validate the coordinate array for envelope type
if (coordinates.children.size() != 2) {
throw new ElasticsearchParseException("invalid number of points [{}] provided for " +
"geo_shape [{}] when expecting an array of 2 coordinates", coordinates.children.size(), GeoShapeType.ENVELOPE.shapename);
throw new ElasticsearchParseException(
"invalid number of points [{}] provided for geo_shape [{}] when expecting an array of 2 coordinates",
coordinates.children.size(), GeoShapeType.ENVELOPE.shapename);
}
// verify coordinate bounds, correct if necessary
Coordinate uL = coordinates.children.get(0).coordinate;
@ -604,7 +607,8 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
* LineStringBuilder should throw a graceful exception if < 2 coordinates/points are provided
*/
if (coordinates.children.size() < 2) {
throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)", coordinates.children.size());
throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)",
coordinates.children.size());
}
CoordinatesBuilder line = new CoordinatesBuilder();
@ -636,10 +640,10 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
throw new ElasticsearchParseException(error);
}
int numValidPts;
if (coordinates.children.size() < (numValidPts = (coerce) ? 3 : 4)) {
throw new ElasticsearchParseException("invalid number of points in LinearRing (found [{}] - must be >= " + numValidPts + ")(",
coordinates.children.size());
int numValidPts = coerce ? 3 : 4;
if (coordinates.children.size() < numValidPts) {
throw new ElasticsearchParseException("invalid number of points in LinearRing (found [{}] - must be >= [{}])",
coordinates.children.size(), numValidPts);
}
if (!coordinates.children.get(0).coordinate.equals(
@ -655,7 +659,8 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri
protected static PolygonBuilder parsePolygon(CoordinateNode coordinates, final Orientation orientation, final boolean coerce) {
if (coordinates.children == null || coordinates.children.isEmpty()) {
throw new ElasticsearchParseException("invalid LinearRing provided for type polygon. Linear ring must be an array of coordinates");
throw new ElasticsearchParseException(
"invalid LinearRing provided for type polygon. Linear ring must be an array of coordinates");
}
LineStringBuilder shell = parseLinearRing(coordinates.children.get(0), coerce);

View File

@ -21,6 +21,8 @@ package org.elasticsearch.common.geo.builders;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import java.util.List;
/**
@ -137,4 +139,16 @@ public class ShapeBuilders {
public static EnvelopeBuilder newEnvelope(Coordinate topLeft, Coordinate bottomRight) {
return new EnvelopeBuilder(topLeft, bottomRight);
}
public static void register(NamedWriteableRegistry namedWriteableRegistry) {
namedWriteableRegistry.register(ShapeBuilder.class, PointBuilder.TYPE.shapeName(), PointBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, CircleBuilder.TYPE.shapeName(), CircleBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, EnvelopeBuilder.TYPE.shapeName(), EnvelopeBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, MultiPointBuilder.TYPE.shapeName(), MultiPointBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, LineStringBuilder.TYPE.shapeName(), LineStringBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, MultiLineStringBuilder.TYPE.shapeName(), MultiLineStringBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, PolygonBuilder.TYPE.shapeName(), PolygonBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, MultiPolygonBuilder.TYPE.shapeName(), MultiPolygonBuilder::new);
namedWriteableRegistry.register(ShapeBuilder.class, GeometryCollectionBuilder.TYPE.shapeName(), GeometryCollectionBuilder::new);
}
}

View File

@ -210,34 +210,6 @@ public enum DistanceUnit implements Writeable<DistanceUnit> {
return defaultUnit;
}
/**
* Write a {@link DistanceUnit} to a {@link StreamOutput}
*
* @param out {@link StreamOutput} to write to
* @param unit {@link DistanceUnit} to write
*/
public static void writeDistanceUnit(StreamOutput out, DistanceUnit unit) throws IOException {
out.writeByte((byte) unit.ordinal());
}
/**
* Read a {@link DistanceUnit} from a {@link StreamInput}
*
* @param in {@link StreamInput} to read the {@link DistanceUnit} from
* @return {@link DistanceUnit} read from the {@link StreamInput}
* @throws IOException if no unit can be read from the {@link StreamInput}
* @throws IllegalArgumentException if no matching {@link DistanceUnit} can be found
*/
public static DistanceUnit readDistanceUnit(StreamInput in) throws IOException {
byte b = in.readByte();
if(b<0 || b>=values().length) {
throw new IllegalArgumentException("No type for distance unit matching [" + b + "]");
} else {
return values()[b];
}
}
/**
* This class implements a value+unit tuple.
*/
@ -324,23 +296,30 @@ public enum DistanceUnit implements Writeable<DistanceUnit> {
}
}
private static final DistanceUnit PROTOTYPE = DEFAULT;
/**
* Read a {@link DistanceUnit} from a {@link StreamInput}.
*
* @param in {@link StreamInput} to read the {@link DistanceUnit} from
* @return {@link DistanceUnit} read from the {@link StreamInput}
* @throws IOException if no unit can be read from the {@link StreamInput}
* @throws IllegalArgumentException if no matching {@link DistanceUnit} can be found
*/
public static DistanceUnit readFromStream(StreamInput in) throws IOException {
byte b = in.readByte();
@Override
public DistanceUnit readFrom(StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown DistanceUnit ordinal [" + ordinal + "]");
if (b < 0 || b >= values().length) {
throw new IllegalArgumentException("No type for distance unit matching [" + b + "]");
}
return values()[ordinal];
}
public static DistanceUnit readUnitFrom(StreamInput in) throws IOException {
return PROTOTYPE.readFrom(in);
return values()[b];
}
/**
* Write a {@link DistanceUnit} to a {@link StreamOutput}.
*
* @param out {@link StreamOutput} to write to
*/
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(this.ordinal());
out.writeByte((byte) this.ordinal());
}
}

View File

@ -21,21 +21,13 @@ package org.elasticsearch.search;
import org.apache.lucene.search.BooleanQuery;
import org.elasticsearch.common.geo.ShapesAvailability;
import org.elasticsearch.common.geo.builders.CircleBuilder;
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.geo.builders.ShapeBuilder;
import org.elasticsearch.common.geo.builders.ShapeBuilders;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.percolator.PercolatorHighlightSubFetchPhase;
import org.elasticsearch.index.query.BoolQueryParser;
import org.elasticsearch.index.query.BoostingQueryParser;
import org.elasticsearch.index.query.CommonTermsQueryParser;
@ -216,7 +208,6 @@ import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.innerhits.InnerHitsFetchSubPhase;
import org.elasticsearch.search.fetch.matchedqueries.MatchedQueriesFetchSubPhase;
import org.elasticsearch.search.fetch.parent.ParentFieldSubFetchPhase;
import org.elasticsearch.index.percolator.PercolatorHighlightSubFetchPhase;
import org.elasticsearch.search.fetch.script.ScriptFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.source.FetchSourceSubPhase;
import org.elasticsearch.search.fetch.version.VersionFetchSubPhase;
@ -479,15 +470,7 @@ public class SearchModule extends AbstractModule {
private void configureShapes() {
if (ShapesAvailability.JTS_AVAILABLE && ShapesAvailability.SPATIAL4J_AVAILABLE) {
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, CircleBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, EnvelopeBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, LineStringBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiLineStringBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PolygonBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPolygonBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, GeometryCollectionBuilder.PROTOTYPE);
ShapeBuilders.register(namedWriteableRegistry);
}
}

View File

@ -211,7 +211,7 @@ public class GeoDistanceAggregatorBuilder extends ValuesSourceAggregatorBuilder<
}
factory.keyed = in.readBoolean();
factory.distanceType = GeoDistance.readGeoDistanceFrom(in);
factory.unit = DistanceUnit.readDistanceUnit(in);
factory.unit = DistanceUnit.readFromStream(in);
return factory;
}
@ -225,7 +225,7 @@ public class GeoDistanceAggregatorBuilder extends ValuesSourceAggregatorBuilder<
}
out.writeBoolean(keyed);
distanceType.writeTo(out);
DistanceUnit.writeDistanceUnit(out, unit);
unit.writeTo(out);
}
@Override

View File

@ -154,7 +154,7 @@ public class GeoDistanceSortBuilder extends SortBuilder<GeoDistanceSortBuilder>
fieldName = in.readString();
points.addAll((List<GeoPoint>) in.readGenericValue());
geoDistance = GeoDistance.readGeoDistanceFrom(in);
unit = DistanceUnit.readDistanceUnit(in);
unit = DistanceUnit.readFromStream(in);
order = SortOrder.readFromStream(in);
sortMode = in.readOptionalWriteable(SortMode::readFromStream);
nestedFilter = in.readOptionalQuery();

View File

@ -50,15 +50,7 @@ public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder> exte
public static void init() {
if (namedWriteableRegistry == null) {
namedWriteableRegistry = new NamedWriteableRegistry();
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, CircleBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, EnvelopeBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, LineStringBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiLineStringBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PolygonBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPolygonBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, GeometryCollectionBuilder.PROTOTYPE);
ShapeBuilders.register(namedWriteableRegistry);
}
}

View File

@ -19,30 +19,21 @@
package org.elasticsearch.common.geo.builders;
import org.locationtech.spatial4j.shape.Rectangle;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.locationtech.spatial4j.shape.Rectangle;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
public class EnvelopeBuilderTests extends AbstractShapeBuilderTestCase<EnvelopeBuilder> {
public void testInvalidConstructorArgs() {
try {
new EnvelopeBuilder(null, new Coordinate(1.0, -1.0));
fail("Exception expected");
} catch (NullPointerException e) {
assertThat("topLeft of envelope cannot be null", equalTo(e.getMessage()));
}
try {
new EnvelopeBuilder(new Coordinate(1.0, -1.0), null);
fail("Exception expected");
} catch (NullPointerException e) {
assertThat("bottomRight of envelope cannot be null", equalTo(e.getMessage()));
}
NullPointerException e;
e = expectThrows(NullPointerException.class, () -> new EnvelopeBuilder(null, new Coordinate(1.0, -1.0)));
assertEquals("topLeft of envelope cannot be null", e.getMessage());
e = expectThrows(NullPointerException.class, () -> new EnvelopeBuilder(new Coordinate(1.0, -1.0), null));
assertEquals("bottomRight of envelope cannot be null", e.getMessage());
}
@Override
@ -60,16 +51,21 @@ public class EnvelopeBuilderTests extends AbstractShapeBuilderTestCase<EnvelopeB
// move one corner to the middle of original
switch (randomIntBetween(0, 3)) {
case 0:
mutation = new EnvelopeBuilder(new Coordinate(randomDoubleBetween(-180.0, original.bottomRight().x, true), original.topLeft().y), original.bottomRight());
mutation = new EnvelopeBuilder(
new Coordinate(randomDoubleBetween(-180.0, original.bottomRight().x, true), original.topLeft().y),
original.bottomRight());
break;
case 1:
mutation = new EnvelopeBuilder(new Coordinate(original.topLeft().x, randomDoubleBetween(original.bottomRight().y, 90.0, true)), original.bottomRight());
mutation = new EnvelopeBuilder(new Coordinate(original.topLeft().x, randomDoubleBetween(original.bottomRight().y, 90.0, true)),
original.bottomRight());
break;
case 2:
mutation = new EnvelopeBuilder(original.topLeft(), new Coordinate(randomDoubleBetween(original.topLeft().x, 180.0, true), original.bottomRight().y));
mutation = new EnvelopeBuilder(original.topLeft(),
new Coordinate(randomDoubleBetween(original.topLeft().x, 180.0, true), original.bottomRight().y));
break;
case 3:
mutation = new EnvelopeBuilder(original.topLeft(), new Coordinate(original.bottomRight().x, randomDoubleBetween(-90.0, original.topLeft().y, true)));
mutation = new EnvelopeBuilder(original.topLeft(),
new Coordinate(original.bottomRight().x, randomDoubleBetween(-90.0, original.topLeft().y, true)));
break;
}
return mutation;

View File

@ -27,31 +27,15 @@ import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
import java.io.IOException;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
public class LineStringBuilderTests extends AbstractShapeBuilderTestCase<LineStringBuilder> {
public void testInvalidConstructorArgs() {
try {
new LineStringBuilder((List<Coordinate>) null);
fail("Exception expected");
} catch (IllegalArgumentException e) {
assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage()));
}
try {
new LineStringBuilder(new CoordinatesBuilder());
fail("Exception expected");
} catch (IllegalArgumentException e) {
assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage()));
}
try {
new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0));
fail("Exception expected");
} catch (IllegalArgumentException e) {
assertThat("invalid number of points in LineString (found [1] - must be >= 2)", equalTo(e.getMessage()));
}
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new LineStringBuilder((List<Coordinate>) null));
assertEquals("cannot create point collection with empty set of points", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> new LineStringBuilder(new CoordinatesBuilder()));
assertEquals("cannot create point collection with empty set of points", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0)));
assertEquals("invalid number of points in LineString (found [1] - must be >= 2)", e.getMessage());
}
@Override

View File

@ -68,9 +68,6 @@ public class MultiLineStringBuilderTests extends AbstractShapeBuilderTestCase<Mu
}
static MultiLineStringBuilder createRandomShape() {
if (true) {
return new MultiLineStringBuilder();
}
return (MultiLineStringBuilder) RandomShapeGenerator.createShape(getRandom(), ShapeType.MULTILINESTRING);
return new MultiLineStringBuilder();
}
}

View File

@ -20,29 +20,20 @@
package org.elasticsearch.common.geo.builders;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import java.util.List;
public class MultiPointBuilderTests extends AbstractShapeBuilderTestCase<MultiPointBuilder> {
public void testInvalidBuilderException() {
try {
new MultiPointBuilder(null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage()));
}
try {
new MultiPointBuilder(new CoordinatesBuilder().build());
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage()));
}
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new MultiPointBuilder((List<Coordinate>) null));
assertEquals("cannot create point collection with empty set of points", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> new MultiPointBuilder(new CoordinatesBuilder().build()));
assertEquals("cannot create point collection with empty set of points", e.getMessage());
// one point is minimum
new MultiPointBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).build());

View File

@ -80,7 +80,8 @@ public class PolygonBuilderTests extends AbstractShapeBuilderTestCase<PolygonBui
* This is done so we don't have to expose a setter for orientation in the actual class
*/
private static PolygonBuilder polyWithOposingOrientation(PolygonBuilder pb) {
PolygonBuilder mutation = new PolygonBuilder(pb.shell(), pb.orientation() == Orientation.LEFT ? Orientation.RIGHT : Orientation.LEFT);
PolygonBuilder mutation = new PolygonBuilder(pb.shell(),
pb.orientation() == Orientation.LEFT ? Orientation.RIGHT : Orientation.LEFT);
for (LineStringBuilder hole : pb.holes()) {
mutation.hole(hole);
}

View File

@ -83,7 +83,7 @@ public class DistanceUnitTests extends ESTestCase {
try (BytesStreamOutput out = new BytesStreamOutput()) {
unit.writeTo(out);
try (StreamInput in = StreamInput.wrap(out.bytes())) {
assertThat("Roundtrip serialisation failed.", DistanceUnit.readDistanceUnit(in), equalTo(unit));
assertThat("Roundtrip serialisation failed.", DistanceUnit.readFromStream(in), equalTo(unit));
}
}
}