Ось дещо приблизний (але, сподіваємось, ефективний) спосіб це зробити.
Спочатку трохи математики. Нам потрібно розібратися, скільки символів у певному розмірі шрифту може містити функція. Тут потрібно знати / припущення:
- припускаючи метричні одиниці, (додано невелику зміну нижче, яка може зробити цю роботу для нас стоп.)
- розмір шрифту - це міра висоти шрифту. Більшість шрифтів приблизно вдвічі ширші, ніж високі.
- використовуючи pt для висоти шрифту, 1pt грубо 0,035 СМ
- якщо припустити, що ваші посилки є прямокутними / правильними
Щоб дізнатися, як довго елемент знаходиться на екрані / друку, ми можемо використовувати його найдовший розмір (довжина або висота або просто довжина, якщо ваші мітки мають лише горизонтальний розмір) / масштаб * 100 (для переходу від M до CM)
Тоді ми можемо побачити, чи підходить наша етикетка.
Ви можете зробити це все в механізмі виразів, але користувацький вираз python був би більш ефективним. Ось підручник про те, як його створити.
Мій спеціальний вираз:
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
Тоді просто використовуйте цей вираз у мітці:
if(labelFits( "yourAttribute" , 8 , @map_scale ), "yourAttribute",$id)
Вам потрібно буде підключити будь-який атрибут, який ви фактично використовуєте, і змінити розмір шрифту від 8 до того, що ви використовуєте. Крім того, оскільки шрифти різняться, можливо, вам доведеться трохи підправити його, поки він не виглядає правильно.
Ви також можете використовувати цей вираз, щоб зробити такі речі, як зміна кольору на основі, якщо ярлик підходить чи ні.
Щоб використовувати цей вираз поза полотном карти (тобто в таблиці міток композитора чи таблиці атрибутів), нам потрібен спосіб програмного отримання масштабу певного елемента карти. Я розмістив код, щоб досягти цього в іншій відповіді тут
. Метод там дає нам вираз getScale ('composername', 'namename'), щоб включити його у наш вираз:
if(
labelFits( "yourAttribute" , 8 , getScale('composername','mapname')),
"yourAttribute",$id)