Making LineStringBuilder and MultiLineStringBuilder writable and add equals/hashCode

This commit is contained in:
Christoph Büscher 2015-11-19 13:48:50 +01:00
parent 315b0c263d
commit 31f90c91af
9 changed files with 224 additions and 8 deletions

View File

@ -36,6 +36,8 @@ public class CircleBuilder extends ShapeBuilder {
public static final String FIELD_RADIUS = "radius"; public static final String FIELD_RADIUS = "radius";
public static final GeoShapeType TYPE = GeoShapeType.CIRCLE; public static final GeoShapeType TYPE = GeoShapeType.CIRCLE;
static final CircleBuilder PROTOTYPE = new CircleBuilder();
private DistanceUnit unit; private DistanceUnit unit;
private double radius; private double radius;
private Coordinate center; private Coordinate center;

View File

@ -34,6 +34,8 @@ public class EnvelopeBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE; public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE;
static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder();
protected Coordinate topLeft; protected Coordinate topLeft;
protected Coordinate bottomRight; protected Coordinate bottomRight;

View File

@ -22,8 +22,12 @@ package org.elasticsearch.common.geo.builders;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
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.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
@ -34,6 +38,8 @@ public class LineStringBuilder extends PointCollection<LineStringBuilder> {
public static final GeoShapeType TYPE = GeoShapeType.LINESTRING; public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;
static final LineStringBuilder PROTOTYPE = new LineStringBuilder();
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
@ -139,4 +145,42 @@ public class LineStringBuilder extends PointCollection<LineStringBuilder> {
} }
return coordinates; return coordinates;
} }
@Override
public int hashCode() {
return Objects.hash(points, translated);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
LineStringBuilder other = (LineStringBuilder) obj;
return Objects.equals(points, other.points) &&
(translated == other.translated);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(points.size());
for (Coordinate point : points) {
writeCoordinateTo(point, out);
}
out.writeBoolean(translated);
}
@Override
public LineStringBuilder readFrom(StreamInput in) throws IOException {
LineStringBuilder lineStringBuilder = new LineStringBuilder();
int size = in.readVInt();
for (int i=0; i < size; i++) {
lineStringBuilder.point(readCoordinateFrom(in));
}
lineStringBuilder.translated = in.readBoolean();
return lineStringBuilder;
}
} }

View File

