Контроль маркування на основі правил за допомогою PyQGIS?


15

Виходячи з цього питання: Як увімкнути / вимкнути всі мітки всіх шарів у QGIS , ОП зазначив у своєму коментарі, що він використовує мітки на основі правил. Я спробував шукати в Інтернеті, як можна читати та змінювати ці типи міток, але мені вдалося знайти цю публікацію лише з lutraconsulting :

Для полегшення додавання маркування на основі правил були внесені деякі внутрішні зміни в інтерфейс двигуна маркування QGIS. Зараз маркування веде новий клас, QgsLabelingEngineV2який може мати декілька постачальників етикеток.

Звучить прекрасно. Однак, читаючи через клас QgsLabelingEngineV2 , він згадує:

цей клас ще не є частиною публічного API.

Чи можна в даний час контролювати маркування на основі правил, використовуючи python?


1
Я знайшов тут відкрите питання щодо проекту Qgis Documentation в Github, який також згадує про це . Я не зміг знайти прив’язку SIP для цього класу у гілках MASTER або 2.18, тому підозрюю, що він доступний лише для коду C ++.
Стівен Кей

@StevenKay - Чудова знахідка, дякую! Було б дуже корисно, якби вони зробили для нього API ... Також дякую за редагування, я подумав, що я вставив правильне посилання для класу :)
Джозеф

@StevenKay - Я думаю, що вони зробили для цього API, точніше клас QgsRuleBasedLabeling :)
Джозеф

Відповіді:


6

Нижче наведено довідку щодо встановлення етикетки на основі правил з нуля за допомогою нового API QGIS 3

#Configure label settings
settings = QgsPalLayerSettings()
settings.fieldName = 'myFieldName'
textFormat = QgsTextFormat()
textFormat.setSize(10)
settings.setFormat(textFormat)
#create and append a new rule
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
rule = QgsRuleBasedLabeling.Rule(settings)
rule.setDescription(fieldName)
rule.setFilterExpression('myExpression')
root.appendChild(rule)
#Apply label configuration
rules = QgsRuleBasedLabeling(root)
myLayer.setLabeling(rules)
myLayer.triggerRepaint()

На жаль, я не можу знайти, як перебирати існуючі правила, метод labeling (), доступний для векторних шарів, повертає об'єкт класу QgsAbpositeVectorLayerLabeling, але, здається, немає способу отримати кореневе правило ( QgsRuleBasedLabeling ) з цього класу, єдина можливість Я виявив, що потрібно безпосередньо отримати налаштування за допомогою ідентифікаторів постачальників, але я не можу отримати доступ до дерева правил. Хтось має підказку?

EDIT

Тепер це виправлено, функція labeling () повертає QgsRuleBasedLabeling (): https://github.com/qgis/QGIS/commit/4b365a8f47d96b35f7609859e580388927ae0606


Дякуємо за вашу відповідь, чудово опрацьовано! Сподіваюсь, ви не заперечуєте, але я трохи відредагував вашу публікацію, щоб включити myLayer.triggerRepaint()для оновлення шару та дозволити показ ярликів одразу після встановлення правил :)
Джозеф

3

З QGIS 3 з'явився новий клас QgsRuleBasedLabeling, який дозволить вам керувати маркування на основі правил за допомогою нового API.

Правила можна додавати за допомогою QgsRuleBasedLabeling :: Правило .


( На жаль, наразі я не можу перевірити версію 2.99. Але я б із задоволенням прийняв би відповідь, якщо вона надає робочий приклад. )


1

Це те, що я використовую, щоб змінити вираз фільтра в символіці, заснованій на правилах у QGIS 2.18, не впевнений, що це те, що ви просите. Посилання API за адресою http://qgis.org/api/2.18/classQgsRuleBasedRendererV2.html

import re
lddLrs = qgis.utils.iface.legendInterface().layers()    #get all loaded layers
for lyr in lddLrs:
    if (lyr.type()==QgsMapLayer.VectorLayer and lyr.name()=='layer_with_rules'): rLyr = lyr

newType = 1
for child in rLyr.rendererV2().rootRule().children():
    oldFilter = child.filterExpression()  #you can print this to see what the old expression is
    print oldFilter

    newFilter = re.sub(r"type = (\d*)", r"type = {0}".format(newType), oldFilter)  #this is an example to substitute a rule-based filter to a new number
    print newFilter

    child.setFilterExpression(newFilter)

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