6

I'm trying to figure out a way to plot points along a polyline at distances that I have in a .csv file (not a point layer with valid lat/long).

There seem to be quite a few ways to create points along a line:

However, I have not been able to figure out a way based on a given value.

Here is an example of what I am trying to accomplish with this csv data:

points on line from .csv values

5
  • Are you comfortable using python/pyqgis?
    – YoLecomte
    Nov 9, 2017 at 16:34
  • My python skills are fairly basic, but I commonly use the python console in qgis for basic operations.
    – jamierob
    Nov 9, 2017 at 16:49
  • Do you have many lines ? If yes, how the points can be link to a Line?
    – YoLecomte
    Nov 9, 2017 at 17:06
  • It's just a qgis layer containing a single polyline feature which is not a multi-part feature. So, i think it would be fine to have the input just be the qgis layer name. But if that complicates things, adding a value to the csv of 'routename' (meters, name, routename) would be possible, and then have a matching 'routename' attribute on the polyline feature itself.
    – jamierob
    Nov 9, 2017 at 17:12
  • It would not be necessary. I provide an answer as soon as possible
    – YoLecomte
    Nov 9, 2017 at 17:40

1 Answer 1

5

It's kind of easy to do with a python script that you can run from the editor of the Qgis console.

First, you need to get your line layer and get the feature inside. Then, you need to loop on your csvfile to get the distance and create the point with the interpolate method of QgsGeometry. Finally, add the created point to a new point layer.

The following do the trick, you just need to replace the values in the firsts lines (line_layer, csvfilepath, EPSG) to fit to your data:

import csv
from PyQt4.QtCore import QVariant

#Change as appropriate
layer_name = 'line_truck'
csvfile_path = 'C:/Users/ylecomte/Desktop/test.csv'
EPSG = '29902' # projected in meters units

#get layer and create csv iterator
layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]
csvfile = open(csvfile_path, 'rb')
reader = csv.reader(csvfile, delimiter=';')
header = reader.next()

#prepare output layer
mem_layer = QgsVectorLayer("Point?crs=epsg:"+EPSG, 'point', 'memory')
mem_layer.startEditing()
attr = [QgsField(header[0],QVariant.String),QgsField(header[1],QVariant.Double)]
prov =mem_layer.dataProvider()
prov.addAttributes(attr)
mem_layer.updateFields()

#preform the trick by looping on feature and csv
for feat in layer.getFeatures():
    for row in reader:
        new_feat = QgsFeature()
        new_feat.setGeometry(feat.geometry().interpolate(float(row[0])))
        new_feat.setAttributes(attr)
        new_feat.setAttribute(0, float(row[0]))
        new_feat.setAttribute(1,row[1])
        mem_layer.addFeatures([new_feat])

#save results and add output to the canvas
mem_layer.commitChanges()
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

the new layer is added to your map canvas as a memory layer containing the needed points and the csv data in corresponding fields.

3
  • This is amazing! It worked perfectly to plot the points along the line. Do you know how I would go about attaching the "name" value from the entry in the .csv to the resulting memory layer so other data can be attached to them?
    – jamierob
    Nov 9, 2017 at 22:44
  • 1
    Yes of course. See my edited answer.
    – YoLecomte
    Nov 10, 2017 at 7:31
  • Perfect. You are a life-saver.
    – jamierob
    Nov 10, 2017 at 15:45

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.