QGISのプラグイン作成 ラバーバンドサンプル


はじめに

このサンプルプラグインでは、ラバーバンドを使ってオブジェクトを描画することができます。
描画が終わったら、Pythonコンソールにオブジェクトの座標を表示します。


使い方

f:id:Chiakikun:20210514003656p:plain

ここからプラグインのzipファイルをダウンロードしてインストールします。プラグインを実行した状態で、マップ上でマウスの左ボタンを押下すると図形を描画できます。
右ボタンを押下で決定され、Pythonコンソールにオブジェクトの座標が表示されます。


コード

class RubberbandSample(QgsMapTool):

    def printGeometry(self, geom):
        print(geom)


    def start(self):
        maptool = RubberBandClass(self.iface, self.canvas, self.objtype)
        maptool.getObject.connect(self.printGeometry)

~略~

    def __init__(self, iface):
        self.objtype     = QgsWkbTypes.PolygonGeometry # QgsWkbTypes.PointGeometry, QgsWkbTypes.LineGeometry, QgsWkbTypes.PolygonGeometry
~略~

class RubberBandClass(QgsMapTool):
    getObject = pyqtSignal(QgsGeometry)

    def __init__(self, iface, canvas, type):
        QgsMapTool.__init__(self, canvas)

        self.canvas = canvas
        self.iface = iface
        self.type = type

        self.myRubberBand = None


    def canvasMoveEvent(self, event):
        if self.myRubberBand == None: # 一度も左ボタンをクリックしてない時にこのメソッドが呼ばれた場合
            return

        # 地物の描画中に、マウスカーソルを追って形状が変わるように
        point = self.canvas.getCoordinateTransform().toMapCoordinates(event.pos())
        self.myRubberBand.movePoint(point)


    def canvasPressEvent(self, event):
        currentPos = self.toMapCoordinates(event.pos())

        # 地物の最初の一点目
        if event.button() == Qt.LeftButton and self.myRubberBand == None:
            if self.type == QgsWkbTypes.PointGeometry:
                self.getObject.emit(QgsGeometry.fromPointXY(currentPos))
                return
            else:
                self.myRubberBand = QgsRubberBand( self.canvas, self.type )
                self.myRubberBand.setColor( QColor(255, 0, 0, 128) )
                self.myRubberBand.addPoint( QgsPointXY(currentPos) )

        # 地物の二点目以降
        if event.button() == Qt.LeftButton and self.myRubberBand.numberOfVertices() > 0:
            self.myRubberBand.addPoint( QgsPointXY(currentPos) )

        # オブジェクト確定
        if event.button() == Qt.RightButton:
            if self.myRubberBand == None:
                return

            self.getObject.emit(self.myRubberBand.asGeometry()) # ラバーバンドのオブジェクト取り出し


            self.canvas.scene().removeItem(self.myRubberBand) # ラバーバンドで描いた図形はもう必要ないので消す
            self.myRubberBand = None


    def deactivate(self):
        try: # 右クリックしてmyRubberBandを解放していた場合は例外発生するので。
            self.myRubberBand.reset(True)
        except:
            pass

14行目 このプラグインで描画するオブジェクトのタイプを指定します。ここではポリゴンを描画する設定になっていますが、ポイントを描画したい(ラバーバンドの意味が無いですが)場合はQgsWkbTypes.PointGeometryを、ラインを描画したい場合はQgsWkbTypes.LineGeometryを指定してください。
9行目 オブジェクトを描画し終わったら呼ばれるメソッドを登録します。
43行目 マップで左クリックすると、オブジェクトの1点目が描画されます。
35行目 ラバーバンドが表示されている状態でマウスを動かすと、ラバーバンドも一緒に動きます。
53行目 左クリックで次のノードを決定します。
61行目 オブジェクトの描画を終了します。
4行目 描画したオブジェクトの座標がPythonコンソールに表示されます。
ソース全文


マルチオブジェクトを描画したい場合

インストール直後のサンプルではマルチオブジェクトを描画することはできませんが、上のコードの8行目を以下の様に書き換えると、一つオブジェクトを書き終えた後に右クリックで決定するのではなく、左ボタンをダブルクリックすることで、2つ目のパーツを描画することができます。

        maptool = RubberBandClassEx(self.iface, self.canvas, self.objtype)

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