2

I'm trying to create points in a new layer with a given distance along all lines of another layer.

Here my function so far:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtCore import QVariant
from qgis.core import *
from qgis.core import (QgsFeature, QgsGeometry,
                   QgsVectorLayer, QgsMapLayerRegistry,
                   QgsField, QGis)
from qgis.gui import *
from qgis.utils import iface
import math

def pointsAlongLine(dist):
  try:
    inputlayer = QgsMapLayerRegistry.instance().mapLayersByName('route')[0]
    print ('route-layer found')
    sum = 0
    sumdistances = []
    epsg = inputlayer.crs().postgisSrid()
    uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
    memlayer = QgsVectorLayer(uri, 'itpoint', 'memory')
    QgsMapLayerRegistry.instance().addMapLayer(memlayer)
    iface.setActiveLayer(inputlayer)
    inputlayer.selectAll()
    feat = inputlayer.selectedFeatures()
    for f in feat:
      length = f.geometry().length()
      print(length)
      for sum in range (0, (math.ceil(length) - dist), dist):
        sumdistances.append(sum)
      geompoints = [f.geometry().interpolate(distance).exportToWkt()
                       for distance in range (0, (math.ceil(length) - dist), dist)]
      memlayer.startEditing()
      prov = memlayer.dataProvider()
      feats = [ QgsFeature() for i in range(len(sumdistances)) ]
      for i, ft in enumerate(feats):
        ft.setAttributes([i])
        if i>(len(geompoints) -1):
            break
        ft.setGeometry(QgsGeometry.fromWkt(geompoints[i]))
      prov.addFeatures(feats)
      memlayer.commitChanges()
      memlayer.updateExtents()
  except IndexError:
    print ('route does not exist')

It seems that all works fine (layer is created and all points calculated and set correctly) but now I realized, that the new created points don't have their geometry defined.

How do I manage that and give them point geometries?

1

Your function create a lot of empty geometries and is way too much complicated. Here is a way to do this with the same approach but without some useless steps + some lines to transfer an attribute to the memlayer...

def pointsAlongLine(dist):
  try:
    inputlayer = QgsMapLayerRegistry.instance().mapLayersByName('ADR_ROUTE__LineString')[0]
    print ('route-layer found')
    epsg = inputlayer.crs().postgisSrid()
    uri = "Point?crs=epsg:" + str(epsg) + "&index=yes"
    memlayer = QgsVectorLayer(uri, 'itpoint', 'memory')
    prov = memlayer.dataProvider()
    prov.addAttributes([QgsField("NAMETEXT", QVariant.String)])
    memlayer.startEditing()
    for f in inputlayer.getFeatures():
      value = f.attribute('NAMETEXT')
      print value
      length = f.geometry().length()
      for distance in range (0, (int(length)), dist):
        feat = QgsFeature()
        feat.setGeometry(f.geometry().interpolate(distance))
        feat.setAttributes([value])   #be careful with the order of the attributes in the list if you add more than one...
        prov.addFeatures([feat])
    memlayer.commitChanges()
    memlayer.updateExtents()
    QgsMapLayerRegistry.instance().addMapLayer(memlayer)
  except IndexError:
    print ('route does not exist')

Let me now and if it's working well

  • You're awesome! it's remarkably faster without the useless steps (I couldn't see) :D – Nico Aug 9 '17 at 13:21
  • @store attributes: is not necessary but because you ask ;-) how could I copy and past a column of the inputlayer into the new memlayer? – Nico Aug 9 '17 at 13:27
  • What is the name of the attribute of input layer and the type? – YoLecomte Aug 9 '17 at 13:30
  • with the attribute "NAMETEXT" are the names of the streets saved (I don't know where to look up which type it is, but therefore it should be a string). – Nico Aug 9 '17 at 13:46
  • I have edit my answer to add attributes NAMETEXT in the memlayer – YoLecomte Aug 9 '17 at 14:03

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.