Ітерація над шарами карти в QGIS Python?


30

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

Я не бачу нічого в API, що забезпечує простий доступ до цієї функціональності і не міг знайти хороший приклад в Інтернеті, але, можливо, я щось пропустив?


Я не бачу, як ви, хлопці, використовуєте QgsMapLayerRegistry або QgsProject. У QGIS 3.0.2 це не працює. Однак, якщо Iface.mapCanvas (). Layer () так і є. Ну, начебто. Це, здається, дає вам активні шари (ті, які ви перевірили на панелі "Шари"). Хтось знає, як отримати список усіх шарів, навіть тих, які не встановлені у вікні "Шари"? Крім того, якщо ви використовуєте Plugin Builder, він створює оболонку вашого плагіна для вас. Функція запуску має параметр "self", який необхідний для використання iface. тобто self.iface.mapCanvas (). шари (), просто fyi.
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

Здійснено виклик з consolidthread.py з плагіна QConsolidate .

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

Редагувати : додано інформацію про "самості" вище.


Спасибі! Це зробило трюк. Я думаю, що я занадто звик до світу ESRI, де легенда є об’єктом у макеті карти, а зміст посилається на список шарів.
spencerrecneps

2
Зауважте, що існує різниця в тому, що повертається між цією технікою mapCanvas (), яку згадує Натан. Об'єкт legendInterface () поверне всі шари, навіть якщо вони не відображаються на полотні карти, тоді як mapCanvas () повертає лише ті, що показані на полотні. Використання mapCanvas () - хороший, швидкий спосіб отримати посилання на видимі шари.
даккарто

1
З іншого боку, останні версії QGIS (> = 1.8) дозволяють користувачеві визначати порядок відображення шарів окремо від порядку, зазначеного в легенді (дуже приємно!). Методи legendInterface () і mapCanvas () повертають порядок шарів для кожного відповідно.
dakcarto

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()метод словника, який повертає просто a, 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циклу.
Кадір Şahbaz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.