Distance calculation between neighbouring points

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!

Hi Isoptero, Welcome.

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

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

1 Like

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!

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.

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/

1 Like

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 :slight_smile:
Yeah, sorry for the typos.. I was so sleepy when I was writing the solution :sweat_smile: . Thanks for pointing it out. Updated my answer too :slightly_smiling_face: