PyQGIS 一時レイヤ作成サンプル


どんな動きをするの?

プラグイン実行時に一時レイヤを作成し、終了時に一時レイヤを削除します。以前紹介したラバーバンドのサンプルを使って、オブジェクトを一時レイヤに追加できるようにしました。


コード

import qgis
from qgis.core import *
from qgis.gui  import *

class TemporaryLayer:
    def __init__(self, iface, canvas, layername, type, fields): # type = Point or LineString, Polygon

        self.canvas = canvas
        self.iface = iface

        fieldsstr = ''
        for f in fields:
            fieldsstr += '&field=' + f

        epsg = iface.mapCanvas().mapSettings().destinationCrs().authid()
        self.layer = QgsVectorLayer(type + '?&crs='+epsg+fieldsstr, layername, 'memory')

        QgsProject.instance().addMapLayer(self.layer)

    def addFeature(self, geometry, attrs):

            qf = QgsFields()
            for field in self.layer.fields():
                qf.append(QgsField(str(field.name()), typeName=field.typeName()))
            record = QgsFeature(qf) 

            # 地物をセットする
            record.setGeometry(geometry) 

            # 属性をセットする
            record.setAttributes(attrs)

            # 作成したレコードをレイヤに追加
            self.layer.dataProvider().addFeatures([record])
            self.layer.updateExtents() # これが無いと『レイヤの領域にズーム』した時に、レイヤの最初のオブジェクト部分しかズームされない

            self.canvas.refreshAllLayers()


    def __del__(self):
        self.canvas.refreshAllLayers()
        QgsProject.instance().removeMapLayer(self.layer.id())

ソースはこちら


使い方

例として、ここからダウンロードできるサンプルプラグインに追加します。

地物を追加したいので、こちらで紹介したrubberbandSample.pyも使います。

nodialog_skelton.pyと同じフォルダにソースを置いて、インポート部分に次のコードを追記します。

from .rubberbandSample import RubberBandSample
from .temporarylayer import TemporaryLayer

nodialog_skelton.pyのstartを次のコードに書き換えます。

    def start(self):
        maptool = RubberBandSample(self.iface, self.canvas, QgsWkbTypes.PolygonGeometry)  # ポリゴンの場合
        maptool.getObject.connect(self.setFeature)

        fields = [
            'id:integer',
            'name:string'
        ]
        self.tmp = TemporaryLayer(self.iface, self.canvas, '一時レイヤ', 'Polygon', fields)

        self.canvas.setMapTool(maptool)
        self.canvas.mapToolSet.connect(self.unsetTool) # このサンプル実行中に他のアイコンを押した場合

nodialog_skelton.pyのfinishを次のコードに書き換えます。

    def finish(self):
        self.tmp = None
        self.canvas.mapToolSet.disconnect(self.unsetTool)

次のメソッドを追加します。

    def setFeature(self, geom):
        self.tmp.addFeature(geom, [])

このようになればOKです。

~略~
from .rubberbandSample import RubberBandSample
from .temporarylayer import TemporaryLayer

class NodialogSkelton(qgis.gui.QgsMapTool):

    def setFeature(self, geom):
        self.tmp.addFeature(geom, [])


    def start(self):
        maptool = RubberBandSample(self.iface, self.canvas, QgsWkbTypes.PolygonGeometry)  # ポリゴンの場合
        maptool.getObject.connect(self.setFeature)

        fields = [
            'id:integer',
            'name:string'
        ]
        self.tmp = TemporaryLayer(self.iface, self.canvas, '一時レイヤ', 'Polygon', fields)

        self.canvas.setMapTool(maptool)
        self.canvas.mapToolSet.connect(self.unsetTool) # このサンプル実行中に他のアイコンを押した場合


    def finish(self):
        self.tmp = None
        self.canvas.mapToolSet.disconnect(self.unsetTool)
~略~

緑の箇所はラバーバンドサンプルの時の設定箇所で、赤い箇所は今回紹介させていただいた一時レイヤ作成のための設定箇所です。


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