4

I have a situation as you see below:

enter image description here

I have imported the .dxf file from AutoCAD, which finally looks like the above. Each layer includes lines and polylines. I need to have them merged with each other.

I found some similar problems here:

Batch process for merging features in multiple layers

Merging multiple temporal inputs in QGIS Graphical Modeler

which utilizes the graphical modeler. It does make sense, although I haven't used the graphical modeler so far, therefore I don't know how to start.

Is there a chance to make this merge in one go?

1 Answer 1

6

If you are open to a PyQGIS solution, it can be done very simply:

p = QgsProject.instance()

# get all layers in project
lyrs = p.mapLayers().values()

# filter layers if necessary (could also filter by geometry type)
line_layers = [x for x in lyrs if 'line' in x.name().lower()]

# merge layers (don't forget to specify your coordinate system)
merged = processing.run("native:mergevectorlayers", {'LAYERS':line_layers,'CRS':QgsCoordinateReferenceSystem('EPSG:4326'),'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']

# add to canvas
p.addMapLayer(merged)

To merge layers per group (using the hierarchy in your screenshot):

# reference to the project
p = QgsProject.instance()

# reference to the layer tree
root = p.layerTreeRoot()

# reference to the group called 'Batch'
group = root.findGroup('Batch')

# loop through all the items in the Batch group
for child in group.children():
    # find sub-groups
    if isinstance(child, QgsLayerTreeGroup):      
        sub_group = child
        
        # empty list to store the layers ready to merge
        lyrs_to_merge = []

        # find line layers in the sub-group
        for sub_child in sub_group.children():
            # check whether the child is a layer and has 'line' in its name
            if isinstance(sub_child, QgsLayerTreeLayer) and 'line' in sub_child.name().lower():
                lyr = sub_child
                # add to list
                lyrs_to_merge.append(lyr.layerId())
        
        # perform merge
        merged = processing.run("native:mergevectorlayers", {'LAYERS':lyrs_to_merge,'CRS':QgsCoordinateReferenceSystem('EPSG:4326'),'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']    
        
        # name the merged layer
        merged.setName('merged | ' + sub_group.name())
        
        # add layer to project, but prevent adding to canvas and layer tree (with False) 
        p.addMapLayer(merged, False)
        
        # insert the merged layer at the top of each sub-group
        sub_group.insertLayer(0, merged)

Result:

enter image description here

9
  • It works, but I need to have it merge not as a whole, but within the given group. How could I change the code?
    – Geographos
    Commented Nov 7, 2022 at 9:25
  • see my updated answer
    – Matt
    Commented Nov 7, 2022 at 13:07
  • I see no reaction. Shall I select some particular layer for it?
    – Geographos
    Commented Nov 7, 2022 at 14:08
  • I have added a screenshot of the resulting layer tree. Each sub-group has a merged layer inserted at the top.
    – Matt
    Commented Nov 7, 2022 at 14:15
  • I see nothing executed in my QGIS, although he code looks fine. Your answer has been accepted anyway. I will figure out the error from my side. Thank you!
    – Geographos
    Commented Nov 7, 2022 at 16:28

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.