Iterowanie po warstwach mapy w QGIS Python?

30

Mam problem z ustaleniem, jak iterować warstwy mapy. Mogę uzyskać dostęp do aktualnie podświetlonej warstwy w spisie treści, iface.activeLayer()ale chcę, aby mój kod działał na wszystkich warstwach.

W interfejsie API nie widzę niczego, co zapewnia łatwy dostęp do tej funkcji i nie mogę znaleźć dobrego przykładu online, ale może coś przeoczyłem?

spencerrecneps
źródło
Nie rozumiem, jak używacie QgsMapLayerRegistry lub QgsProject. W QGIS 3.0.2 to nie działa. Jednak robi to iface.mapCanvas (). Layer (). Cóż, w pewnym sensie. Wydaje się, że daje tylko aktywne warstwy (te, które zaznaczyłeś w panelu Warstwy). Czy ktoś wie, jak uzyskać listę wszystkich warstw, nawet tych niezaznaczonych w panelu Warstwy? Ponadto, jeśli używasz Plugin Builder, tworzy on dla Ciebie powłokę wtyczki. Funkcja Run ma parametr „self”, który jest potrzebny do użycia iface. tj. self.iface.mapCanvas (). layer (), tylko fyi.
ajpieri,

Odpowiedzi:

24

Próbować...

# 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

Zaczerpnięte z consolidatethread.py z wtyczką QConsolidate .

Opis obiektu QgsLegendInterface zwrócony z legendInterface ().

Edycja : dodano informacje o „ja” powyżej.

dakcarto
źródło
Dzięki! To załatwiło sprawę. Myślę, że jestem zbyt przyzwyczajony do świata ESRI, w którym legenda jest obiektem w układzie mapy, a spis treści odnosi się do listy warstw.
spencerrecneps
2
Zauważ, że istnieje różnica w tym, co jest zwracane między tym a techniką mapCanvas (), o której wspomina Nathan. Obiekt legendInterface () zwróci wszystkie warstwy, nawet jeśli nie są pokazane na kanwie mapy, podczas gdy mapCanvas () zwraca tylko te pokazane na kanwie. Korzystanie z mapCanvas () to dobry, szybki sposób na uzyskanie odniesienia do widocznych warstw.
dakcarto
1
Z drugiej strony, najnowsze wersje QGIS (> = 1.8) pozwalają użytkownikowi zdefiniować kolejność renderowania warstw oddzielnie od kolejności wymienionej w legendzie (bardzo miło!). Metody legendInterface () i mapCanvas () zwracają odpowiednio kolejność warstw dla każdej z nich.
dakcarto
19

Istnieją również dwa inne sposoby:

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

da ci listę warstw

lub

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Nathan W.
źródło
Ta odpowiedź wydaje się nie działać 2.16powyżej i powyżej
raphael
10

W przypadku QGIS 2.6 poniżej znajduje się kod identyfikujący każdą warstwę i grupujący ją:

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

Uwaga: Po zgrupowaniu muszę usunąć zduplikowaną warstwę, więc użyłem root.removeLayer(lyr).

Abhijit Gujar
źródło
9

W przypadku QGIS 3 QgsMapLayerRegistryprzeniesiono funkcjonalność do QgsProject.

Tak więc, do iteracji po warstwach mapy, powinieneś użyć tej struktury:

layers = QgsProject.instance().mapLayers()

.mapLayers()zwraca słownik o strukturze {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Następnie możesz iterować po warstwach takich jak:

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

Ponieważ .mapLayers()zwraca słownik ( dict), możesz także użyć .values()metody słownika, która zwraca tylko taką, listktóra zawiera w tym przypadku warstwy. Następnie możesz iterować po warstwach takich jak:

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

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

Jeśli wolisz, możesz iterować w ten sposób:

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

for layer in layers.values():
    print(layer.name())
Kadir Şahbaz
źródło
Cześć! Dzięki za udostępnienie. Drukowanie nazw warstw działa dobrze ... ale nie mogę wydrukować kluczy słownika. Czy możesz mi z tym pomóc?
caio villaca
1
for layer in layers: print(layer)Możesz użyć skryptu, aby wydrukować klucze. Lub po prostu użyj print(layers.keys())bez forpętli.
Kadir Şahbaz