使用PyQGIS控制基于规则的标签?


15

接下来是这个问题:如何在QGIS中打开/​​关闭所有层的所有标签,OP在他的评论中提到他使用基于规则的标签。我尝试在线搜索有关如何读取和修改这些类型的标签,但只能通过lutraconsulting找到这篇文章

为了便于添加基于规则的标签,对QGIS标签引擎界面进行了一些内部更改。现在,标签由新类驱动,新类QgsLabelingEngineV2可能具有与其关联的多个标签提供程序。

听起来不错。但是,在阅读QgsLabelingEngineV2类时,它提到:

此类尚未成为公共API的一部分。

目前是否可以使用python控制基于规则的标签?


1
在Github的Qgis文档项目中发现了一个未解决的问题,该问题也提到了这一点。我在MASTER或2.18分支中找不到该类的SIP绑定,因此我怀疑它仍然仅对C ++代码可用。
史蒂文·凯

@StevenKay-很好,谢谢!如果他们确实为此制作了API,那将非常有用...还要感谢您的编辑,我想我已经为该类粘贴了正确的链接:)
Joseph

@StevenKay-我认为他们现在为此制作了一个API,更具体地说是QgsRuleBasedLabeling类:)
Joseph

Answers:


6

下面是使用新的QGIS 3 API从头开始设置基于规则的标签的一些帮助

#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()方法返回QgsAbstractVectorLayerLabeling类的对象,但似乎没有办法从此类中获取根规则(QgsRuleBasedLabeling),这是唯一的可能性我发现是使用提供程序ID直接获得pal设置,但是我无法访问规则树。有人知道吗?

编辑

现在已修复,labeling()函数返回QgsRuleBasedLabeling():https : //github.com/qgis/QGIS/commit/4b365a8f47d96b35f7609859e580388927ae0606


感谢您的回答,很好地解决了!希望您不介意,但我对您的帖子进行了略微编辑,以包括myLayer.triggerRepaint()刷新图层并在设置规则后立即显示标签:)
Joseph


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)

感谢您的回答,但正如您所说,我认为这仅适用于符号系统,而不适用于标签 :)
约瑟夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.