1

I have delineated a river network for a large area using a DEM. I have tried different approaches through SAGA GIS and/or ARC GIS. The resulting file in all cases has a simple problem. The river network needs some merging in order to get acceptable results. For example in the image the order 2 segment is divided into 3 different parts. I want it to be merged into 1 record in the attribute table. In the database I have a column "ORDER" stating the order of each segment. I need to find a way to merge the intersecting segments that have the same ORDER number. i.e. in the picture provided I need to merge the "ORDER 2" segments that intersect one to another but keep separate the order 1 segments. This has to be done for all the area (about 11.000 segments so it is very time consuming to do this manually). Also I have 2 other columns: NODE A and NODE B, representing for each line segment where it starts and where it ends.

Left: What I have, Right : What I need to do.

enter image description here

1 Answer 1

1

This can be done with 'qgis:collect' Processing method of Processing Tool Box as in following script:

import processing

registry = QgsProject.instance()

layer = registry.mapLayersByName('river')

feats = [ feat for feat in layer[0].getFeatures() ]

index_field = feats[0].fieldNameIndex('ORDER')

feats = [ feat for feat in layer[0].getFeatures() if feat.attribute(index_field) == 2 ]

epsg = layer[0].crs().postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'line',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    feat.setAttributes([i])

prov.addFeatures(feats)

parameters = {'FIELD' : [], 
              'INPUT' : mem_layer,
              'OUTPUT' : 'TEMPORARY_OUTPUT' }

processing.runAndLoadResults('qgis:collect',
                             parameters)

For testing my approach, I digitized that portion of the river as follows. It can be observed ORDER field in its attributes table.

enter image description here

After running above script in Python Console of QGIS 3.12, I got result of following image. It is observed that collected geometry was "merged" with one unique id. In your case, with 11.000 segments, no connected geometries with same ORDER field should have different ids.

enter image description here

Editing Note:

With your shapefile, following script version works.

import processing

registry = QgsProject.instance()

layer = registry.mapLayersByName('temp2')

feats = [ feat for feat in layer[0].getFeatures() ]

index_field = feats[0].fieldNameIndex('ORDER_')

feats = [ feat for feat in layer[0].getFeatures() if feat.attribute(index_field) == 2 ]

epsg = layer[0].crs().postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'line',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    feat.setAttributes([i])

prov.addFeatures(feats)

parameters = {'FIELD' : [], 
              'INPUT' : mem_layer,
              'OUTPUT' : 'TEMPORARY_OUTPUT' }

processing.runAndLoadResults('qgis:collect',
                             parameters)

However, this is the result:

enter image description here

Is it as expected?

3
  • Thank you !! I am getting some errors when trying to apply this to my data. Can you test it on a sample shapefile I provide? Thanks! 1drv.ms/u/s!AkmYF_SsN2i-k-tC8UKjjHnC5JPu7g?e=uorP5v
    – baskon1
    Commented Mar 7, 2020 at 18:02
  • Result of running my script with your shapefile can be observed in my Editing Note.
    – xunilk
    Commented Mar 7, 2020 at 19:35
  • I had some problems running the script, however I managed to do it. Unfortunately no it doesn't give me what I want..
    – baskon1
    Commented Mar 10, 2020 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.