Aquí hay una forma aproximada (pero con suerte efectiva) de hacerlo.
Primero algo de matemática. Necesitamos averiguar cuántos caracteres en un determinado tamaño de fuente puede contener una característica. Aquí cosas / supuestos para saber:
- asumiendo unidades métricas, (se agregó un ligero cambio a continuación que puede hacer que esto funcione para nosotros).
- El tamaño de fuente es una medida de la altura de la fuente. La mayoría de las fuentes son aproximadamente la mitad de anchas que altas.
- usando pt para la altura de la fuente, 1pt es aproximadamente 0.035 cm
- asumiendo que sus paquetes son aproximadamente rectangulares / regulares
Para saber cuánto tiempo está un elemento en la pantalla / impresión, podemos usar su dimensión más larga (longitud o altura, o solo longitud si sus etiquetas son solo horizontales) / escala * 100 (para ir de M a CM)
Entonces podemos ver si nuestra etiqueta encajaría.
Podría hacerlo todo en el motor de expresión, pero una expresión personalizada de Python sería más eficiente. Aquí hay un tutorial sobre cómo crear uno.
Mi expresion 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
Luego solo usa esa expresión en la etiqueta:
if(labelFits( "yourAttribute" , 8 , @map_scale ), "yourAttribute",$id)
Necesitará conectar cualquier atributo que esté usando, por supuesto, y cambiar el tamaño de fuente de 8 a lo que esté usando. Además, dado que las fuentes varían bastante, es posible que deba modificarlas un poco hasta que se vean bien.
También puede usar esa expresión para hacer cosas como cambiar el color en función de si la etiqueta se ajusta o no.
Para usar esta expresión fuera del lienzo del mapa (es decir, en una etiqueta de compositor o en una tabla de atributos) necesitamos una forma de obtener mediante programación la escala de un elemento de mapa dado. He publicado código para lograr eso en otra respuesta aquí.
El método allí nos da una expresión getScale ('nombre del compositor', 'nombre del mapa') para incorporarlo a nuestra expresión:
if(
labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
"yourAttribute",$id)