¿Hay alguna manera de interrumpir una línea de contorno debajo de una etiqueta de elevación?
¿Hay alguna manera de interrumpir una línea de contorno debajo de una etiqueta de elevación?
Respuestas:
Sí, factible Normalmente sugeriría un búfer parcialmente transparente, pero veo por qué quieres hacer esto cartográficamente.
Esto podría ser lento, y debe decidir manualmente dónde quiere que vayan las etiquetas, pero cartográficamente hablando, ¡eso no es algo malo!
Aquí hay una captura de pantalla ...
Como puede ver, no hay amortiguadores. La trama debajo no se ve afectada. He incluido líneas de contorno intermedias más delgadas y las he diseñado para que solo se muestren cuando ELEV% 50 <> 0
Lo hice en QGIS 2.12 ... su millaje puede variar con versiones anteriores.
Supongo que aquí tiene un campo "ELEV" en cada línea de contorno.
Segmentar las líneas de contorno
Utilice el procesamiento y el algoritmo GRASS v.split.length para dividir sus contornos en segmentos de igual longitud. Debe elegir una longitud que se acerque al tamaño de su etiqueta en unidades de mapa, suponiendo que esté usando metros. Aquí usé 200m.
Tenga cuidado con esto, ya que hará que su archivo sea mucho, mucho más grande (tenga en cuenta que la función cuenta en la captura de pantalla).
Para evitar esto, es posible que desee generar solo las líneas de contornos que desea diseñar (por ejemplo, cada 50 o 100 metros) para evitar el procesamiento de todas las líneas de contorno intermedias.
A esta capa, agregue un campo entero de 1 dígito llamado showLabel . Por defecto a 0 o NULL.
Cambie la etiqueta para que solo se muestre en un segmento donde este campo esté establecido en 1. Use esto para la expresión de texto de la etiqueta ...
if ( "showlabel" is not null, "ELEV", "")
Creo que si (expresión, valor verdadero, valor falso) es bastante nuevo; si usa una versión anterior, puede usar CASE-ELSE
Cambie el estilo de línea para que todos los segmentos de longitud fija se dibujen, excepto aquellos segmentos donde se muestra la etiqueta. Por lo tanto, use la representación basada en reglas con dos reglas
Rule 1: "showLabel" is null
Black, 0% transparent
Rule 2: "showLabel" is not null
Any colour, 100% transparent
Ahora, todos los contornos se mostrarán de manera predeterminada, pero sin etiquetas.
Edite manualmente segmentos donde desea mostrar etiquetas
Vaya al modo de edición y seleccione manualmente los segmentos donde desea que se muestren los valores de contorno, y establezca el valor showLabel
en 1 para las características seleccionadas. Puede usar Ctrl+ select (en Ubuntu / Win, Cmd+ Ctrl+ Click / en Mac?) Para seleccionar múltiples segmentos para acelerar las cosas.
Esto ahora debería 'recortar' los contornos donde desea que se muestren las etiquetas, y las etiquetas se mostrarán en los huecos.
En este caso, mi configuración de etiqueta fue:
CRS: EPSG 27700 (Local UTM for UK, in meters)
Text size: 50 map units
Placement: Parallel, On Line
¡Espero que ayude!
Uso la opción "Buffer" en la pestaña "Configuración de etiqueta". (Usando el botón de etiquetas, no la opción de etiquetas antiguas en el cuadro de diálogo de propiedades de capa). Esto no borra la línea de contorno, como imagino que quieres hacer, pero hace que la etiqueta sea legible.
Creo que lo más cercano que puede estar con las habilidades actuales de QGIS es usar el efecto de halo (o fondo) con el color procedente de la tabla, que se basará en el valor de elevación y el esquema de color igual al utilizado para la cuadrícula subyacente. Por supuesto, esto no tomaría en cuenta el sombreado y todo lo demás debajo del halo en el mapa. Ejemplo de color aleatorio: con un poco de código, esto podría reescribirse como función para reflejar el color de la cuadrícula.
En teoría, debería ser posible utilizar un patrón de línea personalizado y repetir la etiqueta + desplazamiento . Desafortunadamente no hay una configuración de desplazamiento de etiqueta.
Después de encontrarme con el mismo problema recientemente, armé un script QGIS Python para llevar a cabo el trabajo pesado. El guión que incluye algunos datos de prueba (Reino Unido), Léame (Guía) y hojas de estilo utilizadas se puede encontrar en https://github.com/pjgeng/Contour-Labels
En resumen, el script utiliza dos capas vectoriales como entrada: la capa de contorno anotada y una capa de "guías". Este último consiste en polilíneas que intersecan los contornos en las ubicaciones de etiquetas deseadas.
La secuencia de comandos luego se basa en la distancia entre los contornos y el intervalo de contornos de índice que las etiquetas a aplicar, agrega un valor de rotación a los puntos de la etiqueta y eventualmente recorta la capa de contorno original para producir los espacios.
El enfoque funciona particularmente bien si el usuario necesita producir mapas de contorno a diferentes intervalos en la misma área (es decir, las guías no cambian). Un inconveniente es la incapacidad de cambiar la posición de la etiqueta una vez que el guión ha finalizado. Para esto, el usuario tendría que ajustar las líneas de guía y volver a ejecutar el script contra la entrada original. Anteriormente trabajé mucho con las memorias intermedias alrededor de las etiquetas para crear el efecto interrumpido, pero esto resultó ser estéticamente desagradable en los mapas basados en datos vectoriales.
Lamentablemente, no puedo agregar más imágenes en este momento para documentar o ilustrar el proceso más.
PD: Si usa las capas de estilo proporcionadas en el repositorio, los usuarios pueden necesitar "activar" los campos personalizados para "Rotación", "Mostrar etiqueta" y "Mostrar siempre" en el menú de etiquetado. En algunas instalaciones de QGIS, estos se aplican automáticamente desde la hoja de estilo; todavía no he descubierto qué causa esto.
Aquí hay otra solución para el problema de enmascaramiento de etiquetas de contorno QGIS, donde aprovecho la funcionalidad Spatialite de QGIS (actualmente QGIS 3.x) junto con un generador de geometría para la colocación de etiquetas.
Esta solución muy dinámica nos permite cambiar todos los tamaños de texto de etiquetas y posiciones de etiquetas de forma inmediata, ¡e incluso sobrevive a una exportación de vectores PDF!
Para que esto sea posible, necesitamos las siguientes partes:
Una capa virtual llamada, es decir, "contours_with_labels" con estilo basado en reglas:
Regla 2: ELSE ... línea simple
y un texto de etiqueta condicional para la Regla 1:
CASO CUANDO etiqueta = 1 LUEGO once más '' FIN
make_line (start_point ($ geometry), end_point ($ geometry))
atributo (get_feature ('configuración', 'variable', 'contourlabel_size'), 'valor')
y por último pero no menos importante, aquí va la consulta SQL para la capa 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)
Eso es.
¡Muchas gracias a todas estas personas entusiastas que hacen esto posible!
Te acuerdas de esto hilo Martin? La única forma en que puedo pensar para acercarme a una solución a su problema sería superponer su capa de contorno con una capa de contorno recortada, usar esto para etiquetar y cambiar el color de la línea a algo neutral que enmascare los contornos debajo de las etiquetas, uno espera sin ser demasiado intrusivo. NORTE.
Agregado más tarde: podría valer la pena mirar este hilo también, la segunda respuesta. ¿Quizás romper las líneas de contorno podría ser una respuesta, quizás usando la capa de amortiguación utilizada para recortar los contornos?
Para hacer que las etiquetas sean más perfectas, cambié la consulta SQL de la capa virtual para respetar las líneas de borrador que corren paralelas a las líneas de contorno (consulte la solución a continuación):
Y aquí está el nuevo SQL para la capa 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)
Entrada de blog de ESRI: http://blogs.esri.com/esri/arcgis/2011/11/28/variable-depth-masking-contour-label-example/
El enmascaramiento de profundidad variable para etiquetas de contorno implica tres pasos:
1creando anotaciones a partir de las etiquetas, 2 usando la herramienta Máscaras de contorno de entidades para crear máscaras, y 3 usando las Opciones avanzadas de dibujo> Configuración de enmascaramiento para especificar qué capas enmascararán las máscaras.