【问题标题】:How to iterate over features of two different qgis layers?如何迭代两个不同 qgis 层的特征?
【发布时间】:2026-01-06 03:40:01
【问题描述】:

回答:感谢@nils-werner 和@goyo 为我指明了正确的方向:我需要通过Move iterTwo = layerTwo.getFeatures() right before for feat in iterTwo :

layerOne = QgsVectorLayer( '~/FirstLayer.shp', 'layerOne', 'ogr')
layerTwo = QgsVectorLayer( '~/SecondLayer.shp', 'layerTwo', 'ogr')

iterOne = layerOne.getFeatures()

for feature in iterOne: 
    layerOneId = feature.attributes()[0]
    print layerOneId
    iterTwo = layerTwo.getFeatures()
    for feat in iterTwo :
        layerTwoId = feat.attributes()[0]
        print "LayerOneId",LayerOneId, "LayerTwoId", LayerTwoId"
        # do something if LayerOneId == LayerTwoId

我有两层,我想比较一下:

layerOne = QgsVectorLayer( '~/FirstLayer.shp', 'layerOne', 'ogr')
layerTwo = QgsVectorLayer( '~/SecondLayer.shp', 'layerTwo', 'ogr')

iterOne = layerOne.getFeatures()
iterTwo = layerTwo.getFeatures()
for feature in iterOne: 
    layerOneId = feature.attributes()[0]
    print layerOneId
    for feat in iterTwo :
        layerTwoId = feat.attributes()[0]
        print "LayerOneId",LayerOneId, "LayerTwoId", LayerTwoId"
        # do something if LayerOneId == LayerTwoId

此代码在 LayerOne 的第一次迭代中正确运行,但随后仅迭代第一层而不检查第二层。结果如下所示:

LayerOneId, 0

LayerOneId, 0, LayerTwoId, 0

LayerOneId, 0, LayerTwoId, 1

...

LayerOneId, 0, LayerTwoId, n

LayerOneId, 1

LayerOneId, 2

...

LayerOneId, n

为什么我的函数只迭代第一层的第一个特征?

更准确地说,我正在寻找可以在 python 控制台中运行的类似结果:

arrayOne = [1,2]
arrayTwo = [1,2]
for a in arrayOne :
    for b in arrayTwo:
        print a,b
>>> 1,1
>>> 1,2
>>> 2,1
>>> 2,2

【问题讨论】:

  • 也许 layerTwo.getFeatures() 返回一个在一次运行后将耗尽的交互器。您是否尝试过使用list(layerTwo.getFeatures()) 将其转换为列表?或者你可以试试for feat in layerTwo.getFeatures()
  • 这样做是因为您每次iterOne 的迭代只询问一次print layerOneId
  • 第二个迭代器在外循环的第一次迭代中耗尽,您需要在每次迭代中重新创建它。将iterTwo = layerTwo.getFeatures() 移到for feat in iterTwo : 之前

标签: python qgis


【解决方案1】:

我会使用itertools.product 来迭代这两个功能

import itertools

layerOne = QgsVectorLayer( '~/FirstLayer.shp', 'layerOne', 'ogr')
layerTwo = QgsVectorLayer( '~/SecondLayer.shp', 'layerTwo', 'ogr')

for features in itertools.product(layerOne.getFeatures(), layerTwo.getFeatures()):

    id = tuple(feat.attributes()[0] for feat in features)

    print "LayerOneId" ,id[0] , "LayerTwoId", id[1]

    if id[0] == id[1]:
        pass
        # code if both id's match

features 是一个具有两层特征的元组。如果您需要除 id 之外的更多功能,您可以使用类似 zipped_attributes = zip(*feat.attributes() for feat in features) 的内容转置这些功能,并使用 id = zipped_attributes[0] 访问带有 id 的元组

【讨论】:

    【解决方案2】:

    回答:感谢@nils-werner 和@goyo 为我指明了正确的方向:我需要在feat in iterTwo : 之前通过Move iterTwo = layerTwo.getFeatures()

    layerOne = QgsVectorLayer( '~/FirstLayer.shp', 'layerOne', 'ogr')
    layerTwo = QgsVectorLayer( '~/SecondLayer.shp', 'layerTwo', 'ogr')
    
    iterOne = layerOne.getFeatures()
    
    for feature in iterOne: 
        layerOneId = feature.attributes()[0]
        print layerOneId
        iterTwo = layerTwo.getFeatures()
        for feat in iterTwo :
            layerTwoId = feat.attributes()[0]
            print "LayerOneId",LayerOneId, "LayerTwoId", LayerTwoId"
            # do something if LayerOneId == LayerTwoId
    

    【讨论】: