# Calculating distance between consecutive points in same point layer in QGIS

I have a point layer with close to 60.000 points that depict a river course (pixel extracts from satellite image). CRS of the layer is Geographic (Lat, Long).

The pixels are ordered ascendingly from source to outlet with an `"ID"` and each pixel has latitude and longitude. I want to know the distance in meter between two consecutive points (e.g. between point `"ID"=35144` and `"ID"=35145`, between `"ID"=35145` and `"ID"=35146`, etc.). This sounds very simple but I tried in numerous ways but failed.

I have tried:

• to transform the point layer to a line layer to measure the line segments. However, using the Vector Geometry (points to path) or diverse plugins such as NNJoin or MMQGIS I loose the vertexes (individual pixels) and therefore the point to point distance
• to create a distance matrix but this gets messy too, because it is the same layer. Also, other "nearest neighbour"-tools do not work since it is the same layer.
• to use the field calculator and loop through the rows of my dataset --> but how?

You can use the following script in QGIS Python Editor. It returns the distance in meter for geographic crs.

Note: `ID` field should be integer/numeric. If it is string, you get wrong order like: `1, 10, 11, ..., 2, 20, 21, ..., 3, 30, 31, ...`

``````layer_name = 'POINT_LAYER_NAME'
id_field_name = 'ID'

# get layer by name
layer = QgsProject.instance().mapLayersByName(layer_name)[0]

# Add new field. DIST_TO_NXT: distance to the next feature
layer.updateFields()

# get the sorted feature list
feats = list(layer.getFeatures(request))

# find the field's index
field_index = layer.fields().indexFromName("DIST_TO_NXT")

da = QgsDistanceArea()
da.setEllipsoid(layer.crs().ellipsoidAcronym())
# or maybe
# da.setEllipsoid(QgsProject.instance().ellipsoid())

# skipped the last point, not to get IndexError.
for i in range(len(feats[:-1])):
p1 = feats[i].geometry().asPoint()
p2 = feats[i+1].geometry().asPoint()

distance = da.measureLine(p1, p2)

layer.dataProvider().changeAttributeValues(
{feats[i].id(): {field_index: distance}})
``````

PS: The last distance is always NULL.

• Nice solution, I will also appropriate the last distance with `NULL` (vice versa to @BERA), but maybe this `0` (zero). Jan 26 at 7:38
• Hello. Can you help me with the calculation. I create a layer named POINT_LAYER_NAME by adding 4 points with an ID field. I enter the script and QGIS returns a message, Layer 'POINT_LAYER_NAME': Field -1 from object 2 doesnt exist. Why it happens that way ? Feb 6 at 14:29
• @NikolayYordanov Did you specify a field name in `field_index = layer.fields().indexFromName("DIST_TO_NXT")`. You have to change `DIST_TO_NXT` to your field name. Feb 6 at 21:23
• Thanks, it works fine but when the points are more than 10, something goes wrong. The distance between the points in my work file are approximately 130 meters away. When I add 10 points with an approximate distance of 130 meters the calculation looks like this: 1-1255, 2-139, 3-141, 4-134, 5-133, 6-132, 7-173, 8-158, 9-Null, 10-1126. Where am I wrong ? Feb 7 at 16:01
• @NikolayYordanov You should also specify `id_field_name` (containing values 1, 2, ...10 ). In this example, it is `ID`. And `ID` field should be numeric, not string. Your id field is probably string so QGIS returns the order as 1, 10, 11, 2, 3, 4. ... Feb 8 at 13:28

I'm sure there's some less complicated way, but you can use pyqgis like this:

``````lyr = QgsProject.instance().mapLayersByName('Vertices')[0] #Change Vertices to the name of your layer

orderfield = 'vertex_index' #Change to the name of you order field
distancefield = 'distance' #Field to store the distances in. Add before executing script

features = [[f.id(), f[orderfield], f.geometry()] for f in lyr.getFeatures()] #List all points id, orderfield value and geometry
features.sort(key=lambda x: x[1]) #Sort the list by orderfield
distancefieldindex = lyr.fields().indexFromName(distancefield) #Find index of distancefield

attrmap = {} #A dictionary to store each points id, distance field index and distance in
for e, (f1, f2) in enumerate(zip(features[::1], features[1::1])): #For each point pair, for example point 1 and point2, then point2 and point3
if e==0: #If first point set distance to 0
attrmap[f1[0]]={distancefieldindex:0}
else: #Else calculate the distance between the two points
attrmap[f1[0]]={distancefieldindex:f1[-1].distance(f2[-1])}

lyr.dataProvider().changeAttributeValues(attrmap) #Update the values
print('Done')
``````

I am not sure if this is the best / fastest way, but I think it should work for you:

``````length(
make_line(
\$geometry,
geometry(
get_feature_by_id('*NAME/ID_of_your_layer*', "*ID_field*"+1)
)
)
)
``````

For `"ID"` 1 you will get the length from 1 to 2, for 2 you will get 2 to 3 ... for your last point you won't get a length.

• @ Kadir : thanks for that proposition. The formula is correct and a distance is calculated. However, the results are in degrees and are subsequently rounded to 0 if the decimal number is not chosen with enough digits... (the distance between the points is small, between 10 and 20 meters) . In my properties I had set "meters" for area/distance calculations but this doesn't apply to the layer. How can I first transform the Lat Long of the dataset to something metric before doing the calculation you suggest ? Thanks! Jan 25 at 15:44
• use the transform function to project from a geographic to a metric system: docs.qgis.org/3.22/en/docs/user_manual/expressions/… Jan 26 at 8:12