QGIS Processing – How to Merge Selected Polygons with Adjacent Ones Individually

mergeqgisqgis-3qgis-processingvector

I have a vector layer with polygons representing administrative districts of germany. For every polygon smaller than 500 km² I would like to create bigger polygons by merging each of the small polygons with all its adjacent polygons.

You can find the dataset here under vg250_01-01.utm32s.shape.ebenen\vg250_ebenen_0101\VG250_KRS.shp

In this picture you can see the dataset with my selection of the polygons smaller than 500 km² by the processing tool "selectbyexpression" with the expression "$area < 500000000".

enter image description here

I tried the processing tool "eliminateselectedpolygons", however, it is only able to merge with either the biggest or the smallest adjacent polygon or the one with the longest shared border. Unfortunately, I wasn't able to find a tool that does the same with all adjacent polygons.
I also tried to find a solution with "selectbylocation" and "dissolve", which works fine for the isolated small polygons, but I wasn'a able to make it work with the clusters of small polygons, which will end up in one big polygon.

How can I realize this preferably with QGIS? If this isn't possible with QGIS I'm also open for suggestions with other tools, e.g. R.

Best Answer

I asked the question some time ago, but just recently found the time to work on that problem again.

I wrote a Python-script for QGIS that worked fine for me. I just put it here, if anybody has a similar problem and needs some inspiration for a script. The script takes the active layer in QGIS as input and adds the resulting layer to the project.

from qgis import processing

layer = iface.activeLayer()
provider = layer.dataProvider()
layer.selectByExpression("$area<500000000")
selection = layer.selectedFeatures()

vl = QgsVectorLayer("MultiPolygon?crs=epsg:25832", "temporary_polygons", "memory")
pr = vl.dataProvider()
pr.addAttributes(provider.fields())
vl.updateFields()

for feature in selection:
    layer.removeSelection()
    layer.select(feature.id())
    processing.run('native:selectbylocation', {
                'INPUT': layer,
                'PREDICATE': [4],
                'INTERSECT': QgsProcessingFeatureSourceDefinition(layer.id(), selectedFeaturesOnly=True, featureLimit=-1, geometryCheck=QgsFeatureRequest.GeometryAbortOnInvalid),
                'METHOD': 1})
    
    dis = processing.run('native:dissolve', {
                'INPUT': QgsProcessingFeatureSourceDefinition(layer.id(), selectedFeaturesOnly=True, featureLimit=-1, geometryCheck=QgsFeatureRequest.GeometryAbortOnInvalid),
                'OUTPUT': 'memory:'})
    
    fet = next(dis['OUTPUT'].getFeatures())
    fet.setAttributes(feature.attributes())
    pr.addFeatures([fet])

vl.updateExtents()
QgsProject.instance().addMapLayer(vl)
Related Question