QGISでプラグインを作成する その7 rubberbandでの図形選択(円形版)の修正
QGIS 1.7
QGIS 1.7で動作させたところ、下記で公開していたソースだと落ちるようです
QGISでプラグインを作成する その6 rubberbandでの図形選択
QGISでプラグインを作成する その7 rubberbandでの図形選択(円形版)
QgisRubberBand::addPointで同一座標の点を起点、2点目と追加していくと、3点目以降は2点目を上書きされるようです
少しずらした点を追加するようにして回避出来ます
ソース一式を貼っておきます
円形版の方のソースを修正しましたので貼っておきます
四角の方も同様の方法で修正可能です
sweepselect_test3.zip
sweeptest.pyを変更しました
canvasPressEventの際に同一座標の登録を止めて、小さい円を描いています
canvasMoveEventのループの回数も間違えていたので修正しています
# -*- coding: utf-8 -*- from PyQt4.QtCore import * from PyQt4.QtGui import * from qgis.core import * from qgis.gui import * import math import resources_rc class sweepTest: def __init__(self, iface): self.iface = iface def initGui(self): self.action = QAction(QIcon(":icon/qgis-icon.png"), "SweepSelect Test", self.iface.mainWindow()) QObject.connect(self.action, SIGNAL("activated()"), self.run) self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&SeeepSelect Test", self.action) self.toolSweepSelect = QgsMapToolSweepSelect(self.iface.mapCanvas()) def unload(self): self.iface.removePluginMenu("&SweepSelect Test", self.action) self.iface.removeToolBarIcon(self.action) def run(self): canvas = self.iface.mapCanvas() canvas.setMapTool(self.toolSweepSelect) #QgsMapToolクラスを拡張 #canvasPressEventでrubberband開始 #canvasMoveEventでrubberbandの範囲変更 #canvasReleaseEventでrubberband範囲の図形選択 class QgsMapToolSweepSelect(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.canvas = canvas self.rubberBand = QgsRubberBand(canvas, True) self.pressed = False def canvasPressEvent(self, event): #最初のclick位置を円の中心としてとっておく self.center = self.toMapCoordinates(QPoint(event.pos().x(), event.pos().y())) #小さい円を一旦登録 len = 0.1 for cnt in range(0,359): x = math.cos(math.radians(cnt)) * len + self.center.x() y = math.sin(math.radians(cnt)) * len + self.center.y() self.rubberBand.addPoint( QgsPoint(x, y), False) x = math.cos(math.radians(359)) * len + self.center.x() y = math.sin(math.radians(359)) * len + self.center.y() self.rubberBand.addPoint(QgsPoint(x, y),True) self.pressed = True def canvasMoveEvent(self, event): if self.pressed == True: #click位置を円周上の位置とする cpos = self.toMapCoordinates(QPoint(event.pos().x(), event.pos().y())) #1度づつ計算しながら、rubberbandの座標を移動 len = math.sqrt(math.pow(self.center.x()-cpos.x(),2) + math.pow(self.center.y()-cpos.y(),2)) for cnt in range(0,360): x = math.cos(math.radians(cnt)) * len + self.center.x() y = math.sin(math.radians(cnt)) * len + self.center.y() self.rubberBand.movePoint(cnt, QgsPoint(x, y)) def canvasReleaseEvent(self, event): layer = self.canvas.currentLayer() if layer == None or layer.type() != QgsMapLayer.VectorLayer: self.rubberBand.reset() self.pressed = False return layer.removeSelection() #rubberbandの図形を取得 circle = self.rubberBand.asGeometry() #重なる図形のidを入れておくためのリスト fid = provider = layer.dataProvider() provider.select(, circle.boundingBox(), True, True) feat = QgsFeature() while provider.nextFeature(feat): #rubberbandと図形の交差を判定 if circle.intersects(feat.geometry()): #交差した図形のidをとっておく fid.append(feat.id()) #図形idを元に選択 for id in fid: layer.select(id) self.rubberBand.reset(True) self.pressed = False