QGIS/python/plugins/osm/map_tools/MoveMapTool.py
2009-07-30 11:08:18 +00:00

769 lines
29 KiB
Python

"""@package MoveMapTool
This module holds all structures and methods required to perform move operation on OSM data.
Snapping to existing features is supported when moving a feature.
Moving process generates some rubberBands and vertexMarkers so that user can watch
the whole action on the map in a nice way.
There is also an interaction with plugin's "OSM Feature" dialog. Affected features are dynamically
loaded to it; thanks to that user is not confused about what (s)he is moving.
"""
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from math import *
class MoveMapTool(QgsMapTool):
"""This class represents map tool for feature moving (see QgsMapTool from Quantum GIS API).
It enables to move any OSM feature. User is expected to left click, select and move... The second phase (selecting)
is necessary, because there can be more than one feature at the same place.
At the beginning of action left-click is used to choose the position on the map.
Repeatable right-clicking is then used to select required feature from specified position.
After that mouse moving moves selected feature.
The last action is left-clicking again (that confirms the moving operation) or right-clicking (canceling operation).
Snapping to existing features is supported when moving a feature. When moving a line/polygon, only three closest
vertexes to the mouse position can be snapped. If snapping is enabled for all vertexes, operation will be very slow
on features with many vertexes.
When moving a point (also vertex of line/polygon) snapping to both vertexes and segments is done.
When moving a line/polygon snapping to vertexes is supported only.
Moving process generates some rubberBands and vertexMarkers so that user can watch
the whole action on the map in a nice way.
There is also an interaction with plugin's "OSM Feature" dialog. Affected features are dynamically
loaded to it; thanks to that user is not confused about what (s)he is moving.
Map tool catches the signal of changing OSM database. It such case not-ended operation is canceled.
"""
def __init__(self, plugin):
"""The constructor.
Initializes the map tool, creates necessary snappers.
@param plugin pointer to OSM Plugin instance
"""
QgsMapTool.__init__(self,plugin.canvas)
self.canvas=plugin.canvas
self.dockWidget=plugin.dockWidget
self.dbm=plugin.dbm
self.ur=plugin.undoredo
# init info about feature that is being moved!
self.mapPointFrom=None
self.mapPointTo=None
self.movFeatType=None
self.movFeat=None
self.movIsPolygon=False
self.movIndexes=[]
self.snapDeltas=None
self.snapVertexIx=None
self.snapFeat=None
self.snapFeatType=None
# init variables that keeps system state
self.snappingEnabled=True
self.doubleclick=False
self.movingMode="INTRO" # -> "SELECTION" -> "MOVING"
self.moves=0
self.featuresFound=[]
self.ixFeature=0
# init objects to display on canvas
self.rubBands=[] # rubBands of neighbour (non-point) feats that are also affected by moving operation
self.isPolygonFlags=[] # isPolygon flags for self.rubBands[]
self.memberIndexes=[]
self.snapRubBand=self.__createSnapRubberband() # creating rubberband for snapped objects
self.verMarker=self.__createVertexMarker() # creating vertex marker for point moving
# creating Vertex & Segment snapper + creating Vertex (only!) snapper
self.snapperVS=self.__createVSSnapper(self.canvas.mapRenderer())
self.snapperV=self.__createVSnapper(self.canvas.mapRenderer())
# create dialog with feature selection
self.dlgSelect=QDialog(self.dockWidget)
self.dlgSelect.setWindowTitle("Feature identification")
butBox=QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,Qt.Horizontal,self.dlgSelect)
self.lw=QListWidget(self.dlgSelect)
layout=QVBoxLayout(self.dlgSelect)
layout.addWidget(self.lw)
layout.addWidget(butBox)
self.dlgSelect.setLayout(layout)
# set dialog signals
QObject.connect(butBox,SIGNAL("accepted()"),self.__onSelectDlgOK)
QObject.connect(butBox,SIGNAL("rejected()"),self.__onSelectDlgCancel)
self.dockWidget.plugin.iface.mainWindow().statusBar().showMessage("")
def reinit(self):
"""Function re-initializes the map tool, prepare necessary rubberbands again.
After calling this function, move map tool is in the same state as after its creation.
"""
# reinit info about feature that is being moved!
self.mapPointFrom=None
self.mapPointTo=None
self.movFeatType=None
self.movFeat=None
self.movIsPolygon=False
self.movIndexes=[]
self.snapDeltas=None
self.snapVertexIx=None
self.snapFeat=None
self.snapFeatType=None
# reinit variables that keeps system state
self.snappingEnabled=True
self.doubleclick=False
self.movingMode="INTRO" # -> "SELECTION" -> "MOVING"
self.moves=0
self.featuresFound=[]
self.ixFeature=0
# reinit objects to display on canvas
for ix in range(0,len(self.rubBands)):
self.rubBands[ix].reset(self.isPolygonFlags[ix])
del self.rubBands
self.rubBands=[] # rubBands of neighbour feats that are also affected by moving operation
del self.isPolygonFlags
del self.memberIndexes
self.isPolygonFlags=[] # isPolygon flags for self.rubBands[]
self.memberIndexes=[]
self.snapRubBand.reset() # todo: ??? polygon ???
del self.snapRubBand
self.snapRubBand=self.__createSnapRubberband() # recreating rubberband for snapped objects
self.verMarker.setCenter(QgsPoint(-1000,-1000))
del self.verMarker
self.verMarker=self.__createVertexMarker() # recreating vertex marker for point moving
self.dockWidget.plugin.iface.mainWindow().statusBar().showMessage("")
def databaseChanged(self,dbKey):
"""This function is called automatically when current OSM database has changed.
Function calls re-initialization of maptool and create new snappers again.
@param dbKey key of database with new current OSM data
"""
# re-initialization
self.reinit()
# plus creation of new snappers
if dbKey:
del self.snapperVS
self.snapperVS=self.__createVSSnapper(self.canvas.mapRenderer())
del self.snapperV
self.snapperV=self.__createVSnapper(self.canvas.mapRenderer())
def __createFeatRubberband(self,isPolygon):
"""Function creates rubberband that is used for marking moved feature on the map.
@param isPolygon is hint for this function; it says if feature is of polygon type or not
@return rubberband for marking moved feature on the map
"""
# get qgis settings of line width and color for rubberband
settings=QSettings()
qgsLineWidth=settings.value( "/qgis/digitizing/line_width", QVariant(10) ).toInt()
qgsLineRed=settings.value( "/qgis/digitizing/line_color_red", QVariant(255) ).toInt()
qgsLineGreen=settings.value( "/qgis/digitizing/line_color_green", QVariant(0) ).toInt()
qgsLineBlue=settings.value( "/qgis/digitizing/line_color_blue", QVariant(0) ).toInt()
rband=QgsRubberBand(self.canvas,isPolygon)
rband.setColor(QColor(qgsLineRed[0],qgsLineGreen[0],qgsLineBlue[0]))
rband.setWidth( qgsLineWidth[0] )
return rband
def __createSnapRubberband(self):
"""Function creates rubberband that is used for marking map features
to which snapping will be performed.
@return rubberband for marking map features
"""
# get qgis settings of line width and color for rubberband
settings=QSettings()
qgsLineWidth=settings.value( "/qgis/digitizing/line_width", QVariant(10) ).toInt()
rband=QgsRubberBand(self.canvas,False)
rband.setColor(QColor(255,0,0))
rband.setWidth(qgsLineWidth[0])
return rband
def __createVertexMarker(self):
"""Function creates vertexMarker that is used for marking moved feature (point) on the map.
@return vertex marker for marking moved feature on map
"""
# get qgis settings
settings=QSettings()
qgsLineWidth=settings.value("/qgis/digitizing/line_width",QVariant(10)).toInt()
qgsLineRed=settings.value("/qgis/digitizing/line_color_red",QVariant(255)).toInt()
qgsLineGreen=settings.value("/qgis/digitizing/line_color_green",QVariant(0)).toInt()
qgsLineBlue=settings.value("/qgis/digitizing/line_color_blue",QVariant(0)).toInt()
verMarker=QgsVertexMarker(self.canvas)
verMarker.setIconType(2)
verMarker.setIconSize(13)
verMarker.setColor(QColor(qgsLineRed[0],qgsLineGreen[0],qgsLineBlue[0]))
verMarker.setPenWidth(qgsLineWidth[0])
verMarker.setCenter(QgsPoint(-1000,-1000))
return verMarker
def __createVSSnapper(self,canvasRenderer):
"""Function creates snapper that snaps within standard qgis tolerance.
Snapping of this snapper is done to all segments and vertexes
of all three layers of current OSM database.
@param canvasRenderer renderer of current map canvas
@return instance of vertex+segment QgsSnapper
"""
if not self.dbm.currentKey:
# there is no current database -> no layer for snapping
return QgsSnapper(canvasRenderer)
snapper=QgsSnapper(canvasRenderer)
snapLayers=[]
# snap to osm layers from current database only
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.pointLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,canvasRenderer)
sLayer.mSnapTo=QgsSnapper.SnapToVertex
snapLayers.append(sLayer)
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.lineLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,canvasRenderer)
sLayer.mSnapTo=QgsSnapper.SnapToVertexAndSegment
snapLayers.append(sLayer)
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.polygonLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,canvasRenderer)
sLayer.mSnapTo=QgsSnapper.SnapToVertexAndSegment
snapLayers.append(sLayer)
snapper.setSnapLayers(snapLayers)
return snapper
def __createVSnapper(self,canvasRenderer):
"""Function creates snapper that snaps within standard qgis tolerance.
Snapping of this snapper is done to all vertexes (but not segments)
of all three layers of current OSM database.
@param canvasRenderer renderer of current map canvas
@return instance of vertex QgsSnapper
"""
if not self.dbm.currentKey:
# there is no current database -> no layer for snapping
return QgsSnapper(canvasRenderer)
snapper=QgsSnapper(canvasRenderer)
snapLayers=[]
# snap to osm layers from current database only
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.pointLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,canvasRenderer)
sLayer.mSnapTo=QgsSnapper.SnapToVertex
snapLayers.append(sLayer)
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.lineLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,self.canvas.mapRenderer())
sLayer.mSnapTo=QgsSnapper.SnapToVertex
snapLayers.append(sLayer)
sLayer=QgsSnapper.SnapLayer()
sLayer.mLayer=self.dbm.polygonLayers[self.dbm.currentKey]
sLayer.mTolerance=QgsTolerance.vertexSearchRadius(sLayer.mLayer,canvasRenderer)
sLayer.mSnapTo=QgsSnapper.SnapToVertex
snapLayers.append(sLayer)
snapper.setSnapLayers(snapLayers)
return snapper
def deactivate(self):
"""Functions is called when move-map-tool is being deactivated.
Function performs standard cleaning; re-initialization etc.
"""
self.reinit()
self.dockWidget.toolButtons.setExclusive(False)
self.dockWidget.moveButton.setChecked(False)
self.dockWidget.toolButtons.setExclusive(True)
self.dockWidget.activeEditButton=self.dockWidget.dummyButton
def keyPressEvent(self, event):
"""This function is called after keyPressEvent(QKeyEvent *) signal is emmited when using move map tool.
If Control key was pressed, function disables snapping til key is released.
@param event event that occured when key pressing
"""
if (event.key() == Qt.Key_Control):
self.snappingEnabled=False
self.snapRubBand.reset()
self.dockWidget.plugin.iface.mainWindow().statusBar().showMessage("Snapping OFF.")
def keyReleaseEvent(self, event):
"""This function is called after keyReleaseEvent(QKeyEvent *) signal is emmited when using move map tool.
If Control key was released, function enables snapping again.
@param event event that occured when key releasing
"""
if (event.key() == Qt.Key_Control):
self.snappingEnabled = True
self.dockWidget.plugin.iface.mainWindow().statusBar().showMessage("Snapping ON - hold Ctrl to disable it.")
def canvasDoubleClickEvent(self,event):
"""This function is called after doubleclick on map when using move map tool.
Function is interested into left-doubleclicking only.
It finds out all features that are currently at the place where doubleclick was done.
Then it shows simple dialog with the list of all these features. User can select the required one,
close dialog and continue moving.
@param event event that occured when double clicking
"""
if event.button()<>Qt.LeftButton:
return
self.dockWidget.clear()
#self.removeMarkers()
# find out map coordinates from mouse click
mapPoint=self.dockWidget.canvasToOsmCoords(event.pos())
# display modal dialog with features selection
self.featuresFound=self.dbm.findAllFeatures(mapPoint)
self.ixFeature=0
lwItems=[]
for f in self.featuresFound:
feat=f[0]
featType=f[1]
name=self.dbm.getTagValue(feat.id(),featType,"name")
lwItems.append(QString("[%1] ").arg(feat.id()).append(featType).append(QString(" ")).append(name))
self.lw.clear()
self.lw.addItems(lwItems)
self.dockWidget.plugin.iface.mainWindow().statusBar().showMessage("")
self.doubleclick=True
if self.dlgSelect:
# continue only if OK button was clicked
if self.dlgSelect.exec_()==0:
return
def canvasReleaseEvent(self, event):
"""This function is called after mouse button releasing on map when using move map tool.
Such button releasing can have a lot of meanings.
It depends on the current phase of moving. See documentation of the whole move map tool
to know how moving works and how many times user has to release the mouse button to perform the whole moving.
@param event event that occured when button releasing
"""
if self.doubleclick:
self.doubleclick=False
return
if self.movingMode=="INTRO":
# we are interested only in left button clicking
if event.button()<>Qt.LeftButton:
return
# find out map coordinates from mouse click
self.mapPointFrom = self.dockWidget.canvasToOsmCoords(event.pos())
# what to move?
self.featuresFound=self.dbm.findAllFeatures(self.mapPointFrom)
self.ixFeature=0
if len(self.featuresFound)>0:
self.movingMode="SELECTION"
(feat,featType)=self.featuresFound[self.ixFeature]
self.dockWidget.loadFeature(feat,featType,2)
elif self.dockWidget.feature:
self.dockWidget.clear()
self.mapPointFrom=None
return
elif self.movingMode=="SELECTION":
# we are interested only in left/right button clicking
if event.button() not in (Qt.LeftButton,Qt.RightButton):
return
if event.button()==Qt.RightButton:
if len(self.featuresFound)<1:
return
self.ixFeature=self.ixFeature+1
if self.ixFeature>=len(self.featuresFound):
self.ixFeature=0
(feat,featType)=self.featuresFound[self.ixFeature]
self.dockWidget.loadFeature(feat,featType,2)
else: # LeftButton
self.reinit()
if self.dockWidget.feature:
self.dockWidget.clear()
elif self.movingMode=="MOVING":
# finish feature moving
# we are interested only in left button clicking; other buttons just cancel moving operation
if event.button()<>Qt.LeftButton:
self.reinit()
return
whereIAm = self.dockWidget.canvasToOsmCoords(event.pos())
if self.snapDeltas:
self.mapPointTo=QgsPoint(whereIAm.x()+self.snapDeltas[0],whereIAm.y()+self.snapDeltas[1])
else:
# no snapping for this moving
self.snapVertexIx=-1
self.mapPointTo=whereIAm
deltaX=self.mapPointTo.x()-self.mapPointFrom.x()
deltaY=self.mapPointTo.y()-self.mapPointFrom.y()
self.__finishFeatureMoving(deltaX,deltaY)
def __tryIdentifyFeature(self,event):
"""Function just finds first feature at the place when event occured.
Feature is marked on map with rubberBand (or vertexMarker) and is loaded to OSM Feature widget.
@param event event that occured
"""
# find out map coordinates from mouse click
mapPoint=self.dockWidget.canvasToOsmCoords(event.pos())
feature=self.dbm.findFeature(mapPoint)
if feature:
(feat,featType)=feature
if not self.dockWidget.feature or feat.id()<>self.dockWidget.feature.id():
self.dockWidget.loadFeature(feat,featType,1)
elif self.dockWidget.feature:
self.dockWidget.clear()
def canvasMoveEvent(self,event):
"""This function is called after mouse moving.
Mouse moving is ignored before feature (to move) is selected.
@param event event that occured when mouse moving.
"""
# ignore one move from each two moves
if self.moves<>1:
self.moves=self.moves+1
return
self.moves=0
if self.movingMode=="INTRO":
self.__tryIdentifyFeature(event)
return
if self.movingMode=="SELECTION":
# remember what to move
self.movFeat=self.featuresFound[self.ixFeature][0]
self.movFeatType=self.featuresFound[self.ixFeature][1]
self.movIsPolygon=False
self.featuresFound=[]
self.ixFeature=0
# initializing rubberbands
if self.movFeatType in ('Polygon','Line'):
layer=self.dbm.lineLayers[self.dbm.currentKey]
if self.movFeatType=='Polygon':
self.movIsPolygon=True
layer=self.dbm.polygonLayers[self.dbm.currentKey]
# finding out three closest vertexes (for these snapping will be enabled)
self.movIndexes=[]
(p,ix,ixB,ixA,dis)=self.movFeat.geometry().closestVertex(self.mapPointFrom)
self.movIndexes.append(ix)
self.movIndexes.append(ixB)
self.movIndexes.append(ixA)
rubBand=self.__createFeatRubberband(self.movIsPolygon)
rubBand.setToGeometry(self.movFeat.geometry(),layer)
self.rubBands.append(rubBand)
self.isPolygonFlags.append(self.movIsPolygon)
elif self.movFeatType in ('Point'):
# find out parent features
(parentFeats,self.memberIndexes,self.isPolygonFlags)=self.dbm.getNodeParents(self.movFeat)
self.movParentVertices=[]
if len(parentFeats)==0:
self.verMarker.setCenter(self.movFeat.geometry().asPoint())
for ix in range(0,len(parentFeats)):
layer=None
if self.isPolygonFlags[ix]:
layer=self.dbm.polygonLayers[self.dbm.currentKey]
self.movParentVertices=self.movParentVertices+(parentFeats[ix].geometry().asPolygon())[0]
else:
layer=self.dbm.lineLayers[self.dbm.currentKey]
self.movParentVertices=self.movParentVertices+parentFeats[ix].geometry().asPolyline()
parentRubBand=self.__createFeatRubberband(self.isPolygonFlags[ix])
parentRubBand.setToGeometry(parentFeats[ix].geometry(),layer)
self.rubBands.append(parentRubBand)
if self.dockWidget.feature:
self.dockWidget.clear()
# change moving mode to the last one!
self.movingMode="MOVING"
# movingMode ~ "MOVING"
if self.movFeatType=='Point':
(deltaX,deltaY)=self.__getDeltaForPoint(event) # snapping is done in this function
targetPoint=QgsPoint(self.mapPointFrom.x()+deltaX,self.mapPointFrom.y()+deltaY)
if len(self.rubBands)==0:
point=self.movFeat.geometry().asPoint()
self.verMarker.setCenter(QgsPoint(point.x()+deltaX,point.y()+deltaY))
# move rubberbands
for ix in range(0,len(self.rubBands)):
for j in range(0,len(self.memberIndexes[ix])):
vertexIx=self.memberIndexes[ix][j]
lastVertexIx=self.rubBands[ix].numberOfVertices()-1
self.rubBands[ix].movePoint(vertexIx,targetPoint)
if self.isPolygonFlags[ix]:
if vertexIx==1:
self.rubBands[ix].movePoint(lastVertexIx,targetPoint)
elif vertexIx==lastVertexIx:
self.rubBands[ix].movePoint(vertexIx,targetPoint)
if vertexIx==1:
self.rubBands[ix].movePoint(0,targetPoint)
elif self.movFeatType in ('Line','Polygon'):
(deltaX,deltaY)=self.__getDeltaForLinePolygon(event)
# move feature rubberband
self.rubBands[0].setTranslationOffset(deltaX,deltaY)
def __getDeltaForPoint(self,event):
"""Function gets an event object, performs snapping from place where event occured and then counts distance
of found position from the place where the whole moving operation has started.
Special version for points.
@param event event that occured
"""
# find out where and how far (from the place where moving was started) we are now
mapPoint = self.dockWidget.canvasToOsmCoords(event.pos())
if not self.snappingEnabled:
self.snapDeltas=self.snapFeat=self.snapFeatType=None
# returns how far from the place where moving was started we are now
return (mapPoint.x()-self.mapPointFrom.x(),mapPoint.y()-self.mapPointFrom.y())
# perform snapping
self.movParentVertices.append(self.movFeat.geometry().asPoint())
(retval,snappingResults)=self.snapperVS.snapPoint(event.pos(),self.movParentVertices)
if len(snappingResults)==0:
self.snapDeltas=self.snapFeat=self.snapFeatType=None
# returns how far from the place where moving was started we are now
return (mapPoint.x()-self.mapPointFrom.x(),mapPoint.y()-self.mapPointFrom.y())
# we snapped successfully to something
snappedPoint=QgsPoint(snappingResults[0].snappedVertex)
self.snapDeltas=(snappedPoint.x()-mapPoint.x(),snappedPoint.y()-mapPoint.y())
# use snappingResults[0].layer in findFeature() ??? findFeatureInLayer() ???
(self.snapFeat,self.snapFeatType)=self.dbm.findFeature(snappedPoint)
# returns how far from the place where moving was started we are now
return (snappedPoint.x()-self.mapPointFrom.x(),snappedPoint.y()-self.mapPointFrom.y())
def __getDeltaForLinePolygon(self,event):
"""Function gets an event object, performs snapping from place where event occured and then counts distance
of found position from the place where the whole moving operation has started.
Special version for lines and polygons.
@param event event that occured
"""
# find out where and how far (from the place where moving was started) we are now
mapPoint = self.dockWidget.canvasToOsmCoords(event.pos())
deltaX=mapPoint.x()-self.mapPointFrom.x()
deltaY=mapPoint.y()-self.mapPointFrom.y()
if not self.snappingEnabled:
self.snapDeltas=self.snapFeat=self.snapFeatType=None
return (deltaX,deltaY)
lineMembers=[]
for ix in self.movIndexes:
lineMembers.append(self.movFeat.geometry().vertexAt(ix))
allMembers=[]
if self.movFeatType=='Line':
allMembers=self.movFeat.geometry().asPolyline()
else:
polygon=self.movFeat.geometry().asPolygon()
allMembers=polygon[0]
minDistance=99999
bestSnappedPoint=None
bestActualLineMember=None
for i in range(0,len(lineMembers)):
actualLineMember=QgsPoint(lineMembers[i].x()+deltaX,lineMembers[i].y()+deltaY)
point=self.canvas.getCoordinateTransform().transform(actualLineMember)
(retval,snappingResults)=self.snapperV.snapPoint(QPoint(point.x(),point.y()),allMembers)
if len(snappingResults)>0:
snappedPoint=QgsPoint(snappingResults[0].snappedVertex)
dX=snappedPoint.x()-(actualLineMember.x()+deltaX)
dY=snappedPoint.y()-(actualLineMember.y()+deltaY)
dist=sqrt(pow(dX,2)+pow(dY,2)) # pythagoras ;)
if dist<minDistance:
minDistance=dist
bestSnappedPoint=snappedPoint
bestActualLineMember=actualLineMember
self.snapVertexIx=self.movIndexes[i]
if not bestSnappedPoint:
self.snapDeltas=self.snapFeat=self.snapFeatType=None
return (deltaX,deltaY)
self.snapDeltas=(bestSnappedPoint.x()-bestActualLineMember.x(),bestSnappedPoint.y()-bestActualLineMember.y())
# use snappingResults[0].layer in findFeature() ??? findFeatureInLayer() ???
(self.snapFeat,self.snapFeatType)=self.dbm.findFeature(bestSnappedPoint)
return (deltaX+self.snapDeltas[0],deltaY+self.snapDeltas[1])
def __finishFeatureMoving(self,deltaX,deltaY):
"""It finishes the whole moving process.
Function also refreshes map canvas.
@param deltaX distance from target position (of moving) to start position on X axis
@param deltaY distance from target position (of moving) to start position on Y axis
"""
affected=set()
if self.movFeatType=="Point":
self.ur.startAction("Move a point.")
affected=self.dbm.movePoint(self.movFeat,deltaX,deltaY,self.snapFeat,self.snapFeatType)
elif self.movFeatType=="Line":
self.ur.startAction("Move a line.")
affected=self.dbm.moveLine(self.movFeat,deltaX,deltaY,self.snapFeat,self.snapFeatType,self.snapVertexIx)
elif self.movFeatType=="Polygon":
self.ur.startAction("Move a polygon.")
affected=self.dbm.movePolygon(self.movFeat,deltaX,deltaY,self.snapFeat,self.snapFeatType,self.snapVertexIx)
self.ur.stopAction(affected)
self.dbm.recacheAffectedNow(affected)
self.dockWidget.loadFeature(self.movFeat,self.movFeatType,0)
self.reinit()
# reload map canvas so that changes take effect
self.canvas.refresh()
def __onSelectDlgOK(self):
"""This function handles clicking on OK button of selection dialog.
"""
self.dlgSelect.close()
if not self.lw.currentItem():
return
self.ixFeature=self.lw.currentRow()
(feat,featType)=self.featuresFound[self.ixFeature]
if feat:
self.dockWidget.loadFeature(feat,featType,2)
def __onSelectDlgCancel(self):
"""This function handles clicking on Cancel button of selection dialog.
"""
self.dlgSelect.close()