@ -19,6 +19,8 @@
package org.elasticsearch.common.geo.builders; package org.elasticsearch.common.geo.builders;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.Shape;
@ -29,11 +31,14 @@ import com.vividsolutions.jts.geom.LineString;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects;
public class MultiLineStringBuilder extends ShapeBuilder { public class MultiLineStringBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING; public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;
static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder();
private final ArrayList<LineStringBuilder> lines = new ArrayList<>(); private final ArrayList<LineStringBuilder> lines = new ArrayList<>();
public MultiLineStringBuilder linestring(LineStringBuilder line) { public MultiLineStringBuilder linestring(LineStringBuilder line) {
@ -41,6 +46,10 @@ public class MultiLineStringBuilder extends ShapeBuilder {
return this; return this;
} }
public MultiLineStringBuilder linestring(Coordinate[] coordinates) {
return this.linestring(new LineStringBuilder().points(coordinates));
}
public Coordinate[][] coordinates() { public Coordinate[][] coordinates() {
Coordinate[][] result = new Coordinate[lines.size()][]; Coordinate[][] result = new Coordinate[lines.size()][];
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
@ -92,4 +101,39 @@ public class MultiLineStringBuilder extends ShapeBuilder {
} }
return jtsGeometry(geometry); return jtsGeometry(geometry);
} }
@Override
public int hashCode() {
return Objects.hash(lines);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
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

@ -36,6 +36,8 @@ public class MultiPointBuilder extends PointCollection<MultiPointBuilder> {
public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT; public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT;
final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder();
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
@ -90,7 +92,7 @@ public class MultiPointBuilder extends PointCollection<MultiPointBuilder> {
} }
@Override @Override
public ShapeBuilder readFrom(StreamInput in) throws IOException { public MultiPointBuilder readFrom(StreamInput in) throws IOException {
MultiPointBuilder multiPointBuilder = new MultiPointBuilder(); MultiPointBuilder multiPointBuilder = new MultiPointBuilder();
int size = in.readVInt(); int size = in.readVInt();
for (int i=0; i < size; i++) { for (int i=0; i < size; i++) {

View File

@ -32,6 +32,7 @@ import com.vividsolutions.jts.geom.Coordinate;
public class PointBuilder extends ShapeBuilder { public class PointBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.POINT; public static final GeoShapeType TYPE = GeoShapeType.POINT;
static final PointBuilder PROTOTYPE = new PointBuilder();
private Coordinate coordinate; private Coordinate coordinate;

View File

@ -44,10 +44,12 @@ public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder> exte
public static void init() { public static void init() {
if (namedWriteableRegistry == null) { if (namedWriteableRegistry == null) {
namedWriteableRegistry = new NamedWriteableRegistry(); namedWriteableRegistry = new NamedWriteableRegistry();
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, new PointBuilder()); namedWriteableRegistry.registerPrototype(ShapeBuilder.class, PointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, new CircleBuilder()); namedWriteableRegistry.registerPrototype(ShapeBuilder.class, CircleBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, new EnvelopeBuilder()); namedWriteableRegistry.registerPrototype(ShapeBuilder.class, EnvelopeBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, new MultiPointBuilder()); namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiPointBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, LineStringBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(ShapeBuilder.class, MultiLineStringBuilder.PROTOTYPE);
} }
} }
@ -94,9 +96,9 @@ public abstract class AbstractShapeBuilderTestCase<SB extends ShapeBuilder> exte
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) { for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
SB testShape = createTestShapeBuilder(); SB testShape = createTestShapeBuilder();
SB deserializedShape = copyShape(testShape); SB deserializedShape = copyShape(testShape);
assertEquals(deserializedShape, testShape); assertEquals(testShape, deserializedShape);
assertEquals(deserializedShape.hashCode(), testShape.hashCode()); assertEquals(testShape.hashCode(), deserializedShape.hashCode());
assertNotSame(deserializedShape, testShape); assertNotSame(testShape, deserializedShape);
} }
} }

View File

@ -0,0 +1,57 @@
/*
* 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;
import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
import java.io.IOException;
public class LineStringBuilderTests extends AbstractShapeBuilderTestCase<LineStringBuilder> {
@Override
protected LineStringBuilder createTestShapeBuilder() {
LineStringBuilder lsb = (LineStringBuilder) RandomShapeGenerator.createShape(getRandom(), ShapeType.LINESTRING);
return lsb;
}
@Override
protected LineStringBuilder mutate(LineStringBuilder original) throws IOException {
LineStringBuilder mutation = copyShape(original);
Coordinate[] coordinates = original.coordinates(false);
Coordinate coordinate = randomFrom(coordinates);
if (randomBoolean()) {
if (coordinate.x != 0.0) {
coordinate.x = coordinate.x / 2;
} else {
coordinate.x = randomDoubleBetween(-180.0, 180.0, true);
}
} else {
if (coordinate.y != 0.0) {
coordinate.y = coordinate.y / 2;
} else {
coordinate.y = randomDoubleBetween(-90.0, 90.0, true);
}
}
return mutation.points(coordinates);
}
}

View File

@ -0,0 +1,62 @@
/*
* 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;
import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
import java.io.IOException;
public class MultiLineStringBuilderTests extends AbstractShapeBuilderTestCase<MultiLineStringBuilder> {
@Override
protected MultiLineStringBuilder createTestShapeBuilder() {
return (MultiLineStringBuilder) RandomShapeGenerator.createShape(getRandom(), ShapeType.MULTILINESTRING);
}
@Override
protected MultiLineStringBuilder mutate(MultiLineStringBuilder original) throws IOException {
MultiLineStringBuilder mutation = copyShape(original);
Coordinate[][] coordinates = mutation.coordinates();
int lineToChange = randomInt(coordinates.length - 1);
for (int i = 0; i < coordinates.length; i++) {
Coordinate[] line = coordinates[i];
if (i == lineToChange) {
Coordinate coordinate = randomFrom(line);
if (randomBoolean()) {
if (coordinate.x != 0.0) {
coordinate.x = coordinate.x / 2;
} else {
coordinate.x = randomDoubleBetween(-180.0, 180.0, true);
}
} else {
if (coordinate.y != 0.0) {
coordinate.y = coordinate.y / 2;
} else {
coordinate.y = randomDoubleBetween(-90.0, 90.0, true);
}
}
}
}
return mutation;
}
}