Iterasi pada layer peta dalam QGIS Python?

30

Saya mengalami kesulitan mencari tahu cara beralih di atas lapisan peta. Saya dapat mengakses lapisan yang saat ini disorot dalam daftar isi melalui iface.activeLayer()tetapi saya ingin kode saya beroperasi di semua lapisan.

Saya tidak melihat apa pun di API yang menyediakan akses mudah ke fungsi ini dan tidak bisa menemukan contoh online yang bagus tapi mungkin saya melewatkan sesuatu?

spencerrecneps
sumber
Saya tidak melihat bagaimana kalian menggunakan QgsMapLayerRegistry atau QgsProject. Di QGIS 3.0.2 ini tidak berfungsi. Namun, iface.mapCanvas (). Layers () tidak. Yah, agak. Tampaknya hanya memberi Anda lapisan aktif (yang telah Anda centang di panel Layers). Adakah yang tahu cara mendapatkan daftar semua Layers, bahkan yang tidak dicentang di panel Layers? Juga, jika menggunakan Plugin Builder, itu menciptakan shell plugin Anda untuk Anda. Fungsi run memiliki parameter "mandiri", yang diperlukan untuk menggunakan iface. yaitu self.iface.mapCanvas (). layers (), hanya fyi.
ajpieri

Jawaban:

24

Mencoba...

# 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

Dipilih dari konsolidatethread.py dari plugin QConsolidate .

Deskripsi objek QgsLegendInterface dikembalikan dari legendInterface ().

Edit : menambahkan info tentang 'diri' di atas.

dakcarto
sumber
Terima kasih! Itu berhasil. Saya kira saya terlalu terbiasa dengan dunia ESRI di mana legenda adalah objek dalam tata letak peta dan daftar isi mengacu pada daftar lapisan.
spencerrecneps
2
Perhatikan bahwa ada perbedaan dalam apa yang dikembalikan antara ini dan teknik mapCanvas () yang Nathan sebutkan. Objek legendInterface () akan mengembalikan semua lapisan, bahkan jika mereka tidak ditampilkan di kanvas peta, sementara mapCanvas () mengembalikan hanya yang ditunjukkan pada kanvas. Menggunakan mapCanvas () adalah cara cepat dan bagus untuk mendapatkan referensi ke lapisan yang terlihat.
dakcarto
1
Pada catatan lain, versi terbaru QGIS (> = 1.8) memungkinkan pengguna untuk mendefinisikan urutan render layer secara terpisah dari urutan yang tercantum dalam legenda (sangat bagus!). Metode legendInterface () dan mapCanvas () mengembalikan urutan layer untuk masing-masing.
dakcarto
19

Ada juga dua cara lain:

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

akan memberi Anda daftar lapisan

atau

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Nathan W
sumber
Jawaban ini tampaknya tidak berhasil di dalam 2.16dan di atas
raphael
10

Untuk QGIS 2.6 di sini adalah kode untuk mengidentifikasi setiap lapisan dan mengelompokkannya:

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

Catatan: Setelah pengelompokan saya harus menghapus layer duplikat jadi saya gunakan root.removeLayer(lyr).

Abhijit Gujar
sumber
9

Untuk QGIS 3, QgsMapLayerRegistryfungsionalitas telah dipindahkan ke QgsProject.

Jadi, untuk mengulangi lapisan peta, Anda harus menggunakan struktur itu:

layers = QgsProject.instance().mapLayers()

.mapLayers()mengembalikan kamus yang terstruktur sebagai {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Kemudian Anda dapat beralih di atas lapisan seperti:

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

Karena .mapLayers()mengembalikan kamus ( dict), Anda juga dapat menggunakan .values()metode kamus yang mengembalikan hanya listyang berisi lapisan dalam kasus itu. Kemudian Anda dapat beralih di atas lapisan seperti:

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

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

Jika Anda suka, Anda dapat menggunakannya dengan cara ini:

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

for layer in layers.values():
    print(layer.name())
Kadir Şahbaz
sumber
Hai! Terima kasih telah membagikannya. Untuk mencetak nama-nama layer berfungsi dengan baik ... tapi saya tidak bisa mencetak kunci dari kamus. Bisakah Anda membantu saya dengan itu?
caio villaca
1
for layer in layers: print(layer)Anda dapat menggunakan skrip untuk mencetak kunci. Atau cukup gunakan print(layers.keys())tanpa forloop.
Kadir Şahbaz