Skip to content

Commit

Permalink
Small refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
murermader committed Aug 21, 2024
1 parent fcd6158 commit bc9d006
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public class MqlGeoFunctionsTest extends MqlTestTemplate {

@Test
public void docGeoWithinTest() {
// TODO: Compare values with MongoDB, instead of with the values that I expect.
// Somehow possible to execute the commands once on mongodb, and once on
// hsqldb?
String insertDocuments = """
db.%s.insertMany([
{
Expand All @@ -57,8 +60,8 @@ public void docGeoWithinTest() {
legacy: {
$geoWithin: {
$box: [
[ 0, 0 ],
[ 1, 1 ]
[0,0],
[1,1]
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1642,26 +1642,27 @@ private RexNode convertGeoIntersects( BsonValue bson, String parentKey, AlgDataT
) );
}


private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType rowType ) {
// We convert the $geometry object to a PolyGeometry String.
BsonDocument geometry = bson.asDocument().get( "$geoWithin" ).asDocument();
PolyGeometry polyGeometry = null;
PolyDouble distance = new PolyDouble( -1d );

if(geometry.containsKey( "$geometry" )){
if ( geometry.containsKey( "$geometry" ) ) {
try {
polyGeometry = PolyGeometry.fromGeoJson( geometry.toJson() );
} catch ( InvalidGeometryException e ) {
throw new GenericRuntimeException( "$geometry operand of $geoWithin could not be parsed as GeoJSON.", e );
}
}

if(geometry.containsKey( "$box" )){
if ( geometry.containsKey( "$box" ) ) {
BsonArray box = geometry.get( "$box" ).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);
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.
Coordinate[] linearRing = new Coordinate[]{
bottomLeft,
Expand All @@ -1671,47 +1672,41 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType
bottomLeft
};
GeometryFactory geoFactory = new GeometryFactory();
polyGeometry = new PolyGeometry( geoFactory.createPolygon(linearRing) );
}

if(geometry.containsKey("$polygon")){
polyGeometry = new PolyGeometry( geoFactory.createPolygon( linearRing ) );
} else if ( geometry.containsKey( "$polygon" ) ) {
BsonArray polygon = geometry.get( "$polygon" ).asArray();
ArrayList<Coordinate> linearRing = new ArrayList<>();
for ( BsonValue coordinate : polygon ){
for ( BsonValue coordinate : polygon ) {
linearRing.add( convertArrayToCoordinate( coordinate.asArray() ) );
}
GeometryFactory geoFactory = new GeometryFactory();
polyGeometry = new PolyGeometry( geoFactory.createPolygon(linearRing.toArray(new Coordinate[0])) );
}

if(geometry.containsKey("$center")){
polyGeometry = new PolyGeometry( geoFactory.createPolygon( linearRing.toArray( new Coordinate[0] ) ) );
} else if ( geometry.containsKey( "$center" ) ) {
BsonArray circle = geometry.get( "$center" ).asArray();
Coordinate center = convertArrayToCoordinate( circle.get(0).asArray() );
double radius = convertBsonValueToDouble(circle.get(1));
distance = new PolyDouble(radius);
Coordinate center = convertArrayToCoordinate( circle.get( 0 ).asArray() );
double radius = convertBsonValueToDouble( circle.get( 1 ) );
distance = new PolyDouble( radius );

// As GeoJSON does not define a circle shape, we will create a Point instead. Then we can
// check if the distance between the shape and the point is inside the radius.
GeometryFactory geoFactory = new GeometryFactory();
polyGeometry = new PolyGeometry( geoFactory.createPoint(center) );
}

if(geometry.containsKey("$centerSphere")){
polyGeometry = new PolyGeometry( geoFactory.createPoint( center ) );
} else if ( geometry.containsKey( "$centerSphere" ) ) {
BsonArray circle = geometry.get( "$centerSphere" ).asArray();
Coordinate center = convertArrayToCoordinate( circle.get(0).asArray() );
double radius = convertBsonValueToDouble(circle.get(1));
distance = new PolyDouble(radius);
Coordinate center = convertArrayToCoordinate( circle.get( 0 ).asArray() );
double radius = convertBsonValueToDouble( circle.get( 1 ) );
distance = new PolyDouble( radius );

// As $centerSphere works in the spherical instead of the planar coordinate system, we need
// to use the default WGS84 CRS when creating the shape.
GeometryFactory geoFactory = new GeometryFactory(new PrecisionModel(), WGS_84);
GeometryFactory geoFactory = new GeometryFactory( new PrecisionModel(), WGS_84 );
// As GeoJSON does not define a circle shape, we will create a Point instead. Then we can
// check if the distance between the shape and the point is inside the radius.
polyGeometry = new PolyGeometry( geoFactory.createPoint(center) );
polyGeometry = new PolyGeometry( geoFactory.createPoint( center ) );
}

if(polyGeometry == null){
throw new GenericRuntimeException( "$geoWithin arguments needs to be one of the following: $geometry, $box, $polygon, $center, $centerSphere");
if ( polyGeometry == null ) {
throw new GenericRuntimeException( "$geoWithin arguments needs to be one of the following: $geometry, $box, $polygon, $center, $centerSphere" );
}

return new RexCall(
Expand All @@ -1725,27 +1720,29 @@ private RexNode convertGeoWithin( BsonValue bson, String parentKey, AlgDataType
) );
}

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

private static Coordinate convertArrayToCoordinate( BsonArray array ) {
if ( array.size() != 2 ) {
throw new GenericRuntimeException( "Coordinates need to be of the form [x,y]" );
}
double x = convertBsonValueToDouble(array.get(0));
double y = convertBsonValueToDouble(array.get(1));
return new Coordinate(x,y);
double x = convertBsonValueToDouble( array.get( 0 ) );
double y = convertBsonValueToDouble( array.get( 1 ) );
return new Coordinate( x, y );
}

private static double convertBsonValueToDouble(BsonValue bsonValue){

private static double convertBsonValueToDouble( BsonValue bsonValue ) {
Double result = null;
if ( bsonValue.isDouble() ) {
result = bsonValue.asDouble().getValue();
}
if ( bsonValue.isInt32() ) {
int intValue = bsonValue.asInt32().getValue();
result = (double)intValue;
result = (double) intValue;
}
if ( bsonValue.isInt64() ) {
long intValue = bsonValue.asInt64().getValue();
result = (double)intValue;
result = (double) intValue;
}
if ( result == null ) {
throw new GenericRuntimeException( "Legacy Coordinates needs to be of type INTEGER or DOUBLE." );
Expand Down

0 comments on commit bc9d006

Please sign in to comment.