|
@@ -9,16 +9,14 @@ package org.elasticsearch.xpack.spatial.index.fielddata;
|
|
|
|
|
|
|
|
import org.apache.lucene.document.ShapeField;
|
|
import org.apache.lucene.document.ShapeField;
|
|
|
import org.apache.lucene.geo.LatLonGeometry;
|
|
import org.apache.lucene.geo.LatLonGeometry;
|
|
|
|
|
+import org.apache.lucene.geo.Point;
|
|
|
import org.apache.lucene.util.BytesRef;
|
|
import org.apache.lucene.util.BytesRef;
|
|
|
import org.elasticsearch.common.geo.GeoPoint;
|
|
import org.elasticsearch.common.geo.GeoPoint;
|
|
|
import org.elasticsearch.common.geo.Orientation;
|
|
import org.elasticsearch.common.geo.Orientation;
|
|
|
-import org.elasticsearch.common.geo.ShapeRelation;
|
|
|
|
|
import org.elasticsearch.geometry.Geometry;
|
|
import org.elasticsearch.geometry.Geometry;
|
|
|
-import org.elasticsearch.geometry.Point;
|
|
|
|
|
import org.elasticsearch.geometry.utils.GeographyValidator;
|
|
import org.elasticsearch.geometry.utils.GeographyValidator;
|
|
|
import org.elasticsearch.geometry.utils.WellKnownText;
|
|
import org.elasticsearch.geometry.utils.WellKnownText;
|
|
|
import org.elasticsearch.index.mapper.GeoShapeIndexer;
|
|
import org.elasticsearch.index.mapper.GeoShapeIndexer;
|
|
|
-import org.elasticsearch.index.mapper.GeoShapeQueryable;
|
|
|
|
|
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
|
|
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
|
|
|
import org.elasticsearch.xcontent.ToXContentFragment;
|
|
import org.elasticsearch.xcontent.ToXContentFragment;
|
|
|
import org.elasticsearch.xcontent.XContentBuilder;
|
|
import org.elasticsearch.xcontent.XContentBuilder;
|
|
@@ -93,11 +91,13 @@ public abstract class GeoShapeValues {
|
|
|
private final GeometryDocValueReader reader;
|
|
private final GeometryDocValueReader reader;
|
|
|
private final BoundingBox boundingBox;
|
|
private final BoundingBox boundingBox;
|
|
|
private final Tile2DVisitor tile2DVisitor;
|
|
private final Tile2DVisitor tile2DVisitor;
|
|
|
|
|
+ private final LatLonGeometryRelationVisitor component2DRelationVisitor;
|
|
|
|
|
|
|
|
public GeoShapeValue() {
|
|
public GeoShapeValue() {
|
|
|
this.reader = new GeometryDocValueReader();
|
|
this.reader = new GeometryDocValueReader();
|
|
|
this.boundingBox = new BoundingBox();
|
|
this.boundingBox = new BoundingBox();
|
|
|
this.tile2DVisitor = new Tile2DVisitor();
|
|
this.tile2DVisitor = new Tile2DVisitor();
|
|
|
|
|
+ this.component2DRelationVisitor = new LatLonGeometryRelationVisitor(CoordinateEncoder.GEO);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -117,8 +117,16 @@ public abstract class GeoShapeValues {
|
|
|
*/
|
|
*/
|
|
|
public GeoPoint labelPosition() throws IOException {
|
|
public GeoPoint labelPosition() throws IOException {
|
|
|
// For polygons we prefer to use the centroid, as long as it is within the polygon
|
|
// For polygons we prefer to use the centroid, as long as it is within the polygon
|
|
|
- if (reader.getDimensionalShapeType() == DimensionalShapeType.POLYGON && intersects(new Point(lon(), lat()))) {
|
|
|
|
|
- return new GeoPoint(lat(), lon());
|
|
|
|
|
|
|
+ if (reader.getDimensionalShapeType() == DimensionalShapeType.POLYGON) {
|
|
|
|
|
+ Component2DVisitor visitor = Component2DVisitor.getVisitor(
|
|
|
|
|
+ LatLonGeometry.create(new Point(lat(), lon())),
|
|
|
|
|
+ ShapeField.QueryRelation.INTERSECTS,
|
|
|
|
|
+ CoordinateEncoder.GEO
|
|
|
|
|
+ );
|
|
|
|
|
+ reader.visit(visitor);
|
|
|
|
|
+ if (visitor.matches()) {
|
|
|
|
|
+ return new GeoPoint(lat(), lon());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
// For all other cases, use the first triangle (or line or point) in the tree which will always intersect the shape
|
|
// For all other cases, use the first triangle (or line or point) in the tree which will always intersect the shape
|
|
|
LabelPositionVisitor<GeoPoint> visitor = new LabelPositionVisitor<>(CoordinateEncoder.GEO, (x, y) -> new GeoPoint(y, x));
|
|
LabelPositionVisitor<GeoPoint> visitor = new LabelPositionVisitor<>(CoordinateEncoder.GEO, (x, y) -> new GeoPoint(y, x));
|
|
@@ -137,21 +145,14 @@ public abstract class GeoShapeValues {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Determine if the current shape value intersects the specified geometry.
|
|
|
|
|
- * Note that the intersection must be true in quantized space, so it is possible that
|
|
|
|
|
- * points on the edges of geometries will return false due to quantization shifting them off the geometry.
|
|
|
|
|
- * To deal with this, one option is to pass in a circle around the point with a 1m radius
|
|
|
|
|
- * which is enough to cover the resolution of the quantization.
|
|
|
|
|
|
|
+ * Determine the {@link GeoRelation} between the current shape and a {@link LatLonGeometry}. It only supports
|
|
|
|
|
+ * simple geometries, therefore it will fail if the LatLonGeometry is a {@link org.apache.lucene.geo.Rectangle}
|
|
|
|
|
+ * that crosses the dateline.
|
|
|
*/
|
|
*/
|
|
|
- public boolean intersects(Geometry geometry) throws IOException {
|
|
|
|
|
- LatLonGeometry[] latLonGeometries = GeoShapeQueryable.toQuantizeLuceneGeometry(geometry, ShapeRelation.INTERSECTS);
|
|
|
|
|
- Component2DVisitor visitor = Component2DVisitor.getVisitor(
|
|
|
|
|
- LatLonGeometry.create(latLonGeometries),
|
|
|
|
|
- ShapeField.QueryRelation.INTERSECTS,
|
|
|
|
|
- CoordinateEncoder.GEO
|
|
|
|
|
- );
|
|
|
|
|
- reader.visit(visitor);
|
|
|
|
|
- return visitor.matches();
|
|
|
|
|
|
|
+ public GeoRelation relate(LatLonGeometry latLonGeometry) throws IOException {
|
|
|
|
|
+ component2DRelationVisitor.reset(latLonGeometry);
|
|
|
|
|
+ reader.visit(component2DRelationVisitor);
|
|
|
|
|
+ return component2DRelationVisitor.relation();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public DimensionalShapeType dimensionalShapeType() {
|
|
public DimensionalShapeType dimensionalShapeType() {
|