cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! Site migration is underway. Phase 1: replicate users.

Distance calculation between neighbouring points

isoptero
Node Link

I have a sequence of points which are arranged in a 2D grid such as the drawing below:

These points are stored in NEO4J along with their respective cartesian location as:
{
"pid": "P001",
"location": point({srid:7203, x:0, y:0})
}

{
"pid": "P002",
"location": point({srid:7203, x:1, y:0})
}

{
"pid": "P004",
"location": point({srid:7203, x:3, y:0})
}

{
"pid": "P010",
"location": point({srid:7203, x:4, y:1})
}

and so on.

Points do not have a direct relationship to each other, but are connected to a node representing the whole grid:

(:Point {pid:"P001"}) -[:PART_OF]-> (:Grid {gid:"G01"}) <-[:pART_OF]-(:Point {pid:"P002"})

I know that I can calculate the distance between any arbitrary pair of points just doing

MATCH (p1:Point {pid:"P002"})
MATCH (p2:Point {pid:"P004"})
RETURN distance(p1.location,p2.location)

But, how can I automatically calculate the distances between pairs of neighbouring points? That is,
distance(p001,p002)
distance(p002,p004)
distance(p004, p010)

and so on? Please be aware that my dataset has hundreds of sequential points.

Thank you in advance for your help!

1 ACCEPTED SOLUTION

Excellent, it did work, thank you @ganesanmithun323!

Two small typos had to be fixed, so that it would work on Neo4j Browser version: 4.0.3 + Neo4j Browser version: 4.0.3

I'm inserting the edited version of your query here, with my edits in bold, to help other newbies as me:

Replace:
WITH g, apoc.coll.sort( COLLECT (point),"^pid") as points
by:
WITH g, apoc.coll.sortNodes( COLLECT (point),"^pid") as points

and

replace:
RETURN distance(points[ x ].location,points[ x+1 ].location)
by:
RETURN distance(points[ index ].location,points[ index + 1].location)

Full solution is:

MATCH (point: Point)--(g:Grid {qid: "G01"}) 
WITH g, apoc.coll.sortNodes(collect (point), "^pid") AS points
UNWIND RANGE (0,size(points)-2) AS index
RETURN points[index].pid, points[index+1].pid, distance(points[index].location, points[index+1].location)

View solution in original post

8 REPLIES 8

Joel
Ninja
Ninja

Hi Isoptero, Welcome.

Do you have relationships/edges in your graph? is this question related to a relationship?

Sorry @Joel and @ganesanmithun323

In trying to be concise I think I failed to convey the full picture. I have now edited my post with more detail. Have a look.

Many thanks for your interest in my post!

ganesanmithun32
Graph Buddy

what do you mean by consecutive points?
it would be better explain that part since we dont know what your graph is .

Hi isoptero,

Do you want something like the following?

MATCH (a:Point), (b:Point) WHERE toInteger(right(a.pid,1)) = toInteger(right(b.pid,1)) -1
RETURN a.pid, b.pid, distance (a.location, b.location)

Regards,
Elena

Hi @elena.kohlwey

many thanks for your interest in my post. I believe your solution is close to what I want. The only drawback is that point id is not necessarily sequential. I have edited my post aiming for clarity. Have a look.

ganesanmithun32
Graph Buddy
MATCH (point : Point) --(g:Grid) 
WITH g, apoc.coll.sortNodes( COLLECT (point),"^pid") as points
UNWIND RANGE (0,SIZE(points)-2) as index 
RETURN distance(points[index].location,points[index+1].location)

taking all the nodes connected to grid , and then sorting based on pid property .
iterating over size(node list) - 1 and finally computing distance between all consecutive pairs .

i assumed that you want to compute between points in same grid . But if you dont want , you can just remove the relation to grid in the above query in the first line.

you can find more apoc list functions here -> https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.5/utilities/collection-list-functions/

Excellent, it did work, thank you @ganesanmithun323!

Two small typos had to be fixed, so that it would work on Neo4j Browser version: 4.0.3 + Neo4j Browser version: 4.0.3

I'm inserting the edited version of your query here, with my edits in bold, to help other newbies as me:

Replace:
WITH g, apoc.coll.sort( COLLECT (point),"^pid") as points
by:
WITH g, apoc.coll.sortNodes( COLLECT (point),"^pid") as points

and

replace:
RETURN distance(points[ x ].location,points[ x+1 ].location)
by:
RETURN distance(points[ index ].location,points[ index + 1].location)

Full solution is:

MATCH (point: Point)--(g:Grid {qid: "G01"}) 
WITH g, apoc.coll.sortNodes(collect (point), "^pid") AS points
UNWIND RANGE (0,size(points)-2) AS index
RETURN points[index].pid, points[index+1].pid, distance(points[index].location, points[index+1].location)

Glad it helped
Yeah, sorry for the typos.. I was so sleepy when I was writing the solution . Thanks for pointing it out. Updated my answer too

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online