You can get the same effect of an index-backed within-polygon search by first converting the polygon to a bounding box, searching and then filtering by the original polygon. This requires two additional functions:
In that video I had written the two functions in the namespace amanzi.*, however, since then we have created a newer library called spatial-algorithms that has two functions:
Are r.first_coor and r.last_coor really the bottom left and top right of the polygon? The names make me think they are just the first and last coordinates of the polygon.
Do you perhaps have a list of coordinates for the entire polygon, because that is what you really need. For example, I could imagine you have a r.coordinates which is an array of point instances. Then you could do the following:
MATCH (r:region {region_name: '12 Ulu'}
WITH spatial.boundingBox(r.coordinates) as bbox
MATCH (p:position {deviceid: 2284} where point.withinBBox(p.positions_point, bbox.min, bbox.max)
CREATE (p)-[:IN]->(r)
I do not know why you wanted to use APOC to create relationships, so I replaced that with normal Cypher.
Yes r.first_coor and r.last_coor represent the min and max points of the polygon.
Currently I have polygon data type, which is long list of coordinates.
I have also looked into the github link and checked all the latest versions, using the link below.
There is no version for neo4j v4.4 which is what I am currently using.
I have installed the latest plugin spatial-algorithms-algo-0.2.5-neo4j-4.2.11.jar but when I try to find the spatial.algo.withinPolygon within the neo4j browser, it is unable to find it.
call dbms.procedures()
yield name where name starts with 'spatial.algo.withinPolygon'
return name
Is there a version of spatial algorithms meant for neo4j 4.4?
I took a look at this over the weekend, and there is no spatial-algorithms release for Neo4j 4.3 or Neo4j 4.4. So I did a test port to 4.3, but there are some changes in the kernel relating to cursor closing that has prevented completion of this port. I'll see if I can get some support to fix that, and then port to 4.4 as well later.
The other option you have is to try extracting just the withinPolygon function or try use the older version from the spatial3d library.
I appreciate that you looked into my issue regarding the spatial-algorithms.
Personally, I think I will wait for more news on the fix. I honestly have no idea how to extract the withinPolygon and since my organization still plans on using the latest Neo4j 4.4, I do not think trying the older version of spatial3d library would be of any use either.
Lastly, I was hoping if there any additional resources on how to use withinPolygon and other use cases for it, utilizing Python drivers to display onto Neomap or into OpenStreetMap. Other than the sources listed below:
The main challenge was the preceding port to Neo4j 4.3, which involved some bigger algorithm changes to cope with a change in behaviour in the Neo4j kernel. But once that was done, porting to Neo4j 4.4 was trivial.
I have tried to import the jar file in the link you provided below.
Unfortunately, when I restarted my Neo4j 4.4.11 desktop application to apply the changes, it refused to connect to my Neo4j db instance
A coworker of mine who uses Neo4j 4.4.12 desktop application was able to connect to Neo4j db instance after importing the plugin, however it still produces 0 results using the query below to check
call dbms.procedures()
yield name where name starts with 'spatial.algo.withinPolygon'
return name
That is the latest update I have for using the spatial algorithms
As a workaround, I currently using this function
match (n:Node)
call spatial.intersects('geom',n)
yield Node return node.name
The below function is what I use to create the node
unwind [{name:'a',latitude:0.79157,longitude:101.3333}] as point
merge (n:Node{name:point.name,
latitude:point.latitude,
longitude:point.longitude})
Note, I have imported shape file prior to this to extract my POLYGON data
The spatial.algo.withinPolygon() function is a function not a procedure, so you will not find it using dbms.procedures() but need to look using dbms.functions().
Also, the procedure spatial.intersects() is provided by the spatial library, which itself is not ported to Neo4j 4.4. The latest release of that library is for 4.2.
Using the two libraries together should work, but it not something I've tested much. But you should then use the 4.2 version of both libraries in Neo4j 4.2. If you want to use Neo4j 4.4, only the spatial-algorithms library has been ported to that so far.
Am am not very familiar with Neo4j Desktop, so I do not know for sure why it could not connect, but if you can find the Neo4j log files (neo4j.log and debug.log) it is very likely that they will contain the errors encountered starting Neo4j. If you find that, you can post it here and we can see what the problem is.
Appreciate the comments, for now I am just using the link below
I was able to call the function spatial.algo.withinPolygon() successfully.
But I am unclear as to how to use the information in my imported shape file and using it with the spatial.algo function. and I keep getting the error below
OK. So it looks like you are using two libraries together. This means you need to understand the different internal structures of the geometries as understood by those two libraries in order to pass data from one to the other. A polygon in the spatial library could be a WKT string, while a polygon in the algorithms library is always a list of points, and it will never understand WKT, so you need to convert it to a list of points.
Also, the query you are using to get the polygon will not work because you are looking for a geometry on the SpatialLayer node which never has geometries, so s.geom will always have value null, and that is why you got that error.
The SpatialLayer node is just the root of a data tree containing all the data you want. You can traverse that tree using Cypher, but that is not the intention. It is intended to be searched using the spatial procedures provided by the spatial library.
While I could point out errors in the queries you provide here, I think in order to properly support you, I would need to know what the original data is that you imported, and what type of queries you are trying to perform? For example, it seems like you have two different types of data and want to use one to search the other. I could speculate further, but it would be better if you simply describe the situation here, and then I can give more comprehensive support.
For example, you could say:
We have polygons imported as WKT from, shapefiles
We have points imported as latitude/longitude properties of nodes
We want to find a particular polygon from the shapefile
And use it to find points within the polygon
Then I could describe a query that would work for this scenario.
We have polygons imported as WKT from, shapefiles
We have points imported as latitude/longitude properties of nodes
We want to find a particular polygon from the shapefile
And use it to find points(from the imported nodes) within the polygon
Lastly, the shapefiles I imported as WKT layer, has null values as shown below.
I notice the property values stored in the SpatialLayer node is in string and uses () brackets, and it cannot be treated as a list, I have tried using the apoc.convert.toList and it still converts to string and not as a list.
Hope that this helps. Is there any function or procedure that can help to convert info in one type of spatial library to spatial algo library.
Converting WKT into a list of native points for use in the spatial.algo.withinPolygon function
Before I explain more about how to fix those two points, have you considered just using the spatial library by itself? I mean store both polygons and points using that library, instead of mixing and matching two different ways of working with geospatial data? The advantage would be not having to worry about WKT conversion. The disadvantage would be slower searching for points because the spatial index used by the spatial library is not nearly as well optimized as the spatial index used by native Neo4j points.
Anyway, back to the main answer. The first thing is to find the polygon. The Cypher expression you used would find all kinds of nodes in the graph, only some of which are actual data nodes, which is why you are getting null values (you are finding index nodes, and anything connected to the layer, even config setting nodes). You could write a more complex Cypher expression to avoid this, but that would be missing the point of the spatial library. It comes with a number of procedures for spatial search. I don't know what polygon you are looking for, but can suggest a few functions, like spatial.withinDistance, or spatial.intersects. Then you will have the polygon (or polygons) with WKT geometries, and can use that for the point search.
The second thing would be to convert the WKT into points. This is not trivial, because there is no existing function I can see that does this job directly. The spatial library has a function spatial.asGeometrywhich converts the WKT into an internal Neo4j geometry type, but no other code understands that type. You need a function that generates the list of points from that type. This would be very easy to write, but currently does not exist in either of the libraries you are trying to use. It could probably be added to either one, or written by yourself.