Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LUCENE-8632: New XYShape Field and Queries for indexing and searching general cartesian geometries #726

Closed
wants to merge 13 commits into from
Closed
12 changes: 8 additions & 4 deletions lucene/core/src/java/org/apache/lucene/geo/Polygon2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,22 @@
*/
// Both Polygon.contains() and Polygon.crossesSlowly() loop all edges, and first check that the edge is within a range.
// we just organize the edges to do the same computations on the same subset of edges more efficiently.
public final class Polygon2D extends EdgeTree {
public class Polygon2D extends EdgeTree {
// each component/hole is a node in an augmented 2d kd-tree: we alternate splitting between latitude/longitude,
// and pull up max values for both dimensions to each parent node (regardless of split).
/** tree of holes, or null */
private final Polygon2D holes;
protected final Polygon2D holes;
private final AtomicBoolean containsBoundary = new AtomicBoolean(false);

private Polygon2D(Polygon polygon, Polygon2D holes) {
super(polygon.minLat, polygon.maxLat, polygon.minLon, polygon.maxLon, polygon.getPolyLats(), polygon.getPolyLons());
protected Polygon2D(final double minLat, final double maxLat, final double minLon, final double maxLon, double[] lats, double[] lons, Polygon2D holes) {
super(minLat, maxLat, minLon, maxLon, lats, lons);
this.holes = holes;
}

protected Polygon2D(Polygon polygon, Polygon2D holes) {
this(polygon.minLat, polygon.maxLat, polygon.minLon, polygon.maxLon, polygon.getPolyLats(), polygon.getPolyLons(), holes);
}

/**
* Returns true if the point is contained within this polygon.
* <p>
Expand Down
311 changes: 27 additions & 284 deletions lucene/sandbox/src/java/org/apache/lucene/document/LatLonShape.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@
*/
package org.apache.lucene.document;

import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.geo.Rectangle2D;
import org.apache.lucene.index.PointValues.Relation;

/**
* Finds all previously indexed shapes that intersect the specified bounding box.
* Finds all previously indexed geo shapes that intersect the specified bounding box.
*
* <p>The field must be indexed using
* {@link org.apache.lucene.document.LatLonShape#createIndexableFields} added per document.
*
* @lucene.experimental
**/
final class LatLonShapeBoundingBoxQuery extends LatLonShapeQuery {
final class LatLonShapeBoundingBoxQuery extends ShapeQuery {
final Rectangle rectangle;
final Rectangle2D rectangle2D;

public LatLonShapeBoundingBoxQuery(String field, LatLonShape.QueryRelation queryRelation, double minLat, double maxLat, double minLon, double maxLon) {
public LatLonShapeBoundingBoxQuery(String field, QueryRelation queryRelation, double minLat, double maxLat, double minLon, double maxLon) {
super(field, queryRelation);
this.rectangle = new Rectangle(minLat, maxLat, minLon, maxLon);
this.rectangle2D = Rectangle2D.create(this.rectangle);
Expand All @@ -46,9 +47,9 @@ protected Relation relateRangeBBoxToQuery(int minXOffset, int minYOffset, byte[]

/** returns true if the query matches the encoded triangle */
@Override
protected boolean queryMatches(byte[] t, int[] scratchTriangle, LatLonShape.QueryRelation queryRelation) {
protected boolean queryMatches(byte[] t, int[] scratchTriangle, QueryRelation queryRelation) {
// decode indexed triangle
LatLonShape.decodeTriangle(t, scratchTriangle);
ShapeField.decodeTriangle(t, scratchTriangle);

int aY = scratchTriangle[0];
int aX = scratchTriangle[1];
Expand All @@ -57,7 +58,7 @@ protected boolean queryMatches(byte[] t, int[] scratchTriangle, LatLonShape.Quer
int cY = scratchTriangle[4];
int cX = scratchTriangle[5];

if (queryRelation == LatLonShape.QueryRelation.WITHIN) {
if (queryRelation == QueryRelation.WITHIN) {
return rectangle2D.containsTriangle(aX, aY, bX, bY, cX, cY);
}
return rectangle2D.intersectsTriangle(aX, aY, bX, bY, cX, cY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@

import java.util.Arrays;

import org.apache.lucene.document.LatLonShape.QueryRelation;
import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.geo.Line;
import org.apache.lucene.geo.Line2D;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.util.NumericUtils;

/**
* Finds all previously indexed shapes that intersect the specified arbitrary {@code Line}.
* Finds all previously indexed geo shapes that intersect the specified arbitrary {@code Line}.
* <p>
* Note:
* <ul>
Expand All @@ -43,7 +43,7 @@
*
* @lucene.experimental
**/
final class LatLonShapeLineQuery extends LatLonShapeQuery {
final class LatLonShapeLineQuery extends ShapeQuery {
final Line[] lines;
final private Line2D line2D;

Expand Down Expand Up @@ -85,7 +85,7 @@ protected Relation relateRangeBBoxToQuery(int minXOffset, int minYOffset, byte[]

@Override
protected boolean queryMatches(byte[] t, int[] scratchTriangle, QueryRelation queryRelation) {
LatLonShape.decodeTriangle(t, scratchTriangle);
ShapeField.decodeTriangle(t, scratchTriangle);

double alat = GeoEncodingUtils.decodeLatitude(scratchTriangle[0]);
double alon = GeoEncodingUtils.decodeLongitude(scratchTriangle[1]);
Expand All @@ -94,7 +94,7 @@ protected boolean queryMatches(byte[] t, int[] scratchTriangle, QueryRelation qu
double clat = GeoEncodingUtils.decodeLatitude(scratchTriangle[4]);
double clon = GeoEncodingUtils.decodeLongitude(scratchTriangle[5]);

if (queryRelation == LatLonShape.QueryRelation.WITHIN) {
if (queryRelation == QueryRelation.WITHIN) {
return line2D.relateTriangle(alon, alat, blon, blat, clon, clat) == Relation.CELL_INSIDE_QUERY;
}
// INTERSECTS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@

import java.util.Arrays;

import org.apache.lucene.document.LatLonShape.QueryRelation;
import org.apache.lucene.document.ShapeField.QueryRelation;
import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Polygon2D;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.util.NumericUtils;

/**
* Finds all previously indexed shapes that intersect the specified arbitrary.
* Finds all previously indexed geo shapes that intersect the specified arbitrary.
* <p>
* Note:
* <ul>
* <li>Dateline crossing is not yet supported. Polygons should be cut at the dateline and provided as a multipolygon query</li>
* </ul>
*
* <p>The field must be indexed using
* {@link org.apache.lucene.document.LatLonShape#createIndexableFields} added per document.
*
* @lucene.experimental
**/
final class LatLonShapePolygonQuery extends LatLonShapeQuery {
final class LatLonShapePolygonQuery extends ShapeQuery {
final Polygon[] polygons;
final private Polygon2D poly2D;

Expand Down Expand Up @@ -74,7 +79,7 @@ protected Relation relateRangeBBoxToQuery(int minXOffset, int minYOffset, byte[]

@Override
protected boolean queryMatches(byte[] t, int[] scratchTriangle, QueryRelation queryRelation) {
LatLonShape.decodeTriangle(t, scratchTriangle);
ShapeField.decodeTriangle(t, scratchTriangle);

double alat = GeoEncodingUtils.decodeLatitude(scratchTriangle[0]);
double alon = GeoEncodingUtils.decodeLongitude(scratchTriangle[1]);
Expand Down
Loading