2

Is possible to check whether a WKT geometry intersects with another piece of geometry (via Cypher)?

For instance how would one do a spatial search against them to return any that intersect with a given bounding box?

For example, if I have spatially indexed nodes:

@NodeEntity
class Route {
    @GraphId Long id;
    @Indexed(indexType = IndexType.POINT, indexName = "routeSpatial") String wkt
}

and two such instances:

{ wkt: "LINESTRING (12 10, 14 12, 17 12, 18 10) }

and

{ wkt: LINESTRING (18 15, 18 12, 14 9, 14 6, 17 3, 20 3) }

it appears that:

@Query("START n=node:routeSpatial('bbox:[15.000000, 20.000000, 9.000000, 16.000000]') RETURN n")

doesn't return anything despite intersecting with both lines.

Whereas a bounding box fully surrounding both geometries,

@Query("START n=node:routeSpatial('bbox:[7.000000, 24.000000, 2.000000, 17.000000]') RETURN n")

returns both.

Can someone help me please?

Dr Joe
  • 718
  • 5
  • 19

1 Answers1

0

Ok, perhaps here's some answer to the question.

Looking in the neo4j-spatial code, we find the following in file SpatialPlugin.java

@PluginTarget(GraphDatabaseService.class)
@Description("search a layer for geometries in a bounding box. To achieve more complex CQL searches, pre-define the dynamic layer with addCQLDynamicLayer.")
public Iterable<Node> findGeometriesInBBox(
        @Source GraphDatabaseService db,
        @Description("The minimum x value of the bounding box") @Parameter(name = "minx") double minx,
        @Description("The maximum x value of the bounding box") @Parameter(name = "maxx") double maxx,
        @Description("The minimum y value of the bounding box") @Parameter(name = "miny") double miny,
        @Description("The maximum y value of the bounding box") @Parameter(name = "maxy") double maxy,
        @Description("The layer to search. Can be a dynamic layer with pre-defined CQL filter.") @Parameter(name = "layer") String layerName) {
//    System.out.println("Finding Geometries in layer '" + layerName + "'");
    SpatialDatabaseService spatialService = getSpatialDatabaseService(db);

    try (Transaction tx = db.beginTx()) {

        Layer layer = spatialService.getDynamicLayer(layerName);
        if (layer == null) {
            layer = spatialService.getLayer(layerName);
        }
        // TODO why a SearchWithin and not a SearchIntersectWindow?

        List<Node> result = GeoPipeline
                .startWithinSearch(layer, layer.getGeometryFactory().toGeometry(new Envelope(minx, maxx, miny, maxy)))
                .toNodeList();
        tx.success();
        return result;
    }
}

Notice the "TODO why a SearchWithin and not a SearchIntersectWindow?". Looks like the original author of the plugin has had a similar thought.

Dr Joe
  • 718
  • 5
  • 19