In QGIS Python über Kartenebenen iterieren?

30

Ich habe Probleme, herauszufinden, wie ich über Kartenebenen iterieren kann. Ich kann über auf die aktuell hervorgehobene Ebene im Inhaltsverzeichnis zugreifen iface.activeLayer(), möchte jedoch, dass mein Code auf allen Ebenen ausgeführt wird.

Ich sehe nichts in der API, das einen einfachen Zugriff auf diese Funktionalität ermöglicht, und konnte kein gutes Online-Beispiel finden, aber vielleicht habe ich etwas verpasst?

spencerrecneps
quelle
Ich verstehe nicht, wie ihr QgsMapLayerRegistry oder QgsProject benutzt. In QGIS 3.0.2 funktioniert dies nicht. Iface.mapCanvas (). Layers () dagegen schon. So in etwa. Es werden nur die aktiven Ebenen angezeigt (die, die Sie im Ebenenfenster aktiviert haben). Weiß jemand, wie man eine Liste aller Ebenen abruft, auch derjenigen, die im Ebenenfenster deaktiviert sind? Wenn Sie Plugin Builder verwenden, wird auch die Shell Ihres Plugins für Sie erstellt. Die run-Funktion hat einen "self" -Parameter, der zur Verwendung von iface benötigt wird. dh self.iface.mapCanvas (). levels (), nur zu Ihrer Information.
Ajpieri

Antworten:

24

Versuchen...

# 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

Wurde aus consolidatethread.py vom QConsolidate-Plug-in entfernt .

Beschreibung des QgsLegendInterface-Objekts, das von legendInterface () zurückgegeben wurde.

Bearbeiten : oben wurden Informationen zu "Selbst" hinzugefügt.

dakcarto
quelle
Vielen Dank! Das hat den Trick gemacht. Ich bin wohl zu sehr an die ESRI-Welt gewöhnt, in der die Legende das Objekt im Kartenlayout ist und das Inhaltsverzeichnis auf die Liste der Ebenen verweist.
Spencerrecneps
2
Beachten Sie, dass es einen Unterschied gibt, was zwischen dieser und der von Nathan erwähnten mapCanvas () -Technik zurückgegeben wird. Das legendInterface () -Objekt gibt alle Ebenen zurück, auch wenn sie nicht im Kartenbereich angezeigt werden, während mapCanvas () nur die im Bereich angezeigten zurückgibt. Mit mapCanvas () können Sie schnell und einfach einen Verweis auf sichtbare Ebenen erstellen.
dakcarto
1
In der neuesten Version von QGIS (> = 1.8) kann der Benutzer eine Renderreihenfolge von Layern separat von der in der Legende angegebenen Reihenfolge definieren (sehr schön!). Die Methoden legendInterface () und mapCanvas () geben jeweils die Ebenenreihenfolge zurück.
dakcarto
19

Es gibt auch zwei andere Möglichkeiten:

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

Sie erhalten eine Liste der Ebenen

oder

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Nathan W
quelle
Diese Antwort scheint nicht zu Arbeit in 2.16und oben
raphael
10

Für QGIS 2.6 ist hier der Code zum Identifizieren und Gruppieren der einzelnen Ebenen:

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

Hinweis: Nach dem Gruppieren muss ich die doppelte Ebene entfernen, damit ich sie verwendet habe root.removeLayer(lyr).

Abhijit Gujar
quelle
9

Für QGIS 3 wurde QgsMapLayerRegistrydie Funktionalität nach verschoben QgsProject.

Wenn Sie also über Kartenebenen iterieren, sollten Sie diese Struktur verwenden:

layers = QgsProject.instance().mapLayers()

.mapLayers()gibt ein Wörterbuch zurück, das wie folgt strukturiert ist {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Dann können Sie über Ebenen wie folgt iterieren:

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

Da .mapLayers()dictionary ( dict) zurückgegeben wird, können Sie auch eine Dictionary- .values()Methode verwenden, listdie in diesem Fall nur Layer zurückgibt . Dann können Sie über Ebenen wie folgt iterieren:

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

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

Wenn Sie möchten, können Sie folgendermaßen iterieren:

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

for layer in layers.values():
    print(layer.name())
Kadir Şahbaz
quelle
Hallo! Danke, dass du es geteilt hast. Die Namen der Ebenen zu drucken funktioniert einwandfrei ... aber ich kann die Schlüssel des Wörterbuchs nicht drucken. Kannst du mir damit helfen?
Caio Villaca
1
for layer in layers: print(layer)Sie können das Skript zum Drucken der Schlüssel verwenden. Oder einfach print(layers.keys())ohne forSchleife verwenden.
Kadir Şahbaz