Skip to content

Commit

Permalink
Geo: replace intermediate geo objects with libs/geo (#37721)
Browse files Browse the repository at this point in the history
Replaces intermediate geo objects built by ShapeBuilders with
objects from the libs/geo hierarchy. This should allow us to build
all geo functionality around a single hierarchy.

Follow up for #35320
  • Loading branch information
imotov committed Jan 25, 2019
1 parent e88ae99 commit 68149b6
Show file tree
Hide file tree
Showing 29 changed files with 465 additions and 365 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ allprojects {
"org.elasticsearch:elasticsearch-core:${version}": ':libs:core',
"org.elasticsearch:elasticsearch-nio:${version}": ':libs:nio',
"org.elasticsearch:elasticsearch-x-content:${version}": ':libs:x-content',
"org.elasticsearch:elasticsearch-geo:${version}": ':libs:elasticsearch-geo',
"org.elasticsearch:elasticsearch-secure-sm:${version}": ':libs:secure-sm',
"org.elasticsearch.client:elasticsearch-rest-client:${version}": ':client:rest',
"org.elasticsearch.client:elasticsearch-rest-client-sniffer:${version}": ':client:sniffer',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ public double getLon(int i) {
return lons[i];
}

public double[] getLats() {
return lats.clone();
}

public double[] getLons() {
return lons.clone();
}

@Override
public ShapeType type() {
return ShapeType.LINESTRING;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public ShapeType type() {
return ShapeType.POINT;
}

public double lat() {
public double getLat() {
return lat;
}

public double lon() {
public double getLon() {
return lon;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ public Void visit(MultiLine multiLine) {
public Void visit(MultiPoint multiPoint) {
// walk through coordinates:
sb.append(LPAREN);
visitPoint(multiPoint.get(0).lon(), multiPoint.get(0).lat());
visitPoint(multiPoint.get(0).getLon(), multiPoint.get(0).getLat());
for (int i = 1; i < multiPoint.size(); ++i) {
sb.append(COMMA);
sb.append(SPACE);
Point point = multiPoint.get(i);
visitPoint(point.lon(), point.lat());
visitPoint(point.getLon(), point.getLat());
}
sb.append(RPAREN);
return null;
Expand All @@ -146,7 +146,7 @@ public Void visit(Point point) {
sb.append(EMPTY);
} else {
sb.append(LPAREN);
visitPoint(point.lon(), point.lat());
visitPoint(point.getLon(), point.getLat());
sb.append(RPAREN);
}
return null;
Expand Down
3 changes: 2 additions & 1 deletion server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ dependencies {
compile "org.elasticsearch:elasticsearch-core:${version}"
compile "org.elasticsearch:elasticsearch-secure-sm:${version}"
compile "org.elasticsearch:elasticsearch-x-content:${version}"

compile "org.elasticsearch:elasticsearch-geo:${version}"

compileOnly project(':libs:plugin-classloader')
testRuntime project(':libs:plugin-classloader')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ CoordinateNode validate(CoordinateNode coordinates, boolean coerce) {
},
GEOMETRYCOLLECTION("geometrycollection") {
@Override
public ShapeBuilder<?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
public ShapeBuilder<?, ?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
Orientation orientation, boolean coerce) {
// noop, handled in parser
return null;
Expand Down Expand Up @@ -298,7 +298,7 @@ public static GeoShapeType forName(String geoshapename) {
throw new IllegalArgumentException("unknown geo_shape ["+geoshapename+"]");
}

public abstract ShapeBuilder<?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
public abstract ShapeBuilder<?, ?, ?> getBuilder(CoordinateNode coordinates, DistanceUnit.Distance radius,
ShapeBuilder.Orientation orientation, boolean coerce);
abstract CoordinateNode validate(CoordinateNode coordinates, boolean coerce);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import java.io.IOException;
import java.util.Objects;

public class CircleBuilder extends ShapeBuilder<Circle, CircleBuilder> {
public class CircleBuilder extends ShapeBuilder<Circle, org.elasticsearch.geo.geometry.Circle, CircleBuilder> {

public static final ParseField FIELD_RADIUS = new ParseField("radius");
public static final GeoShapeType TYPE = GeoShapeType.CIRCLE;
Expand Down Expand Up @@ -164,7 +164,7 @@ public Circle buildS4J() {
}

@Override
public Object buildLucene() {
public org.elasticsearch.geo.geometry.Circle buildGeometry() {
throw new UnsupportedOperationException("CIRCLE geometry is not supported");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import java.io.IOException;
import java.util.Objects;

public class EnvelopeBuilder extends ShapeBuilder<Rectangle, EnvelopeBuilder> {
public class EnvelopeBuilder extends ShapeBuilder<Rectangle, org.elasticsearch.geo.geometry.Rectangle, EnvelopeBuilder> {

public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE;

Expand Down Expand Up @@ -113,8 +113,8 @@ public Rectangle buildS4J() {
}

@Override
public org.apache.lucene.geo.Rectangle buildLucene() {
return new org.apache.lucene.geo.Rectangle(bottomRight.y, topLeft.y, topLeft.x, bottomRight.x);
public org.elasticsearch.geo.geometry.Rectangle buildGeometry() {
return new org.elasticsearch.geo.geometry.Rectangle(bottomRight.y, topLeft.y, topLeft.x, bottomRight.x);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class GeometryCollectionBuilder extends ShapeBuilder<Shape, GeometryCollectionBuilder> {
public class GeometryCollectionBuilder extends ShapeBuilder<Shape,
org.elasticsearch.geo.geometry.GeometryCollection<org.elasticsearch.geo.geometry.Geometry>, GeometryCollectionBuilder> {

public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION;

Expand Down Expand Up @@ -185,19 +185,14 @@ public Shape buildS4J() {
}

@Override
public Object buildLucene() {
List<Object> shapes = new ArrayList<>(this.shapes.size());
public org.elasticsearch.geo.geometry.GeometryCollection<org.elasticsearch.geo.geometry.Geometry> buildGeometry() {
List<org.elasticsearch.geo.geometry.Geometry> shapes = new ArrayList<>(this.shapes.size());

for (ShapeBuilder shape : this.shapes) {
Object o = shape.buildLucene();
if (o.getClass().isArray()) {
shapes.addAll(Arrays.asList((Object[])o));
} else {
shapes.add(o);
}
shapes.add(shape.buildGeometry());
}

return shapes.toArray(new Object[shapes.size()]);
return new org.elasticsearch.geo.geometry.GeometryCollection<>(shapes);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@

package org.elasticsearch.common.geo.builders;

import org.apache.lucene.geo.Line;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;

import org.elasticsearch.common.geo.GeoShapeType;
import org.elasticsearch.common.geo.parsers.ShapeParser;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.geo.geometry.Line;
import org.elasticsearch.geo.geometry.MultiLine;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.spatial4j.shape.jts.JtsGeometry;

import java.io.IOException;
Expand All @@ -39,7 +39,7 @@
import static org.elasticsearch.common.geo.GeoUtils.normalizeLat;
import static org.elasticsearch.common.geo.GeoUtils.normalizeLon;

public class LineStringBuilder extends ShapeBuilder<JtsGeometry, LineStringBuilder> {
public class LineStringBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.geo.geometry.Geometry, LineStringBuilder> {
public static final GeoShapeType TYPE = GeoShapeType.LINESTRING;

/**
Expand Down Expand Up @@ -125,15 +125,15 @@ public JtsGeometry buildS4J() {
}

@Override
public Object buildLucene() {
public org.elasticsearch.geo.geometry.Geometry buildGeometry() {
// decompose linestrings crossing dateline into array of Lines
Coordinate[] coordinates = this.coordinates.toArray(new Coordinate[this.coordinates.size()]);
if (wrapdateline) {
ArrayList<Line> linestrings = decomposeLucene(coordinates, new ArrayList<>());
List<Line> linestrings = decomposeGeometry(coordinates, new ArrayList<>());
if (linestrings.size() == 1) {
return linestrings.get(0);
} else {
return linestrings.toArray(new Line[linestrings.size()]);
return new MultiLine(linestrings);
}
}
return new Line(Arrays.stream(coordinates).mapToDouble(i->normalizeLat(i.y)).toArray(),
Expand All @@ -149,7 +149,7 @@ static ArrayList<LineString> decomposeS4J(GeometryFactory factory, Coordinate[]
return strings;
}

static ArrayList<Line> decomposeLucene(Coordinate[] coordinates, ArrayList<Line> lines) {
static List<Line> decomposeGeometry(Coordinate[] coordinates, List<Line> lines) {
for (Coordinate[] part : decompose(+DATELINE, coordinates)) {
for (Coordinate[] line : decompose(-DATELINE, part)) {
lines.add(new Line(Arrays.stream(line).mapToDouble(i->normalizeLat(i.y)).toArray(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@

package org.elasticsearch.common.geo.builders;

import org.apache.lucene.geo.Line;
import org.elasticsearch.common.geo.GeoShapeType;
import org.elasticsearch.common.geo.parsers.GeoWKTParser;
import org.elasticsearch.common.geo.parsers.ShapeParser;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.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.elasticsearch.geo.geometry.MultiLine;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.spatial4j.shape.jts.JtsGeometry;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

public class MultiLineStringBuilder extends ShapeBuilder<JtsGeometry, MultiLineStringBuilder> {
public class MultiLineStringBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.geo.geometry.Geometry, MultiLineStringBuilder> {

public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING;

Expand Down Expand Up @@ -150,24 +150,24 @@ public JtsGeometry buildS4J() {
}

@Override
public Object buildLucene() {
public org.elasticsearch.geo.geometry.Geometry buildGeometry() {
if (wrapdateline) {
ArrayList<Line> parts = new ArrayList<>();
List<org.elasticsearch.geo.geometry.Line> parts = new ArrayList<>();
for (LineStringBuilder line : lines) {
LineStringBuilder.decomposeLucene(line.coordinates(false), parts);
LineStringBuilder.decomposeGeometry(line.coordinates(false), parts);
}
if (parts.size() == 1) {
return parts.get(0);
}
return parts.toArray(new Line[parts.size()]);
return new MultiLine(parts);
}
Line[] linestrings = new Line[lines.size()];
List<org.elasticsearch.geo.geometry.Line> linestrings = new ArrayList<>(lines.size());
for (int i = 0; i < lines.size(); ++i) {
LineStringBuilder lsb = lines.get(i);
linestrings[i] = new Line(lsb.coordinates.stream().mapToDouble(c->c.y).toArray(),
lsb.coordinates.stream().mapToDouble(c->c.x).toArray());
linestrings.add(new org.elasticsearch.geo.geometry.Line(lsb.coordinates.stream().mapToDouble(c->c.y).toArray(),
lsb.coordinates.stream().mapToDouble(c->c.x).toArray()));
}
return linestrings;
return new MultiLine(linestrings);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
import org.elasticsearch.common.geo.parsers.ShapeParser;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.geo.geometry.MultiPoint;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.spatial4j.shape.Point;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class MultiPointBuilder extends ShapeBuilder<XShapeCollection<Point>, MultiPointBuilder> {
public class MultiPointBuilder extends ShapeBuilder<XShapeCollection<Point>, MultiPoint, MultiPointBuilder> {

public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT;

Expand Down Expand Up @@ -74,14 +76,9 @@ public XShapeCollection<Point> buildS4J() {
}

@Override
public double[][] buildLucene() {
double[][] points = new double[coordinates.size()][];
Coordinate coord;
for (int i = 0; i < coordinates.size(); ++i) {
coord = coordinates.get(i);
points[i] = new double[] {coord.x, coord.y};
}
return points;
public MultiPoint buildGeometry() {
return new MultiPoint(coordinates.stream().map(coord -> new org.elasticsearch.geo.geometry.Point(coord.y, coord.x))
.collect(Collectors.toList()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.geo.geometry.MultiPolygon;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.spatial4j.shape.Shape;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

public class MultiPolygonBuilder extends ShapeBuilder<Shape, MultiPolygonBuilder> {
public class MultiPolygonBuilder extends ShapeBuilder<Shape, MultiPolygon, MultiPolygonBuilder> {

public static final GeoShapeType TYPE = GeoShapeType.MULTIPOLYGON;

Expand Down Expand Up @@ -185,31 +185,20 @@ public Shape buildS4J() {
//note: ShapeCollection is probably faster than a Multi* geom.
}

@SuppressWarnings({"unchecked"})
@Override
public Object buildLucene() {
List<org.apache.lucene.geo.Polygon> shapes = new ArrayList<>(this.polygons.size());
public MultiPolygon buildGeometry() {
List<org.elasticsearch.geo.geometry.Polygon> shapes = new ArrayList<>(this.polygons.size());
Object poly;
if (wrapdateline) {
for (PolygonBuilder polygon : this.polygons) {
poly = polygon.buildLucene();
if (poly instanceof org.apache.lucene.geo.Polygon[]) {
shapes.addAll(Arrays.asList((org.apache.lucene.geo.Polygon[])poly));
} else {
shapes.add((org.apache.lucene.geo.Polygon)poly);
}
}
} else {
for (int i = 0; i < this.polygons.size(); ++i) {
PolygonBuilder pb = this.polygons.get(i);
poly = pb.buildLucene();
if (poly instanceof org.apache.lucene.geo.Polygon[]) {
shapes.addAll(Arrays.asList((org.apache.lucene.geo.Polygon[])poly));
} else {
shapes.add((org.apache.lucene.geo.Polygon)poly);
}
for (PolygonBuilder polygon : this.polygons) {
poly = polygon.buildGeometry();
if (poly instanceof List) {
shapes.addAll((List<org.elasticsearch.geo.geometry.Polygon>) poly);
} else {
shapes.add((org.elasticsearch.geo.geometry.Polygon)poly);
}
}
return shapes.stream().toArray(org.apache.lucene.geo.Polygon[]::new);
return new MultiPolygon(shapes);
}

@Override
Expand Down
Loading

0 comments on commit 68149b6

Please sign in to comment.