question 1
You first need to initialize once a layer and create the spatial index using the REST calls:
POST /db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"layer" : "geom",
"lat" : "lat",
"lon" : "lon"
}
and:
POST /db/data/index/node/ HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"name" : "geom",
"config" : {
"provider" : "spatial",
"geometry_type" : "point",
"lat" : "lat",
"lon" : "lon"
}
}
Create a node with lon/lat properties using Cypher via the transactional endpoint:
POST /db/data/transaction/commit HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"statements" : [
{
"statement" : "create (city:City {data}) return id(city)",
"parameters" : {
"data" : {
"name" : "MyTown",
"lon": 15.2,
"lat": 60.1
}
}
}
]
}
and add it to the spatial index - be sure to adopt the node id with the id of the node returned from the previous request:
POST /db/data/ext/SpatialPlugin/graphdb/addNodeToLayer HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"layer": "geom",
"node": "http://localhost:7474/db/data/node/<my_nodeid_goes_here>"
}
In order to enable Spatial play nice with Cypher a hack is required: every geo-indexed node should carry a property called id
with the value of the node id. This can be accomplished with a simple cypher statement (the example below does this for all City nodes):
POST /db/data/transaction/commit HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"statements" : [
{ "statement" : "match (n:City) set n.id=id(n)" }
]
}
With that in place you can use Cypher for geo queries, e.g.:
POST /db/data/transaction/commit HTTP/1.1
Host: localhost:7474
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
{
"statements" : [
{
"statement" : "start city = node:geom('withinDistance:[60.1,15.2, 100.0]') return city",
"parameters" : {}
}
]
}
NB: for withinDistance
you have to specify lat
,lon
, distanceInKm
.
question 2
As described above you need to have a separate REST call for adding a node to the spatial index. This is currently not possible with Cypher directly. As a workaround use LOAD CSV
to create the nodes with lon/lat properties. In a preprocessing step run a statement like MATCH (n:City) where not has(n.id) set n.id = id(n) return id(n) as id
. This will set the id properties (the hack described above) and returns a list of ids of the new nodes. For each of them emit the REST call to add a node to the geo index.
question 3
Has been answered already above :-)