Skip to content

Commit

Permalink
Use Z coordinate for euclidean distance calculation in CypherFunction…
Browse files Browse the repository at this point in the history
…s.distance
  • Loading branch information
murermader committed Oct 20, 2024
1 parent 5028f07 commit ee28cd6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
24 changes: 20 additions & 4 deletions core/src/main/java/org/polypheny/db/functions/CypherFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -469,6 +470,7 @@ public static PolyGeometry point(
return point( PolyMap.of( map ) );
}


@SuppressWarnings("unused")
public static PolyGeometry point( PolyValue map ) {
if ( !map.isMap() ) {
Expand Down Expand Up @@ -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();
Expand All @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,13 @@ 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" );
geometry = convertJsonToPolyGeometry( res.data[0][0] );
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;
}

Expand Down Expand Up @@ -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( """
Expand All @@ -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;
}


Expand Down

0 comments on commit ee28cd6

Please sign in to comment.