Зміна на альтернативну мітку, якщо перша мітка не входить у QGIS?


10

Я намагаюся створити карту для друку, і розмір моїх полігонів сильно різниться. Оскільки це буде довідкова карта, мені потрібно позначити кожен багатокутник, але деякі назви не будуть вміщуватися в полігоні. У цих випадках я хотів би скористатися ідентифікатором функції замість цього, а потім таблиця атрибутів пов'язує ідентифікатор з іменем.

Що я хотів би зробити - це якийсь вираз, який я можу використовувати, щоб вибрати мітку, яку використовувати на карті, а також які рядки включити до таблиці атрибутів. Щось подібне isLabelledмогло б врахувати масштаб карти, довжину мітки, розмір шрифту тощо.


2
Майте на увазі, що це може бути заплутаним для користувача карти, коли полігони одного класу ознак позначаються різними способами, а крім того, лише деякі з них відображаються в таблиці атрибутів.
таллістроан

Я думаю про карту округу ГБ
Ян Тертон

А що з динамічною зміною шрифту на відповідний? Ви можете взяти найдовший з розмірів функцій, розділити на кількість символів у рядку мітки, або виконати математику зі шкалою, або просто використовувати це для зміни вже встановленого розміру шрифту ... Або ви можете використовувати цей показник (найдовший розмір функції / розмір рядка) і якщо вона занадто довга мітка з ідентифікатором.
Джессі Макміллан

в основному я переймаюся читабельністю, тому не хочу возитися з розміром шрифту
Ian Turton

1
Ви можете використовувати спеціальний вираз Python, беручи мітку, розмір шрифту та масштаб і повертаючи істинне чи хибне, якщо воно відповідатиме. Тоді в виразі engine використовуйте клавішу if для перемикання міток. Пізніше я розробіть відповідь для вас із прикладами.
Джессі Макміллан

Відповіді:


8

Ось дещо приблизний (але, сподіваємось, ефективний) спосіб це зробити.

Спочатку трохи математики. Нам потрібно розібратися, скільки символів у певному розмірі шрифту може містити функція. Тут потрібно знати / припущення:

  • припускаючи метричні одиниці, (додано невелику зміну нижче, яка може зробити цю роботу для нас стоп.)
  • розмір шрифту - це міра висоти шрифту. Більшість шрифтів приблизно вдвічі ширші, ніж високі.
  • використовуючи 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)

1
Я думав і про щось подібне. Особливо якщо використовувати одиниці карт та проекцію в метрах. Тут можуть допомогти нові оператори геометрії, якщо мітки зосереджені на центроїді. Це буде краще працювати з шрифтом фіксованої ширини (однорозмірним), ніж пропорційним шрифтом (де, наприклад, "W" набагато ширше, ніж "я"). Ви тут щось надіслали, але я підозрюю, що пропорційні шрифти і кернінг додадуть складності.
Стівен Кей

Ви можете використовувати pil's imagefont.getsize (). Це дасть вам точну ширину рядка, відображеного обраним вами шрифтом, але я думаю, що це призвело б до головного успіху. Приблизна математика вище набагато простіша, особливо якщо на екрані у вас сотні ярликів
Джессі Макміллан

Єдина незначна проблема полягає в тому, що ця функція, здається, не працює як фільтр у таблицях атрибутів у композиторі друку.
Ян Тертон

Чи варіюється масштаб вашої карти залежно від сторінки до сторінки? Спробуйте вручну ввести шкалу замість змінної @map_scale. я думаю, що таблиця атрибутів не може знати масштаб вашої карти. (Тому що, наприклад, у композитора може бути декілька елементів карти в різних масштабах)
Jesse McMillan

1
@iant Я розмістив посилання на інший спеціальний вираз, який програмно отримає масштаб вашої карти композитора.
Джессі Макміллан

3

Дублюйте шар, який не має символіки, і встановлюйте різні рівні масштабування / перешкоди для міток для кожного.


1

У мене була подібна ситуація із зобов’язанням маркувати кожну дорогу в дорожньому шарі. Моїм рішенням було створити полотно в більшому розмірі, експортувати в PDF, а потім надрукувати PDF до потрібного розміру.

Наприклад, готовий продукт повинен був бути А3. На полотні в форматі A3 я не зміг помістити всі етикетки. Тож я зробив полотно A2, і це дозволило побачити всі етикетки. Створіть PDF-карту розміру A2 та роздрукуйте її як A3.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.