1

I have two layers, one point and one line. I need the distance to the closest line from the point layer. Not NNJoin, MMQGIS nor the distance hub in QGIS provided accurate measures. Any ideas?

2
  • 1
    Just to get it right: You want for each point the shortest distance to some line? You are not looking for the distance to vertices but to some position along the lines?
    – Detlev
    Jul 24, 2015 at 6:17
  • Yes. I ended up using the measure tool for each point to the nearest line. We wanted to know what stream was the closest to a camera trap site for a wildlife study.
    – Amy Deane
    Jul 25, 2015 at 15:56

2 Answers 2

3

If you have to measure the distances once again, the following Python code may save you some time.

Have your points and lines loaded as map layers. Change the names 'point' and 'line' in line 4 and 5 resp. to the names of your layers. Copy the code into the Python console.

The function iterates over all points and finds the closest segment of all lines, and writes the closest position along the segment to a list. Then takes the position with the minimum distance to a points and builds a connecting line. The length of the line goes to the field distance.

d_lyr = QgsVectorLayer('LineString?field=distance:float', 'dist', 'memory')
QgsMapLayerRegistry.instance().addMapLayer(d_lyr)

p_lyr = QgsMapLayerRegistry.instance().mapLayersByName('point')[0]
l_lyr = QgsMapLayerRegistry.instance().mapLayersByName('line')[0]
d_lyr = QgsMapLayerRegistry.instance().mapLayersByName('dist')[0]
prov = d_lyr.dataProvider()
feats = []      
for p in p_lyr.getFeatures():
    minDistPoint = min([l.geometry().closestSegmentWithContext(QgsPoint(p.geometry().asPoint())) for l in l_lyr.getFeatures()])[1]
    feat = QgsFeature()
    feat.setGeometry(QgsGeometry.fromPolyline([QgsPoint(p.geometry().asPoint()), QgsPoint(minDistPoint[0], minDistPoint[1])]))
    feat.setAttributes([feat.geometry().length()])
    feats.append(feat)

prov.addFeatures(feats)
d_lyr.updateExtents()
d_lyr.triggerRepaint()

To test the code initiate 2 memory layers, a point layer named 'point' and a line layer named 'line', digitize some features, and run the code.

An example:

enter image description here

1
  • I tried out your answer and it works perfectly. +1
    – xunilk
    Nov 8, 2015 at 11:30
2

The NNJoin plugin uses QgsGeometry.distance, which in turn uses GEOS. It should return the minimum distance:

Returns the minimum distanace between this geometry and another geometry, using GEOS.

So I am a bit surprised that NNJoin does not work as expected (as long as you do not choose to use approximate geometries).

Are you using a non-projected coordinate system? Geos does not support that:

GEOS distance calculations are linear – in other words, GEOS does not perform a spherical calculation even if the SRID specifies a geographic coordinate system.

If you are not using a non-projected coordinate system, it would be interesting to see example data sets. You could also open an issue on the NNJoin issue tracker.

1
  • 1
    I went back and re-ran the NNJoin and it worked. It gave measurement close to the hand calculated ones. Not sure what I did wrong. The data is projected, and I did not use approximate geometries, today. Maybe that was the problem. Thank you.
    – Amy Deane
    Aug 5, 2015 at 21:27

Your Answer

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

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