Bir yükseklik etiketinin altındaki kontür çizgisini kesmenin bir yolu var mı?
Bir yükseklik etiketinin altındaki kontür çizgisini kesmenin bir yolu var mı?
Yanıtlar:
Evet, yapılabilir. Normalde kısmen şeffaf bir tampon öneririm, ancak bunu neden kartografik olarak yapmak istediğinizi anlıyorum.
Bu yavaş olabilir ve etiketlerin nereye gitmesini istediğinize elle karar vermeniz gerekir - ancak kartografik olarak konuşursanız, bu kötü bir şey değil!
İşte bir ekran görüntüsü ...
Gördüğünüz gibi tampon yok. Altındaki raster etkilenmez. Daha ince orta kontur çizgileri ekledim ve onları stillendirdik, böylece ELEV% 50 <> 0
Bunu QGIS 2.12 de yaptım ... kilometreniz önceki sürümlere göre değişebilir.
Burada her kontur çizgisinde bir "ELEV" alanı olduğunu varsayıyorum.
Kontur çizgilerini bölümlere ayır
Konturlarınızı eşit uzunlukta bölümlere ayırmak için işleme ve GRASS algoritmasını v.split.length kullanın. Metreleri kullandığınız varsayılarak, harita birimlerinde etiketinizin boyutuna yakın olacak bir uzunluk seçmeniz gerekir. Burada 200m kullandım.
Dosyanızı çok daha büyük hale getireceğinden bu konuda dikkatli olun (özelliğin ekran görüntüsünde önemli olduğunu unutmayın).
Bunu aşmak için, tüm orta kontur çizgilerini işlemekten kaçınmak için yalnızca stillendirmek istediğiniz kontür çizgilerini (örneğin her 50 veya 100 metrede) oluşturmak isteyebilirsiniz.
Bu katmana, showLabel adlı 1 basamaklı bir tamsayı alanı ekleyin . Varsayılan 0 veya NULL.
Etiketi yalnızca bu alanın 1 olarak ayarlandığı bir segmentte gösterilecek şekilde değiştirin. Bunu etiket metni ifadesi için kullanın ...
if ( "showlabel" is not null, "ELEV", "")
Bence (ifade, gerçek değer, yanlış değer) oldukça yenidir; daha eski bir sürüm kullanıyorsanız, CASE-ELSE kullanabilirsiniz.
Çizgi stilini değiştirin, böylece etiketin gösterildiği bölümler hariç , sabit uzunluktaki bölümlerin tümü çizilir . Dolayısıyla Kural Tabanlı renderlemeyi iki kuralla kullanın
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Şimdi, tüm konturlar varsayılan olarak gösterilecek, ancak etiket göstermeyecektir.
Etiket göstermek istediğiniz bölgeleri manuel olarak düzenleyin
Gidin düzenleme modunda ve elle ekrana kontur değerlerini istediğiniz bölümleri seçin ve değerini ayarlamak showLabel
seçilen özellikler için 1. İşleri hızlandırmak için çoklu seçim yapmak için Ctrl+ select'i (Ubuntu / Win'de, Cmd+ Ctrl+ Mac'te / Mac'te mi?)) Kullanabilirsiniz .
Bu, etiketlerin gösterilmesini istediğiniz konturları 'kırpmalıdır' ve etiketler boşluklarda gösterilecektir.
Bu durumda, etiket ayarlarım:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
Umarım yardımcı olur!
"Label setting" sekmesindeki "Buffer" seçeneğini kullanıyorum. (Katman özellikleri iletişim kutusundaki eski etiketler seçeneğini değil, etiketler düğmesini kullanın.) Bu, yapmak istediğinizi düşündüğüm gibi kontur çizgisini silmez, ancak etiketi okunaklı hale getirir.
Mevcut QGIS yetenekleri ile elde edebileceği en yakın şeyin, altta yatan ızgara için kullanılan yükseklik değerine ve renk şemasına dayanacak olan tablodan elde edilen renkle halo (veya arka plan) efekti kullanmak olduğunu düşünüyorum . Tabii ki bu, tepe gölgesini ve haritadaki halo altındaki her şeyi hesaba katmaz . Rastgele renk örneği: Bazı kod biti ile bu, ızgara rengini yansıtan bir işlev olarak yeniden yazılabilir.
Teoride, özel çizgi deseni ve etiket tekrarı + ofseti kullanmak mümkün olmalıdır . Ne yazık ki etiket ofset ayarı yoktur.
Son zamanlarda aynı problemle karşılaştıktan sonra ağır kaldırma işlemini gerçekleştirmek için bir QGIS Python senaryosu hazırladım. Bazı (İngiltere) test verileri, Readme (Guide) ve kullanılan stil sayfalarını içeren komut dosyası https://github.com/pjgeng/Contour-Labels adresinde bulunabilir.
Kısacası komut dosyası, giriş olarak iki vektör katmanını kullanır - açıklamalı kontur katmanı ve bir "kılavuzlar" katmanı. İkincisi, konturları istenen etiket lokasyonlarında kesişen polillerden oluşur.
Komut daha sonra konturlar arasındaki mesafeye ve etiketlerin uygulanacağı, etiket noktalarına bir dönme değeri ekleyen endeks kontur aralığı arasındaki mesafeye bağlı olarak çalışır ve sonunda boşlukları üretmek için orijinal kontur katmanını klipler.
Yaklaşım özellikle kullanıcının aynı alanda farklı aralıklarla kontur haritaları üretmesi gerektiğinde iyi çalışır (örn. Kılavuzlar değişmez). Bir dezavantaj, kod tamamlandıktan sonra etiket konumunu değiştirememesidir. Bunun için kullanıcının kılavuz çizgilerini ayarlaması ve betiği orijinal girdiyle tekrar çalıştırması gerekir. Daha önce kesikli efekt oluşturmak için etiketlerin etrafındaki tamponlarla çok çalıştım, ancak bunun vektör veriye dayalı haritalarda estetik açıdan nahoş olduğu ortaya çıktı.
Ne yazık ki, işlemi daha fazla belgelemek veya göstermek için şu anda daha fazla resim ekleyemiyorum.
Not: Depoda sağlanan stil katmanlarını kullanıyorsanız, etiketleme menüsünde "Döndürme", "Etiketi Göster" ve "Her Zaman Göster" için özel alanları "etkinleştirmeleri" gerekebilir. Bazı QGIS kurulumlarında bunlar otomatik olarak stil sayfasından uygulanır - Buna henüz neyin sebep olduğunu bulamadım.
İşte QGIS kontur-etiket-maskeleme problemi için başka bir çözüm, burada QGIS Spatialite işlevselliğini (şu anda QGIS 3.x) etiket yerleştirme için bir geometri üreteci ile birlikte kullanıyorum.
Bu çok dinamik çözüm, tüm etiket metni boyutlarını ve etiket konumlarını hemen değiştirmemize olanak sağlar ve hatta bir PDF vektörü dışa aktarma işleminden de kurtulabilir!
Bunu mümkün kılmak için aşağıdaki parçalara ihtiyacımız var:
Kural tabanlı stil içeren “contours_with_labels” adında sanal bir katman:
Kural 2: ELSE… basit çizgi
ve Kural 1 için koşullu bir etiket metni:
OLDUĞU DURUMDA etiket = 1 SONRA ELSE '' SON
make_line (başlangıç_ noktası ($ geometri), bitiş_ noktası ($ geometri))
özniteliği (get_feature ('settings', 'değişken', 'contourlabel_size'), 'değer')
ve son fakat en az değil, işte sanal katman için SQL sorgusu:
------------------------------------------------------------------------
-- 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)
Bu kadar.
Bunu mümkün kılan tüm bu coşkulu insanlara çok teşekkürler!
Bu konuyu hatırlıyor musun Martin? Sorununuza bir çözüme yaklaşmak için düşünebilmemin tek yolu, kontur katmanınızı kırpılmış bir kontur katmanıyla kaplamak, bunu etiketleme için kullanmak ve çizgi rengini etiketlerin altındaki konturları maskeleyecek nötr bir şeye değiştirmek olacaktır. insan çok müdahaleci olmadan umut ediyor. N.
Sonra eklendi: bu konuya bakmak da faydalı olabilir , ikinci cevap. Belki kontür çizgilerini kesmek, belki kontürleri kırpmak için kullanılan tampon katmanını kullanarak bir cevap olabilir.
ESRI blog girişi: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
Kontur etiketleri için değişken derinlikli maskeleme üç adımdan oluşur:
1 etiketlerden açıklama oluşturma, 2 maskeleri oluşturmak için Özellik Anahat Maskeleri aracını kullanma ve maskeleri hangi katmanları maskeleyeceğini belirtmek için Gelişmiş Çizim Seçenekleri> Maskeleme ayarlarını kullanma.
Etiketleri daha mükemmel hale getirmek için, sanal katmanın SQL sorgusunu, kontur çizgilerine paralel çalışan çizik çizgilere uyması için değiştirdim (aşağıdaki çözüme bakın):
Ve işte sanal katman için yeni SQL:
------------------------------------------------------------------------
-- 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)