Saya ditanya dalam kursus pelatihan baru-baru ini jika QGIS dapat secara otomatis menghitung nomor halaman berikutnya / sebelumnya dan di atas / di bawah untuk buku peta yang dibuat menggunakan generator atlas. Saya berhasil membuat ekspresi label yang cukup masuk akal untuk kisi biasa jika Anda tahu lebar dan tinggi kisi.
Tetapi kami kemudian mulai memikirkan contoh-contoh realistis di mana kami tidak ingin menggambar halaman yang tidak mengandung distrik minat kami, seperti ini salah satu daerah asal saya:
Jadi sore ini saya bermain di skrip python untuk mengetahui 4 tetangga yang saya tertarik untuk setiap sel grid dan menambahkan nilai-nilai itu ke kotak saya (ini sangat didasarkan pada tutorial Ujaval Gandhi ):
for f in feature_dict.values():
print 'Working on %s' % f[_NAME_FIELD]
geom = f.geometry()
# Find all features that intersect the bounding box of the current feature.
# We use spatial index to find the features intersecting the bounding box
# of the current feature. This will narrow down the features that we need
# to check neighboring features.
intersecting_ids = index.intersects(geom.boundingBox())
# Initalize neighbors list and sum
neighbors = []
neighbors_sum = 0
for intersecting_id in intersecting_ids:
# Look up the feature from the dictionary
intersecting_f = feature_dict[intersecting_id]
int_geom = intersecting_f.geometry()
centroid = geom.centroid()
height = geom.boundingBox().height()
width = geom.boundingBox().width()
# For our purpose we consider a feature as 'neighbor' if it touches or
# intersects a feature. We use the 'disjoint' predicate to satisfy
# these conditions. So if a feature is not disjoint, it is a neighbor.
if (f != intersecting_f and
not int_geom.disjoint(geom)):
above_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
centroid.asPoint().y()+height))
below_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
centroid.asPoint().y()-height))
left_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()-width,
centroid.asPoint().y()))
right_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()+width,
centroid.asPoint().y()))
above = int_geom.contains(above_point)
below = int_geom.contains(below_point)
left = int_geom.contains(left_point)
right = int_geom.contains(right_point)
if above:
print "setting %d as above %d"%(intersecting_f['id'],f['id'])
f['above']=intersecting_f['id']
if below:
print "setting %d as below %d"%(intersecting_f['id'],f['id'])
f['below']=intersecting_f['id']
if left:
print "setting %d as left of %d"%(intersecting_f['id'],f['id'])
f['left']=intersecting_f['id']
if right:
print "setting %d as right of %d"%(intersecting_f['id'],f['id'])
f['right']=intersecting_f['id']
# Update the layer with new attribute values.
layer.updateFeature(f)
layer.commitChanges()
Ini berfungsi dengan baik.
Tapi jujur saja, keseluruhan menciptakan titik uji ke Utara dan kemudian menguji semua tetangga yang mungkin tampak salah. Namun setelah satu sore mengacaukan otak saya, saya tidak bisa memikirkan cara yang lebih baik untuk menentukan apa tetangga utara sel grid tertentu?
Idealnya saya ingin sesuatu yang cukup sederhana untuk dimasukkan ke dalam kotak teks komposer cetak, tapi saya kira itu terlalu banyak untuk diminta.
sumber
Jawaban:
Jika Anda tidak menyesuaikan setiap batas halaman (dari lapisan indeks) tepat ke komposer, tetapi memiliki batas yang tumpang tindih dengan halaman yang berdekatan (seperti yang ditunjukkan pada tangkapan layar kedua), maka Anda dapat menggunakan label dari lapisan indeks, dengan kelemahan yang mereka akan berada di dalam perbatasan peta.
Jika tidak ada tumpang tindih, maka Anda dapat meniru teknik yang saya gunakan dengan sukses di masa lalu (kebetulan di E & W Sussex!) Di MapInfo, di mana saya menulis skrip kecil yang menghasilkan serangkaian empat poin untuk setiap fitur indeks , diimbangi ke fitur yang berdekatan, dengan atribut dari kedua nomor sheet, dan arah offset. Lapisan titik kemudian digunakan untuk menghasilkan label lagi, dengan arah ofset memungkinkan orientasi label disesuaikan untuk efek yang lebih baik.
Saya belum mencoba ini, tetapi Anda mungkin dapat menghindari pembuatan lapisan data terpisah di QGIS melalui penggunaan fungsi penataan generator geometri baru, ini akan membuat solusi yang lebih elegan dan dinamis yang tidak dapat dicapai di MapInfo!
sumber
Sebenarnya, Anda sudah melakukan sebagian besar pekerjaan yang diperlukan untuk menentukan ubin yang ingin Anda cetak menggunakan atlas. Tetapi intinya adalah bagaimana menyesuaikan semuanya untuk hanya menampilkan ID ubin yang Anda butuhkan. Untuk menunjukkan ide saya, saya akan menggunakan dalam contoh ini gambar DEM dan file vektor kotak, seperti yang Anda lihat di bawah:
Pertama-tama kita perlu menunjukkan label setiap kotak.
Dalam tampilan tata letak, saya menggunakan kisi sebagai lapisan cakupan di atlas, saya membuat dua peta: peta jendela tampilan utama, dan peta indeks yang hanya menampilkan kisi, seperti yang Anda lihat di bawah:
Kemudian saya melakukan yang berikut:
Preview atlas
, danOverview
untuk melihat jangkauan dan lokasi peta tampilan utama, seperti yang Anda lihat di bawah:Untuk peta jendela tampilan utama, saya memperbaiki skala sejauh setiap blok kotak, untuk memastikan bahwa skala tidak akan berubah jika terjadi sesuatu, seperti yang Anda lihat di bawah;
Menggunakan peta indeks, Anda dapat dengan mudah melihat ID dan lokasi setiap ubin dengan merujuk ke ubin lain, bahkan ketika Anda mematikan grid dari jendela peta tampilan utama. Misalnya, peta berikut memiliki ID ubin = 14, dan Anda dapat melihat ID ubin di sekitarnya.
Perbarui :
Saya akan memperbarui jawaban saya karena saya menyadari bahwa Anda ingin menampilkan indeks nomor halaman dari tata letak di sekitarnya, bukan ID dari tata letak di sekitarnya.
Untuk memudahkan pemahaman proses, saya akan memperbarui nomor ID di peta indeks untuk menampilkan nomor halaman tata letak, seperti yang ditunjukkan di bawah ini:
Karena ID yang saya mulai dari 0 (Nol), ID dari grid pertama yang ditunjukkan pada peta indeks akan mulai dari 3. Oleh karena itu, saya ingin mengubah nomor halaman untuk memulai dari 1 dengan mengurangi 2 dari nomor ID di Atlas:
Page number: ID -2
, maka saya akan menggunakan nomor halaman saat ini sebagai referensi dalam ekspresi untuk membuat label untuk halaman saat ini, halaman sebelumnya, halaman berikutnya, halaman atas dan halaman di bawah, sebagai berikut:Halaman Saat Ini memiliki ungkapan ini di kotak teks label:
Current Page Number: [%@atlas_pagename%]
Ekspresi Halaman Sebelumnya:
[%if((@atlas_pagename = 1), Null, '↑ Page Number: ' || (@atlas_pagename - 1))%]
karena tidak ada halaman sebelum 1Ekspresi Halaman Berikutnya:
[%if( (@atlas_pagename = 25), Null, '↓ Page Number: ' || (@atlas_pagename + 1))%]
karena tidak ada halaman setelah 25Ekspresi Halaman Atas:
[%if((@atlas_pagename <= 6),NULL,'↑ Page Number: ' || (@atlas_pagename -6))%]
karena tidak ada halaman sebelum 6 di arah atasDi bawah ekspresi Halaman:
[%if((@atlas_pagename >= 20), Null, '↓ Page Number: ' || (@atlas_pagename + 6))%]
karena tidak ada halaman setelah 20 di arah bawahBeberapa hasil keluaran:
sumber
Solusi ini akan bekerja untuk kisi-kisi persegi panjang dan otomatis (harus bekerja untuk skenario apa pun tanpa menyesuaikan apa pun secara manual).
Anggap Anda memiliki kisi dengan nomor halaman. Anda dapat menjalankan skrip Pemrosesan saya dengan memilih layer grid dan bidang nomor halamannya sebagai parameter. Script membuat empat bidang (
right, left, above, below
) di layer grid dan menghitung id halaman tetangga yang sesuai untuk setiap sel grid. Kemudian Anda dapat menggunakan ekspresi Anda (misalnya,[% if( "left" is not NULL, 'to page' || "left", "" ) %]
) untuk menampilkan label halaman tetangga.Cukup tambahkan repositori saya ( https://github.com/gacarrillor/QGIS-Resources.git ) dari plugin QGIS Resource Sharing dan instal skrip:
Bagaimana itu bekerja
Script menentukan hubungan (kanan, kiri, atas, atau di bawah) dengan membandingkan koordinat kotak pembatas dari sel kisi saat ini dan setiap sel yang berpotongan. Ternyata untuk setiap relasi, salah satu koordinat tidak ada.
Jika hubungannya adalah
above
, koordinat yang hilang adalahyMin
, yaitu, semua 3 koordinat lainnya dari kotak pembatas sel grid saat ini akan hadir dalam kotak pembatas sel di atas. Ingat bahwa QGIS kotak bounding didefinisikan dalam urutan ini:[xMin, yMin, xMax, yMax]
.Sebagai contoh numerik, mari kita ambil persegi panjang dengan sisi panjang 1. Katakanlah kotak pembatas sel saat ini didefinisikan sebagai
bbox1=[0,0,1,1]
. Kotak pembatas sel di atas akan didefinisikan sebagaibbox2=[0,1,1,2]
. Koordinat X dari bbox1 ada di bbox2, sedangkan bbox1yMin
hilang dalam koordinat Y dari bbox2.Kita dapat mendefinisikan 4 relasi kita dengan cara ini (o: sekarang, #: hilang):
Seperti yang Anda lihat, indeks yang hilang memberi kami semua informasi yang kami butuhkan.
sumber