【问题标题】:How to remove all layers *except* some specific ones in pyqgis?如何删除所有层*除了*pyqgis中的一些特定层?
【发布时间】:2021-02-13 19:29:44
【问题描述】:

我需要为我的 QGIS 项目加载几个矢量图层,以便在每个矢量图层中测试我的脚本的每个功能。但是,最后我只想处理一两层感兴趣的层并丢弃其他层,所以我想自动执行此操作。

我在一些层上成功地做到了,但有一层给我带来了问题,我还没有弄清楚原因。

这里有一些代码:

加载层(这些不应该是问题几乎肯定):

a2 = iface.addVectorLayer(path + ardida2, "", "ogr")
if not a2:
  print("Layer failed to load!")
  
a3 = iface.addVectorLayer(path + ardida3, "", "ogr")
if not a3:
  print("Layer failed to load!")

现在这是我创建的功能,用于删除所有已加载的图层,除了我想要使用的图层。 prints where 只是因为我试图理解这个问题。

def RemoveAllLayersExcept(*layers):
    layer_ids = []
    for l in layers:
        layer_ids.append(l.id())
    print('layer_ids', layer_ids)
    for lyr in QgsProject.instance().mapLayers():
        print(lyr)
        if lyr not in layer_ids:
            print('not')
            QgsProject.instance().removeMapLayer(lyr)
        else:
            pass

然后我创建了一个新层 - 导致我出现问题的层。稍后我需要在迭代过程中编辑该层。我按照 OpenSourceOptions 教程中名为 PyQGIS: Create a Shapefile 的分步示例进行操作:

# OPENSOURCEOPTIONS TUTORIAL - PYQGIS: Create a Shapefile

# create fields
layerFields = QgsFields()
layerFields.append(QgsField('ID', QVariant.Int))
layerFields.append(QgsField('Value', QVariant.Double))
layerFields.append(QgsField('Name', QVariant.String))

# Now define the file path for the new shapefile
# Note: the CRS used here is NAD 1983 UTM Zone 11 N

fn = 'D:/Sara/Trabalho/QGIS/pnogas/fireball_points.shp'
writer = QgsVectorFileWriter(fn, 'UTF-8', layerFields, QgsWkbTypes.Point,QgsCoordinateReferenceSystem('EPSG:26912'), 'ESRI Shapefile')

# For each feature we need to set the geometry (in this case a point)
# set the attribute values, then add it to the vector layer. 
feat = QgsFeature() # create an empty QgsFeature()
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(cx14, cy14)))   # create a point and use it to set the feature geometry
feat.setAttributes([1, 1.1, 'one']) # set the attribute values
writer.addFeature(feat) # add the feature to the layer

layer_fireball = iface.addVectorLayer(fn, '', 'ogr')
if not layer_fireball:
  print("Layer failed to load!")
del(writer)

然后我删除我不感兴趣的图层:

RemoveAllLayersExcept(layer, layer_fireball)

就是这样。当我第一次运行该程序时,什么也没有发生。这是我得到的:

layer_ids ['COS2018_ardida2018_3_clip_cbf56f4b_e668_4c2e_9259_7d22d5943097', 'fireball_points_f92b32e0_f8bf_42c1_95e6_b317ddf6ee84']
COS2018_ardida2018_2_clip_45b241c4_fb9b_4654_9916_5ff08514c559
not
COS2018_ardida2018_3_clip_cbf56f4b_e668_4c2e_9259_7d22d5943097
fireball_points_f92b32e0_f8bf_42c1_95e6_b317ddf6ee84

这符合我的预期。但在第二次和第 n 次,我得到:

Layer failed to load!
Traceback (most recent call last):
  File "C:\PROGRA~1\QGIS3~1.10\apps\Python37\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "<string>", line 676, in <module>
  File "<string>", line 104, in RemoveAllLayersExcept
AttributeError: 'NoneType' object has no attribute 'id'

你能发现问题出在哪里吗?为什么会出现这个错误?为什么它只发生在第二次运行?

谢谢!

【问题讨论】:

  • 我对 PyQGIS 不熟悉。但是,该错误表明for l in layers: 生成的l 值具有None 值。这意味着传递给RemoveAllLayersExcept()*layers 参数之一就是那个值。
  • @martineau 没错,但我不明白为什么会这样。甚至只有第一次运行没有返回错误的事实。
  • 问题与在 call 中传递给RemoveAllLayersExcept() 的参数有关。但是,您的问题中的任何代码都没有显示这是如何发生的,因此非常怀疑是否有人能够帮助您。

标签: python python-3.x geometry layer pyqgis


【解决方案1】:

更改RemoveAllLayersExcept 方法如下:

def RemoveAllLayersExcept(*keep_layers):
    layers = QgsProject.instance().mapLayers().values()
    will_be_deleted = [l for l in layers if l not in keep_layers]

    for layer in will_be_deleted:
        QgsProject.instance().removeMapLayer(layer)

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多