QgsTextAnnotationをadd

QgsTextAnnotationはQgsAnnotationから派生された地図上の注釈クラス

QgsMapToolAnnotationクラスのC++ソースを参考にPythonでQgsTextAnnotationをMapCanvas上に追加する

間違ったコード

txt = QTextDocument('HELLO\r\nHELLO') 
annotation = QgsTextAnnotation()
annotation.setDocument(txt)
mapPos = QgsPointXY(138.9776,35.6712)
annotation.setMapPosition(mapPos)
annotation.setMapPositionCrs(iface.mapCanvas().mapSettings().destinationCrs())
annotation.setRelativePosition(QPointF(0, 0))
#annotation.setFrameSize(QSize(100, 50))
annotation.setFrameSize(txt.size())
annotationManager = QgsProject.instance().annotationManager()
annotationManager.addAnnotation(annotation)

※setMapPositionには緯度、経度をセットしているが必要があればMapCanvasのDestinationCrsの座標系に変換が行う。

全てのAnnotationはQgsAnnotationManagerのannotationsに入っている

annotations= QgsProject.instance().annotationManager().annotations()
for annotation in annotations :
    print(annotation.document().toPlainText())

座標を指定してMapCanvas上のAnnotationを照会するにはMapCanvasのitemsを使用する

items = iface.mapCanvas().items(QPoint(10,10))
for item in items :
    if item.__class__.__name__ == 'QgsMapToolAnnotation' :
        print(item.document().toPlainText())
        

ところがここでitemsにQgsMapToolAnnotationが存在しない。

全てがQGraphicsItemになっている

どうやらPythonでQgsAnnotationをMapCanvasに追加するには「annotationManager.addAnnotation」ではなく

「QgsMapCanvasAnnotationItem」を使うみたい

正しいコード

txt = QTextDocument('HELLO\r\nHELLO') 
annotation = QgsTextAnnotation()
annotation.setDocument(txt)
mapPos = QgsPointXY(138.9776,35.6712)
annotation.setMapPosition(mapPos)
annotation.setMapPositionCrs(iface.mapCanvas().mapSettings().destinationCrs())
#annotation.setRelativePosition(QPointF(0, 0))
annotation.setFrameOffsetFromReferencePoint(QtCore.QPointF(30, 30))
#annotation.setFrameSize(QSize(100, 50))
annotation.setFrameSize(txt.size())
i = QgsMapCanvasAnnotationItem(annotation, iface.mapCanvas())

setRelativePositionではなく、setFrameOffsetFromReferencePointを使用して吹き出しの位置を設定

参考

Programatically adding annotations