当前位置: 首页 > 知识库问答 >
问题:

如何删除pyqgis中除某些特定图层之外的所有图层?

左丘楷
2023-03-14

我需要为我的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!")

现在,我创建了这个函数来删除所有加载的层,除了我想使用的层。打印出了,这仅仅是因为我试图理解这个问题。

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:创建形状文件的分步示例:

# 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'

你能发现问题出在哪里吗?为什么会出现这种错误?为什么它只发生在第二次跑步之后?

谢谢

共有1个答案

华宣
2023-03-14

更改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)
 类似资料:
  • 我想知道如何使用正则表达式删除除所有图像标记之外的所有内容。 我已经试过了: (?s)^[^ (?s)^([^ 有谁知道如何将这 2 个组合为多个图像? 下面是我想应用它的内容示例: 我期望的结果应该是:

  • 问题内容: 我有一个这样的表: 我正在尝试删除具有3个以上具有相同ID的名称的记录,但要删除所有记录。因此,我试图得到这样的东西: 我不了解如何编写此查询。我已经达到了保留一个记录但没有记录阈值的程度: 给我: 有什么建议?哦,对了,我不在乎合并时会保留哪些记录。 问题答案: 您可以使用CTE做到这一点

  • 问题内容: 我正在寻找一种简单的方法,可以一次从一个超级视图中删除所有子视图,而不是一个一个地删除它们。 我缺少什么? 更新 我的应用有一个main 。我必须添加其他不同的视图作为子视图,以便提供一种导航。 因此,当单击按钮“打开”特定页面时,我需要删除所有子视图并添加新的子视图。 更新2-可行的解决方案(OS X) 我猜苹果已经解决了。 现在,它比以往更容易了,只需致电: 问题答案: 编辑:(感

  • 问题内容: 我想删除指定字符或一组字符之前的所有字符(例如): 现在,我想删除以前的(或更具体地说是)。有什么建议? 问题答案: 使用。只需匹配所有字符,然后将匹配的字符替换为。

  • 我有一个文件夹,我希望拒绝访问,但我希望有一个子目录(及其所有文件和任何子目录)是可访问的。 .htaccess文件需要在“模块”中,因为它的子目录是用户提供的(它们是CMS的插件),每个用户提供的文件夹可能有一个“公共”目录,只有“公共”中的文件和文件夹才可以访问。

  • 我是python的新手,正在为一个特定的任务而苦苦挣扎: 我有一个字符串,它可以包含任何东西,但它总是“结束”相同的。它可以只是一个文件名,一个完整的路径,或者只是一个随机字符串,以一个版本号结尾。 示例: 什么总是相同的(从结尾看)是,如果你到达第二个点,在它前面走2个字符,你总是匹配的部分,我感兴趣。在某个字符串之后剪切所有东西是“容易的”,我自己解决了它--这就是为什么字符串以现在的版本结尾