PyQGIS – Calculate Line Lengths of Road Network Efficiently

geometrylengthlinepyqgis

I have a road network 'TR_ROAD' with EPSG:4283 crs and 1200 features. I am trying to calculate length of each line segment in road by using "length" geometry in PyQGIS.

When I tried below code, the PyQGIS editor got hanged for long time and program terminates.

I followed the existing answers to Calculating line lengths using PyQGIS and Calculating elipsoidal length of line in PyQGIS, but they didn't work for me.

layer = QgsProject.instance().mapLayersByName('TR_ROAD')[0]
features = layer.getFeatures()

for f in features:
    geom = f.geometry()
    leng = geom.length()
    res = layer.dataProvider().addAttributes([QgsField("Length", QVariant.Int)])
    layer.updateFields()


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

Best Answer

You are adding the field once for each feature, you only need to add the field once for the table.

When updating features like this:

with edit(layer):
    ....

I have found it often hangs with many features (thousands).

Try storing the new data in a dictionary, and update with changeAttributeValues.

Like this:

lyr = QgsProject.instance().mapLayersByName('jl_riks_wgs84')[0]
p = lyr.dataProvider()
p.addAttributes([QgsField('Length', QVariant.Double)])
lyr.updateFields()

distance = QgsDistanceArea()
distance.setEllipsoid(lyr.crs().ellipsoidAcronym())

fieldindex = lyr.fields().indexFromName('Length')
attrmap = {} #Dictionary of {feature id: {field index: field value}}

for f in lyr.getFeatures():
    leng = distance.measureLength(f.geometry())
    attrmap[f.id()] = {fieldindex:leng}
p.changeAttributeValues(attrmap)

enter image description here

Related Question