2

I have two lines that overlap, so I clip the overlap, and I should get its length in kilometers.

enter image description here

The clip part is ok but I can't find any resources on how to get the length. It can be printed in the console or add a field in the clipped shapefile that contains the km length. I used Calculating line lengths using PyQGIS as a guide but it didn't work.

import processing
from PyQt5.QtCore import QVariant

overlay_layer = QgsProject.instance().mapLayersByName("route2")[0]
bottom_layer = QgsProject.instance().mapLayersByName("route1")[0]
overlap = r'C:\Users\imper\Documents\python\calculate_overlap_lines\overlap.shp'

# clip overlap - works
processing.run("native:clip", {'INPUT': bottom_layer, \
                               'OVERLAY': overlay_layer, \
                               'OUTPUT': overlap})
iface.addVectorLayer(overlap, '', 'ogr')

# get length - doesn't work
overlap_lyr = QgsProject.instance().mapLayersByName("overlap")[0]
for overlap_lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    features = overlap_lyr.getFeatures()
    for f in features:
        geom = f.geometry()
        leng = geom.length()
        res = overlap_lyr.dataProvider().addAttributes([QgsField("Length", QVariant.Int)])
        overlap_lyr.updateFields()
        fieldIndex = overlap_lyr.dataProvider().fieldNameIndex("Length")
        attrFeatMap = {}
        attrMap = { fieldIndex : leng }
        for feature in overlap_lyr.getFeatures():
            attrFeatMap[ feature.id() ] = attrMap
        overlap_lyr.dataProvider().changeAttributeValues(attrFeatMap)

I'm getting this error:

raise QgsProcessingException(msg) _core.QgsProcessingException: There were errors executing the algorithm.

2
  • @BERA , is that what the for loop does? I'm not yet comfortable with PyQGIS so I just copied it from the GIS SE post I linked and replaced the variables.
    – BallpenMan
    Nov 18, 2020 at 8:15
  • 1
    Hi Taras! Yes, I forgot about this one. Will do :D
    – BallpenMan
    Sep 2, 2021 at 7:53

1 Answer 1

2

You are adding the same field for every feature in your layer. I think this should work:

for overlap_lyr in QgsProject.instance().mapLayers().values(): #For each layer in the layer tree
    #Add the field once
    res = overlap_lyr.dataProvider().addAttributes([QgsField("Length", QVariant.Int)])
    overlap_lyr.updateFields()

    with edit(overlap_lyr):
        for f in overlap_lyr.getFeatures(): #For each feature/line in the layer calculate length
            f['Length'] = f.geometry().length()/1000
            overlap_lyr.updateFeature(f)

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.