class ObstacleAreaJigSelectArea(QgsMapTool): def __init__(self, canvas, areaType): self.mCanvas = canvas self.areaType = areaType QgsMapTool.__init__(self, canvas) self.mCursor = Qt.ArrowCursor self.mRubberBand = None self.mDragging = False self.mSelectRect = QRect() self.mRubberBandResult = None self.mSnapper = QgsMapCanvasSnapper(canvas) self.lineCount = 0 self.resultGeomList = [] self.geomList = [] self.area = None self.isFinished = False # QgsRubberBand* mRubberBand; # def reset(self): # self.startPoint = None # self.endPoint = None # self.isDrawing = False # SelectByRect.RubberRect.reset(QGis.Polygon) # self.layer = self.canvas.currentLayer() def canvasPressEvent(self, e): QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mSelectRect.setRect( 0, 0, 0, 0 ) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.startPoint, self.pointID, self.layer= self.snapPoint(e.pos()) def canvasMoveEvent(self, e): if self.areaType == ProtectionAreaType.Secondary: if self.lineCount == 0: define._messageLabel.setText("Select a line or arc representing the INNER edge of the secondary area.") elif self.lineCount == 1: define._messageLabel.setText("Select a line representing the OUTER edge of the secondary area.") elif self.areaType == ProtectionAreaType.Primary: define._messageLabel.setText("") elif self.areaType == ProtectionAreaType.PrimaryAndSecondary: if self.lineCount == 0: define._messageLabel.setText("Select a line or arc representing the INNER edge of the FIRST secondary area.") elif self.lineCount == 1: define._messageLabel.setText("Select a line representing the OUTER edge of the FIRST secondary area.") elif self.lineCount == 2: define._messageLabel.setText("Select a line or arc representing the INNER edge of the SECOND secondary area.") elif self.lineCount == 3: define._messageLabel.setText("Select a line representing the OUTER edge of the SECOND secondary area.") else: define._messageLabel.setText("") if ( e.buttons() != Qt.LeftButton ): return if ( not self.mDragging ): self.mDragging = True self.mSelectRect.setTopLeft( e.pos() ) self.mSelectRect.setBottomRight( e.pos() ) QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect,self.mRubberBand ) def canvasReleaseEvent(self, e): self.endPoint, self.pointID, self.layer= self.snapPoint(e.pos()) vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer( self.mCanvas ) if ( vlayer == None ): if ( self.mRubberBand != None): self.mRubberBand.reset( QGis.Polygon ) del self.mRubberBand self.mRubberBand = None self.mDragging = False return if (not self.mDragging ): QgsMapToolSelectUtils.expandSelectRectangle(self. mSelectRect, vlayer, e.pos() ) else: if ( self.mSelectRect.width() == 1 ): self.mSelectRect.setLeft( self.mSelectRect.left() + 1 ) if ( self.mSelectRect.height() == 1 ): self.mSelectRect.setBottom( self.mSelectRect.bottom() + 1 ) if ( self.mRubberBand != None ): QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect, self.mRubberBand ) selectGeom = self.mRubberBand.asGeometry() selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1( self.mCanvas, selectGeom, e ) if len(selectedFeatures) > 0: self.lineCount += 1 geom = selectedFeatures[0].geometry() resultArray = QgisHelper.findArcOrLineInLineGeometry(geom, selectGeom) # if resultArray != None: # bulge = MathHelper.smethod_60(resultArray[0], resultArray[int(len(resultArray)/2)], resultArray[len(resultArray)-1]) # bulge1 = MathHelper.smethod_60(resultArray[len(resultArray)-1], resultArray[int(len(resultArray)/2)], resultArray[0]) # n = 0 pointArray0 = geom.asPolyline() self.resultGeomList.append(resultArray) self.geomList.append(pointArray0) if self.lineCount == 2 and self.areaType != ProtectionAreaType.PrimaryAndSecondary and self.areaType != ProtectionAreaType.Complex: self.area = self.makeArea(self.resultGeomList, self.areaType) pointArray = self.getPointArray(self.resultGeomList).method_14_closed() self.mRubberBandResult = None self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100)) self.mRubberBandResult.setBorderColor(QColor(0, 0, 0)) for point in pointArray: self.mRubberBandResult.addPoint(point) self.mRubberBandResult.show() self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult) self.lineCount = 0 self.resultGeomList = [] self.isFinished = True # self.rubberBandLine.reset(QGis.Line) elif self.lineCount == 4 and self.areaType == ProtectionAreaType.PrimaryAndSecondary: self.area = self.makeArea(self.resultGeomList, self.areaType) pointArray = self.getPointArray([self.resultGeomList[1], self.resultGeomList[3]]).method_14_closed() self.mRubberBandResult = None self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100)) self.mRubberBandResult.setBorderColor(QColor(0, 0, 0)) for point in pointArray: self.mRubberBandResult.addPoint(point) self.mRubberBandResult.show() self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult) self.lineCount = 0 self.resultGeomList = [] # else: # return del selectGeom self.mRubberBand.reset( QGis.Polygon ) del self.mRubberBand self.mRubberBand = None self.mDragging = False def getPointArray(self, geomList): pointArrayInner = geomList[0] pointArray1Outer = geomList[1] innerStartPoint = pointArrayInner[0] innerEndPoint = pointArrayInner[1] innerBulge = pointArrayInner[2] outerStartPoint = pointArray1Outer[0] outerEndPoint = pointArray1Outer[1] outerBulge = pointArray1Outer[2] line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint]) line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint]) # for i in range(1, len(pointArray0)): if line0.intersects(line1): tempPoint = outerStartPoint outerStartPoint = outerEndPoint outerEndPoint = tempPoint outerBulge = -outerBulge polylineArea = PolylineArea() polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge)) polylineArea.Add(PolylineAreaPoint(innerEndPoint)) polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge)) polylineArea.Add(PolylineAreaPoint(outerStartPoint)) return polylineArea def makeArea(self, geomList, areaType): if areaType == ProtectionAreaType.Primary or areaType == ProtectionAreaType.Secondary: return self.makePrimaryAreaOrSecondaryArea(geomList, areaType) elif areaType == ProtectionAreaType.PrimaryAndSecondary: pointArray0 = geomList[0] pointArray1 = geomList[1] pointArray2 = geomList[2] pointArray3 = geomList[3] primaryArea = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray2], ProtectionAreaType.Primary) secondaryArea1 = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray1], ProtectionAreaType.Secondary) secondaryArea2 = self.makePrimaryAreaOrSecondaryArea([pointArray2, pointArray3], ProtectionAreaType.Secondary) return PrimarySecondaryObstacleArea(primaryArea, secondaryArea1, secondaryArea2) # if len(geomList[0]) == 2 and len(geomList[1]) == 2 and len(geomList[2]) == 2 and len(geomList[3]) == 2: # for i in range(1, len(geomList)): # pointArray0 = geomList[0] # pointArray1 = geomList[i] # line0 = QgsGeometry.fromPolyline([pointArray0[0], pointArray1[0]]) # line1 = QgsGeometry.fromPolyline([pointArray0[len(pointArray0) - 1], pointArray1[len(pointArray1) - 1]]) # if line0.intersects(line1): # pointArray1.reverse() # pointArray0 = geomList[0] # pointArray1 = geomList[1] # pointArray2 = geomList[2] # pointArray3 = geomList[3] # area = PrimarySecondaryObstacleArea() # area.set_areas(pointArray0, pointArray1, pointArray2, pointArray3) # return area # return None return None def makePrimaryAreaOrSecondaryArea(self, geomList, areaType): pointArrayInner = geomList[0] pointArray1Outer = geomList[1] innerStartPoint = pointArrayInner[0] innerEndPoint = pointArrayInner[1] innerBulge = pointArrayInner[2] outerStartPoint = pointArray1Outer[0] outerEndPoint = pointArray1Outer[1] outerBulge = pointArray1Outer[2] line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint]) line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint]) # for i in range(1, len(pointArray0)): if line0.intersects(line1): tempPoint = Point3D(outerStartPoint.get_X(), outerStartPoint.get_Y()) outerStartPoint = Point3D(outerEndPoint.get_X(), outerEndPoint.get_Y()) outerEndPoint = Point3D(tempPoint.get_X(), tempPoint.get_Y()) outerBulge = -outerBulge if areaType == ProtectionAreaType.Primary: polylineArea = PolylineArea() polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge)) polylineArea.Add(PolylineAreaPoint(innerEndPoint)) polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge)) polylineArea.Add(PolylineAreaPoint(outerStartPoint)) return PrimaryObstacleArea(polylineArea) elif areaType == ProtectionAreaType.Secondary: if innerBulge == 0 and outerBulge == 0: return SecondaryObstacleArea(innerStartPoint, innerEndPoint, outerStartPoint, outerEndPoint, MathHelper.getBearing(innerStartPoint, innerEndPoint)) elif innerBulge != 0 and outerBulge != 0: if round(innerBulge, 1) != round(outerBulge, 1): return None innerCenterPoint = MathHelper.smethod_71(innerStartPoint, innerEndPoint, innerBulge) outerCenterPoint = MathHelper.smethod_71(outerStartPoint, outerEndPoint, outerBulge) innerRadius = MathHelper.calcDistance(innerCenterPoint, innerStartPoint); outerRadius = MathHelper.calcDistance(outerCenterPoint, outerStartPoint); bearing = (MathHelper.getBearing(innerCenterPoint, innerStartPoint) + MathHelper.getBearing(innerCenterPoint, innerEndPoint)) / 2 innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius) if round(MathHelper.smethod_60(innerStartPoint, innerMiddlePoint, innerEndPoint), 4) != round(outerBulge, 4): bearing += 3.14159265358979 innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius) bearing = (MathHelper.getBearing(outerCenterPoint, outerStartPoint) + MathHelper.getBearing(outerCenterPoint, outerEndPoint)) / 2 outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius) if round(MathHelper.smethod_60(outerStartPoint, outerMiddlePoint, outerEndPoint), 4) != round(outerBulge, 4): bearing += 3.14159265358979 outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius) return SecondaryObstacleArea(innerStartPoint, innerMiddlePoint, innerEndPoint, outerStartPoint, None, outerMiddlePoint, outerEndPoint, innerBulge, innerBulge) return None def snapPoint(self, p, bNone = False): if define._snapping == False: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers( p ) if ( snappingResults[0] != 0 or len(snappingResults[1]) < 1 ): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer)
class InfoTool(QgsMapTool): infoResults = pyqtSignal(dict) def __init__(self, canvas, snapradius = 2): super(InfoTool, self).__init__(canvas) self.canvas = canvas self.radius = snapradius self.band = QgsRubberBand(self.canvas) self.band.setColor(QColor.fromRgb(224,162,16)) self.band.setWidth(3) self.selectband = None self.selectrect = QRect() self.dragging = False self.selectionlayers = [] def getFeatures(self, rect): self.band.reset() for layer in self.selectionlayers: if (not layer.type() == QgsMapLayer.VectorLayer or layer.geometryType() == QGis.NoGeometry): continue rect = self.toLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect).setFlags(QgsFeatureRequest.ExactIntersect) features = [] for feature in layer.getFeatures(rq): if feature.isValid(): features.append(feature) yield layer, features def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * ( self.radius / 100.0 ) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect def canvasPressEvent(self, event): self.dragging = False self.selectrect.setRect( 0, 0, 0, 0 ) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon ) self.selectband.setColor(QColor.fromRgb(0,0,255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.selectrect.setTopLeft(event.pos()) self.dragging = True self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() else: rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() results = OrderedDict((l,f) for l, f in self.getFeatures(rect)) print results self.infoResults.emit(results)
class MincutConnec(QgsMapTool): canvasClicked = pyqtSignal() def __init__(self, iface, controller): """ Class constructor """ self.iface = iface self.canvas = self.iface.mapCanvas() self.controller = controller # Call superclass constructor and set current action QgsMapTool.__init__(self, self.canvas) self.dragging = False # Vertex marker color = QColor(255, 100, 255) self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CIRCLE) self.vertex_marker.setColor(color) self.vertex_marker.setIconSize(15) self.vertex_marker.setPenWidth(3) # Rubber band self.rubber_band = QgsRubberBand(self.canvas, QGis.Line) self.rubber_band.setColor(color) self.rubber_band.setWidth(1) # Select rectangle self.select_rect = QRect() # TODO: Parametrize self.connec_group = ["Wjoin", "Tap", "Fountain", "Greentap"] #self.snapperManager = SnappingConfigManager(self.iface) self.snapper = QgsMapCanvasSnapper(self.canvas) def activate(self): pass def canvasPressEvent(self, event): #@UnusedVariable self.select_rect.setRect(0, 0, 0, 0) self.rubber_band.reset() def canvasMoveEvent(self, event): """ With left click the digitizing is finished """ if event.buttons() == Qt.LeftButton: if not self.dragging: self.dragging = True self.select_rect.setTopLeft(event.pos()) self.select_rect.setBottomRight(event.pos()) self.set_rubber_band() else: # Hide highlight self.vertex_marker.hide() # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snap_point in result: element_type = snap_point.layer.name() if element_type in self.connec_group: # Get the point point = QgsPoint(snap_point.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() break def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Not dragging, just simple selection if not self.dragging: # Snap to node (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: element_type = snapped_point.layer.name() if element_type in self.connec_group: feat_type = 'connec' else: continue point = QgsPoint( snapped_point.snappedVertex) # @UnusedVariable # layer.removeSelection() # layer.select([result[0].snappedAtGeometry]) #snapped_point.layer.removeSelection() snapped_point.layer.select( [snapped_point.snappedAtGeometry]) else: # Set valid values for rectangle's width and height if self.select_rect.width() == 1: self.select_rect.setLeft(self.select_rect.left() + 1) if self.select_rect.height() == 1: self.select_rect.setBottom(self.select_rect.bottom() + 1) self.set_rubber_band() self.select_multiple_features(self.selected_rectangle) self.dragging = False # Refresh map canvas self.rubber_band.reset() self.refresh_map_canvas() def set_rubber_band(self): # Coordinates transform transform = self.canvas.getCoordinateTransform() # Coordinates ll = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.bottom()) lr = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.bottom()) ul = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.top()) ur = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.top()) # Rubber band self.rubber_band.reset() self.rubber_band.addPoint(ll, False) self.rubber_band.addPoint(lr, False) self.rubber_band.addPoint(ur, False) self.rubber_band.addPoint(ul, False) self.rubber_band.addPoint(ll, True) self.selected_rectangle = QgsRectangle(ll, ur) def select_multiple_features(self, rectangle): if self.connec_group is None: return if QGis.QGIS_VERSION_INT >= 21600: # Selection for all connec group layers for layer_name in self.connec_group: # Get layer by his name layer = self.controller.get_layer_by_layername(layer_name, log_info=True) if layer: self.group_pointers_connec.append(layer) layer.selectByRect(rectangle) else: for layer_name in self.connec_group: self.iface.setActiveLayer(layer) layer.removeSelection() layer.select(rectangle, True)
class InfoTool(TouchMapTool): infoResults = pyqtSignal(dict) def __init__(self, canvas, snapradius=2): super(InfoTool, self).__init__(canvas) self.radius = snapradius self.band = QgsRubberBand(self.canvas) self.band.setColor(QColor.fromRgb(224, 162, 16)) self.band.setWidth(3) self.selectband = None self.selectrect = QRect() self.dragging = False self.selectionlayers = [] def getFeatures(self, rect): self.band.reset() for layer in self.selectionlayers.itervalues(): if (not layer.type() == QgsMapLayer.VectorLayer or layer.geometryType() == QGis.NoGeometry): continue rect = self.toLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect)\ .setFlags(QgsFeatureRequest.ExactIntersect)\ .setSubsetOfAttributes([]) features = [] for feature in layer.getFeatures(rq): if feature.isValid(): features.append(feature) yield layer, features def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * (self.radius / 100.0) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect def canvasPressEvent(self, event): if self.pinching: return self.dragging = False self.selectrect.setRect(0, 0, 0, 0) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon) self.selectband.setColor(QColor.fromRgb(0, 0, 255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if self.pinching: return if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.selectrect.setTopLeft(event.pos()) self.dragging = True self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.pinching: return if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() else: rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() results = OrderedDict((l, f) for l, f in self.getFeatures(rect)) self.infoResults.emit(results)
class EditTool(MapTool): """ Inspection tool which copies the feature to a new layer and copies selected data from the underlying feature. """ finished = pyqtSignal(object, QgsFeature) featuresfound = pyqtSignal(dict) def __init__(self, canvas, forms, snapradius=2): MapTool.__init__(self, canvas, []) self.canvas = canvas self.radius = snapradius self.forms = forms self.band = QgsRubberBand(self.canvas) self.band.setColor(QColor.fromRgb(224, 162, 16)) self.band.setWidth(3) self.selectband = None self.selectrect = QRect() self.dragging = False self.cursor = QCursor( QPixmap([ "16 16 3 1", " c None", ". c #FF0000", "+ c #FFFFFF", " ", " +.+ ", " ++.++ ", " +.....+ ", " +. .+ ", " +. . .+ ", " +. . .+ ", " ++. . .++", " ... ...+... ...", " ++. . .++", " +. . .+ ", " +. . .+ ", " ++. .+ ", " ++.....+ ", " ++.++ ", " +.+ " ])) def addForm(self, form): self.forms.append(form) self.layersupdated.emit(True) def layers(self): """ Return a set of layers that this edit tool can work on """ return set([form.QGISLayer for form in self.forms]) def formsforlayer(self, layer): for form in self.forms: if form.QGISLayer == layer: yield form def reset(self): self.forms = [] self.layersupdated.emit(False) def getFeatures(self, rect): rq = QgsFeatureRequest().setFilterRect(rect) self.band.reset() for layer in self.layers(): forms = list(self.formsforlayer(layer)) rq = QgsFeatureRequest().setFilterRect(rect) for feature in layer.getFeatures(rq): if feature.isValid(): yield feature, forms def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * (self.radius / 100.0) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect def canvasPressEvent(self, event): self.selectrect.setRect(0, 0, 0, 0) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon) self.selectband.setColor(QColor.fromRgb(0, 0, 255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.dragging = True self.selectrect.setTopLeft(event.pos()) self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() else: rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() features = dict(self.getFeatures(rect)) if len(features) == 1: feature = features.keys()[0] forms = features.values()[0] if len(forms) == 1: self.finished.emit(forms[0], feature) else: self.featuresfound.emit(features) elif len(features) > 0: self.featuresfound.emit(features) def isEditTool(self): return True
class ArkMapToolInteractive(QgsMapTool): _active = False _dragging = False _panningEnabled = False _zoomingEnabled = False _zoomRubberBand = None #QgsRubberBand() _zoomRect = None # QRect() _snappingEnabled = False _snapper = None #QgsMapCanvasSnapper() _snappingMarker = None # QgsVertexMarker() _showSnappableVertices = False _snappableVertices = [] # [QgsPoint()] _snappableMarkers = [] # [QgsVertexMarker()] def __init__(self, canvas, snappingEnabled=False, showSnappableVertices=False): super(ArkMapToolInteractive, self).__init__(canvas) self._snappingEnabled = snappingEnabled self._showSnappableVertices = showSnappableVertices def __del__(self): if self._active: self.deactivate() def isActive(self): return self._active def activate(self): super(ArkMapToolInteractive, self).activate() self._active = True self._startSnapping() def deactivate(self): self._active = False if self._snappingEnabled: self._stopSnapping() if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None super(ArkMapToolInteractive, self).deactivate() def setAction(self, action): super(ArkMapToolInteractive, self).setAction(action) self.action().triggered.connect(self._activate) def _activate(self): self.canvas().setMapTool(self) def panningEnabled(self): return self._panningEnabled def setPanningEnabled(self, enabled): self._panningEnabled = enabled def zoomingEnabled(self): return self._zoomingEnabled def setZoomingEnabled(self, enabled): self._zoomingEnabled = enabled def snappingEnabled(self): return self._snappingEnabled def setSnappingEnabled(self, enabled): if (self._snappingEnabled == enabled): return self._snappingEnabled = enabled if not self._active: return if enabled: self._startSnapping() else: self._stopSnapping() def _startSnapping(self): self._snapper = QgsMapCanvasSnapper() self._snapper.setMapCanvas(self.canvas()) if self._showSnappableVertices: self._startSnappableVertices() def _stopSnapping(self): self._deleteSnappingMarker() self._snapper = None if self._showSnappableVertices: self._stopSnappableVertices() def showSnappableVertices(self): return self._showSnappableVertices def setShowSnappableVertices(self, show): if (self._showSnappableVertices == show): return self._showSnappableVertices = show if not self._active: return if show: self._startSnappableVertices() else: self._stopSnappableVertices() def _startSnappableVertices(self): self.canvas().layersChanged.connect(self._layersChanged) self.canvas().extentsChanged.connect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.connect(self._layersChanged) self._layersChanged() def _stopSnappableVertices(self): self._deleteSnappableMarkers() self._snappableLayers = [] self.canvas().layersChanged.disconnect(self._layersChanged) self.canvas().extentsChanged.disconnect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.disconnect(self._layersChanged) def canvasMoveEvent(self, e): super(ArkMapToolInteractive, self).canvasMoveEvent(e) if not self._active: return e.ignore() if (self._panningEnabled and e.buttons() & Qt.LeftButton): # Pan map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self.canvas().panAction(e) e.accept() elif (self._zoomingEnabled and e.buttons() & Qt.RightButton): # Zoom map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self._zoomRubberBand = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor(Qt.blue) color.setAlpha(63) self._zoomRubberBand.setColor(color) self._zoomRect = QRect(0, 0, 0, 0) self._zoomRect.setTopLeft(e.pos()) self._zoomRect.setBottomRight(e.pos()) if self._zoomRubberBand is not None: self._zoomRubberBand.setToCanvasRectangle(self._zoomRect) self._zoomRubberBand.show() e.accept() elif self._snappingEnabled: mapPoint, snapped = self._snapCursorPoint(e.pos()) if (snapped): self._createSnappingMarker(mapPoint) else: self._deleteSnappingMarker() def canvasReleaseEvent(self, e): super(ArkMapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(capture_point_cursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform() ll = coordinateTransform.toMapCoordinates(self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates(self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept() def keyPressEvent(self, e): super(ArkMapToolInteractive, self).keyPressEvent(e) if (e.key() == Qt.Key_Escape): self.canvas().unsetMapTool(self) e.accept() def _snapCursorPoint(self, cursorPoint): res, snapResults = self._snapper.snapToBackgroundLayers(cursorPoint) if (res != 0 or len(snapResults) < 1): return self.toMapCoordinates(cursorPoint), False else: # Take a copy as QGIS will delete the result! snappedVertex = QgsPoint(snapResults[0].snappedVertex) return snappedVertex, True def _createSnappingMarker(self, snapPoint): if (self._snappingMarker is None): self._snappingMarker = QgsVertexMarker(self.canvas()) self._snappingMarker.setIconType(QgsVertexMarker.ICON_CROSS) self._snappingMarker.setColor(Qt.magenta) self._snappingMarker.setPenWidth(3) self._snappingMarker.setCenter(snapPoint) def _deleteSnappingMarker(self): if (self._snappingMarker is not None): self.canvas().scene().removeItem(self._snappingMarker) self._snappingMarker = None def _createSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return extent = self.canvas().extent() for vertex in self._snappableVertices.asMultiPoint(): if (extent.contains(vertex)): marker = QgsVertexMarker(self.canvas()) marker.setIconType(QgsVertexMarker.ICON_X) marker.setColor(Qt.gray) marker.setPenWidth(1) marker.setCenter(vertex) self._snappableMarkers.append(marker) def _deleteSnappableMarkers(self): for marker in self._snappableMarkers: self.canvas().scene().removeItem(marker) del self._snappableMarkers[:] def _layersChanged(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._buildSnappableLayers() self._deleteSnappableMarkers() self._createSnappableMarkers() def _redrawSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._deleteSnappableMarkers() self._createSnappableMarkers() def _buildSnappableLayers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return vertices = [] for layer in self.canvas().layers(): ok, enabled, type, units, tolerance, avoid = QgsProject.instance().snapSettingsForLayer(layer.id()) if (ok and enabled and not layer.isEditable()): for feature in layer.getFeatures(): geometry = feature.geometry() if geometry is None: pass elif geometry.type() == QGis.Point: vertices.extend([geometry.asPoint()]) elif geometry.type() == QGis.Line: vertices.extend(geometry.asPolyline()) elif geometry.type() == QGis.Polygon: lines = geometry.asPolygon() for line in lines: vertices.extend(line) self._snappableVertices = QgsGeometry.fromMultiPoint(vertices) self._snappableVertices.simplify(0)
class SelectByRect(QgsMapTool): def __init__(self, canvas): self.mCanvas = canvas QgsMapTool.__init__(self, canvas) self.mCursor = Qt.ArrowCursor self.mRubberBand = None self.mDragging = False self.mSelectRect = QRect() # QgsRubberBand* mRubberBand; # def reset(self): # self.startPoint = None # self.endPoint = None # self.isDrawing = False # SelectByRect.RubberRect.reset(QGis.Polygon) # self.layer = self.canvas.currentLayer() def canvasPressEvent(self, e): self.mSelectRect.setRect(0, 0, 0, 0) self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) # self.reset() # self.startPoint = self.toMapCoordinates(e.pos()) # self.isDrawing = True def canvasMoveEvent(self, e): if (e.buttons() != Qt.LeftButton): return if (not self.mDragging): self.mDragging = True self.mSelectRect.setTopLeft(e.pos()) self.mSelectRect.setBottomRight(e.pos()) QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) # if not self.isDrawing: # return # SelectByRect.RubberRect.reset(QGis.Polygon) # self.endPoint = self.toMapCoordinates(e.pos()) # self.rect = QgsRectangle(self.startPoint, self.endPoint) # SelectByRect.RubberRect.addGeometry(QgsGeometry.fromRect(self.rect), None) # SelectByRect.RubberRect.show() def canvasReleaseEvent(self, e): selectedFeatures = None vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(self.mCanvas) if (vlayer == None): if (self.mRubberBand != None): self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False return if (not self.mDragging): QgsMapToolSelectUtils.expandSelectRectangle( self.mSelectRect, vlayer, e.pos()) else: if (self.mSelectRect.width() == 1): self.mSelectRect.setLeft(self.mSelectRect.left() + 1) if (self.mSelectRect.height() == 1): self.mSelectRect.setBottom(self.mSelectRect.bottom() + 1) if (self.mRubberBand != None): QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) selectGeom = self.mRubberBand.asGeometry() # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, selectGeom, e ) selectedFeatures = QgsMapToolSelectUtils.setSelectFeatures1( self.mCanvas, selectGeom, e) del selectGeom self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False self.emit(SIGNAL("getSelectedFeatures"), selectedFeatures)
class MapToolInteractive(QgsMapTool): """Tool to interact with map, including panning, zooming, and snapping""" def __init__(self, canvas, snappingEnabled=False): super(MapToolInteractive, self).__init__(canvas) self._active = False self._dragging = False self._panningEnabled = False self._zoomingEnabled = False self._zoomRubberBand = None # QgsRubberBand() self._zoomRect = None # QRect() self._snappingEnabled = snappingEnabled self._snapper = None # QgsMapCanvasSnapper() self._snappingMarker = None # QgsVertexMarker() def __del__(self): if self._active: self.deactivate() def isActive(self): return self._active def activate(self): super(MapToolInteractive, self).activate() self._active = True self._startSnapping() def deactivate(self): self._active = False if self._snappingEnabled: self._stopSnapping() if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None super(MapToolInteractive, self).deactivate() def setAction(self, action): super(MapToolInteractive, self).setAction(action) self.action().triggered.connect(self._activate) def _activate(self): self.canvas().setMapTool(self) def panningEnabled(self): return self._panningEnabled def setPanningEnabled(self, enabled): self._panningEnabled = enabled def zoomingEnabled(self): return self._zoomingEnabled def setZoomingEnabled(self, enabled): self._zoomingEnabled = enabled def snappingEnabled(self): return self._snappingEnabled def setSnappingEnabled(self, enabled): if (self._snappingEnabled == enabled): return self._snappingEnabled = enabled if not self._active: return if enabled: self._startSnapping() else: self._stopSnapping() def _startSnapping(self): self._snapper = QgsMapCanvasSnapper() self._snapper.setMapCanvas(self.canvas()) def _stopSnapping(self): self._deleteSnappingMarker() self._snapper = None def canvasMoveEvent(self, e): super(MapToolInteractive, self).canvasMoveEvent(e) if not self._active: return e.ignore() if (self._panningEnabled and e.buttons() & Qt.LeftButton): # Pan map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self.canvas().panAction(e) e.accept() elif (self._zoomingEnabled and e.buttons() & Qt.RightButton): # Zoom map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self._zoomRubberBand = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor(Qt.blue) color.setAlpha(63) self._zoomRubberBand.setColor(color) self._zoomRect = QRect(0, 0, 0, 0) self._zoomRect.setTopLeft(e.pos()) self._zoomRect.setBottomRight(e.pos()) if self._zoomRubberBand is not None: self._zoomRubberBand.setToCanvasRectangle(self._zoomRect) self._zoomRubberBand.show() e.accept() elif self._snappingEnabled: mapPoint, mapPointV2, snapped = self._snapCursorPoint(e.pos()) if (snapped): self._createSnappingMarker(mapPoint) else: self._deleteSnappingMarker() def canvasReleaseEvent(self, e): super(MapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(CapturePointCursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform( ) ll = coordinateTransform.toMapCoordinates( self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates( self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept() def keyPressEvent(self, e): super(MapToolInteractive, self).keyPressEvent(e) if (e.key() == Qt.Key_Escape): self.canvas().unsetMapTool(self) e.accept() def _snapCursorPoint(self, cursorPoint): res, snapResults = self._snapper.snapToBackgroundLayers(cursorPoint) if (res != 0 or len(snapResults) < 1): clicked = self.toMapCoordinates(cursorPoint) clickedV2 = QgsPointV2(clicked) return clicked, clickedV2, False else: # Take a copy as QGIS will delete the result! snapped = QgsPoint(snapResults[0].snappedVertex) snappedV2 = QgsPointV2(snapped) return snapped, snappedV2, True def _createSnappingMarker(self, snapPoint): if (self._snappingMarker is None): self._snappingMarker = QgsVertexMarker(self.canvas()) self._snappingMarker.setIconType(QgsVertexMarker.ICON_CROSS) self._snappingMarker.setColor(Qt.magenta) self._snappingMarker.setPenWidth(3) self._snappingMarker.setCenter(snapPoint) def _deleteSnappingMarker(self): if (self._snappingMarker is not None): self.canvas().scene().removeItem(self._snappingMarker) self._snappingMarker = None
class InfoTool(QgsMapTool): def __init__(self, canvas, snapradius=2): super(InfoTool, self).__init__(canvas) self.canvas = canvas self.radius = snapradius self.selectband = QgsRubberBand(self.canvas, QGis.Polygon) self.selectrect = QRect() self.dragging = False self.selectionlayers = [] def getFeatures(self, rect, firstonly=False): # The MS SQL driver seems to crash with a empty rectangle. # Need to check QGIS to patch issue if rect.isEmpty(): return for layer in self.selectionlayers.itervalues(): if (not layer.type() == QgsMapLayer.VectorLayer or layer.geometryType() == QGis.NoGeometry): continue rect = self.toLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect) \ .setFlags(QgsFeatureRequest.ExactIntersect) features = [] for feature in layer.getFeatures(rq): if feature.isValid(): features.append(feature) yield layer, features def toSearchRect(self, point): size = 20 rect = QRectF() rect.setLeft(point.x() - size) rect.setRight(point.x() + size) rect.setTop(point.y() - size) rect.setBottom(point.y() + size) transform = self.canvas.getCoordinateTransform() ll = transform.toMapCoordinates(rect.left(), rect.bottom()) ur = transform.toMapCoordinates(rect.right(), rect.top()) rect = QgsRectangle(ur, ll) return rect def canvasPressEvent(self, event): self.dragging = False self.selectrect.setRect(0, 0, 0, 0) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon) self.selectband.setColor(QColor.fromRgb(0, 0, 255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.selectrect.setTopLeft(event.pos()) self.dragging = True self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() firstonly = False else: firstonly = True rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() results = OrderedDict((l, f) for l, f in self.getFeatures(rect)) RoamEvents.selectioncleared.emit() RoamEvents.selectionchanged.emit(results)
class SelectedFeatureByRectTasDraw(QgsMapTool): def __init__(self, canvas, distance): self.mCanvas = canvas QgsMapTool.__init__(self, canvas) self.mCursor = Qt.ArrowCursor self.mRubberBand = None self.mDragging = False self.mSelectRect = QRect() self.rubberBandLine = None self.distance = distance self.mSnapper = QgsMapCanvasSnapper(canvas) # QgsRubberBand* mRubberBand; # def reset(self): # self.startPoint = None # self.endPoint = None # self.isDrawing = False # SelectByRect.RubberRect.reset(QGis.Polygon) # self.layer = self.canvas.currentLayer() def canvasPressEvent(self, e): self.mSelectRect.setRect(0, 0, 0, 0) self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) self.startPoint, self.pointID, self.layer = self.snapPoint(e.pos()) # self.reset() # self.startPoint = self.toMapCoordinates(e.pos()) # self.isDrawing = True def canvasMoveEvent(self, e): if (e.buttons() != Qt.LeftButton): return if (not self.mDragging): self.mDragging = True self.mSelectRect.setTopLeft(e.pos()) self.mSelectRect.setBottomRight(e.pos()) QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) # if not self.isDrawing: # return # SelectByRect.RubberRect.reset(QGis.Polygon) # self.endPoint = self.toMapCoordinates(e.pos()) # self.rect = QgsRectangle(self.startPoint, self.endPoint) # SelectByRect.RubberRect.addGeometry(QgsGeometry.fromRect(self.rect), None) # SelectByRect.RubberRect.show() def canvasReleaseEvent(self, e): self.endPoint, self.pointID, self.layer = self.snapPoint(e.pos()) if len(define._newGeometryList) > 0: geom = define._newGeometryList[0] if geom.intersects(self.mRubberBand.asGeometry()): pointArray = geom.asPolyline() # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200) if self.rubberBandLine != None: self.rubberBandLine.reset(QGis.Line) del self.rubberBandLine self.rubberBandLine = None self.rubberBandLine = QgsRubberBand(self.mCanvas, QGis.Line) self.rubberBandLine.setColor(Qt.blue) bearing = 0.0 if self.startPoint.y() >= self.endPoint.y() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) < math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(180) elif self.startPoint.x() >= self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(270) elif self.startPoint.x() < self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(90) else: bearing = 0.0 for point in pointArray: pt = MathHelper.distanceBearingPoint( Point3D(point.x(), point.y()), bearing, self.distance ) # MathHelper.getBearing(self.startPoint, self.endPoint), self.distance) self.rubberBandLine.addPoint(pt) gg = self.rubberBandLine.asGeometry() g = gg.asPolyline() # self.rubberBandLine.show() if (self.mRubberBand != None): self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False self.emit( SIGNAL("resultSelectedFeatureByRectTasDraw"), gg, self.distance, bearing ) # MathHelper.getBearing(self.startPoint, self.endPoint)) return vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(self.mCanvas) if (vlayer == None): if (self.mRubberBand != None): self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False return if (not self.mDragging): QgsMapToolSelectUtils.expandSelectRectangle( self.mSelectRect, vlayer, e.pos()) else: if (self.mSelectRect.width() == 1): self.mSelectRect.setLeft(self.mSelectRect.left() + 1) if (self.mSelectRect.height() == 1): self.mSelectRect.setBottom(self.mSelectRect.bottom() + 1) if (self.mRubberBand != None): QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) selectGeom = self.mRubberBand.asGeometry() # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, selectGeom, e ) selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1( self.mCanvas, selectGeom, e) if len(selectedFeatures) > 0: geom = selectedFeatures[0].geometry() if geom.intersects(self.mRubberBand.asGeometry()): pointArray = geom.asPolyline() # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200) if self.rubberBandLine != None: self.rubberBandLine.reset(QGis.Line) del self.rubberBandLine self.rubberBandLine = None self.rubberBandLine = QgsRubberBand( self.mCanvas, QGis.Line) self.rubberBandLine.setColor(Qt.blue) bearing = 0.0 gg = None if self.startPoint.y() >= self.endPoint.y() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) < math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(180) gg = self.newCreateLine(geom, self.distance, 180) elif self.startPoint.x() >= self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(270) gg = self.newCreateLine(geom, self.distance, 270) elif self.startPoint.x() < self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(90) gg = self.newCreateLine(geom, self.distance, 90) else: bearing = 0.0 gg = self.newCreateLine(geom, self.distance, 0) for point in pointArray: pt = MathHelper.distanceBearingPoint( Point3D(point.x(), point.y()), bearing, self.distance ) #MathHelper.getBearing(self.startPoint, self.endPoint), self.distance) self.rubberBandLine.addPoint(pt) # gg= self.newCreateLine(geom, -self.distance, 0) self.emit( SIGNAL("resultSelectedFeatureByRectTasDraw"), gg, self.distance, bearing ) #MathHelper.getBearing(self.startPoint, self.endPoint)) self.rubberBandLine.reset(QGis.Line) del selectGeom self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False # self.canvasMoveEvent(e) # if self.layer != None: # self.layer.removeSelection() # if self.layer.crs().mapUnits() != self.canvas.mapUnits(): # if self.layer.crs().mapUnits == QGis.Meters: # lstPoint = QgisHelper.Degree2MeterList([self.startPoint, self.endPoint]) # else: # lstPoint = QgisHelper.Meter2DegreeList([self.startPoint, self.endPoint]) # rect = QgsRectangle(lstPoint[0], lstPoint[1]) # self.layer.select(rect, True) # else: # self.layer.select(self.rect, False) # else: # QMessageBox.warning(None, "Information", "Please select layer!") # self.reset() def snapPoint(self, p, bNone=False): if define._snapping == False: return ( define._canvas.getCoordinateTransform().toMapCoordinates(p), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers(p) if (snappingResults[0] != 0 or len(snappingResults[1]) < 1): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform(). toMapCoordinates(p), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer) def newCreateLine(self, geom, dist, angle): if define._units != QGis.Meters: dist = define._qgsDistanceArea.convertMeasurement( dist, QGis.Meters, QGis.Degrees, False)[0] g = geom.offsetCurve(dist, 0, 2, 2) pointArrayOld = geom.asPolyline() pointArrayNew = g.asPolyline() if MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]): array = [] i = len(pointArrayNew) - 1 while i >= 0: array.append(pointArrayNew[i]) i -= 1 pointArrayNew = array if angle == 0: if pointArrayNew[0].y() < pointArrayOld[0].y(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 90: if pointArrayNew[0].x() < pointArrayOld[0].x(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 180: if pointArrayNew[0].y() > pointArrayOld[0].y(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 270: if pointArrayNew[0].x() > pointArrayOld[0].x(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() if MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]): array = [] i = len(pointArrayNew) - 1 while i >= 0: array.append(pointArrayNew[i]) i -= 1 pointArrayNew = array i = 0 while i < len(pointArrayNew) - 1: if i == 0: i += 1 continue line = None if define._units == QGis.Meters: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), 100000000) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(100000000, pointArrayOld[0].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline( [pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), 0)]) elif angle == 270: line = QgsGeometry.fromPolyline( [pointArrayOld[0], QgsPoint(0, pointArrayOld[0].y())]) else: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), pointArrayOld[0].y() + 0.1) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x() + 0.1, pointArrayOld[0].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), pointArrayOld[0].y() - 0.1) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x() - 0.1, pointArrayOld[0].y()) ]) lineNew = QgsGeometry.fromPolyline([ MathHelper.distanceBearingPoint( Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()), MathHelper.getBearing(pointArrayNew[i], pointArrayNew[i - 1]), 100000), pointArrayNew[i] ]) if line.intersects(lineNew): pointGeom = line.intersection(lineNew) intersectPoint = pointGeom.asPoint() pointArrayNew.pop(i - 1) pointArrayNew.insert(i - 1, intersectPoint) break else: pointArrayNew.pop(i - 1) continue i += 1 i = len(pointArrayNew) - 1 while i > 1: line = None if define._units == QGis.Meters: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 100000000) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(100000000, pointArrayOld[len(pointArrayOld) - 1].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 0) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(0, pointArrayOld[len(pointArrayOld) - 1].y()) ]) else: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x(), pointArrayOld[len(pointArrayOld) - 1].y() + 0.1) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x() + 0.1, pointArrayOld[len(pointArrayOld) - 1].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x(), pointArrayOld[len(pointArrayOld) - 1].y() - 0.1) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x() - 0.1, pointArrayOld[len(pointArrayOld) - 1].y()) ]) # line = QgsGeometry.fromPolyline([pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 100000000)]) lineNew = QgsGeometry.fromPolyline([ MathHelper.distanceBearingPoint( Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()), MathHelper.getBearing(pointArrayNew[i - 1], pointArrayNew[i]), 100000), pointArrayNew[i - 1] ]) if line.intersects(lineNew): pointGeom = line.intersection(lineNew) intersectPoint = pointGeom.asPoint() pointArrayNew.pop(i) pointArrayNew.insert(i, intersectPoint) break else: pointArrayNew.pop(i) i -= 1 continue i -= 1 return QgsGeometry.fromPolyline(pointArrayNew)
class ConnecMapTool(ParentMapTool): """ Button 20: User select connections from layer 'connec' Execute SQL function: 'gw_fct_connect_to_network' """ def __init__(self, iface, settings, action, index_action): """ Class constructor """ # Call ParentMapTool constructor super(ConnecMapTool, self).__init__(iface, settings, action, index_action) self.dragging = False # Select rectangle self.select_rect = QRect() """ QgsMapTools inherited event functions """ def canvasMoveEvent(self, event): """ With left click the digitizing is finished """ if event.buttons() == Qt.LeftButton: if not self.dragging: self.dragging = True self.select_rect.setTopLeft(event.pos()) self.select_rect.setBottomRight(event.pos()) self.set_rubber_band() else: # Hide marker self.vertex_marker.hide() # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped features if result: for snapped_feat in result: # Check if it belongs to 'connec' or 'gully' group exist_connec = self.snapper_manager.check_connec_group( snapped_feat.layer) exist_gully = self.snapper_manager.check_gully_group( snapped_feat.layer) if exist_connec or exist_gully: # Get the point and add marker point = QgsPoint(result[0].snappedVertex) self.vertex_marker.setCenter(point) self.vertex_marker.show() break def canvasPressEvent(self, event): #@UnusedVariable self.select_rect.setRect(0, 0, 0, 0) self.rubber_band.reset(QGis.Polygon) def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Simple selection if not self.dragging: # Snap to connec or gully (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped features if result: # Check if it belongs to 'connec' or 'gully' group exist_connec = self.snapper_manager.check_connec_group( result[0].layer) exist_gully = self.snapper_manager.check_gully_group( result[0].layer) if exist_connec or exist_gully: key = QApplication.keyboardModifiers() # If Ctrl+Shift is clicked: deselect snapped feature if key == (Qt.ControlModifier | Qt.ShiftModifier): result[0].layer.deselect( [result[0].snappedAtGeometry]) else: # If Ctrl is not clicked: remove previous selection if key != Qt.ControlModifier: result[0].layer.removeSelection() result[0].layer.select( [result[0].snappedAtGeometry]) # Hide marker self.vertex_marker.hide() # Multiple selection else: # Set valid values for rectangle's width and height if self.select_rect.width() == 1: self.select_rect.setLeft(self.select_rect.left() + 1) if self.select_rect.height() == 1: self.select_rect.setBottom(self.select_rect.bottom() + 1) self.set_rubber_band() selected_geom = self.rubber_band.asGeometry() #@UnusedVariable self.select_multiple_features(self.selected_rectangle) self.dragging = False # Refresh map canvas self.rubber_band.reset() elif event.button() == Qt.RightButton: # Check selected records number_features = 0 for layer in self.layer_connec_man: number_features += layer.selectedFeatureCount() if number_features > 0: message = ("Number of features selected in the 'connec' group") title = "Interpolate value - Do you want to update values" answer = self.controller.ask_question( message, title, parameter=str(number_features)) if answer: # Create link self.link_selected_features('connec', self.layer_connec_man) if self.layer_gully_man: # Check selected records number_features = 0 for layer in self.layer_gully_man: number_features += layer.selectedFeatureCount() if number_features > 0: message = ( "Number of features selected in the 'gully' group") title = "Interpolate value - Do you want to update values" answer = self.controller.ask_question( message, title, parameter=str(number_features)) if answer: # Create link self.link_selected_features('gully', self.layer_gully_man) def activate(self): # Check button self.action().setChecked(True) # Rubber band self.rubber_band.reset() # Store user snapping configuration self.snapper_manager.store_snapping_options() # Clear snapping self.snapper_manager.clear_snapping() # Set snapping to 'connec' and 'gully' self.snapper_manager.snap_to_connec_gully() # Change cursor cursor = self.get_cursor_multiple_selection() self.canvas.setCursor(cursor) # Show help message when action is activated if self.show_help: message = "Right click to use current selection, select connec points by clicking or dragging (selection box)" self.controller.show_info(message) def deactivate(self): # Call parent method ParentMapTool.deactivate(self) def link_selected_features(self, geom_type, layers): """ Link selected @geom_type to the pipe """ # Check features selected number_features = 0 for layer in layers: number_features += layer.selectedFeatureCount() if number_features == 0: message = "You have to select at least one feature!" self.controller.show_warning(message) return # Get selected features from layers of selected @geom_type aux = "{" field_id = geom_type + "_id" # Iterate over all layers for layer in layers: if layer.selectedFeatureCount() > 0: # Get selected features of the layer features = layer.selectedFeatures() for feature in features: feature_id = feature.attribute(field_id) aux += str(feature_id) + ", " list_feature_id = aux[:-2] + "}" # Execute function function_name = "gw_fct_connect_to_network" sql = ("SELECT " + self.schema_name + "." + function_name + "" "('" + list_feature_id + "', '" + geom_type.upper() + "');") self.controller.execute_sql(sql, log_sql=True) layer.removeSelection() # Refresh map canvas self.rubber_band.reset() self.refresh_map_canvas() self.iface.actionPan().trigger() def set_rubber_band(self): # Coordinates transform transform = self.canvas.getCoordinateTransform() # Coordinates ll = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.bottom()) lr = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.bottom()) ul = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.top()) ur = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.top()) # Rubber band self.rubber_band.reset(QGis.Polygon) self.rubber_band.addPoint(ll, False) self.rubber_band.addPoint(lr, False) self.rubber_band.addPoint(ur, False) self.rubber_band.addPoint(ul, False) self.rubber_band.addPoint(ll, True) self.selected_rectangle = QgsRectangle(ll, ur) def select_multiple_features(self, selectGeometry): if self.layer_connec_man is None and self.layer_gully_man is None: return key = QApplication.keyboardModifiers() # If Ctrl+Shift clicked: remove features from selection if key == (Qt.ControlModifier | Qt.ShiftModifier): behaviour = QgsVectorLayer.RemoveFromSelection # If Ctrl clicked: add features to selection elif key == Qt.ControlModifier: behaviour = QgsVectorLayer.AddToSelection # If Ctrl not clicked: add features to selection else: behaviour = QgsVectorLayer.AddToSelection # Selection for all connec and gully layers for layer in self.layer_connec_man: layer.selectByRect(selectGeometry, behaviour) if self.layer_gully_man: for layer in self.layer_gully_man: layer.selectByRect(selectGeometry, behaviour)
class InfoTool(QgsMapTool): def __init__(self, canvas, snapradius = 2): super(InfoTool, self).__init__(canvas) self.canvas = canvas self.radius = snapradius self.selectband = QgsRubberBand(self.canvas, QGis.Polygon ) self.selectrect = QRect() self.dragging = False self.selectionlayers = [] def getFeatures(self, rect, firstonly=False): # The MS SQL driver seems to crash with a empty rectangle. # Need to check QGIS to patch issue if rect.isEmpty(): return for layer in self.selectionlayers.itervalues(): if (not layer.type() == QgsMapLayer.VectorLayer or layer.geometryType() == QGis.NoGeometry): continue rect = self.toLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect) \ .setFlags(QgsFeatureRequest.ExactIntersect) features = [] for feature in layer.getFeatures(rq): if feature.isValid(): features.append(feature) yield layer, features def toSearchRect(self, point): size = 20 rect = QRectF() rect.setLeft(point.x() - size) rect.setRight(point.x() + size) rect.setTop(point.y() - size) rect.setBottom(point.y() + size) transform = self.canvas.getCoordinateTransform() ll = transform.toMapCoordinates(rect.left(), rect.bottom()) ur = transform.toMapCoordinates(rect.right(), rect.top()) rect = QgsRectangle(ur, ll) return rect def canvasPressEvent(self, event): self.dragging = False self.selectrect.setRect(0, 0, 0, 0) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon ) self.selectband.setColor(QColor.fromRgb(0,0,255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.selectrect.setTopLeft(event.pos()) self.dragging = True self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() firstonly = False else: firstonly = True rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() results = OrderedDict((l,f) for l, f in self.getFeatures(rect)) RoamEvents.selectioncleared.emit() RoamEvents.selectionchanged.emit(results)
class ExtractRasterValue(ParentMapTool): """ Button 18. User select nodes and assign raster elevation or value """ def __init__(self, iface, settings, action, index_action): """ Class constructor """ # Call ParentMapTool constructor super(ExtractRasterValue, self).__init__(iface, settings, action, index_action) self.dragging = False # Vertex marker self.vertexMarker = QgsVertexMarker(self.canvas) self.vertexMarker.setColor(QColor(255, 25, 25)) self.vertexMarker.setIconSize(11) self.vertexMarker.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X self.vertexMarker.setPenWidth(5) # Rubber band self.rubberBand = QgsRubberBand(self.canvas, True) mFillColor = QColor(100, 0, 0) self.rubberBand.setColor(mFillColor) self.rubberBand.setWidth(3) mBorderColor = QColor(254, 58, 29) self.rubberBand.setBorderColor(mBorderColor) # Select rectangle self.selectRect = QRect() # Init self.vectorLayer = None self.rasterLayer = None def reset(self): """ Clear selected features """ layer = self.vectorLayer if layer is not None: layer.removeSelection() # Graphic elements self.rubberBand.reset() def set_config_action(self, action_99): """ Get the config form action""" self.configAction = action_99 """ QgsMapTools inherited event functions """ def canvasMoveEvent(self, event): """ With left click the digitizing is finished """ if self.vectorLayer is None: return if event.buttons() == Qt.LeftButton: if not self.dragging: self.dragging = True self.selectRect.setTopLeft(event.pos()) self.selectRect.setBottomRight(event.pos()) self.set_rubber_band() else: # Hide highlight self.vertexMarker.hide() # Get the click x = event.pos().x() y = event.pos().y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) # @UnusedVariable # That's the snapped point if result <> []: # Check Arc or Node for snapPoint in result: if snapPoint.layer == self.vectorLayer: # Get the point point = QgsPoint(result[0].snappedVertex) # Add marker self.vertexMarker.setCenter(point) self.vertexMarker.show() break def canvasPressEvent(self, event): self.selectRect.setRect(0, 0, 0, 0) self.rubberBand.reset() def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get the click x = event.pos().x() y = event.pos().y() eventPoint = QPoint(x, y) # Node layer layer = self.vectorLayer # Not dragging, just simple selection if not self.dragging: # Snap to node (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) # @UnusedVariable # That's the snapped point if result <> [] and (result[0].layer.name() == self.vectorLayer.name()): point = QgsPoint(result[0].snappedVertex) # @UnusedVariable layer.removeSelection() layer.select([result[0].snappedAtGeometry]) # Interpolate values self.raster_interpolate() # Hide highlight self.vertexMarker.hide() else: # Set valid values for rectangle's width and height if self.selectRect.width() == 1: self.selectRect.setLeft(self.selectRect.left() + 1) if self.selectRect.height() == 1: self.selectRect.setBottom(self.selectRect.bottom() + 1) self.set_rubber_band() selectGeom = self.rubberBand.asGeometry() # @UnusedVariable self.select_multiple_features(self.selectRectMapCoord) self.dragging = False # Interpolate values self.raster_interpolate() elif event.button() == Qt.RightButton: # Interpolate values self.raster_interpolate() def activate(self): # Check button self.action().setChecked(True) # Rubber band self.rubberBand.reset() # Store user snapping configuration self.snapperManager.storeSnappingOptions() # Clear snapping self.snapperManager.clearSnapping() # Get layers res = self.find_raster_layers() # if res == 0: # self.controller.show_warning("Raster configuration tool not properly configured.") # return # Change cursor self.canvas.setCursor(self.cursor) # Show help message when action is activated if self.show_help: message = ( "Right click to use current selection, select connec points by clicking or dragging (selection box)" ) self.controller.show_info(message, context_name="ui_message") # Control current layer (due to QGIS bug in snapping system) try: if self.canvas.currentLayer().type() == QgsMapLayer.VectorLayer: self.canvas.setCurrentLayer(self.layer_arc) except: self.canvas.setCurrentLayer(self.layer_arc) def deactivate(self): # Check button self.action().setChecked(False) # Rubber band self.rubberBand.reset() # Restore previous snapping self.snapperManager.recoverSnappingOptions() # Recover cursor self.canvas.setCursor(self.stdCursor) def nearestNeighbor(self, thePoint): ident = self.dataProv.identify(thePoint, QgsRaster.IdentifyFormatValue) value = None if ident is not None: # and ident.has_key(choosenBand+1): try: value = float(ident.results()[int(self.band)]) except TypeError: value = None if value == self.noDataValue: return None return value def writeInterpolation(self, f, fieldIdx): thePoint = f.geometry().asPoint() value = self.nearestNeighbor(thePoint) self.vectorLayer.changeAttributeValue(f.id(), fieldIdx, value) def raster_interpolate(self): """ Interpolate features value from raster """ # Interpolate values if self.vectorLayer is None and self.rasterLayer is None: return # Get data provider layer = self.vectorLayer self.dataProv = self.rasterLayer.dataProvider() if self.dataProv.srcNoDataValue(int(self.band)): self.noDataValue = self.dataProv.srcNoDataValue(int(self.band)) else: self.noDataValue = None self.continueProcess = True self.fieldIdx = "" self.fieldIdx = layer.fieldNameIndex(self.fieldName) if self.band == 0: self.controller.show_warning("You must choose a band for the raster layer.") return if self.fieldName == "": self.controller.show_warning("You must choose a field to write values.") return if self.fieldIdx < 0: self.controller.show_warning("Selected field does not exist in feature layer.") return k = 0 c = 0 f = QgsFeature() # Check features selected if layer.selectedFeatureCount() == 0: message = "You have to select at least one feature!" self.controller.show_warning(message, context_name="ui_message") return # Check editable if not layer.isEditable(): layer.startEditing() # Get selected id's ids = self.vectorLayer.selectedFeaturesIds() for fid in ids: k += 1 layer.getFeatures(QgsFeatureRequest(fid)).nextFeature(f) c += 1 self.writeInterpolation(f, self.fieldIdx) QCoreApplication.processEvents() self.controller.show_info( "%u values have been updated in layer %s.%s over %u points using %s raster" % (c, self.vectorLayer.name(), self.fieldName, k, self.table_raster) ) # Check editable if layer.isEditable(): layer.commitChanges() # Refresh map canvas self.rubberBand.reset() self.iface.mapCanvas().refresh() def set_rubber_band(self): # Coordinates transform transform = self.canvas.getCoordinateTransform() # Coordinates ll = transform.toMapCoordinates(self.selectRect.left(), self.selectRect.bottom()) lr = transform.toMapCoordinates(self.selectRect.right(), self.selectRect.bottom()) ul = transform.toMapCoordinates(self.selectRect.left(), self.selectRect.top()) ur = transform.toMapCoordinates(self.selectRect.right(), self.selectRect.top()) # Rubber band self.rubberBand.reset() self.rubberBand.addPoint(ll, False) self.rubberBand.addPoint(lr, False) self.rubberBand.addPoint(ur, False) self.rubberBand.addPoint(ul, False) self.rubberBand.addPoint(ll, True) self.selectRectMapCoord = QgsRectangle(ll, ur) def select_multiple_features(self, selectGeometry): # Default choice behaviour = QgsVectorLayer.SetSelection # Modifiers modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ControlModifier: behaviour = QgsVectorLayer.AddToSelection elif modifiers == Qt.ShiftModifier: behaviour = QgsVectorLayer.RemoveFromSelection if self.vectorLayer is None: return # Change cursor QApplication.setOverrideCursor(Qt.WaitCursor) # Selection self.vectorLayer.selectByRect(selectGeometry, behaviour) # Old cursor QApplication.restoreOverrideCursor() def find_raster_layers(self): # Query database (form data) sql = "SELECT *" sql += " FROM " + self.schema_name + ".config_extract_raster_value" rows = self.controller.get_rows(sql) if not rows: self.controller.show_warning("Any data found in table config_extract_raster_value") self.configAction.activate(QAction.Trigger) return 0 # Layers row = rows[0] self.table_raster = row[1] self.band = row[2] self.table_vector = row[3] self.fieldName = row[4] # Check if we have any layer loaded layers = self.iface.legendInterface().layers() if len(layers) == 0: return # Init layers self.rasterLayer = None self.vectorLayer = None # Iterate over all layers to get the ones specified in 'db' config section for cur_layer in layers: if cur_layer.name() == self.table_raster: self.rasterLayer = cur_layer (uri_schema, uri_table) = self.controller.get_layer_source(cur_layer) # @UnusedVariable if uri_table is not None: if self.table_vector in uri_table: self.vectorLayer = cur_layer # Check config if self.vectorLayer is None or self.rasterLayer is None: self.configAction.activate(QAction.Trigger) # Set snapping if self.vectorLayer <> None: self.snapperManager.snapToLayer(self.vectorLayer) else: self.controller.show_warning("Check vector_layer in config form, layer does not exist or is not defined.") return 0 if self.rasterLayer == None: self.controller.show_warning("Check raster_layer in config form, layer does not exist or is not defined.") return 0 return 1
class InfoTool(TouchMapTool): infoResults = pyqtSignal(dict) def __init__(self, canvas, snapradius = 2): super(InfoTool, self).__init__(canvas) self.radius = snapradius self.band = QgsRubberBand(self.canvas) self.band.setColor(QColor.fromRgb(224,162,16)) self.band.setWidth(3) self.selectband = None self.selectrect = QRect() self.dragging = False self.selectionlayers = [] def getFeatures(self, rect, firstonly=False): self.band.reset() for layer in self.selectionlayers.itervalues(): if (not layer.type() == QgsMapLayer.VectorLayer or layer.geometryType() == QGis.NoGeometry): continue rect = self.toLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect)\ .setFlags(QgsFeatureRequest.ExactIntersect)\ .setSubsetOfAttributes([]) features = [] if firstonly: try: feature = layer.getFeatures(rq).next() if feature.isValid(): features.append(feature) except StopIteration: continue else: for feature in layer.getFeatures(rq): if feature.isValid(): features.append(feature) yield layer, features def toSearchRect(self, point): point = self.toMapCoordinates(point) rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10) return rect def canvasPressEvent(self, event): if self.pinching: return self.dragging = False self.selectrect.setRect(0, 0, 0, 0) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon ) self.selectband.setColor(QColor.fromRgb(0,0,255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if self.pinching: return if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.selectrect.setTopLeft(event.pos()) self.dragging = True self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.pinching: return if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() firstonly = False else: firstonly = True rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() results = OrderedDict((l,f) for l, f in self.getFeatures(rect)) self.infoResults.emit(results)
class EditTool(MapTool): """ Inspection tool which copies the feature to a new layer and copies selected data from the underlying feature. """ finished = pyqtSignal(object, QgsFeature) featuresfound = pyqtSignal(dict) def __init__(self, canvas, forms, snapradius = 2): MapTool.__init__(self, canvas, []) self.canvas = canvas self.radius = snapradius self.forms = forms self.band = QgsRubberBand(self.canvas) self.band.setColor(QColor.fromRgb(224,162,16)) self.band.setWidth(3) self.selectband = None self.selectrect = QRect() self.dragging = False self.cursor = QCursor(QPixmap(["16 16 3 1", " c None", ". c #FF0000", "+ c #FFFFFF", " ", " +.+ ", " ++.++ ", " +.....+ ", " +. .+ ", " +. . .+ ", " +. . .+ ", " ++. . .++", " ... ...+... ...", " ++. . .++", " +. . .+ ", " +. . .+ ", " ++. .+ ", " ++.....+ ", " ++.++ ", " +.+ "])) def addForm(self, form): self.forms.append(form) self.layersupdated.emit(True) def layers(self): """ Return a set of layers that this edit tool can work on """ return set([form.QGISLayer for form in self.forms]) def formsforlayer(self, layer): for form in self.forms: if form.QGISLayer == layer: yield form def reset(self): self.forms = [] self.layersupdated.emit(False) def getFeatures(self, rect): rq = QgsFeatureRequest().setFilterRect(rect) self.band.reset() for layer in self.layers(): forms = list(self.formsforlayer(layer)) rq = QgsFeatureRequest().setFilterRect(rect) for feature in layer.getFeatures(rq): if feature.isValid(): yield feature, forms def toSearchRect(self, point): searchRadius = self.canvas.extent().width() * ( self.radius / 100.0 ) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) return rect def canvasPressEvent(self, event): self.selectrect.setRect( 0, 0, 0, 0 ) self.selectband = QgsRubberBand(self.canvas, QGis.Polygon ) self.selectband.setColor(QColor.fromRgb(0,0,255, 65)) self.selectband.setWidth(5) def canvasMoveEvent(self, event): if not event.buttons() == Qt.LeftButton: return if not self.dragging: self.dragging = True self.selectrect.setTopLeft(event.pos()) self.selectrect.setBottomRight(event.pos()) maptoolutils.setRubberBand(self.canvas, self.selectrect, self.selectband) def canvasReleaseEvent(self, event): if self.dragging: geometry = self.selectband.asGeometry() if not geometry: return rect = geometry.boundingBox() else: rect = self.toSearchRect(event.pos()) self.dragging = False self.selectband.reset() features = dict(self.getFeatures(rect)) print features if len(features) == 1: feature = features.keys()[0] forms = features.values()[0] if len(forms) == 1: self.finished.emit(forms[0], feature) else: self.featuresfound.emit(features) elif len(features) > 0: self.featuresfound.emit(features) def isEditTool(self): return True
class ConnecMapTool(ParentMapTool): """ Button 20. User select connections from layer 'connec' Execute SQL function: 'gw_fct_connect_to_network' """ def __init__(self, iface, settings, action, index_action): """ Class constructor """ # Call ParentMapTool constructor super(ConnecMapTool, self).__init__(iface, settings, action, index_action) self.dragging = False # Vertex marker self.vertexMarker = QgsVertexMarker(self.canvas) self.vertexMarker.setColor(QColor(255, 25, 25)) self.vertexMarker.setIconSize(11) self.vertexMarker.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X self.vertexMarker.setPenWidth(5) # Rubber band self.rubberBand = QgsRubberBand(self.canvas, True) mFillColor = QColor(100, 0, 0) self.rubberBand.setColor(mFillColor) self.rubberBand.setWidth(3) mBorderColor = QColor(254, 58, 29) self.rubberBand.setBorderColor(mBorderColor) # Select rectangle self.selectRect = QRect() def reset(self): """ Clear selected features """ layer = self.layer_connec if layer is not None: layer.removeSelection() # Graphic elements self.rubberBand.reset() """ QgsMapTools inherited event functions """ def canvasMoveEvent(self, event): """ With left click the digitizing is finished """ if event.buttons() == Qt.LeftButton: if not self.dragging: self.dragging = True self.selectRect.setTopLeft(event.pos()) self.selectRect.setBottomRight(event.pos()) self.set_rubber_band() else: # Hide highlight self.vertexMarker.hide() # Get the click x = event.pos().x() y = event.pos().y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) # @UnusedVariable # That's the snapped point if result <> []: # Check Arc or Node for snapPoint in result: if snapPoint.layer == self.layer_connec: # Get the point point = QgsPoint(result[0].snappedVertex) # Add marker self.vertexMarker.setCenter(point) self.vertexMarker.show() break def canvasPressEvent(self, event): self.selectRect.setRect(0, 0, 0, 0) self.rubberBand.reset() def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get the click x = event.pos().x() y = event.pos().y() eventPoint = QPoint(x, y) # Node layer layer = self.layer_connec # Not dragging, just simple selection if not self.dragging: # Snap to node (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) # @UnusedVariable # That's the snapped point if result <> [] and (result[0].layer.name() == self.layer_connec.name()): point = QgsPoint(result[0].snappedVertex) # @UnusedVariable layer.removeSelection() layer.select([result[0].snappedAtGeometry]) # Create link self.link_connec() # Hide highlight self.vertexMarker.hide() else: # Set valid values for rectangle's width and height if self.selectRect.width() == 1: self.selectRect.setLeft(self.selectRect.left() + 1) if self.selectRect.height() == 1: self.selectRect.setBottom(self.selectRect.bottom() + 1) self.set_rubber_band() selectGeom = self.rubberBand.asGeometry() # @UnusedVariable self.select_multiple_features(self.selectRectMapCoord) self.dragging = False # Create link self.link_connec() elif event.button() == Qt.RightButton: # Create link self.link_connec() def activate(self): # Check button self.action().setChecked(True) # Rubber band self.rubberBand.reset() # Store user snapping configuration self.snapperManager.storeSnappingOptions() # Clear snapping self.snapperManager.clearSnapping() # Set snapping to arc and node self.snapperManager.snapToConnec() # Change cursor self.canvas.setCursor(self.cursor) # Show help message when action is activated if self.show_help: message = ( "Right click to use current selection, select connec points by clicking or dragging (selection box)" ) self.controller.show_info(message, context_name="ui_message") # Control current layer (due to QGIS bug in snapping system) try: if self.canvas.currentLayer().type() == QgsMapLayer.VectorLayer: self.canvas.setCurrentLayer(self.layer_connec) except: self.canvas.setCurrentLayer(self.layer_connec) def deactivate(self): # Check button self.action().setChecked(False) # Rubber band self.rubberBand.reset() # Restore previous snapping self.snapperManager.recoverSnappingOptions() # Recover cursor self.canvas.setCursor(self.stdCursor) def link_connec(self): """ Link selected connec to the pipe """ # Get selected features (from layer 'connec') aux = "{" layer = self.layer_connec if layer.selectedFeatureCount() == 0: message = "You have to select at least one feature!" self.controller.show_warning(message, context_name="ui_message") return features = layer.selectedFeatures() for feature in features: connec_id = feature.attribute("connec_id") aux += str(connec_id) + ", " connec_array = aux[:-2] + "}" # Execute function function_name = "gw_fct_connect_to_network" sql = "SELECT " + self.schema_name + "." + function_name + "('" + connec_array + "');" self.controller.execute_sql(sql) # Refresh map canvas self.rubberBand.reset() self.iface.mapCanvas().refresh() def set_rubber_band(self): # Coordinates transform transform = self.canvas.getCoordinateTransform() # Coordinates ll = transform.toMapCoordinates(self.selectRect.left(), self.selectRect.bottom()) lr = transform.toMapCoordinates(self.selectRect.right(), self.selectRect.bottom()) ul = transform.toMapCoordinates(self.selectRect.left(), self.selectRect.top()) ur = transform.toMapCoordinates(self.selectRect.right(), self.selectRect.top()) # Rubber band self.rubberBand.reset() self.rubberBand.addPoint(ll, False) self.rubberBand.addPoint(lr, False) self.rubberBand.addPoint(ur, False) self.rubberBand.addPoint(ul, False) self.rubberBand.addPoint(ll, True) self.selectRectMapCoord = QgsRectangle(ll, ur) def select_multiple_features(self, selectGeometry): # Default choice behaviour = QgsVectorLayer.SetSelection # Modifiers modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ControlModifier: behaviour = QgsVectorLayer.AddToSelection elif modifiers == Qt.ShiftModifier: behaviour = QgsVectorLayer.RemoveFromSelection if self.layer_connec is None: return # Change cursor QApplication.setOverrideCursor(Qt.WaitCursor) # Selection self.layer_connec.selectByRect(selectGeometry, behaviour) # Old cursor QApplication.restoreOverrideCursor()