QGISのプラグイン作成 リレーションのサンプル


はじめに

このサンプルは、あるレイヤのレコードに紐付く別のレイヤのレコードを抽出するためのサンプルです。


使い方

ここからzipファイルをダウンロードしてインストールします。
インストールできたら、relation_sample.pyの以下の部分を変更します。

        self.referencedLayerName  = '〇〇〇' # 被参照のレイヤ名
        self.referencingLayerName = '□□□' # 参照元のレイヤ名
        self.referencedField  = '△△△'     # 参照元とのリンクに使うフィールド名
        self.referencingField = '×××'     # 被参照とのリンクに使うフィールド名

f:id:Chiakikun:20200606202506p:plain

プラグインを実行したままで、被参照レイヤの地物を選択すると...

 

f:id:Chiakikun:20200606202518p:plain

選択した地物とリンクする参照元レイヤの地物が選択状態になり、属性テーブルが表示されます。

 

f:id:Chiakikun:20200606202451p:plain

プラグイン実行中は、上の画像のようなリレーションが作られています。


コード

class RelationSample(QgsMapTool):

    def showChildren(self):
        parent = self.rel.referencedLayer()
        child = self.rel.referencingLayer()

        features = parent.selectedFeatures()
        if len(features) == 0:
            return

        child.removeSelection() # クリアしないと、属性テーブルに余計に表示されるから 
        for c in self.rel.getRelatedFeatures(features[0]):
            child.select(c.id())

        selectedlayer = self.iface.activeLayer() # 現在のアクティブレイヤ退避
        try:
            # このプログラム実行中は属性テーブルは選択中のフューチャーしか表示しないように設定する
            self.oldsetting = QSettings().value('/Qgis/attributeTableBehaviour')
            QSettings().setValue('/Qgis/attributeTableBehavior', 'ShowSelected')
            # テーブル表示
            self.iface.setActiveLayer(child)
            self.iface.mainWindow().findChild(QtWidgets.QAction, 'mActionOpenTable' ).trigger()
        finally:
            # 設定を戻す
            self.iface.setActiveLayer(selectedlayer)
            QSettings().setValue('/Qgis/attributeTableBehavior', self.oldsetting)


    def start(self):
        self.referencedLayer  = QgsProject.instance().mapLayersByName(self.referencedLayerName)[0]
        self.referencingLayer = QgsProject.instance().mapLayersByName(self.referencingLayerName)[0]
        self.rel = QgsRelation()

        self.rel.setReferencingLayer(self.referencingLayer.id())
        self.rel.setReferencedLayer(self.referencedLayer.id())
        self.rel.addFieldPair(self.referencingField, self.referencedField)
        self.rel.setId('適当なID')
        self.rel.setName('適当な名前')
        QgsProject.instance().relationManager().addRelation(self.rel)

        self.referencedLayer.selectionChanged.connect(self.showChildren)


    def finish(self):
        QgsProject.instance().relationManager().removeRelation(self.rel)
        self.referencedLayer.selectionChanged.disconnect(self.showChildren)
        

    def __init__(self, iface):

~略~

        self.referencedLayerName  = '〇〇〇' # 被参照のレイヤ名
        self.referencingLayerName = '□□□' # 参照元のレイヤ名
        self.referencedField  = '△△△'     # 参照元とのリンクに使うフィールド名
        self.referencingField = '×××'     # 被参照とのリンクに使うフィールド名

32~38行目 リレーションを作成します。
39行目 作成したリレーションを現在のプロジェクトに登録します。
41行目 被参照レイヤの地物を選択したときに呼ばれるメソッドを登録します。
12行目 選択した地物とリンクする参照元レイヤのレコードを選択状態にします。
18~22行目 テーブル設定を、選択地物だけしか表示できないように設定して、被参照レイヤをテーブル表示します。
45行目 プラグインが終了したら、リレーションを削除します。
コード全文


最後までご覧いただき、ありがとうございました。