Bagaimana cara membuat Atlas berdasarkan atribut titik?

9

Pada dasarnya saya ingin membuat atlas berdasarkan bidang kategoris pada layer titik.

yaitu saya memiliki lapisan titik penyedia pengasuhan anak dengan bidang kategoris "Penyediaan". Saya telah mengategorikan setiap fitur dalam bidang ini dengan "After School Club", "Breakfast Club" dll, dan sekarang saya ingin membuat satu set peta yang beralih ke setiap kategori dan hanya menunjukkan poin untuk masing-masing. Satu peta klub setelah sekolah, satu peta klub sarapan, dll. Luasnya mungkin agak berbeda.

Saya bisa melakukannya satu per satu tetapi sepertinya harus ada cara untuk menghasilkan atlas berdasarkan luasan masing-masing kategori? (Saya merasa saya kehilangan sesuatu yang jelas :))

Atau sebagai alternatif apakah ada cara mengotomatisasi pembuatan lapisan poligon dan menggunakannya sebagai cakupan tersembunyi untuk atlas?

EDIT: Saya telah membuat sedikit kemajuan dengan ini - Anda dapat menggunakan gaya berdasarkan aturan untuk mengaktifkan dan menonaktifkan fitur yang relevan dengan fitur cakupan atlas saat ini. itu benar-benar berfungsi dengan baik jika semua yang ingin Anda lakukan adalah menunjukkan serangkaian poin yang berbeda. Saya sekarang melihat mengikat itu kembali ke skema warna dan legenda reaktif.

JonoPatterson
sumber
1
Ini pada dasarnya adalah duplikat dari gis.stackexchange.com/questions/155143
Chris W
Terima kasih Chris - tetapi tidak yakin apakah itu benar. Yang satu itu sepertinya bertanya apakah Anda bisa melakukan sub-atlas untuk setiap area dalam atlas asli? misal masing-masing 4 area dengan 4 halaman? (Meskipun saya berjuang untuk mengikuti apa yang diminta)
JonoPatterson
1
Tidak, pada dasarnya Anda berdua ingin membuat seri peta. Seri ini menunjukkan tingkat peta dan informasi dasar yang sama, tetapi masing-masing fitur berbeda. Komentar saya di sana berbicara tentang dan tautan ke melakukannya di ArcGIS melalui apa yang disebut kueri definisi halaman - yaitu, setiap halaman di atlas / mapbook memiliki kueri definisi yang menentukan lapisan / fitur mana yang ditampilkan pada halaman itu. Dia menginginkan serangkaian seri, di mana Anda hanya ingin satu seri. Namun saya tidak tahu apakah QGIS belum menawarkan fungsi seperti itu (saya pikir saya akan membaca jawaban / komentar yang tidak, tetapi saya tidak dapat menemukannya sekarang).
Chris W
Selain itu, dalam kasus Anda, Anda dapat membuat kotak pembatas berdasarkan luasan setiap titik yang berbagi atribut yang sama dan kemudian menggunakannya sebagai fitur indeks Anda, tetapi Anda masih memiliki masalah untuk secara otomatis menghidupkan dan mematikan berbagai kelompok titik yang berbeda. . Bahkan jika Anda membaginya menjadi lapisan yang terpisah, tanpa semacam permintaan definisi, tidak ada cara untuk mematikan titik-titik itu pada halaman tertentu.
Chris W
Ya Anda mati. Ini juga merupakan pengulangan dari gis.stackexchange.com/questions/121802/… yang satu ini - jadi saya mungkin harus resor untuk melakukannya secara manual.
JonoPatterson

Jawaban:

9

Saya akhirnya memecahkan ini untuk tujuan saya jadi inilah solusi yang saya buat jika itu membantu siapa pun:

Tulis skrip python (milik saya di akhir ini) yang pada dasarnya melakukan ini:

  1. mengidentifikasi kategori unik di bidang lapisan poin yang menarik
  2. untuk setiap kategori, pilih semua titik yang cocok dan tentukan sejauh mana set ini
  3. untuk setiap tingkat menghasilkan poligon baru di lapisan cakupan atlas kosong dengan atribut kunci "CategoryName"

Ini memberi saya lapisan cakupan atlas dengan satu poligon untuk setiap kategori yang menarik seperti ini: Lapisan cakupan Atlas

