Oto nieco przybliżony (ale miejmy nadzieję skuteczny) sposób na zrobienie tego.
Najpierw trochę matematyki. Musimy dowiedzieć się, ile znaków przy określonym rozmiarze czcionki może zawierać funkcja. Oto rzeczy / założenia, które należy wiedzieć:
- przy założeniu jednostek metrycznych (dodana niewielka zmiana poniżej, która może sprawić, że będzie to dla nas działaniem crs.)
- rozmiar czcionki jest miarą wysokości czcionki. Większość czcionek ma około połowy szerokości i wysokości.
- przy użyciu pt dla wysokości czcionki, 1pt to z grubsza 0,035 cm
- zakładając, że twoje paczki są w przybliżeniu prostokątne / regularne
Aby dowiedzieć się, jak długi jest element na ekranie / wydruku, możemy użyć jego najdłuższego wymiaru (długość lub wysokość lub tylko długość, jeśli twoje etykiety są tylko poziome) / skala * 100 (aby przejść z M do CM)
Następnie możemy sprawdzić, czy nasza etykieta będzie pasować.
Można to zrobić w silniku wyrażeń, ale niestandardowe wyrażenie w języku Python byłoby bardziej wydajne. Oto samouczek, jak go utworzyć.
Moje niestandardowe wyrażenie:
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
Następnie użyj tego wyrażenia na etykiecie:
if(labelFits( "yourAttribute" , 8 , @map_scale ), "yourAttribute",$id)
Musisz oczywiście podłączyć dowolny atrybut, którego faktycznie używasz, i zmienić rozmiar czcionki z 8 na cokolwiek, którego używasz. Ponadto, ponieważ czcionki różnią się nieco, być może trzeba będzie je nieco poprawić, aby wyglądało poprawnie.
Możesz także użyć tego wyrażenia, aby zmienić kolor na podstawie tego, czy etykieta pasuje, czy nie.
Aby użyć tego wyrażenia poza obszarem mapy (tj. W etykiecie kompozytora lub tabeli atrybutów), potrzebujemy sposobu, aby programowo uzyskać skalę danego elementu mapy.
Umieściłem kod, aby to osiągnąć w innej odpowiedzi tutaj . Metoda daje nam wyrażenie getScale („nazwa kompozytora”, „nazwa mapy”), aby włączyć go do naszego wyrażenia:
if(
labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
"yourAttribute",$id)