C'è un modo per interrompere una linea di contorno sotto un'etichetta di elevazione?
C'è un modo per interrompere una linea di contorno sotto un'etichetta di elevazione?
Risposte:
Sì, fattibile. Normalmente suggerirei un buffer parzialmente trasparente, ma vedo perché vuoi farlo cartograficamente.
Questo potrebbe essere lento e devi decidere manualmente dove vuoi che vadano le etichette, ma dal punto di vista cartografico, non è una brutta cosa!
Ecco uno screenshot ...
Come puoi vedere, nessun buffer. Il raster sottostante non è interessato. Ho incluso linee di contorno intermedie più sottili e le ho disegnate in modo che vengano visualizzate solo quando ELEV% 50 <> 0
L'ho fatto in QGIS 2.12 ... il tuo chilometraggio può variare con le versioni precedenti.
Suppongo che qui ci sia un campo "ELEV" su ogni linea di contorno.
Segmenta le linee di contorno
Utilizzare l'elaborazione e l'algoritmo GRASS v.split.length per dividere i contorni in segmenti di uguale lunghezza. Devi scegliere una lunghezza che sarà vicina alla dimensione dell'etichetta in unità della mappa, supponendo che tu stia utilizzando i metri. Qui ho usato 200m.
Fai attenzione perché renderà il tuo file molto, molto più grande (nota che la funzione conta nello screenshot).
Per ovviare a questo, potresti voler generare solo quelle linee di contorno che desideri modellare (ad esempio ogni 50 o 100 metri) per evitare di elaborare tutte le linee di contorno intermedie.
A questo livello, aggiungi un campo intero di 1 cifra chiamato showLabel . L'impostazione predefinita è 0 o NULL.
Modifica l'etichetta per mostrarla solo su un segmento in cui questo campo è impostato su 1. Utilizzalo per l'espressione del testo dell'etichetta ...
if ( "showlabel" is not null, "ELEV", "")
Penso che (espressione, valore reale, valore falso) sia abbastanza nuovo; se si utilizza una versione precedente, è possibile utilizzare CASE-ELSE
Cambia lo stile della linea in modo che tutti i segmenti a lunghezza fissa siano disegnati, ad eccezione di quelli in cui viene visualizzata l'etichetta. Quindi usa il rendering basato su regole con due regole
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Ora, tutti i contorni verranno visualizzati per impostazione predefinita, ma nessuna etichetta.
Modifica manualmente i segmenti in cui desideri mostrare le etichette
Passare alla modalità di modifica e selezionare manualmente i segmenti in cui si desidera visualizzare i valori del contorno, quindi impostare il valore su showLabel
1 per le funzioni selezionate. Puoi usare Ctrl+ select (su Ubuntu / Win, Cmd+ Ctrl+ Click / su Mac?) Per selezionare più segmenti per velocizzare le cose.
Questo dovrebbe ora "tagliare" i contorni in cui si desidera mostrare le etichette e le etichette verranno visualizzate negli spazi.
In questo caso, le mie impostazioni dell'etichetta erano:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
Spero che sia d'aiuto!
Uso l'opzione "Buffer" nella scheda "Impostazione etichetta". (Usando il pulsante etichette, non la vecchia opzione etichette nella finestra di dialogo delle proprietà del livello.) Questo non cancella la linea di contorno, come immagino che tu voglia fare, ma rende leggibile l'etichetta.
Penso che il più vicino che possa ottenere con le attuali abilità di QGIS sia usare l' effetto alone (o di sfondo) con il colore proveniente dalla tabella che si baserà sul valore di elevazione e sulla combinazione di colori identici a quelli usati per la griglia sottostante. Naturalmente questo non prenderebbe in considerazione la sfumatura e tutto il resto sotto l' alone nella mappa. Esempio di colore casuale: con un po 'di codice questo potrebbe essere riscritto come funzione per riflettere il colore della griglia.
In teoria dovrebbe essere possibile utilizzare lo schema di linea personalizzato e l'etichetta ripetizione + offset . Sfortunatamente non esiste un'impostazione di offset dell'etichetta.
Di recente, dopo essermi imbattuto nello stesso problema, ho messo insieme uno script QGIS Python per eseguire il lavoro pesante. Lo script che include alcuni dati di test (Regno Unito), file Leggimi (Guida) e fogli di stile utilizzati è disponibile all'indirizzo https://github.com/pjgeng/Contour-Labels
In breve, lo script utilizza due livelli vettoriali come input: il livello contorno annotato e un livello "guide". Quest'ultimo è costituito da polilinee che intersecano i contorni nelle posizioni dell'etichetta desiderate.
Lo script funziona quindi in base alla distanza tra i contorni e all'intervallo del contorno dell'indice quali etichette applicare, aggiunge un valore di rotazione ai punti dell'etichetta e infine ritaglia il livello del contorno originale per produrre gli spazi.
L'approccio funziona particolarmente bene qualora l'utente debba produrre mappe di contorno a intervalli diversi nella stessa area (ovvero le guide non cambiano). Uno svantaggio è l'incapacità di modificare la posizione dell'etichetta al termine dello script. Per questo l'utente dovrebbe regolare le linee guida e rieseguire lo script rispetto all'input originale. In precedenza ho lavorato molto con i buffer attorno alle etichette per creare l'effetto interrotto, ma questo si è rivelato esteticamente sgradevole sulle mappe guidate dai dati vettoriali.
Purtroppo non posso aggiungere altre foto in questo momento per documentare o illustrare ulteriormente il processo.
PS: se si utilizzano gli strati di stile forniti nel repository, potrebbe essere necessario "attivare" i campi personalizzati per "Rotazione", "Mostra etichetta" e "Mostra sempre" nel menu di etichettatura. Su alcune installazioni di QGIS, queste vengono applicate automaticamente dal foglio di stile: non ho ancora scoperto le cause.
Ecco un'altra soluzione al problema del mascheramento dell'etichetta di contorno QGIS, in cui utilizzo la funzionalità Spatialite di QGIS (attualmente QGIS 3.x) insieme a un generatore di geometria per il posizionamento dell'etichetta.
Questa soluzione molto dinamica ci consente di modificare immediatamente tutte le dimensioni del testo e le posizioni delle etichette e sopravvive persino all'esportazione di un vettore PDF!
Per renderlo possibile abbiamo bisogno delle seguenti parti:
Un livello virtuale chiamato ie "contours_with_labels" con uno stile basato su regole:
Regola 2: ELSE ... linea semplice
e un testo condizionale dell'etichetta per la Regola 1:
CASO QUANDO etichetta = 1 THEN elev ELSE '' END
make_line (start_point ($ geometry), end_point ($ geometry))
attributo (get_feature ('settings', 'variabile', 'contourlabel_size'), 'value')
e ultimo ma non meno importante, ecco la query SQL per il livello virtuale:
------------------------------------------------------------------------
-- 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)
Questo è tutto.
Mille grazie a tutte queste persone entusiaste che lo hanno reso possibile!
Ti ricordi questa discussione Martin? L'unico modo in cui mi viene in mente di avvicinarmi a una soluzione al tuo problema sarebbe quello di sovrapporre il tuo livello del contorno con un livello del contorno ritagliato, usarlo per l'etichettatura e cambiare il colore della linea in qualcosa di neutro che maschererebbe i contorni sotto le etichette, si spera senza essere troppo invadenti. N.
Aggiunto in seguito: potrebbe valere la pena guardare anche questa discussione , la seconda risposta. Forse rompere le linee di contorno potrebbe essere una risposta, forse usando lo strato buffer usato per tagliare i contorni?
Per rendere le etichette più perfette, ho modificato la query SQL del livello virtuale per rispettare le linee di scratch che corrono parallele alle linee di contorno (vedere la soluzione di seguito):
Ed ecco il nuovo SQL per il livello virtuale:
------------------------------------------------------------------------
-- 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)
Voce del blog ESRI: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
La mascheratura a profondità variabile per le etichette dei contorni prevede tre passaggi:
1creare l'annotazione dalle etichette, 2utilizzare lo strumento Maschere struttura delle funzioni per creare maschere e 3utilizzare le Opzioni di disegno avanzate> Impostazioni di mascheratura per specificare quali livelli verranno mascherati dalle maschere.