Skip to content

Commit

Permalink
add function to convert neo4j native point(s) to WKT format
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy2003 committed May 30, 2024
1 parent 95f88c4 commit 0324b62
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/main/java/org/neo4j/gis/spatial/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,8 @@ public interface Constants {
int GTYPE_MULTILINESTRING = 5;
int GTYPE_MULTIPOLYGON = 6;


int SRID_COORDINATES_2D = 4326;
int SRID_COORDINATES_3D = 4979;

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.gis.spatial.encoders.neo4j;

import org.neo4j.gis.spatial.Constants;
import org.neo4j.values.storable.CoordinateReferenceSystem;

public class Neo4jCRS implements org.neo4j.graphdb.spatial.CRS {
Expand Down Expand Up @@ -51,7 +52,7 @@ public int dimensions() {
public static Neo4jCRS findCRS(String crs) {
return switch (crs) { // name in Neo4j CRS table
case "WGS-84", "WGS84(DD)" -> // name in geotools crs library
makeCRS(4326);
makeCRS(Constants.SRID_COORDINATES_2D);
case "Cartesian" -> makeCRS(7203);
default -> throw new IllegalArgumentException("Cypher type system does not support CRS: " + crs);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@

package org.neo4j.gis.spatial.functions;

import static org.neo4j.gis.spatial.Constants.SRID_COORDINATES_2D;
import static org.neo4j.gis.spatial.Constants.SRID_COORDINATES_3D;

import java.util.Arrays;
import java.util.Collection;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.io.WKTWriter;
import org.neo4j.gis.spatial.Layer;
import org.neo4j.gis.spatial.procedures.SpatialProcedures.GeometryResult;
import org.neo4j.gis.spatial.utilities.SpatialApiBase;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
import org.neo4j.procedure.UserFunction;
Expand Down Expand Up @@ -54,5 +62,38 @@ public Object asGeometry(@Name("geometry") Object geometry) {
return toNeo4jGeometry(null, geometry);
}

@UserFunction("spatial.convert.nativeToWkt")
@Description("Converts a point or point array to WKT")
public String nativeToWkt(@Name("data") Object object) {
if (object instanceof Point point) {
var coordinate = convertToCoordinate(point);
return WKTWriter.toPoint(coordinate);
}
if (object instanceof Point[] points) {
var coordinates = Arrays.stream(points).map(SpatialFunctions::convertToCoordinate)
.toArray(Coordinate[]::new);
return WKTWriter.toLineString(coordinates);
}
if (object instanceof Collection<?> points) {
var coordinates = points.stream()
.filter(Point.class::isInstance)
.map(Point.class::cast)
.map(SpatialFunctions::convertToCoordinate)
.toArray(Coordinate[]::new);
return WKTWriter.toLineString(coordinates);

}
throw new IllegalArgumentException("Unsupported type: " + object.getClass());
}

private static Coordinate convertToCoordinate(Point point) {
double[] coordinate = point.getCoordinate().getCoordinate();
if (point.getCRS().getCode() == SRID_COORDINATES_3D) {
return new Coordinate(coordinate[0], coordinate[1], coordinate[2]);
} else if (point.getCRS().getCode() == SRID_COORDINATES_2D) {
return new Coordinate(coordinate[0], coordinate[1]);
} else {
throw new IllegalArgumentException("Unsupported CRS: " + point.getCRS().getCode());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
import org.geotools.referencing.CRS;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.neo4j.gis.spatial.Constants;
import org.neo4j.gis.spatial.SpatialDatabaseException;

/**
Expand Down Expand Up @@ -54,8 +55,8 @@ public static CoordinateReferenceSystem getCRS(String crsText) {

public static Integer getEPSGCode(CoordinateReferenceSystem crs) {
try {
// TODO: upgrade geotools to avoid Java11 failures on CRS.lookupEpsgCode
return (crs == WGS84) ? Integer.valueOf(4326) : (crs == GENERIC_2D) ? null : CRS.lookupEpsgCode(crs, true);
return (crs == WGS84) ? Integer.valueOf(Constants.SRID_COORDINATES_2D)
: (crs == GENERIC_2D) ? null : CRS.lookupEpsgCode(crs, true);
} catch (FactoryException e) {
System.err.println("Failed to lookup CRS: " + e.getMessage());
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

package org.neo4j.gis.spatial.functions;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;

import java.util.Map;
Expand Down Expand Up @@ -69,4 +71,19 @@ public void literal_geometry_return() {
"WITH spatial.asGeometry({latitude: 5.0, longitude: 4.0}) AS geometry RETURN geometry", "geometry");
assertInstanceOf(Geometry.class, geometry, "Should be Geometry type");
}

@Test
public void testPointToWkt() {
Object wkt = executeObject("return spatial.convert.nativeToWkt(point({longitude: 1, latitude: 2})) as wkt",
"wkt");
assertThat(wkt, equalTo("POINT ( 1 2 )"));
}

@Test
public void testPointArrayToWkt() {
Object wkt = executeObject(
"return spatial.convert.nativeToWkt([point({longitude: 1, latitude: 2}), point({longitude: 3, latitude: 4}) ]) as wkt",
"wkt");
assertThat(wkt, equalTo("LINESTRING (1 2, 3 4)"));
}
}

0 comments on commit 0324b62

Please sign in to comment.