4

I have a line geometry and a point geometry. I need to know the distance along the line at the point. I can see the QgsGeometry.interpolate() function but that's the reverse of what I want to do. I have a point, I need the function to return the distance. Is this feature missing in the API?

For those versed in PostGIS, I need something like the ST_Line_Locate_Point() function but in PyQGIS.

4

You're right, this does seem to be missing from the API, both in QgsGeometry and in QgsGeos

QGIS uses GEOS as the geometry engine, and that seems to be missing this option.

You can work around it by iterating over line segments, tallying up their lengths. Once you hit the segment which intersects your point, add on the length from the start of the line to your point, then exit the loop.

In this case, I've set up a simple geometric shape which starts with two lines of length sqrt(2), and made the point half way along the 2nd segment. The result is as expected, 1.5*sqrt(2)

# your point
point_x = 2.5
point_y = 1.5

# your line
gLine = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2),QgsPoint(3,1),QgsPoint(6,1)])
gPoint = QgsGeometry.fromPoint(QgsPoint(point_x,point_y))
lineGeom = gLine.asPolyline() 

# step through line segments
total_len = 0
for seg_start, seg_end in zip(lineGeom, lineGeom[1:]):
   line_start = QgsPoint(seg_start)
   line_end = QgsPoint(seg_end) 
   segment = QgsGeometry.fromPolyline([line_start,line_end])
   print segment.exportToWkt()
   if gPoint.intersects(segment):
       to_point = QgsGeometry.fromPolyline([line_start, QgsPoint(point_x,point_y)])
       total_len += to_point.length()
       break
   else:
       total_len += segment.length()
print total_len

That code gives the cumulative distance along the line from the first vertex, but could tweaked to give similar results to the postgis function, which gives a normalized distance along the line from 0.0 - 1.0

credit to Gene for the segment iteration code here

2

This isn't a PyQGIS solution, but I did something similar about a year ago using the "LRS" plugin in QGIS. In my situation, I needed the distance along a stream (line feature class) to measuring points (GPS measurements in point feature class). The plugin allowed setting a distance within which the points were assumed to intersect the line, even if the GPS was slightly off.

You can find the plugin through QGIS by searching "LRS". Their homepage is here: http://blazek.github.io/lrs/ and has a link to decent documentation. I got it working after a few tries. If I recall, you need to set the input in the calbiration tab and the output location in the measures tab prior to running. It looks like they also have a locate tab for individual measures.

The plugin was written in Python, and you can download their code at http://blazek.github.io/lrs/ to see how they did it, although @Steven Kay's answer is simpler than that if your points are directly on the line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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