Skip to content

Commit

Permalink
Fixed behavior of docGeoWithin, when a Point lies on the edge of anot…
Browse files Browse the repository at this point in the history
…her shape.

Use coveredBy() instead of within(), as this matches the behavior of
MongoDB.
  • Loading branch information
murermader committed Aug 21, 2024
1 parent 11fb7c8 commit c6b0bac
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,9 @@ public static PolyBoolean docGeoWithin( PolyValue input, PolyValue geometry, Pol
if(distanceValue > 0){
return inputGeometry.isWithinDistance( geometryFilter, distanceValue ) ? PolyBoolean.TRUE : PolyBoolean.FALSE;
}
return inputGeometry.within( geometryFilter ) ? PolyBoolean.TRUE : PolyBoolean.FALSE;
// coveredBy also works if the input geometry lies along the edges of the filter geometry.
// For example: A point [0,0] is inside a box [0,0 to 1,1], because it lies on a corner / edge.
return inputGeometry.coveredBy( geometryFilter ) ? PolyBoolean.TRUE : PolyBoolean.FALSE;
} catch ( InvalidGeometryException | GeometryTopologicalException e ) {
throw new GenericRuntimeException( "$geometry could not be parsed as GeoJSON" );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.bson.BsonArray;
import org.bson.BsonBoolean;
Expand All @@ -42,7 +41,6 @@
import org.jetbrains.annotations.Nullable;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.geom.PrecisionModel;
import org.polypheny.db.algebra.AlgCollation;
import org.polypheny.db.algebra.AlgCollations;
Expand Down Expand Up @@ -1660,8 +1658,8 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType

if(geometry.containsKey( "$box" )){
BsonArray box = geometry.get( "$box" ).asArray();
Coordinate bottomLeft = parseCoordinate(box.get( 0 ).asArray());
Coordinate topRight = parseCoordinate(box.get( 1 ).asArray());
Coordinate bottomLeft = convertArrayToCoordinate(box.get( 0 ).asArray());
Coordinate topRight = convertArrayToCoordinate(box.get( 1 ).asArray());
Coordinate topLeft = new Coordinate(bottomLeft.x, topRight.y);
Coordinate bottomRight = new Coordinate(topRight.x, bottomLeft.y);
// Form a closed Ring, starting on the bottom left and going clockwise.
Expand All @@ -1680,15 +1678,15 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType
BsonArray polygon = geometry.get( "$polygon" ).asArray();
ArrayList<Coordinate> linearRing = new ArrayList<>();
for ( BsonValue coordinate : polygon ){
linearRing.add( parseCoordinate( coordinate.asArray() ) );
linearRing.add( convertArrayToCoordinate( coordinate.asArray() ) );
}
GeometryFactory geoFactory = new GeometryFactory();
polyGeometry = new PolyGeometry( geoFactory.createPolygon(linearRing.toArray(new Coordinate[0])) );
}

if(geometry.containsKey("$center")){
BsonArray circle = geometry.get( "$center" ).asArray();
Coordinate center = parseCoordinate( circle.get(0).asArray() );
Coordinate center = convertArrayToCoordinate( circle.get(0).asArray() );
double radius = convertBsonValueToDouble(circle.get(1));
distance = new PolyDouble(radius);

Expand All @@ -1700,7 +1698,7 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType

if(geometry.containsKey("$centerSphere")){
BsonArray circle = geometry.get( "$centerSphere" ).asArray();
Coordinate center = parseCoordinate( circle.get(0).asArray() );
Coordinate center = convertArrayToCoordinate( circle.get(0).asArray() );
double radius = convertBsonValueToDouble(circle.get(1));
distance = new PolyDouble(radius);

Expand All @@ -1727,7 +1725,7 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType
) );
}

private static Coordinate parseCoordinate(BsonArray array){
private static Coordinate convertArrayToCoordinate(BsonArray array){
if(array.size() != 2){
throw new GenericRuntimeException( "Coordinates need to be of the form [x,y]");
}
Expand Down

0 comments on commit c6b0bac

Please sign in to comment.