Something that I need to do now and then is generate points along a line at supplied distance. I had never really looked into doing it in QGIS until this question poped up on gis.stackexchange.com. This is a quick blog post because I thought it was a pretty handy little thing to do.
In the development version there is a new method on QgsGeometry
called interpolate
. This method takes a distance and returns a point along a line at that distance. Perfect! We can then just wrap this in a loop and generate a point increasing the distance as we move along
from qgis.core import (QgsFeature, QgsGeometry, QgsVectorLayer, QgsMapLayerRegistry, QgsField) from PyQt4.QtCore import QVariant from qgis.utils import iface def createPointsAt(distance, geom): length = geom.length() currentdistance = distance feats = [] while currentdistance < length: # Get a point along the line at the current distance point = geom.interpolate(currentdistance) # Create a new QgsFeature and assign it the new geometry fet = QgsFeature() fet.setAttributeMap( { 0 : currentdistance } ) fet.setGeometry(point) feats.append(fet) # Increase the distance currentdistance = currentdistance + distance return feats def pointsAlongLine(distance): # Create a new memory layer and add a distance attribute vl = QgsVectorLayer("Point", "distance nodes", "memory") pr = vl.dataProvider() pr.addAttributes( [ QgsField("distance", QVariant.Int) ] ) layer = iface.mapCanvas().currentLayer() # Loop though all the selected features for feature in layer.selectedFeatures(): geom = feature.geometry() features = createPointsAt(distance, geom) pr.addFeatures(features) vl.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(vl)
The above code might look a bit scary at first if you have never done any Python/pyqgis but hopefully the comments will ease the pain a little. The main bit is the createPointsAt
function.
Cool! If we want to use this we can just stick it in a file in the .qgis/python
folder (lets call it pointtools.py) and then run import pointtools
in the python console.
So lets have a go. First select some objects then run the following in the Python Console
import pointtools pointtools.pointsAlongLine(40)
That will generate a point every 40 meters along then selected lines
To generate nodes along different lines, select the new features, then call pointtools.pointsAlongLine(40)
in the Python console.
Simple as that!
(Who knows, someone (maybe me) might even add this as a core object function in QGIS in the future)
Hmm… There is a “Densify geometries” tool in fTools that have same functionality
Not really. That tool creates new vertices on a line, also the new vertices are not equal distance. This generates a new point layer with equal distance points along that line. More useful for labelling a line with distance markers for reporting, etc.
[…] omething that I need to do now and then is generate points along a line at supplied distance. I had never really looked into doing it in QGIS until this question poped up on gis.stackexchange.com. This is a quick blog post because I thought it was a pretty handy little thing to do. In the development version there is a new method on QgsGeometry called interpolate. This method takes a distance and returns a point along a line at that distance. Perfect! We can then just wrap this in a loop and generate a point increasing the distance as we move along……. […]
Hi,
Great tool you ve got there! I am new at Python/Qgis and I was wondering how to make this point feature (not sure what kind object it is??) into a shapefile, within the script?
Thanks!
Great!! now i want to know how to save it to a shape file, within the code, i know how to save with TOC options
Great Nathan !! Thanks.
But I don’t understand why I am not able to see the new layer of points created. The script is working since I have now a new shapefile, but I can’t see it.
Do you have any idea what could be wrong ?
Thanks in advance.
Nice tools Nathan and yes put it in the core library !!!
Well, it’s 2016 now, and alas there’s a crack in the tool.
… line 17, … fet.setAttributeMap( { 0 : currentdistance } )
AttributeError: ‘QgsFeature’ object has no attribute ‘setAttributeMap’
And with the obvious change:
QgsFeature.setAttribute(QString, QVariant): argument 1 has unexpected type ‘dict’
But when I do this:
fet.setAttribute( { 0 : currentdistance.toInt() } )
I get this:
AttributeError: ‘int’ object has no attribute ‘toInt’
Agh! (I give up for today. Having said that – Thanks for the tool, as-is!)
You should use the QChainage plugin. This script is very old and isn’t updated for any of the new APIs.
Ok, I’ll look for the plugin – but the script ~almost~ works, and it is maybe? a good place to start trying to learn a little… Thanks again.