diff --git a/core/src/main/java/org/polypheny/db/functions/CypherFunctions.java b/core/src/main/java/org/polypheny/db/functions/CypherFunctions.java index afdc420dbc..82e3bce487 100644 --- a/core/src/main/java/org/polypheny/db/functions/CypherFunctions.java +++ b/core/src/main/java/org/polypheny/db/functions/CypherFunctions.java @@ -47,6 +47,7 @@ import org.polypheny.db.type.entity.relational.PolyMap; import org.polypheny.db.type.entity.spatial.GeometryTopologicalException; import org.polypheny.db.type.entity.spatial.PolyGeometry; +import org.polypheny.db.type.entity.spatial.PolyPoint; import static org.polypheny.db.type.entity.spatial.PolyGeometry.WGS_84; import static org.polypheny.db.type.entity.spatial.PolyGeometry.WGS_84_3D; @@ -469,6 +470,7 @@ public static PolyGeometry point( return point( PolyMap.of( map ) ); } + @SuppressWarnings("unused") public static PolyGeometry point( PolyValue map ) { if ( !map.isMap() ) { @@ -546,18 +548,32 @@ public static PolyGeometry point( PolyValue map ) { return PolyGeometry.of( geometryFactory.createPoint( coordinate ) ); } + @SuppressWarnings("unused") public static PolyDouble distance( PolyValue p1, PolyValue p2 ) { - PolyGeometry g1 = p1.asGeometry(); - PolyGeometry g2 = p2.asGeometry(); + PolyPoint g1 = p1.asGeometry().asPoint(); + PolyPoint g2 = p2.asGeometry().asPoint(); + + if ( !Objects.equals( g1.getSRID(), g2.getSRID() ) ) { + throw new GenericRuntimeException( "Cannot compute point.distance(%s, %s) because of different SRIDs.".formatted( g1, g2 ) ); + } + Integer srid = g1.getSRID(); try { + if ( g1.hasZ() && g2.hasZ() ) { + if ( srid == 0 ) { + return new PolyDouble( + Math.sqrt( Math.pow( g2.getX() - g1.getX(), 2 ) + Math.pow( g2.getY() - g1.getY(), 2 ) + Math.pow( g2.getZ() - g1.getZ(), 2 ) ) + ); + } + } return new PolyDouble( g1.distance( g2 ) ); } catch ( GeometryTopologicalException e ) { throw new GenericRuntimeException( e ); } } + @SuppressWarnings("unused") public static PolyBoolean withinBBox( PolyValue point, PolyValue bbox ) { PolyGeometry g = point.asGeometry(); @@ -568,10 +584,10 @@ public static PolyBoolean withinBBox( PolyValue point, PolyValue bbox ) { private static double convertPolyValueToDouble( PolyValue value ) { // This should be sufficient, as all numerical values from Cypher are stored as BigDecimal. - if (value.isString()){ + if ( value.isString() ) { return Double.parseDouble( value.toString() ); } - if (value.isDouble()){ + if ( value.isDouble() ) { return value.asDouble().doubleValue(); } diff --git a/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java b/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java index e7e6022072..9a5f6a53cf 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java +++ b/core/src/main/java/org/polypheny/db/type/entity/spatial/PolyGeometry.java @@ -939,9 +939,7 @@ public String toString() { public @NotNull String toWKT() { - if ( geometryType == PolyGeometryType.POINT && - jtsGeometry instanceof Point point && - !Double.isNaN( point.getCoordinate().z ) ) { + if ( isPoint() && jtsGeometry instanceof Point point && !Double.isNaN( point.getCoordinate().z ) ) { Coordinate coordinate = point.getCoordinate(); return String.format( "SRID=%d; POINT(%s %s %s)", diff --git a/dbms/src/test/java/org/polypheny/db/cypher/CypherGeoFunctionsTest.java b/dbms/src/test/java/org/polypheny/db/cypher/CypherGeoFunctionsTest.java index d6a8610bea..1a1db10437 100644 --- a/dbms/src/test/java/org/polypheny/db/cypher/CypherGeoFunctionsTest.java +++ b/dbms/src/test/java/org/polypheny/db/cypher/CypherGeoFunctionsTest.java @@ -55,9 +55,6 @@ public void createPointTest() { assert geometry.getSRID() == 0; assert geometry.asPoint().getX() == 1.0; assert geometry.asPoint().getY() == 2.0; - // TODO: fix this - // JTS Geometry WKT Representation is hardcoded to 2 dimensions - // https://github.com/locationtech/jts/blob/6a9af07059671bdc6e62542c9739137ab53fd4d8/modules/core/src/main/java/org/locationtech/jts/io/WKTWriter.java#L139 assert geometry.asPoint().getZ() == 3.0; res = execute( "MATCH (n) RETURN point({longitude: 55.5, latitude: 12.2, height: 100}) AS point" ); @@ -65,7 +62,6 @@ public void createPointTest() { assert geometry.getSRID() == PolyGeometry.WGS_84_3D; assert geometry.asPoint().getX() == 55.5; assert geometry.asPoint().getY() == 12.2; - // TODO: fix this assert geometry.asPoint().getZ() == 100.0; } @@ -117,7 +113,7 @@ public void distanceTest() { // Compute distance in euclidean coordinate system with 3 coordinates execute( """ CREATE (a:Dot3D {x: 1, y: 1, z:1}), - (b:Dot3D {x: 2, y: 2, z:3}), + (b:Dot3D {x: 2, y: 2, z:2}), (a)-[:CONNECTED]->(b); """ ); res = execute( """ @@ -128,7 +124,7 @@ public void distanceTest() { RETURN point.distance(d1, d2) AS distance; """ ); assert res.data[0].length == 1; - assert Math.abs( PolyValue.fromJson( res.data[0][0] ).asDocument().get( new PolyString( "value" ) ).asDouble().doubleValue() - Math.sqrt( 2 )) < 1e-9; + assert Math.abs( PolyValue.fromJson( res.data[0][0] ).asDocument().get( new PolyString( "value" ) ).asDouble().doubleValue() - 1.7320508075688772) < 1e-9; }