函数 "eliminate selected polygons" 不适用于 PyQGIS

Function "eliminate selected polygons" doesn't work with PyQGIS

我有一个基于栅格层的矢量图层(校正)。它包含一些小功能,我想将这些功能合并到更大的功能中。 “消除选定的多边形”功能在 QGIS 中使用时似乎可以解决问题,但是当我在 pyQGIS 中使用它时,选定的特征没有被考虑在内。

This is my layer with the selection

This is the expected output, the one from QGIS

This is my actual output, the one from pyQGIS

当我 运行 我的代码时,函数不会触发严重错误。 The first log is my code and the second is the process without any polygon selection.

有人遇到过这个问题吗?是否可以使用另一个类似的功能? 提前致谢

QGIS 版本:3.14 (pi)

OS : Linux Mint 20 Ulyana (Ubuntu focal 20.04)

这是我的代码:

chemin_sortie = "/projet_qgis/pente/donnees_traitement/"
#Input   
correction = chemin_sortie + 'correction' + '.shp'
correction_layer = iface.addVectorLayer(correction, '', 'ogr')
#Output 
pente_vecteur_grand = chemin_sortie + 'pente_vecteur_grand' + '.shp'

#Selection and process
correction_layer.selectByExpression('$area < 500')  
processing.run("qgis:eliminateselectedpolygons", {'INPUT':correction_layer,'MODE':2,'OUTPUT':pente_vecteur_grand})
pente_vecteur_grand_layer = iface.addVectorLayer(pente_vecteur_grand, '', 'ogr')

我做了一个函数,实现了和qgis:eliminateselectedpolygons一样的操作。还有一些差异,我认为这与多边形合并的顺序有关。这个函数是可优化的,但对我有用。

This is my layer with the selection

This is the output with the qgis function with min area

This is the output of the pyqgis function with min area

This is the output with the qgis function with max area

This is the output of the pyqgis function with max area

这是代码:

import types
    
chemin_sortie = "/projet_qgis/pente/donnees_traitement/"
    
# Input   
    correction = chemin_sortie + 'correction' + '.shp'
    correction_layer = iface.addVectorLayer(correction, '', 'ogr')
    
# Selection
    correction_layer.selectByExpression('$area < 500')

# Functions
def get_key(dict, val):
    for key, value in dict.items():
         if val == value:
             return key
def eliminateselectedpolygon(layer, param):
    if isinstance(param, types.BuiltinFunctionType):
        features = layer.getFeatures()
        n=0
        index = QgsSpatialIndex()
        allfeatures = {}
        selectedfeatures = {}

        for f in features:
            value=[]
            n = n+1
            geom = f.geometry()
            aire = geom.area()
            aire = '%.5f' % aire
            aire = float(aire)
            value.append(f)
            value.append(aire)
            allfeatures[f.id()]=value
            index.addFeature(f)
        for f in layer.selectedFeatures():
            selectedfeatures[f.id()]=f.id()
        suppression = []

        while len(selectedfeatures) != 0:
            f_id = min(selectedfeatures.values())
            f = allfeatures[f_id]
            f_geom = f[0]
            ids = index.intersects(f_geom.geometry().boundingBox())
            dict_aire = {}
            for a_id in ids:
                if a_id != f_id and allfeatures[a_id][0].geometry().touches(f_geom.geometry()) and QgsWkbTypes.displayString(int(allfeatures[a_id][0].geometry().intersection(f_geom.geometry()).wkbType())) != "Point" :
                    dict_aire[a_id]=allfeatures[a_id][1]
            a_id = get_key(dict_aire, param(dict_aire.values()))
            a = allfeatures[a_id]
            a_geom = a[0]
            attrs = layer.getFeature(a_id).attributes()
            suppression.append(f_id)
            suppression.append(a_id)
            if a_id in selectedfeatures:
                del selectedfeatures[a_id]
            del allfeatures[a_id]
            index.deleteFeature(a_geom)
            layer.startEditing()
            geom = None
            geom = QgsGeometry.fromWkt('GEOMETRYCOLLECTION()')
            geom = geom.combine(f_geom.geometry())
            geom = geom.combine(a_geom.geometry())
            feat = QgsFeature(layer.fields())
            feat.setGeometry(geom)
            feat.setAttributes(attrs)
            layer.addFeature(feat)
            feat.setId(abs(n))
            layer.commitChanges()
            layer.triggerRepaint()
            value_feat = []
            geom = feat.geometry()
            aire = geom.area()
            aire = '%.5f' % aire
            aire = float(aire)
            value_feat.append(feat)
            value_feat.append(aire)
            allfeatures[feat.id()]=value_feat
            index.addFeature(feat)
            del selectedfeatures[f_id]
            del allfeatures[f_id]
            index.deleteFeature(f_geom)
            n = n + 1
        layer.startEditing()
        for feature in suppression:
            res = layer.deleteFeature(feature)
        layer.commitChanges()
        layer.triggerRepaint()
        return layer
    print("Param should be min or max")
    return None

eliminateselectedpolygon(correction_layer, max)