Konfigurasikan atlas dan cetak komposer seperti biasa - hanya menyisakan masalah mematikan dan mengaktifkan fitur.

Untuk ini, sedikit trial and error untuk mengetahui set opsi yang tepat:

  1. Ekspresi di bawah ini memungkinkan Anda mendapatkan nilai yang saat ini dimiliki di bidang CategoryName untuk fitur atlas saat ini

    attribute ($atlasfeature, 'CategoryName') 
    
  2. Gunakan ini untuk membuat gaya berdasarkan aturan untuk layer titik di sepanjang garis

    attribute ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
    
  3. Saya juga punya aturan untuk menjamin semua yang lain menjadi transparan

    attribute ($atlasfeature, 'CategoryName') IS NOT PointCategory
    

Aturan ditampilkan

Menguji ini dengan atlas bekerja dengan sangat baik. Akhirnya cukup gunakan pendekatan yang sama untuk memanipulasi label yang ditampilkan, membuat label dinamis dan memfilter tabel dengan tepat. Mencentang 'legenda filter berdasarkan konten peta' juga sangat efektif jika Anda tidak ingin semua item legenda di semua peta.

Set atlas akhir:

Atlas Berbasis Fitur

Sunting - seperti yang diminta, inilah skrip saya:

    from PyQt4.QtCore import *

#main script----------------------------------------------
    #set up the layer references - you will need to change this
targetlayer=QgsMapLayerRegistry.instance().mapLayer("AtlasExtents20150727154732521")
eylayer = QgsMapLayerRegistry.instance().mapLayer("Early_Years_Providers20150727152919862")

#establish the unique categories 
names = getUniqueAttributes(eylayer, 'Mapping_La')

#get a set of boxes
boxset = getBoundings(eylayer, names)

#ensure layer is emptied, then add bounding boxes
deleteBoxes(targetlayer)
createBoxes(targetlayer, boxset)
 #end main script----------------------------------------------   


 #------functions-------#
#gets unique set of attributes - returns a set()
def getUniqueAttributes(layer, fieldname):
    values = set()
    for feature in layer.getFeatures():
        values.add(feature[fieldname])
    return values

#quickly selects all points on a layer, given a query 
def selectionQuick(layer, queryitem):
    layer.removeSelection ()

    #hardcoded field name
    expr = QgsExpression( "\"Mapping_La\" = '" + queryitem +"'")
    it = layer.getFeatures( QgsFeatureRequest( expr ) )
    ids = [i.id() for i in it]
    layer.setSelectedFeatures( ids )

#for a set of unique items, get bounding boxes 
def getBoundings(layer, itemset):
    bboxes = {}
    for itemname in itemset:
        selectionQuick(layer,itemname)
        box = layer.boundingBoxOfSelected()
        bboxes[itemname] = box
    return bboxes

#for a layer create a bunch of boxes
def createBoxes(layer, boxes):
    id=0
    for boxkey in boxes:
        id = id +1
        box=boxes[boxkey]
        feat = QgsFeature(layer.pendingFields())
        geom = QgsGeometry.fromRect(box)
        feat.setAttribute('id', id)
        #hardcoded field name
        feat.setAttribute('CareType', boxkey)
        feat.setGeometry(geom)
        (res, outFeats) = layer.dataProvider().addFeatures([feat])

def deleteBoxes(layer):
        ids = [f.id() for f in layer.getFeatures()]
        layer.dataProvider().deleteFeatures( ids )
JonoPatterson
sumber
3
@JonoPatterson jika Anda sekarang juga akan membagikan skrip python Anda yang disebutkan di awal, ini akan menjadi jawaban terbaik;)
Bernd V.
Ok akan melakukan ini - meskipun kasar dan siap sehingga perlu beberapa tweak (belum melakukan pengkodean selama bertahun-tahun!). Apa cara terbaik untuk melakukannya - cukup tempel dalam kotak kode?
JonoPatterson
@JonoPatterson Terima kasih banyak untuk skripnya. Bagi saya sebagai pemula, ini sudah terlihat sangat bagus :). Saya yakin saya akan membutuhkan ini segera.
Bernd V.
Contoh ekspresi Anda agak salah - seharusnya "$ atlasfeature", bukan "$ atlasfeatureid"
ndawson