QGIS API: 一時的図形を描画するには

キャンバス上で作業をしている時に、一時的に何か図形を描画したいことがあります。
その場合はレイヤーも属性も不要なので、QgsFeatureとは違う方法が用意されています。
使用するクラスはQgsMapCanvasItemクラスの派生クラスですが、少しずつ使用法が異なります。

連続線分、多角形を描画する場合

この場合はQgsRubberBandクラスを使います。
新規に連続線分、多角形要素を描画している場合やズーム枠で使用されています。

最も簡単な使い方は以下の様な感じでしょうか。

  rubberband = QgsRubberBand(canvas)
  rubberband.setColor(QColor.fromRgb(0,0,255))
  rubberband.addPoint(QgsPoint(140.1,35.8))
  rubberband.addPoint(QgsPoint(140.2,35.8))
  rubberband.addPoint(QgsPoint(140.2,35.9))
  rubberband.addPoint(QgsPoint(140.1,35.9))
  rubberband.addPoint(QgsPoint(140.1,35.8))

コンストラクタの第2引数にTrueを指定するとポリゴンの描画になります。

追加した頂点は後で移動したりもできます。

点要素を描画する場合(とりあえず的)

簡単に点要素を描画したい場合はQgsVertexMarkerクラスを使います。
“VertexMarker”とありますが、要素の頂点にしか描画できないわけではなく、任意の場所に描画できます。
連続線分やポリゴンを編集するときに使用されています。

  vmarker = QgsVertexMarker(canvas)
  vmarker.setIconType(QgsVertexMarker.ICON_BOX)
  vmarker.setCenter(QgsPoint(140.1,35.8))

色、大きさ、線幅は指定することができます。
ただし、頂点のマーカーを想定しているためか、形状は”+”、”X”、”□”しか指定することができません。

テキスト付き点要素を描画する場合

この場合はQgsTextAnnotationItemクラスを使用します。
このクラスはQgsAnnotationItemクラスの派生クラスで、
QgsVertexMarkerクラスよりも色々と柔軟に設定が可能です。

QgsAnnotationItemクラスの派生クラスにはもう一つQgsFormAnnotationItemというものがありますが、
こちらの使い方はよくわかりません。一応FORMを表示することは出来ましたが、FORM内に何かを表示する方法がまだわかっていません。)

以下の例はバルーン付きテキストラベルの設定例です。

  textann = QgsTextAnnotationItem(canvas)
  textdoc = QTextDocument()
  textdoc.setHtml("<h2>ahoka</h2>")
  textann.setDocument(textdoc)
  textann.setMapPosition(QgsPoint(140.1,35.8))
  textann.setFrameBorderWidth(1.0)
  textann.setFrameSize(QSizeF(60,30))
  textann.setFrameBackgroundColor(QColor.fromRgb(0,100,100))
  textann.setOffsetFromReferencePoint(QPointF(20.0,-40.0))
実行結果

実行結果

バルーンのオフセットとサイズはスクリーン座標(左上原点)で指定なので注意。
マーカーは色々と変更することが出来るようです。

なお、バルーンを消す方法がわかっていません。
フレームサイズを0にしても吹き出し線の残りカスと思われる線が描画されてしまいます。
さらに、テキストドキュメントを未指定にすると”QGIS rocks!”という余計な文字列を表示します。

SVG注記

これは上記のテキスト付注記の吹き出しの部分にSVGの図形を表示させるものです。
SVGはファイルまたはリソースを指定することができます。
以下のようにしてフレームサイズ、注記シンボルからフレームまでのオフセット等を指定することができます。

   1:   annotSymbol = QgsMarkerSymbolV2.createSimple(mapProp)
   2:   pos = self.canvas.extent().center()
   3:   self.annot = QgsSvgAnnotationItem(self.canvas)
   4:   self.annot.setFilePath(":/icon/point.svg")
   5:   self.annot.setFrameSize(QSizeF(90,90))
   6:   self.annot.setOffsetFromReferencePoint(QPointF(30.0,-120.0))
   7:   self.annot.setMapPosition(pos)
実行結果

実行結果

点マーカーを変更する

マーカーシンボルは変更することができます。
簡単な変更であれば以下のようにします。

  mapProp = {"color":"255,255,0"}
  mapProp["size"] = "1.5"
  mapProp["outline_width"] = "0.2"
  mapProp["outline_color"] = "red"
  annotSymbol = QgsMarkerSymbolV2.createSimple(mapProp)
  self.annot.setMarkerSymbol(annotSymbol)

その他

QgsAnnotationItemクラスの派生クラスを自作して独自のアイテムを描画することもできるはずです。
Georeferencerプラグインの標定点残差表示がこれに該当します。
ただ、Python上で派生クラスを自作してもうまくいきませんでした。
paint()関数をオーバーライドしたのですが、引数が合わないといって怒られる)

アーカイブ