Apakah ada cara untuk memotong garis kontur di bawah label ketinggian?
Apakah ada cara untuk memotong garis kontur di bawah label ketinggian?
Jawaban:
Ya, bisa dilakukan. Biasanya saya menyarankan buffer transparan sebagian, tapi saya mengerti mengapa Anda ingin melakukan ini secara kartografis.
Ini bisa lambat, dan Anda harus memutuskan secara manual ke mana Anda ingin label pergi - tetapi secara kartografis, itu bukan hal yang buruk!
Ini tangkapan layar ...
Seperti yang Anda lihat, tidak ada buffer. Raster di bawahnya tidak terpengaruh. Saya telah menyertakan garis kontur menengah yang lebih tipis, dan menatanya sehingga hanya ditampilkan ketika ELEV% 50 <> 0
Saya sudah melakukan ini di QGIS 2.12 ... jarak tempuh Anda mungkin berbeda dengan versi sebelumnya.
Saya berasumsi di sini Anda memiliki bidang "ELEV" pada setiap garis kontur.
Segmentasikan garis kontur
Gunakan pemrosesan dan algoritma GRASS v.split.length untuk membagi kontur Anda menjadi segmen dengan panjang yang sama. Anda harus memilih panjang yang akan mendekati ukuran label Anda di unit peta, dengan asumsi Anda menggunakan meter. Di sini saya menggunakan 200m.
Hati-hati dengan ini karena ini akan membuat file Anda jauh, jauh lebih besar (perhatikan fitur yang diperhitungkan dalam tangkapan layar).
Untuk menyiasatinya, Anda mungkin ingin membuat hanya garis kontur yang ingin Anda gaya (misalnya setiap 50 atau 100 meter) untuk menghindari pemrosesan semua garis kontur perantara.
Untuk layer ini, tambahkan bidang integer 1 digit yang disebut showLabel . Default ke 0 atau NULL.
Ubah label untuk hanya ditampilkan pada segmen tempat bidang ini disetel ke 1. Gunakan ini untuk ekspresi teks label ...
if ( "showlabel" is not null, "ELEV", "")
Saya pikir jika (ekspresi, nilai sejati, nilai salah) cukup baru; jika menggunakan versi yang lebih lama, Anda dapat menggunakan CASE-ELSE
Ubah gaya garis sehingga semua segmen panjang tetap digambar, kecuali segmen tempat label ditampilkan. Jadi gunakan rendering Berbasis Rule dengan dua aturan
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Sekarang, semua kontur akan ditampilkan secara default, tetapi tidak ada label.
Edit segmen secara manual di mana Anda ingin menampilkan label
Masuk ke mode edit dan secara manual pilih segmen di mana Anda ingin menampilkan nilai kontur, dan atur nilai showLabel
ke 1 untuk fitur yang dipilih. Anda dapat menggunakan Ctrl+ pilih (di Ubuntu / Menang, Cmd+ Ctrl+ Klik / di Mac?) Untuk segmen multi-pilih untuk mempercepat.
Ini sekarang harus 'klip' kontur di mana Anda ingin label untuk ditampilkan, dan label akan ditampilkan di celah.
Dalam hal ini, pengaturan label saya adalah:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
Semoga itu bisa membantu!
Saya menggunakan opsi "Buffer" pada tab "Label setting". (Menggunakan tombol label, bukan opsi label lama pada dialog properti layer.) Ini tidak menghapus garis kontur, seperti yang saya bayangkan Anda ingin lakukan, tetapi itu membuat label terbaca.
Saya pikir yang paling dekat dengan kemampuan QGIS saat ini adalah menggunakan efek halo (atau latar belakang) dengan warna yang bersumber dari tabel yang akan didasarkan pada nilai ketinggian dan skema warna yang sama seperti yang digunakan untuk grid yang mendasarinya. Tentu saja ini tidak akan memperhitungkan hillshade dan segala sesuatu yang lain di bawah lingkaran cahaya di peta. Contoh warna acak: Dengan sedikit kode ini dapat ditulis ulang sebagai fungsi untuk mencerminkan warna kotak.
Secara teori, mungkin untuk menggunakan pola garis khusus dan label repeat + offset . Sayangnya tidak ada pengaturan offset label.
Setelah mengalami masalah yang sama baru-baru ini saya telah mengumpulkan skrip Python QGIS untuk melakukan pengangkatan berat. Script termasuk beberapa data pengujian (UK), Readme (Guide) dan style sheet yang digunakan dapat ditemukan di https://github.com/pjgeng/Contour-Labels
Singkatnya skrip menggunakan dua lapisan vektor sebagai input - lapisan kontur beranotasi dan lapisan "panduan". Yang terakhir terdiri dari polyline yang memotong kontur di lokasi label yang diinginkan.
Script kemudian bekerja berdasarkan jarak antara kontur dan interval kontur indeks yang label untuk menerapkan, menambahkan nilai rotasi ke titik-titik label dan akhirnya klip lapisan kontur asli untuk menghasilkan kesenjangan.
Pendekatan ini bekerja sangat baik jika pengguna harus menghasilkan peta kontur pada interval yang berbeda di area yang sama (yaitu panduan tidak berubah). Kelemahan adalah ketidakmampuan untuk mengubah posisi label setelah skrip selesai. Untuk ini, pengguna harus menyesuaikan garis panduan dan menjalankan kembali skrip terhadap input asli. Saya sebelumnya bekerja dengan buffer di sekitar label banyak untuk menciptakan efek terganggu, tetapi ini ternyata tidak menyenangkan secara estetika pada peta yang digerakkan oleh data vektor.
Sayangnya saya tidak dapat menambahkan gambar lagi saat ini untuk mendokumentasikan atau mengilustrasikan proses lebih lanjut.
PS: Jika menggunakan lapisan gaya yang disediakan dalam repositori, pengguna mungkin perlu "mengaktifkan" bidang khusus untuk "Rotasi", "Tampilkan Label" dan "Selalu Tampilkan" di menu label. Pada beberapa instalasi QGIS ini diterapkan secara otomatis dari stylesheet - Saya belum menemukan apa yang menyebabkannya.
Berikut adalah solusi lain untuk masalah kontur-label-masking QGIS, di mana saya memanfaatkan fungsionalitas Spatialite QGIS (saat ini QGIS 3.x) bersama-sama dengan generator geometri untuk penempatan label.
Solusi yang sangat dinamis ini memungkinkan kita untuk mengubah semua ukuran teks label dan posisi label dengan segera, dan bahkan bertahan dari ekspor vektor PDF!
Untuk memungkinkan ini kita perlu bagian-bagian berikut:
Lapisan virtual bernama "contours_with_labels" dengan gaya berbasis aturan:
Aturan 2: LAIN ... garis sederhana
dan teks label bersyarat untuk Aturan 1:
KASUS KETIKA label = 1 KEMUDIAN ketinggian ELSE AKHIR
make_line (start_point ($ geometry), end_point ($ geometry))
atribut (get_feature ('pengaturan', 'variabel', 'contourlabel_size'), 'nilai')
dan last but not least, inilah query SQL untuk lapisan virtual:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from
(select c.fid,st_union(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3)) as geom
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(scr.geometry,c.geometry)
group by c.fid) as buf,
contours c
where c.fid = buf.fid
group by c.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all scratch lines (bufferwidth = length(elevation_text) * txtsize/3),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(st_buffer(scr.geometry,length(c.elev) * txtsize.value / 3),c.geometry) as geom,c.elev,1 as label
from scratch_lines scr,
contours c,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
Itu dia.
Terima kasih banyak kepada semua orang yang antusias ini yang memungkinkan hal ini!
Apakah Anda ingat utas ini Martin? Satu-satunya cara saya bisa memikirkan untuk mendekati solusi untuk masalah Anda adalah dengan overlay lapisan kontur Anda dengan lapisan kontur terpotong, gunakan ini untuk memberi label dan mengubah warna garis menjadi sesuatu yang netral yang akan menutupi kontur di bawah label, orang berharap tanpa terlalu mengganggu. N.
Ditambahkan nanti: mungkin layak untuk melihat utas ini juga, jawaban kedua. Mungkin melanggar garis kontur mungkin merupakan jawaban, mungkin menggunakan lapisan penyangga yang digunakan untuk klip kontur?
Untuk membuat label lebih sempurna, saya mengubah kueri SQL dari lapisan virtual untuk menghormati garis awal yang berjalan paralel ke garis kontur (lihat solusi di bawah):
Dan inilah SQL baru untuk lapisan virtual:
------------------------------------------------------------------------
-- select all contour lines that do not intersect any scratch lines
------------------------------------------------------------------------
select c.geometry,c.elev,0 as label
from contours c,
(select st_union(geometry) as geom from scratch_lines) as scr
where not st_intersects(c.geometry,scr.geom)
------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_difference between contour lines and buffers
-- and set attribute "label" to 0
--------------------------------------------------------------------------------------------------------
select st_difference(c.geometry,buf.geom) as geom,c.elev,0 as label
from contours c,
(select c.fid,st_union(st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom
from contours c, scratch_lines scr, (select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
group by c.fid) as buf
where c.fid = buf.fid
--------------------------------------------------------------------------------------------------------
UNION
--------------------------------------------------------------------------------------------------------
-- create buffers around all intersection points (bufferwidth = length(elevation_text) * txtsize/2.5),
-- get st_intersection between contour lines and buffers
-- and set attribute "label" to 1
--------------------------------------------------------------------------------------------------------
select st_intersection(c.geometry,st_buffer(st_intersection(c.geometry,scr.geometry),length(c.elev) * txtsize.value / 3)) as geom,c.elev,1 as label
from contours c,
scratch_lines scr,
(select cast(value as integer) as value from settings where variable = 'contourlabel_size') txtsize
where st_intersects(c.geometry,scr.geometry)
Entri blog ESRI: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
Penyamitan dengan kedalaman variabel untuk label kontur melibatkan tiga langkah:
1membuat anotasi dari label, 2 menggunakan alat Fitur Garis Besar Masker untuk membuat topeng, dan 3 menggunakan Pilihan Gambar Lanjut> pengaturan Masking untuk menentukan lapisan mana topeng akan ditutup.