Kiểm soát ghi nhãn dựa trên quy tắc bằng PyQGIS?


15

Tiếp theo từ câu hỏi này: Cách bật / tắt tất cả các nhãn của tất cả các lớp trong QGIS , OP đã đề cập trong nhận xét của mình rằng anh ấy sử dụng nhãn dựa trên quy tắc. Tôi đã thử tìm kiếm trực tuyến về cách các loại nhãn này có thể được đọc và sửa đổi nhưng chỉ quản lý để tìm thấy bài đăng này từ lutraconsulting :

Để tạo điều kiện bổ sung cho ghi nhãn dựa trên quy tắc, một số thay đổi bên trong đã được thực hiện đối với giao diện công cụ ghi nhãn QGIS. Việc ghi nhãn hiện được điều khiển bởi lớp mới QgsLabelingEngineV2có thể có một số nhà cung cấp nhãn được liên kết với nó.

Âm thanh tuyệt vời. Tuy nhiên, khi đọc qua lớp QssLabelingEngineV2 , nó đề cập đến:

lớp này chưa phải là một phần của API công khai.

Hiện tại có thể kiểm soát ghi nhãn dựa trên quy tắc bằng python không?


1
Tôi đã tìm thấy một vấn đề mở ở đây trong dự án Tài liệu Qgis trong Github cũng đề cập đến vấn đề này . Tôi không thể tìm thấy một ràng buộc SIP cho lớp đó trong các nhánh MASTER hoặc 2.18, vì vậy tôi nghi ngờ nó vẫn chỉ có sẵn cho mã C ++.
Steven Kay

@StevenKay - Tìm tuyệt vời, cảm ơn! Sẽ khá hữu ích nếu họ đã tạo một API cho nó ... Cũng cảm ơn vì đã chỉnh sửa, tôi nghĩ rằng tôi đã dán liên kết chính xác cho lớp :)
Joseph

@StevenKay - Tôi nghĩ rằng họ đã tạo một API cho việc này ngay bây giờ, cụ thể hơn là Lớp QSSRuleBasingLabeling :)
Joseph

Câu trả lời:


6

Bên dưới một số trợ giúp để thiết lập ghi nhãn dựa trên quy tắc từ đầu với API QGIS 3 mới

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

Thật không may, tôi không thể tìm thấy cách lặp lại các quy tắc hiện có, phương thức ghi nhãn () có sẵn cho các lớp vectơ trả về một đối tượng của lớp QssAbTHERVectorLayerLabeling nhưng dường như không có cách nào để có được quy tắc gốc ( QSSRuleBasingLabeling ) từ lớp này, khả năng duy nhất Tôi thấy là để có được cài đặt pal trực tiếp bằng id nhà cung cấp nhưng tôi không thể truy cập vào cây quy tắc. Bất cứ ai cũng có một đầu mối?

BIÊN TẬP

Bây giờ nó đã được sửa, hàm ghi nhãn () trả về một QSSRuleBasingLabeling (): https://github.com/qgis/QGIS/commit/4b365a8f47d96b35f7609859e580388927ae0606


Cảm ơn câu trả lời của bạn, làm việc độc đáo! Hy vọng bạn không phiền nhưng tôi đã chỉnh sửa bài đăng của bạn một chút để bao gồm myLayer.triggerRepaint()để làm mới lớp và cho phép các nhãn hiển thị ngay sau khi đặt quy tắc :)
Joseph

3

Từ QGIS 3 , có Lớp QSSRuleBasingLabeling mới cho phép bạn kiểm soát ghi nhãn dựa trên quy tắc bằng API mới.

Các quy tắc có thể được thêm vào bằng cách sử dụng QssRuleBasingLabeling :: Rule .


( Thật không may, tôi không thể kiểm tra phiên bản 2.99 vào lúc này. Nhưng tôi sẽ vui vẻ chấp nhận câu trả lời nếu nó cung cấp một ví dụ hoạt động. )


1

Đây là những gì tôi sử dụng để thay đổi biểu thức lọc trong hệ thống ký hiệu dựa trên quy tắc trong QGIS 2.18, không chắc đó có phải là điều bạn đang yêu cầu không. Tham chiếu API tại http://qgis.org/api/2.18/ classQgsRuleBasingRendererV2.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)

Cảm ơn câu trả lời của bạn nhưng như bạn đã nói, tôi nghĩ rằng điều này chỉ áp dụng cho hệ thống hiệu chứ không phải nhãn hiệu :)
Joseph
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.