2

I have a shapefile containing 10 test points like so:

enter image description here

The spatial reference is 2157 - Irish Transverse Mercator

I am wanting to find the distance between each point in Python. Ideally, something like so Finding points that are within a set distance of other points

I tried the below code using fiona and shapely as a starting point

import fiona
import shapely.geometry


with fiona.open(r'c:/test/points.shp') as src:
    for feature in src:
        geom = shapely.geometry.shape(feature["geometry"])
        distance_between_pts = geom.distance(geom)
        print(distance_between_pts)

However this just prints 0.0 ten times.

I'm not sure how to find the distance between each point. Or even if I were able to pick a point and return the points which fall within a certain distance would help

3
  • 1
    Your query asks for the distance between a point and itself, so zero is the correct answer. If you want to compare each point with the other points you need to nest the queries.
    – Vince
    Commented Jun 16, 2022 at 12:00
  • @Vince im not quite sure how to Commented Jun 16, 2022 at 12:03
  • 1
    That's a Python programming task. Best practice for small numbers of features is to cache them in a list and double nest the for loops O(n^2/2)
    – Vince
    Commented Jun 16, 2022 at 12:07

1 Answer 1

4

As @Vince notes in a comment:

Your query asks for the distance between a point and itself, so zero is the correct answer. If you want to compare each point with the other points you need to nest the queries.

However, rather than an actual nested loop, you can use itertools.product to simplify the code:

from itertools import product
import fiona
from shapely.geometry import shape


with fiona.open(r'points.shp') as src:
    for feat1, feat2 in product(src, repeat=2):
        id1, id2 = feat1['id'], feat2['id']

        if id1 == id2: # Don't measure distance against itself.
            continue

        geom1, geom2 = shape(feat1["geometry"]), shape(feat2["geometry"])
        distance_between_pts = geom1.distance(geom2)
        print(id1, id2, distance_between_pts)

Output:

0 1 210
0 2 1250
0 3 1102
0 4 846
1 0 210
1 2 1090
1 3 978
1 4 752
2 0 1250
2 1 1090
2 3 290
2 4 534
3 0 1102
3 1 978
3 2 290
3 4 283
4 0 846
4 1 752
4 2 534
4 3 283

Or if you don't want duplicates (e.g 0->1 and 1->0 distance), you can use itertools.combinations:

from itertools import combinations
import fiona
from shapely.geometry import shape

with fiona.open(r'points.shp') as src:
    for feat1, feat2 in combinations(src, r=2):
        id1, id2 = feat1['id'], feat2['id']

        geom1, geom2 = shape(feat1["geometry"]), shape(feat2["geometry"])
        distance_between_pts = geom1.distance(geom2)
        print(id1, id2, int(distance_between_pts))

Output:

0 1 210
0 2 1250
0 3 1102
0 4 846
1 2 1090
1 3 978
1 4 752
2 3 290
2 4 534
3 4 283
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.