Итерирование по слоям карты в QGIS Python?

30

У меня проблемы с выяснением, как перебирать слои карты. Я могу получить доступ к текущему выделенному слою в оглавлении через, iface.activeLayer()но я хочу, чтобы мой код работал на всех слоях.

Я не вижу в API ничего такого, что обеспечивало бы легкий доступ к этой функциональности и не смог найти хорошего онлайн-примера, но, может быть, я что-то упустил?

spencerrecneps
источник
Я не понимаю, как вы, ребята, используете QgsMapLayerRegistry или QgsProject. В QGIS 3.0.2 это не работает. Однако iface.mapCanvas (). Layers () делает. Ну вроде. Это только кажется, что дает вам активные слои (те, которые вы проверили на панели слоев). Кто-нибудь знает, как получить список всех слоев, даже не отмеченных на панели слоев? Кроме того, если вы используете Plugin Builder, он создает оболочку вашего плагина для вас. Функция run имеет параметр self, который необходим для использования iface. т.е. self.iface.mapCanvas (). Layers (), просто к сведению.
ajpieri

Ответы:

24

Пытаться...

# substitute 'self' with 'qgis.utils.iface' when run from Python console
# 'self.iface = iface' would usually precede this command in your class 
layers = self.iface.legendInterface().layers()

for layer in layers:
    layerType = layer.type()
    if layerType == QgsMapLayer.VectorLayer:
        # do some stuff here

Собран из файла consolidatethread.py из плагина QConsolidate .

Описание объекта QgsLegendInterface, возвращенного из legendInterface ().

Редактировать : добавлена ​​информация о себе.

dakcarto
источник
Благодарность! Это добилось цели. Думаю, я слишком привык к миру ESRI, где легенда - это объект в макете карты, а оглавление относится к списку слоев.
spencerrecneps
2
Обратите внимание, что есть разница в том, что возвращается между этим и методом mapCanvas (), который упоминает Натан. Объект legendInterface () вернет все слои, даже если они не отображаются на холсте карты, а mapCanvas () возвращает только те, которые показаны на холсте. Использование mapCanvas () - это хороший и быстрый способ получить ссылку на видимые слои.
Даккарто
1
С другой стороны, последние версии QGIS (> = 1.8) позволяют пользователю определять порядок рендеринга слоев отдельно от порядка, указанного в легенде (очень приятно!). Методы legendInterface () и mapCanvas () возвращают порядок слоев для каждого соответственно.
Даккарто
19

Есть также два других способа:

layers = self.iface.mapCanvas().layers()

даст вам список слоев

или

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Натан У
источник
Этот ответ, кажется, не работает в 2.16и выше
Raphael
10

Для QGIS 2.6 вот код для идентификации каждого уровня и группировки их:

#make the desired groups for layers
toc = self.iface.legendInterface()
root = QgsProject.instance().layerTreeRoot()
group1 = root.insertGroup(0, "Group Point")
group2 = root.insertGroup(1, "Group Line")
group3 = root.insertGroup(2, "Group Polygon")
#get the list of layers  from registry
layers = QgsMapLayerRegistry.instance().mapLayers()
#segregate layers into groups 
for name, layer in layers.iteritems():
    # check the layer geometry type 
    if layer.geometryType() == QGis.Point:
        toc.moveLayer(layer, 0)

    if layer.geometryType() == QGis.Line:
        toc.moveLayer(layer, 1)

    if layer.geometryType() == QGis.Polygon:
        toc.moveLayer(layer, 2)

Примечание: после группировки я должен удалить дубликат слоя, чтобы я использовал root.removeLayer(lyr).

Абхиджит Гуджар
источник
9

Для QGIS 3 QgsMapLayerRegistryфункциональность была перенесена в QgsProject.

Итак, для перебора слоев карты вы должны использовать эту структуру:

layers = QgsProject.instance().mapLayers()

.mapLayers()возвращает словарь, структурированный как {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Затем вы можете перебирать слои, например:

for layer_id, layer in layers.items():
    print(layer.name())

Поскольку .mapLayers()возвращает словарь ( dict), вы также можете использовать .values()метод словаря, который возвращает только тот, listкоторый содержит слои в этом случае. Затем вы можете перебирать слои, например:

layers = QgsProject.instance().mapLayers().values()

for layer in layers:
    print(layer.name())

Если вы предпочитаете, вы можете выполнить итерацию следующим образом:

layers = QgsProject.instance().mapLayers() # dictionary

for layer in layers.values():
    print(layer.name())
Кадир Шахбаз
источник
Здравствуй! Спасибо, что поделились этим. Для печати названий слоев работает нормально ... но я не могу напечатать ключи словаря. Вы можете помочь мне с этим?
Caio Villaca
1
for layer in layers: print(layer)Вы можете использовать скрипт для печати ключей. Или просто использовать print(layers.keys())без forпетли.
Кадир Шахбаз