【问题标题】:Function "eliminate selected polygons" doesn't work with PyQGIS功能“消除选定的多边形”不适用于 PyQGIS
【发布时间】:2020-11-06 08:01:17
【问题描述】:

我有一个基于光栅层的矢量图层(校正)。它包含一些小功能,我想将这些功能合并到更大的功能。 在 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

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

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

QGIS 版本:3.14 (pi)

操作系统:Linux Mint 20 Ulyana(Ubuntu 焦点 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')

【问题讨论】:

    标签: python gis qgis


    【解决方案1】:

    我做了一个函数来实现和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)
    

    【讨论】:

      猜你喜欢
      • 2020-01-10
      • 1970-01-01
      • 2017-12-21
      • 2019-09-21
      • 1970-01-01
      • 2020-09-05
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多