10 votos

¿Cambiar a una etiqueta alternativa si la primera etiqueta no cabe en QGIS?

Estoy intentando crear un mapa para imprimir y el tamaño de mis polígonos varía mucho. Como este será un mapa de referencia necesito etiquetar cada polígono, pero algunos de los nombres no caben en el polígono. En esos casos me gustaría utilizar el id de la característica y luego tener una tabla de atributos que vincule el id con el nombre.

Lo que me gustaría hacer es tener algún tipo de expresión que pueda usar para seleccionar qué etiqueta usar en el mapa y qué filas incluir en la tabla de atributos. Algo así como isLabelled que pueda tener en cuenta la escala del mapa, la longitud de la etiqueta, el tamaño de la letra, etc.

2 votos

Hay que tener en cuenta que puede ser confuso para el usuario del mapa, cuando los polígonos de la misma clase de característica están etiquetados de diferentes maneras y además sólo algunos de ellos aparecen en una tabla de atributos.

0 votos

Estoy pensando en un mapa de condados de GB

0 votos

¿Qué hay de cambiar dinámicamente el tipo de letra para que se ajuste? Podrías tomar la dimensión más larga de las características, dividirla por el número de caracteres de la cadena de etiquetas, y hacer algunos cálculos con la escala o simplemente usarla para alterar el tamaño de la fuente ya establecida... Alternativamente podrías usar esa medida (dimensión de la característica más larga / longitud de la cadena) y si es demasiado larga etiquetar con el id.

8voto

user52245 Puntos 16

He aquí una forma algo aproximada (pero espero que eficaz) de hacerlo.

Primero algo de matemáticas. Tenemos que calcular cuántos caracteres de un determinado tamaño de fuente puede contener una característica. Aquí las cosas / suposiciones para saber:

  • asumiendo las unidades métricas, (se ha añadido un ligero cambio a continuación que puede hacer que esto funcione para nosotros los crs. de pie)
  • El tamaño de la fuente es una medida de la altura de la fuente. La mayoría de las fuentes son aproximadamente la mitad de anchas que de altas.
  • utilizando pt para la altura de la fuente, 1pt es casi 0.035CM
  • asumiendo que sus parcelas son aproximadamente rectangulares / regulares

Para saber la longitud de un artículo en pantalla/impresión podemos utilizar su dimensión más larga (longitud o altura, o sólo longitud si sus etiquetas son sólo horizontales) / escala * 100 (para pasar de M a CM)

Entonces podremos ver si nuestra etiqueta encaja.

Podrías hacerlo todo en el motor de expresión, pero una expresión personalizada en python sería más eficiente. Aquí es un tutorial sobre cómo crear uno.

Mi expresión personalizada:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def labelFits(labelStr, fontPt, scaleM, feature, parent):
    # returns true if a label will fit in the feature at a given
    # font size and scale

    bbox = feature.geometry().boundingBox()

    # for CRS in us foot
    # fontWidth = fontPt * 0.0875

    # for CRS in metric
    # 1pt = 0.035CM
    fontWidth = fontPt * 0.035 * 0.5

    # length of maximum dimension on-screen/print in CM
    labelRoom =  max(bbox.width(),bbox.height()) / scaleM * 100

    # approx length of our label in CM based on font height * 0.5
    labelLen = len(labelStr) * fontWidth

    if labelRoom > labelLen:
        return True
    else:
        return False

Entonces sólo hay que utilizar esa expresión en la etiqueta:

if(labelFits( "yourAttribute" , 8 , @map_scale ), "yourAttribute",$id)

Tendrás que introducir el atributo que estés utilizando, por supuesto, y cambiar el tamaño de la fuente de 8 a lo que estés utilizando. Además, como los tipos de letra varían bastante, es posible que tengas que retocarlo un poco hasta que quede bien.

También puedes usar esa expresión para hacer cosas como cambiar el color en función de si la etiqueta encaja o no.


Para utilizar esta expresión fuera del lienzo del mapa (es decir, en una etiqueta de compositor o una tabla de atributos) necesitamos una forma de obtener mediante programación la escala de un elemento del mapa determinado. He publicado el código para lograr que en otra respuesta aquí El método allí nos da una expresión getScale('composername','mapname') para incorporarla a nuestra expresión:

if(
    labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
    "yourAttribute",$id)

1 votos

Yo también estaba pensando en algo parecido. Especialmente si se utilizan unidades de mapa y una proyección en metros. Los nuevos operadores geométricos también podrían ayudar en este caso, suponiendo que las etiquetas estén centradas en el centroide. Esto funcionará mejor con una fuente de ancho fijo (monoespaciado) que con una fuente proporcional (donde una 'W' es mucho más ancha que una 'i', por ejemplo). Tienes algo en mente, pero sospecho que las fuentes proporcionales y el interletraje añadirán complejidad.

0 votos

Podrías usar imagefont.getsize() de pil. Eso te daría un ancho exacto de una cadena renderizada en tu fuente elegida, pero creo que eso tendría un gran impacto en el rendimiento. El cálculo aproximado de arriba es mucho más simple, especialmente si tienes cientos de etiquetas en la pantalla

0 votos

El único problema menor es que la función no parece funcionar como filtro en las tablas de atributos en print composer.

3voto

Alexander Riccio Puntos 143

Duplique la capa, una sin simbología, y establezca diferentes niveles de zoom/configuración de obstáculos para las etiquetas de cada una.

1voto

Dan Hewett Puntos 995

Tuve una situación similar con la obligación de etiquetar cada carretera en una capa de carreteras. Mi solución fue crear el lienzo a un tamaño mayor, exportar a PDF y luego imprimir el PDF al tamaño que se requería.

Por ejemplo, se exigía que el producto acabado fuera A3. En el lienzo en A3 no me cabían todas las etiquetas. Así que hice el lienzo A2 y eso permitió que se vieran todas las etiquetas. Cree un PDF del mapa en tamaño A2 y lo imprimí en A3.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X