[QGIS]最近地物取得

今回は、指定レイヤの中で最も近い地物の取得方法を紹介します。

次回は、最も近い点の取得方法にしようと考えています。
最近点は何回か使用しているのですが、完璧とはいえない感じだったので
バージョンアップで改善されてると、うれしいです。

プラグインで最近点を使う時には、先に最近地物を取得する必要があります。
最近点を取得する時に、必要なものはQgsGeometry,Pointが必要だからです。

最近点取得の第一歩の最近地物を取得していきます。

最近地物は、QgsSpatialIndexを使えば簡単に取得できます。

        point = QgsPoint(0, 0)
        # 適当なポイント
        layer = iface.activeLayer()
        features = layer.getFeatures()
        spatial = QgsSpatialIndex(features)
        spatial_ids = spatial.nearestNeighbor(point, 1)
        # spatialにある地物の中で、ポイントに近い地物を1つ取得
        # 重なっている場合は、1つ以上になる
        # 返り値は, featureidのリストになっている
        request = QgsFeatureRequest()
        request = request.setFilterFids(spatial_ids)
        features = layer.getFeatures(request)
        # QgsFeatureを取得したいなら、requestでfeatureidでフィルターをかけて取得する

以下は、マップをクリックすると、レイヤの最近地物を選択する簡単なプラグインです。

# -*- coding: utf-8 -*-
from PyQt4.QtGui import QAction, QIcon
import os
from qgis.core import QgsSpatialIndex
from qgis.gui import QgsMapToolEmitPoint


class plugin(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.layer = None
        self.map_tool = QgsMapToolEmitPoint(self.canvas)
        self.spatial = None

    def initGui(self):
        icon_path = os.path.dirname(__file__) + u'/icon/qgis-icon.png'
        self.action = QAction(QIcon(icon_path),
                              u'最近地物', self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)
        self.map_tool.canvasClicked.connect(self.select_near_feature)

    def unload(self):
        self.iface.removeToolBarIcon(self.action)
        if self.map_tool == self.canvas.mapTool():
            self.canvas.setMapTool(self.iface.actionPan())

    def run(self):
        self.layer = self.iface.activeLayer()
        features = self.layer.getFeatures()
        self.spatial = QgsSpatialIndex(features)
        self.canvas.setMapTool(self.map_tool)

    def select_near_feature(self, point):
        spatial_ids = self.spatial.nearestNeighbor(point, 1)
        self.layer.setSelectedFeatures(spatial_ids)
        return

コメントを残す

メールアドレスが公開されることはありません。