Hi Alireza,
I opened your graph in the neo4j server and looked around, and then also write some Java test code (based on your snippet) to see what I could see. The main conclusion is that I see two nodes (not one) that are in the envelope, nodes with
n.id=2 and
n.id=10.
I've attached screenshots of the Neo4j browser looking at the data, a graph view showing the nodes and the spatial layer connected to them, and a cypher query that lists the key properties. The cypher query I used was:
MATCH (n) WHERE has(n.gtype) RETURN id(n), n.id, n.gtype, n.x, n.y, n.bbox, n.dim, n.eid
Some interesting points I can see:
- There are definitely two nodes with x=1, y=1 which should be inside Envelope(0.5,1.5,0.5,1.5).
- The use of a property 'id' is allowed, but a little confusing because it is easy to think that might be the node id (see that I'm listing the node id and the node property 'id' just to be clear)
- I'm surprised by the fact that there are three different gtype values: 1, 2, 3, which mean POINT, LINESTRING, POLYGON respectively, but clearly these are all points (they have only x,y information). This means that these objects were not created by the Neo4j Spatial library, but created by some other code? How did you create them? I suspect there is something not quite right there.
- The BBox values for POINT objects should be points themselves (ie. (x1,y1) == (x2,y2)). And in fact I see for all objects with gtype==1, this is true. For other objects, you have bigger bounding boxes, which makes sense for the type, but since they are actually only points, it no longer makes sense.
- When I look into the layer node, I see that the GeometryEncoder is the SimplePointEncoder, consistent with the observation that all data are x,y pairs (Points)
- But I see the layer implementation is the EditableLayerImpl, which is more often used for WKT Geometries (allowing LineString and Polygon also).
The test code that I wrote was in Java and based on your sample. The main part of the code looks like this:
SpatialDatabaseService spatial = new SpatialDatabaseService(graphDb);
Layer layer = spatial.getLayer(layerName);
GeometryFactory gf = layer.getGeometryFactory();
Envelope envelope = new Envelope(0.5, 1.5, 0.5, 1.5);
Geometry geom = gf.toGeometry(envelope);
try (Transaction tx = graphDb.beginTx()) {
for (Node node : nodes) {
System.out.println("Node[" + node.getId() + ":" + node.getProperty("id") + "]: " + nodeXY(node) + " - "
+ nodeBBox(node));
}
assertEquals("Only one node should be in envelope", nodes.size(), 2);
tx.success();
}
This test passes on the two nodes that look like Point(1,1) as expected. However, since you probably meant the second one to be a LineString (gtype=2), it probably was supposed to intersect the envelope, not be included. But since you use the SimplePointEncoder, it will be seen as a point at 1,1, so it will be included.
My understanding is that you created the data incorrectly, using a SimplePointEncoder for data that you meant to be LineString and Polygon. I suggest that you rather use the WKT encoder. Do not create the nodes yourself, but use the layer.add(Geometry) to create them for you, and then add your own properties to them afterward, so you are sure the geoemtry information is correctly created.
Regards, Craig