การควบคุมการติดฉลากตามกฎโดยใช้ PyQGIS?


15

ตามจากคำถามนี้: วิธีเปิด / ปิดเลเบลทั้งหมดของเลเยอร์ทั้งหมดใน QGISนั้น OP ได้กล่าวถึงในความคิดเห็นของเขาว่าเขาใช้เลเบลแบบอิงกฎ ฉันพยายามค้นหาแบบออนไลน์เพื่อดูว่าสามารถอ่านและแก้ไขป้ายกำกับประเภทเหล่านี้ได้อย่างไร แต่จัดการเพื่อค้นหาโพสต์นี้จาก lutraconsulting :

เพื่อความสะดวกในการเพิ่มการติดฉลากตามกฎการเปลี่ยนแปลงภายในบางอย่างเกิดขึ้นกับส่วนต่อประสานของเอ็นจิ้นการติดฉลาก QGIS ขณะนี้การติดฉลากถูกขับเคลื่อนด้วยคลาสใหม่QgsLabelingEngineV2ซึ่งอาจมีผู้ให้บริการป้ายกำกับหลายรายที่เกี่ยวข้อง

ฟังดูดี. อย่างไรก็ตามเมื่ออ่านผ่านคลาส QgsLabelingEngineV2จะกล่าวถึง:

คลาสนี้ยังไม่ได้เป็นส่วนหนึ่งของ API สาธารณะ

ในปัจจุบันเป็นไปได้หรือไม่ที่จะควบคุมการติดฉลากตามกฎโดยใช้ python


1
ผมพบว่าเปิดประเด็นที่นี่ในโครงการเอกสาร QGIS ใน Github ซึ่งยังกล่าวถึงนี้ ฉันไม่พบการผูก SIP สำหรับชั้นเรียนนั้นในสาขา MASTER หรือ 2.18 ดังนั้นฉันสงสัยว่ามันยังคงใช้ได้เฉพาะกับรหัส C ++ เท่านั้น
Steven Kay

@StevenKay - เยี่ยมมากขอบคุณ! จะเป็นประโยชน์มากถ้าพวกเขาไม่ทำให้ API สำหรับมัน ... นอกจากนี้ขอขอบคุณสำหรับการแก้ไขผมคิดว่าผมวางการเชื่อมโยงที่ถูกต้องสำหรับการเรียน :)
โจเซฟ

@StevenKay - ฉันคิดว่าพวกเขาทำ API สำหรับสิ่งนี้ในตอนนี้โดยเฉพาะอย่างยิ่งQgsRuleBasedLabeling Class :) โดยเฉพาะ
โจเซฟ

คำตอบ:


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()

น่าเสียดายที่ฉันไม่สามารถหาวิธีวนซ้ำกฎที่มีอยู่ได้วิธีการติดฉลาก ()สำหรับเลเยอร์เวกเตอร์ส่งคืนออบเจ็กต์ของคลาสQgsAbstractVectorLayerLabelingแต่ดูเหมือนว่าจะไม่มีวิธีรับกฎรูต ( QgsRuleBasedLabeling ) จากชั้นนี้ ฉันพบว่าได้รับการตั้งค่า pal โดยตรงโดยใช้รหัสผู้ให้บริการ แต่ฉันไม่สามารถเข้าถึงแผนผังกฎ ใครมีเงื่อนงำ?

แก้ไข

ตอนนี้ได้รับการแก้ไขแล้วการติดฉลาก () ฟังก์ชั่นคืน 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)

ขอบคุณสำหรับคำตอบของคุณ แต่ที่คุณกล่าวว่าผมคิดว่านี้ใช้เฉพาะกับสัญลักษณ์และไม่ได้ป้าย :)
โจเซฟ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.