class PolygonDrawMapVisualisation(object): def __init__(self, canvas): self.canvas = canvas self.points = [] # temp layer for side profile trac self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rb.setColor(Qt.red) self.rb.setFillColor(QColor(255, 0, 0, 64)) self.rb.setLineStyle(Qt.SolidLine) self.rb.setWidth(1) self.reset() def close(self): self.points = [] self.reset() # delete the rubberband we've been re-using self.canvas.scene().removeItem(self.rb) def show(self): self.rb.show() def hide(self): self.rb.hide() def add_point(self, point): self.points.append(point) self.rb.addPoint(point, True) self.rb.show() def reset(self): self.points = [] self.rb.reset(QgsWkbTypes.PolygonGeometry)
def getSnapRubberBand(self): rubberBand = QgsRubberBand(self.canvas, geometryType = QGis.Point) rubberBand.setFillColor(QColor(255, 0, 0, 40)) rubberBand.setBorderColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) rubberBand.setIcon(QgsRubberBand.ICON_X) return rubberBand
class MapTool(QgsMapTool): geometry_changed = pyqtSignal(QgsGeometry, bool) tool_deactivated = pyqtSignal() def __init__(self, canvas, cursorstyle=Qt.CrossCursor): self.canvas = canvas QgsMapTool.__init__(self, canvas) self.caller = self.sender() self.cursorStyle = cursorstyle self.active = False # get selection color selcolor = self.canvas.selectionColor() mycolor = QColor(selcolor.red(), selcolor.green(), selcolor.blue(), 40) self.rb = QgsRubberBand(self.canvas) self.rb.setStrokeColor(QColor(255, 0, 0, 40)) self.rb.setFillColor(mycolor) self.rb.setLineStyle(Qt.PenStyle(Qt.SolidLine)) self.rb.setWidth(2) def setCursorStyle(self): cursor = QCursor() cursor.setShape(self.cursorStyle) self.setCursor(cursor) def activate(self): self.caller.setChecked(True) self.setCursorStyle() def deactivate(self): self.canvas.scene().removeItem(self.rb) self.tool_deactivated.emit() self.caller.setChecked(False) QgsMapTool.deactivate(self) def setGeometry(self, geo): self.rb.setToGeometry(geo) def canvasReleaseEvent(self, mouseEvent): if mouseEvent.button() == Qt.LeftButton: if not self.active: self.active = True self.geometry_changed.emit(QgsGeometry(), False) self.rb.reset(QgsWkbTypes.LineGeometry) self.rb.addPoint(mouseEvent.mapPoint()) if self.rb.numberOfVertices() > 1: self.geometry_changed.emit(self.rb.asGeometry(), False) elif mouseEvent.button() == Qt.RightButton: if self.rb.numberOfVertices() > 2: self.active = False self.rb.removeLastPoint() geo = self.rb.asGeometry() self.geometry_changed.emit(geo, True) else: self.rb.reset(QgsWkbTypes.LineGeometry) def canvasMoveEvent(self, mouseEvent): if self.rb.numberOfVertices() > 1 and self.active: self.rb.removeLastPoint() self.rb.addPoint(mouseEvent.mapPoint()) pass
class GeometryDisplayer: def __init__(self, canvas ): self.canvas = canvas # main rubber self.rubber1 = QgsRubberBand(self.canvas) self.rubber1.setWidth(2) self.rubber1.setBorderColor(QColor("#f00")) self.rubber1.setFillColor(QColor("#ff6969")) # old geometry rubber self.rubber2 = QgsRubberBand(self.canvas) self.rubber2.setWidth(2) self.rubber2.setBorderColor(QColor("#bbb")) self.rubber2.setFillColor(QColor("#ccc")) def reset(self): self.rubber1.reset() self.rubber2.reset() def display(self, geom1, geom2 = None): """ @param geom1 base geometry (old geometry for an update) @param geom2 new geometry for an update """ if geom2 is None: bbox = geom1.boundingBox() self.rubber1.setToGeometry(geom1, None) else: bbox = geom1.boundingBox() bbox.combineExtentWith(geom2.boundingBox()) self.rubber1.setToGeometry(geom2, None) self.rubber2.setToGeometry(geom1, None) bbox.scale(1.5) self.canvas.setExtent(bbox)
class QgsMapToolSelectPolygon(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.mRubberBand = None self.mCursor = Qt.ArrowCursor self.mFillColor = QColor(254, 178, 76, 63) self.mBorderColour = QColor(254, 58, 29, 100) self.mCanvas = canvas def canvasPressEvent(self, e): if (self.mRubberBand == None): self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) self.mRubberBand.setFillColor(self.mFillColor) self.mRubberBand.setBorderColor(self.mBorderColour) if (e.button() == Qt.LeftButton): self.mRubberBand.addPoint(self.toMapCoordinates(e.pos())) else: if (self.mRubberBand.numberOfVertices() > 2): polygonGeom = self.mRubberBand.asGeometry() # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, polygonGeom, e ) QgsMapToolSelectUtils.setSelectFeatures1( self.mCanvas, polygonGeom, e) self.mRubberBand.reset(QGis.Polygon) self.mRubberBand = None def canvasMoveEvent(self, e): if (self.mRubberBand == None): return if (self.mRubberBand.numberOfVertices() > 0): self.mRubberBand.removeLastPoint(0) self.mRubberBand.addPoint(self.toMapCoordinates(e.pos()))
def zoomAndShowWKT(self, wtk): geom = QgsGeometry.fromWkt(wtk) canvas = self.iface.mapCanvas() self.clear() r = QgsRubberBand(canvas, geom.type() == 3 ) r.setToGeometry(geom, None) r.setColor(QColor(0, 0, 255)) r.setFillColor(QColor(0, 0, 255, 50)) r.setWidth(3) pt = geom.pointOnSurface().asPoint() m = QgsVertexMarker(canvas) m.setCenter( pt ) m.setColor(QColor(0, 0, 255)) m.setIconSize(5) m.setIconType(QgsVertexMarker.ICON_BOX) m.setPenWidth(3) if geom.type() == 3 or geom.type() == 2: rec = geom.boundingBox() canvas.setExtent(rec) else: self.moveMapTo( pt[0], pt[1], 0) self.graphics.append(r) self.graphics.append(m) self._refresh_layers()
class DrawPolygonMapTool(QgsMapTool): polygonSelected = pyqtSignal(object) def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.canvas = canvas self.extent = None self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rubberBand.setFillColor(RB_FILL) self.rubberBand.setStrokeColor(RB_STROKE) self.rubberBand.setWidth(1) self.vertex_count = 1 # two points are dropped initially def canvasReleaseEvent(self, event): if event.button() == Qt.RightButton: if self.rubberBand is None: return # TODO: validate geom before firing signal self.extent.removeDuplicateNodes() self.polygonSelected.emit(self.extent) self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) del self.rubberBand self.rubberBand = None self.vertex_count = 1 # two points are dropped initially return elif event.button() == Qt.LeftButton: if self.rubberBand is None: self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rubberBand.setFillColor(RB_FILL) self.rubberBand.setStrokeColor(RB_STROKE) self.rubberBand.setWidth(1) self.rubberBand.addPoint(event.mapPoint()) self.extent = self.rubberBand.asGeometry() self.vertex_count += 1 def canvasMoveEvent(self, event): if self.rubberBand is None: pass elif not self.rubberBand.numberOfVertices(): pass elif self.rubberBand.numberOfVertices() == self.vertex_count: if self.vertex_count == 2: mouse_vertex = self.rubberBand.numberOfVertices() - 1 self.rubberBand.movePoint(mouse_vertex, event.mapPoint()) else: self.rubberBand.addPoint(event.mapPoint()) else: mouse_vertex = self.rubberBand.numberOfVertices() - 1 self.rubberBand.movePoint(mouse_vertex, event.mapPoint()) def deactivate(self): QgsMapTool.deactivate(self) if self.rubberBand is not None: self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) self.deactivated.emit()
class MapTool(QgsMapTool): geometry_changed = pyqtSignal(QgsGeometry,bool) tool_deactivated = pyqtSignal() def __init__(self, canvas, cursorstyle = Qt.CrossCursor): self.canvas = canvas QgsMapTool.__init__(self, canvas) self.caller = self.sender() self.cursorStyle=cursorstyle self.active = False self.center=None # get selection color selcolor =self.canvas.selectionColor() mycolor = QColor(selcolor.red(), selcolor.green(), selcolor.blue(), 40) self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rb.setStrokeColor(QColor(255, 0, 0, 40)) self.rb.setFillColor(mycolor) self.rb.setLineStyle(Qt.PenStyle(Qt.SolidLine)) self.rb.setWidth(2) def setCursorStyle(self): cursor = QCursor() cursor.setShape(self.cursorStyle) self.setCursor(cursor) def activate(self): self.caller.setChecked(True) self.setCursorStyle() def deactivate(self): self.canvas.scene().removeItem(self.rb) self.tool_deactivated.emit() self.caller.setChecked(False) QgsMapTool.deactivate(self) def setGeometry(self,geo): self.rb.setToGeometry(geo) def canvasReleaseEvent(self, mouseevent): if mouseevent.button() == Qt.LeftButton: self.active = False self.geometry_changed.emit(self.rb.asGeometry(),True) pass def canvasMoveEvent(self, mouseEvent): if self.active: cp = self.toMapCoordinates(mouseEvent.pos()) rec = QgsRectangle(self.center, cp) self.rb.setToGeometry(QgsGeometry.fromRect(rec)) self.geometry_changed.emit(self.rb.asGeometry(),True) pass def canvasPressEvent(self, e): if e.button() == Qt.LeftButton: self.active = True self.center = self.toMapCoordinates(e.pos()) self.geometry_changed.emit(QgsGeometry(),False) self.rb.reset() pass
def crearNuevoRubberLinea(self): nuevoRubber = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry) nuevoRubber.setFillColor(QColor(0,0,0,0)) nuevoRubber.setStrokeColor(QColor(0,62,240,255)) nuevoRubber.setWidth(2) #penStyle = Qt.PenStyle() nuevoRubber.setLineStyle(Qt.PenStyle(3)) return nuevoRubber
def getSnapRubberBand(self): rubberBand = QgsRubberBand(self.canvas, geometryType=QgsWkbTypes.PointGeometry) rubberBand.setFillColor(QColor(255, 0, 0, 40)) rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) rubberBand.setIcon(QgsRubberBand.ICON_X) return rubberBand
class CoordsTool(QgsMapToolEmitPoint): def __init__(self, canvas, dialog=None): QgsMapToolEmitPoint.__init__(self, canvas) self.canvas = canvas self.dialog = dialog if dialog is not None: self.dialog.hide() self.rubberBand = QgsRubberBand(canvas, True) self.rubberBand.setColor(Qt.red) self.rubberBand.setFillColor(Qt.red) self.rubberBand.setWidth(1) self.start_point = None self.end_point = None self.is_activated = False def canvasReleaseEvent(self, event): """Release left click => reopen dialog window and set end point with the bb coordinates""" self.end_point = self.toMapCoordinates(event.pos()) self.is_activated = False self.rubberBand.reset() if self.dialog is not None: self.dialog.show() def canvasPressEvent(self, event): self.start_point = self.toMapCoordinates(event.pos()) self.is_activated = True def canvasMoveEvent(self, event): if self.is_activated: self.end_point = self.toMapCoordinates(event.pos()) self.show_rect() def show_rect(self): self.rubberBand.reset() point1 = QgsPointXY(self.start_point.x(), self.start_point.y()) point2 = QgsPointXY(self.start_point.x(), self.end_point.y()) point3 = QgsPointXY(self.end_point.x(), self.end_point.y()) point4 = QgsPointXY(self.end_point.x(), self.start_point.y()) self.rubberBand.addPoint(point1, False) self.rubberBand.addPoint(point2, False) self.rubberBand.addPoint(point3, False) self.rubberBand.addPoint(point4, True) # true to update canvas self.rubberBand.show() def get_data(self): return [ (self.start_point.x(), self.start_point.y()), (self.end_point.x(), self.end_point.y()), ] def set_data(self, data): self.start_point = QgsPointXY(*data[0]) self.end_point = QgsPointXY(*data[1])
def init_rubberband(color, lineStyle, alphaF, width, bandType, canvas): """initiate the rubberbands""" rubberBand = QgsRubberBand(canvas, bandType) rubberBand.setStrokeColor(color) color.setAlpha(alphaF) rubberBand.setFillColor(color) rubberBand.setLineStyle(lineStyle) rubberBand.setWidth(width) return rubberBand
def getRubberBand(self): geomType = self.iface.activeLayer().geometryType() if geomType == QGis.Polygon: rubberBand = QgsRubberBand(self.canvas, True) rubberBand.setFillColor(QColor(255, 0, 0, 40)) elif geomType == QGis.Line: rubberBand = QgsRubberBand(self.canvas, False) rubberBand.setBorderColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) return rubberBand
def getRubberBand(self): geomType = self.iface.activeLayer().geometryType() if geomType == QgsWkbTypes.PolygonGeometry: rubberBand = QgsRubberBand(self.canvas, True) rubberBand.setFillColor(QColor(255, 0, 0, 40)) elif geomType == QgsWkbTypes.LineGeometry: rubberBand = QgsRubberBand(self.canvas, False) rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200)) rubberBand.setWidth(2) return rubberBand
def initRubberLayer(self): if self.rubberLayer: rb = self.rubberLayer rb.reset(True) else: rb = QgsRubberBand(self.iface.mapCanvas(), True) rb.setColor(QColor(255, 0, 255, 255)) rb.setWidth(3) rb.setFillColor(QColor(255, 0, 255, 50)) self.rubberLayer = rb
def init_rubberband(styleName, canvas, rbType): """initiate the rubberbands""" rbStyle = RBSTYLES[styleName] rubberBand = QgsRubberBand(canvas, getWKBType(rbType)) rubberBand.setStrokeColor(rbStyle["strokecolor"]) rbStyle["fillcolor"].setAlpha(rbStyle["alphaF"]) rubberBand.setFillColor(rbStyle["fillcolor"]) rubberBand.setLineStyle(rbStyle["linestyle"]) rubberBand.setWidth(rbStyle["strokewidth"]) return rubberBand
class MapTool(QgsMapToolIdentify): geometry_changed = pyqtSignal(QgsGeometry, bool) tool_deactivated = pyqtSignal() def __init__(self, canvas, cursorstyle=Qt.CrossCursor): self.canvas = canvas QgsMapTool.__init__(self, canvas) self.caller = self.sender() self.cursorStyle = cursorstyle self.active = False # get selection color selcolor = self.canvas.selectionColor() mycolor = QColor(selcolor.red(), selcolor.green(), selcolor.blue(), 40) self.rb = QgsRubberBand(self.canvas) self.rb.setStrokeColor(QColor(255, 0, 0, 40)) self.rb.setFillColor(mycolor) self.rb.setLineStyle(Qt.PenStyle(Qt.SolidLine)) self.rb.setWidth(2) self.center = None self.cercle = 120 #circle of 30 segments def setCursorStyle(self): cursor = QCursor() cursor.setShape(self.cursorStyle) self.setCursor(cursor) def activate(self): self.caller.setChecked(True) self.setCursorStyle() def deactivate(self): self.canvas.scene().removeItem(self.rb) self.tool_deactivated.emit() self.caller.setChecked(False) QgsMapTool.deactivate(self) def setGeometry(self, geo): self.rb.setToGeometry(geo) def canvasReleaseEvent(self, mouseEvent): self.geometry_changed.emit(QgsGeometry(), False) if mouseEvent.button() == Qt.LeftButton: results = self.identify(mouseEvent.x(), mouseEvent.y(), self.ActiveLayer, self.VectorLayer) for res in results: if res.mFeature and res.mLayer: geo = res.mFeature.geometry() self.rb.setToGeometry(geo) self.geometry_changed.emit(geo, True) break pass
class RubberBandPolygon(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.mCanvas = canvas self.mRubberBand = None self.mRubberBand0 = QgsRubberBand(self.mCanvas, QGis.Polygon) self.mCursor = Qt.ArrowCursor self.mFillColor = QColor(254, 178, 76, 63) self.mBorderColour = QColor(254, 58, 29, 100) self.mRubberBand0.setBorderColor(self.mBorderColour) self.polygonGeom = None self.drawFlag = False # self.constructionLayer = constructionLayer def canvasPressEvent(self, e): if (self.mRubberBand == None): self.mRubberBand0.reset(QGis.Polygon) # define._canvas.clearCache () self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) self.mRubberBand0 = QgsRubberBand(self.mCanvas, QGis.Polygon) self.mRubberBand.setFillColor(self.mFillColor) self.mRubberBand.setBorderColor(self.mBorderColour) self.mRubberBand0.setFillColor(self.mFillColor) self.mRubberBand0.setBorderColor(self.mBorderColour) if (e.button() == Qt.LeftButton): self.mRubberBand.addPoint(self.toMapCoordinates(e.pos())) else: if (self.mRubberBand.numberOfVertices() > 2): self.polygonGeom = self.mRubberBand.asGeometry() else: return # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, polygonGeom, e ) self.mRubberBand.reset(QGis.Polygon) self.mRubberBand0.addGeometry(self.polygonGeom, None) self.mRubberBand0.show() self.mRubberBand = None self.emit(SIGNAL("outputResult"), self.polygonGeom) def canvasMoveEvent(self, e): pass if (self.mRubberBand == None): return if (self.mRubberBand.numberOfVertices() > 0): self.mRubberBand.removeLastPoint(0) self.mRubberBand.addPoint(self.toMapCoordinates(e.pos())) def deactivate(self): # self.rubberBand.reset(QGis.Point) QgsMapTool.deactivate(self) self.emit(SIGNAL("deactivated()"))
def crearNuevoRubberPoly(self): nuevoRubber = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) r = randint(0, 255) g = randint(0, 255) b = randint(0, 255) color = QColor(r,g,b,36) colorAg = QColor(r,g,b,87) self.pluginM.listaColores.append(colorAg) nuevoRubber.setFillColor(color) nuevoRubber.setStrokeColor(QColor(r,g,b,255)) nuevoRubber.setWidth(2) return nuevoRubber
def update_map(self, north, east, south, west): """ This updates the map to add the new bounding box specified by the north, east, south, west parameters. :param north: The name of the north point :param east: The name of the east point :param south: The name of the south point :param west: The name of the west point :return: """ from qgis.utils import iface from qgis.PyQt.QtCore import Qt # Creates map canvas within the widget in the window canvas = QgsMapCanvas(self.dlg.QgsMapCanvas_wid) canvas.setMinimumSize(460, 250) # Gets the basemap from the server and displays only that layer canvas_layer_list = [self.raster, self.raster] canvas.setLayers(canvas_layer_list) # Sets the coordinate reference system crsDest = QgsCoordinateReferenceSystem(4326) # destination crsSrc = canvas.mapSettings().destinationCrs() # source xform = QgsCoordinateTransform() xform.setSourceCrs(crsSrc) xform.setDestinationCrs(crsDest) canvas.setDestinationCrs(crsDest) # Creating the rubber band rectangle r = QgsRubberBand(canvas, True) # True = a polygon # Sepcifying the points of rectangle points = [[ QgsPointXY(west, north), QgsPointXY(east, north), QgsPointXY(east, south), QgsPointXY(west, south) ]] r.setToGeometry(QgsGeometry.fromPolygonXY(points), None) r.setFillColor(QColor(255, 0, 0, 50)) #R,G,B,Transparency r.setWidth(3) canvas.zoomWithCenter(north - south, east - west, True) canvas.setExtent(self.raster.extent()) canvas.zoomToFullExtent() canvas.zoomScale(2000000000) # scaling for tmp raster #canvas.zoomWithCenter(north-south,east-west,True) canvas.show()
def create(self, canvas, line_width=2, rbs_in="main_dialog"): """Create the tile as a rubber band inside the canvas given""" rubber_band = QgsRubberBand(canvas) points = [QgsPointXY(self.xmin, self.ymax), QgsPointXY(self.xmax, self.ymax), QgsPointXY(self.xmax, self.ymin), QgsPointXY(self.xmin, self.ymin)] rubber_band.setToGeometry(QgsGeometry.fromPolygonXY([points]), None) if rbs_in == "highlight": rubber_band.setColor(QColor("yellow")) else: rubber_band.setColor(self.tile_color) rubber_band.setFillColor(QColor(0, 0, 0, 0)) rubber_band.setWidth(line_width) rubber_band.show() if rbs_in == "main_dialog": self.rbs_in_main_dialog.append(rubber_band) if rbs_in == "nav_dialog": self.rbs_in_nav_dialog.append(rubber_band) if rbs_in == "highlight": return rubber_band
def showSectionsInOverview(self): # clear existing rubberbands for rb in self.sectionsRbs: self.iface.mapCanvas().scene().removeItem(rb) self.sectionsRbs = [] # add new rubberbands for id, sec in enumerate(self.WSMProj.sections): rb = QgsRubberBand(self.iface.mapCanvas(), False) rb_geom = QgsGeometry() rb_geom.fromWkb(sec.aoi) rb.setToGeometry(rb_geom, None) if id == self.currbox.value(): fc = QtGui.QColor(self.colors[-1]) else: fc = QtGui.QColor(self.colors[min(sec.status, 1)]) rb.setColor(fc) fc.setAlpha(128) rb.setFillColor(fc) rb.setWidth(1) self.sectionsRbs.append(rb)
class GeometryDisplayer: def __init__(self, canvas): self.canvas = canvas # main rubber self.rubber1 = QgsRubberBand(self.canvas) self.rubber1.setWidth(2) self.rubber1.setStrokeColor(self.newGeometryColor()) self.rubber1.setFillColor(self.newGeometryColor()) # old geometry rubber self.rubber2 = QgsRubberBand(self.canvas) self.rubber2.setWidth(2) self.rubber2.setStrokeColor(self.oldGeometryColor()) self.rubber2.setFillColor(self.oldGeometryColor()) def reset(self): self.rubber1.reset() self.rubber2.reset() def oldGeometryColor(self): return QColor("#ff5733") def newGeometryColor(self): return QColor("#00f") def display(self, geom1, geom2=None): """ @param geom1 base geometry (old geometry for an update) @param geom2 new geometry for an update """ if geom2 is None: bbox = geom1.boundingBox() self.rubber1.setToGeometry(geom1, None) else: bbox = geom1.boundingBox() bbox.combineExtentWith(geom2.boundingBox()) self.rubber1.setToGeometry(geom2, None) self.rubber2.setToGeometry(geom1, None) bbox.scale(1.5) self.canvas.setExtent(bbox)
def highlight(self,geometry): def processEvents(): try: qApp.processEvents() except: QApplication.processEvents() highlight = QgsRubberBand(self.canvas, geometry.type()) highlight.setColor(QColor("#36AF6C")) highlight.setFillColor(QColor("#36AF6C")) highlight.setWidth(2) highlight.setToGeometry(geometry,self.canvas.currentLayer()) processEvents() sleep(.1) highlight.hide() processEvents() sleep(.1) highlight.show() processEvents() sleep(.1) highlight.reset() processEvents()
def method_9(self): if self.selectedModelIndex == None: self.ui.frame_Track.setVisible(False) return else: selectedArea = self.complexObstacleArea[self.selectedModelIndex.row()] QgisHelper.ClearRubberBandInCanvas(define._canvas) rBand = QgsRubberBand(define._canvas, QGis.Polygon) for point in selectedArea.PreviewArea.method_14_closed(): rBand.addPoint(point) rBand.setFillColor( QColor(46, 64, 142, 100) ) rBand.setBorderColor( QColor(0, 10, 238) ) rBand.show() if not isinstance(selectedArea, SecondaryObstacleArea) or not isinstance(selectedArea.area, SecondaryAreaStraight): self.ui.frame_Track.setVisible(False) return else: self.ui.txtTrack.setText(str(round(Unit.smethod_1(selectedArea.nominalTrack), 4))); self.ui.frame_Track.setVisible(True)
def highlight(self,geometry): def processEvents(): try: QtGui.qApp.processEvents() except: QtWidgets.QApplication.processEvents() highlight = QgsRubberBand(self.iface.mapCanvas(), geometry.type()) highlight.setColor(QtGui.QColor("#36AF6C")) highlight.setFillColor(QtGui.QColor("#36AF6C")) highlight.setWidth(2) highlight.setToGeometry(geometry,self.iface.mapCanvas().currentLayer()) processEvents() sleep(.1) highlight.hide() processEvents() sleep(.1) highlight.show() processEvents() sleep(.1) highlight.reset() processEvents()
class QgsMapToolSelectFreehand(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.mRubberBand = None self.mCursor = Qt.ArrowCursor self.mFillColor = QColor(254, 178, 76, 63) self.mBorderColour = QColor(254, 58, 29, 100) self.mDragging = False self.mCanvas = canvas def canvasPressEvent(self, e): if (e.button() != Qt.LeftButton): return if (self.mRubberBand == None): self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) self.mRubberBand.setFillColor(self.mFillColor) self.mRubberBand.setBorderColor(self.mBorderColour) self.mRubberBand.addPoint(self.toMapCoordinates(e.pos())) self.mDragging = True def canvasMoveEvent(self, e): if (not self.mDragging or self.mRubberBand == None): return self.mRubberBand.addPoint(self.toMapCoordinates(e.pos())) def canvasReleaseEvent(self, e): selectedFeatures = [] if (self.mRubberBand == None): return if (self.mRubberBand.numberOfVertices() > 2): shapeGeom = self.mRubberBand.asGeometry() selectedFeatures = QgsMapToolSelectUtils.setSelectFeatures1( self.mCanvas, shapeGeom, e) self.mRubberBand.reset(QGis.Polygon) self.mRubberBand = None self.mDragging = False self.emit(SIGNAL("getSelectFeatures"), selectedFeatures)
class DailyImagesSearchResultsWidget(RESULTS_BASE, RESULTS_WIDGET): setAOIRequested = pyqtSignal(dict) checkedCountChanged = pyqtSignal(int) def __init__(self): super().__init__() self.setupUi(self) self._p_client = PlanetClient.getInstance() self._has_more = True self._metadata_to_show = [ PlanetNodeMetadata.CLOUD_PERCENTAGE, PlanetNodeMetadata.GROUND_SAMPLE_DISTANCE, ] self._image_count = 0 self._total_count = 0 self._request = None self._local_filters = None self._response_iterator = None self.btnSaveSearch.setIcon(SAVE_ICON) self.btnSort.setIcon(SORT_ICON) self.btnAddPreview.setIcon(ADD_PREVIEW_ICON) self.btnAddPreview.setEnabled(False) self.btnSaveSearch.clicked.connect(self._save_search) self.btnAddPreview.clicked.connect(self._add_preview_clicked) self.btnSort.clicked.connect(self._sort_order_changed) self.btnSettings.clicked.connect(self._open_settings) self.lblImageCount.setOpenExternalLinks(False) self.lblImageCount.linkActivated.connect(self.load_more_link_clicked) self._aoi_box = None self._setup_request_aoi_box() self._set_widgets_visibility(False) def _set_widgets_visibility(self, search_ok): self.tree.setVisible(search_ok) self.widgetActions.setVisible(search_ok) self.widgetNoResults.setVisible(not search_ok) def search_has_been_performed(self): return self._request is not None def _open_settings(self): dlg = ResultsConfigurationDialog(self._metadata_to_show) if dlg.exec_(): self._metadata_to_show = dlg.selection self.update_image_items() def _add_preview_clicked(self): self.add_preview() @waitcursor def add_preview(self): imgs = self.selected_images() send_analytics_for_preview(imgs) create_preview_group("Selected images", imgs) def update_image_items(self): it = QTreeWidgetItemIterator(self.tree) while it.value(): item = it.value() if isinstance(item, SceneItem): w = self.tree.itemWidget(item, 0) w.set_metadata_to_show(self._metadata_to_show) it += 1 def _save_search(self): dlg = SaveSearchDialog(self._request) if dlg.exec_(): self._p_client.create_search(dlg.request_to_save) analytics_track(SAVED_SEARCH_CREATED) def sort_order(self): order = ["acquired"] if self.btnSort.isChecked(): order.append("asc") else: order.append("desc") return order def _sort_order_changed(self): self.update_request(self._request, {}) def load_more_link_clicked(self): self.load_more() @waitcursor def update_request(self, request, local_filters): self._image_count = 0 self._request = request self._local_filters = local_filters self.tree.clear() stats_request = {"interval": "year"} stats_request.update(self._request) resp = self._p_client.stats(stats_request).get() self._total_count = sum([b["count"] for b in resp["buckets"]]) if self._total_count: response = self._p_client.quick_search( self._request, page_size=TOP_ITEMS_BATCH, sort=" ".join(self.sort_order()), ) self._response_iterator = response.iter() self.load_more() self._set_widgets_visibility(True) else: self._set_widgets_visibility(False) @waitcursor def load_more(self): page = next(self._response_iterator, None) if page is not None: for i in range(self.tree.topLevelItemCount()): date_item = self.tree.topLevelItem(i) date_widget = self.tree.itemWidget(date_item, 0) date_widget.has_new = False for j in range(date_item.childCount()): satellite_item = date_item.child(j) satellite_widget = self.tree.itemWidget(satellite_item, 0) satellite_widget.has_new = False links = page.get()[page.LINKS_KEY] next_ = links.get(page.NEXT_KEY, None) self._has_more = next_ is not None images = page.get().get(page.ITEM_KEY) for i, image in enumerate(images): if self._passes_area_coverage_filter(image): sort_criteria = "acquired" date_item, satellite_item = self._find_items_for_satellite( image) date_widget = self.tree.itemWidget(date_item, 0) satellite_widget = self.tree.itemWidget(satellite_item, 0) item = SceneItem(image, sort_criteria) widget = SceneItemWidget( image, sort_criteria, self._metadata_to_show, item, self._request, ) widget.checkedStateChanged.connect( self.checked_count_changed) widget.thumbnailChanged.connect( satellite_widget.update_thumbnail) item.setSizeHint(0, widget.sizeHint()) satellite_item.addChild(item) self.tree.setItemWidget(item, 0, widget) date_widget.update_for_children() self._image_count += 1 for i in range(self.tree.topLevelItemCount()): date_item = self.tree.topLevelItem(i) date_widget = self.tree.itemWidget(date_item, 0) for j in range(date_item.childCount()): satellite_item = date_item.child(j) satellite_widget = self.tree.itemWidget(satellite_item, 0) satellite_widget.update_for_children() satellite_widget.update_thumbnail() satellite_item.sortChildren(0, Qt.AscendingOrder) date_widget.update_for_children() date_widget.update_thumbnail() self.item_count_changed() else: self._has_more = False self.item_count_changed() def _local_filter(self, name): for f in self._local_filters: if f.get("field_name") == name: return f def _passes_area_coverage_filter(self, image): area_coverage = area_coverage_for_image(image, self._request) if area_coverage is None: return True # an ID filter is begin used, so it makes no sense to # check for are acoverage filt = self._local_filter("area_coverage") if filt: minvalue = filt["config"].get("gte", 0) maxvalue = filt["config"].get("lte", 100) return area_coverage > minvalue and area_coverage < maxvalue return True def _find_item_for_date(self, image): sort_criteria = "acquired" date = iso8601.parse_date(image[PROPERTIES][sort_criteria]).date() itemtype = image[PROPERTIES][ITEM_TYPE] count = self.tree.topLevelItemCount() for i in range(count): child = self.tree.topLevelItem(i) if child.date == date and child.itemtype == itemtype: return child date_item = DateItem(image, sort_criteria) widget = DateItemWidget(image, sort_criteria, date_item) widget.checkedStateChanged.connect(self.checked_count_changed) date_item.setSizeHint(0, widget.sizeHint()) self.tree.addTopLevelItem(date_item) self.tree.setItemWidget(date_item, 0, widget) return date_item def _find_items_for_satellite(self, image): date_item = self._find_item_for_date(image) date_widget = self.tree.itemWidget(date_item, 0) satellite = image[PROPERTIES][SATELLITE_ID] instrument = image[PROPERTIES].get(INSTRUMENT, "") count = date_item.childCount() for i in range(count): child = date_item.child(i) if child.satellite == satellite: return date_item, child satellite_item = SatelliteItem(satellite) widget = SatelliteItemWidget(satellite, instrument, satellite_item) widget.thumbnailChanged.connect(date_widget.update_thumbnail) widget.checkedStateChanged.connect(self.checked_count_changed) satellite_item.setSizeHint(0, widget.sizeHint()) date_item.addChild(satellite_item) self.tree.setItemWidget(satellite_item, 0, widget) return date_item, satellite_item def selected_images(self): selected = [] it = QTreeWidgetItemIterator(self.tree) while it.value(): item = it.value() if isinstance(item, SceneItem): w = self.tree.itemWidget(item, 0) w.set_metadata_to_show(self._metadata_to_show) if w.is_selected(): selected.append(w.image) it += 1 return selected def checked_count_changed(self): numimages = len(self.selected_images()) self.btnAddPreview.setEnabled(numimages) self.checkedCountChanged.emit(numimages) def item_count_changed(self): if self._image_count < self._total_count: self.lblImageCount.setText( f"{self._image_count} images. <a href='#'>Load more</a>") else: self.lblImageCount.setText(f"{self._image_count} images") def _setup_request_aoi_box(self): self._aoi_box = QgsRubberBand(iface.mapCanvas(), QgsWkbTypes.PolygonGeometry) self._aoi_box.setFillColor(QColor(0, 0, 0, 0)) self._aoi_box.setStrokeColor(SEARCH_AOI_COLOR) self._aoi_box.setWidth(2) self._aoi_box.setLineStyle(Qt.DashLine) @pyqtSlot() def clear_aoi_box(self): if self._aoi_box: self._aoi_box.reset(QgsWkbTypes.PolygonGeometry) def clean_up(self): self.clear_aoi_box() self.tree.clear() self.lblImageCount.setText("") self._set_widgets_visibility(False) def closeEvent(self, event): self.clean_up() super().closeEvent(self, event) def request_query(self): return self._request
class addPolygon(QgsMapTool): cut = pyqtSignal() deact = pyqtSignal() def __init__(self, iface, action, geometryClass): self.canvas = iface.mapCanvas() self.iface = iface self.action = action self.geometryClass = geometryClass obj_color = QColor(254, 0, 0) obj_color_alpha = QColor(254, 0, 0) obj_color_alpha.setAlpha(60) vert_color = QColor(0, 0, 255) QgsMapTool.__init__(self, self.canvas) self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.GeometryType(3)) self.rubberBand.setWidth(1) self.rubberBand.setStrokeColor(obj_color) self.rubberBand.setFillColor(obj_color_alpha) self.rubberBand_click = QgsRubberBand(self.canvas, QgsWkbTypes.GeometryType(3)) self.rubberBand_click.setWidth(0) self.rubberBand_click.setFillColor(obj_color_alpha) # snap marker self.snap_mark = QgsVertexMarker(self.canvas) self.snap_mark.setColor(vert_color) self.snap_mark.setPenWidth(2) self.snap_mark.setIconType(QgsVertexMarker.ICON_BOX) self.snap_mark.setIconSize(10) self.points = [] def activate(self): self.action.setChecked(True) self.setCursor(Qt.CrossCursor) def canvasMoveEvent(self, e): self.snap_mark.hide() self.snapPoint = False self.snapPoint = self.checkSnapToPoint(e.pos()) if self.snapPoint[0]: self.snap_mark.setCenter(self.snapPoint[1]) self.snap_mark.show() if len(self.points) > 0: self.rubberBand.reset(QgsWkbTypes.GeometryType(3)) point = self.toMapCoordinates(self.canvas.mouseLastXY()) temp_points = self.points[:] temp_points.append(point) polygon = QgsGeometry.fromPolygonXY([temp_points]) self.rubberBand.setToGeometry(polygon, None) self.rubberBand.show() def canvasPressEvent(self, e): # Left mouse button if e.button() == Qt.LeftButton: if self.snapPoint[0]: point = self.snapPoint[1] else: point = self.toMapCoordinates(self.canvas.mouseLastXY()) self.points.append(point) polygon = QgsGeometry.fromPolygonXY([self.points]) self.rubberBand_click.reset(QgsWkbTypes.GeometryType(3)) self.rubberBand_click.setToGeometry(polygon, None) self.rubberBand_click.show() # Right mouse button if e.button() == Qt.RightButton: geometry = QgsGeometry.fromPolygonXY([self.points]) self.geometryClass.geometry = geometry self.cut.emit() self.reset() def checkSnapToPoint(self, point): snapped = False snap_point = self.toMapCoordinates(point) snapper = self.canvas.snappingUtils() snapMatch = snapper.snapToMap(point) if snapMatch.hasVertex(): snap_point = snapMatch.point() snapped = True return snapped, snap_point def deactivate(self): self.action.setChecked(False) self.reset() self.deact.emit() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.reset() def reset(self): self.rubberBand_click.reset(QgsWkbTypes.GeometryType(3)) self.rubberBand.reset(QgsWkbTypes.GeometryType(3)) self.snap_mark.hide() self.points = []
class MapToolSelect(QgsMapTool): ''' Based on the QGIS select tool ''' featuresSelected = pyqtSignal() def __init__(self, canvas): super(MapToolSelect, self).__init__(canvas) self.canvas = canvas self.cursor = QgsApplication.getThemeCursor(QgsApplication.Select) self.rubberBand = None self.dragStart = None self.selectionActive = False def activate(self): super(MapToolSelect, self).activate() self.canvas.setCursor(self.cursor) def deactivate(self): super(MapToolSelect, self).deactivate() self.canvas.unsetCursor() def canvasPressEvent(self, event): if self.rubberBand is None: self.initRubberBand() self.dragStart = event.pos() def canvasMoveEvent(self, event): if event.buttons() != Qt.LeftButton: return r = QRect() if not self.selectionActive: self.selectionActive = True rect = QRect(event.pos(), event.pos()) else: rect = QRect(event.pos(), self.dragStart) if self.rubberBand is not None: self.rubberBand.setToCanvasRectangle(rect) def canvasReleaseEvent(self, event): point = event.pos() - self.dragStart if not self.selectionActive or (point.manhattanLength() < QApplication.startDragDistance()): self.selectionActive = False self.selectFeatures(QgsGeometry.fromPointXY(self.toMapCoordinates(event.pos())), event.modifiers()) if self.rubberBand is not None and self.selectionActive: self.selectFeatures(self.rubberBand.asGeometry(), event.modifiers()) self.rubberBand.reset() self.selectionActive = False self.featuresSelected.emit() def initRubberBand(self): self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rubberBand.setFillColor(FILL_COLOR) self.rubberBand.setStrokeColor(STROKE_COLOR) def selectFeatures(self, geometry, modifiers): if geometry.type() == QgsWkbTypes.PointGeometry: layer = self.canvas.currentLayer() # TODO: check layer validity rect = self.expandSelectRectangle(geometry.asPoint(), layer) self.selectSingleFeature(QgsGeometry.fromRect(rect), modifiers) else: self.selectMultipleFeatures(geometry, modifiers) def expandSelectRectangle(self, mapPoint, layer): boxSize = 0 if layer is None or layer.geometryType() != QgsWkbTypes.PolygonGeometry: # for lines and points make rectangle to simplify selection boxSize = 5 else: boxSize = 1 transform = self.canvas.getCoordinateTransform() point = transform.transform(mapPoint) ll = transform.toMapCoordinates(point.x() - boxSize, point.y() + boxSize) ur = transform.toMapCoordinates(point.x() + boxSize, point.y() - boxSize) return QgsRectangle(ll, ur) def selectSingleFeature(self, geometry, modifiers): layer = self.canvas.currentLayer() # TODO: check layer validity QApplication.setOverrideCursor(Qt.WaitCursor) selectedFeatures = self.getMatchingFeatures(geometry, False, True) if len(selectedFeatures) == 0: if not (modifiers & Qt.ShiftModifier or modifiers & Qt.ControlModifier): layer.removeSelection() QApplication.restoreOverrideCursor() return behavior = QgsVectorLayer.SetSelection if modifiers & Qt.ShiftModifier or modifiers & Qt.ControlModifier: # either shift or control modifier switches to "toggle" selection mode selectId = selectedFeatures[0] layerSelectedFeatures = layer.selectedFeatureIds() if selectId in layerSelectedFeatures: behavior = QgsVectorLayer.RemoveFromSelection else: behavior = QgsVectorLayer.AddToSelection layer.selectByIds(selectedFeatures, behavior) QApplication.restoreOverrideCursor() def selectMultipleFeatures(self, geometry, modifiers): behavior = QgsVectorLayer.SetSelection if modifiers & Qt.ShiftModifier and modifiers & Qt.ControlModifier: behavior = QgsVectorLayer.IntersectSelection elif modifiers & Qt.ShiftModifier: behavior = QgsVectorLayer.AddToSelection elif modifiers & Qt.ControlModifier: behavior = QgsVectorLayer.RemoveFromSelection contains = modifiers & Qt.AltModifier self.setSelectedFeatures(geometry, behavior, contains) def setSelectedFeatures(self, geometry, behavior=QgsVectorLayer.SetSelection, contains=True, singleSelect=False): layer = self.canvas.currentLayer() #TODO: check layer validity QApplication.setOverrideCursor(Qt.WaitCursor) selectedFeatures = self.getMatchingFeatures(geometry, contains, singleSelect) layer.selectByIds(selectedFeatures, behavior) QApplication.restoreOverrideCursor() def getMatchingFeatures(self, geometry, contains, singleSelect): newFeatures = [] if geometry.type() != QgsWkbTypes.PolygonGeometry: return newFeatures layer = self.canvas.currentLayer() if layer is None: return newFeatures selectGeomTrans = QgsGeometry(geometry) try: ct = QgsCoordinateTransform(self.canvas.mapSettings().destinationCrs(), layer.crs(), QgsProject.instance()) if not ct.isShortCircuited() and selectGeomTrans.type() == QgsWkbTypes.PolygonGeometry: poly = selectGeomTrans.asPolygon() if len(poly) == 1 and len(poly[0]) == 5: ringIn = poly[0] ringOut = [] ringOut.append(ringIn[0]) i = 1 for j in range(1, 5): v = QgsVector((ringIn[j] - ringIn[j - 1]) / 10.0) for k in range(9): ringOut.append(ringOut[i - 1] + v) i += 1 ringOut.append(ringIn[j]) i += 1 selectGeomTrans = QgsGeometry.fromPolygonXY([ringOut]) selectGeomTrans.transform(ct) except QgsCsException as e: QgsMessageLog.logMessage("Selection extends beyond layer's coordinate system") return newFeatures context = QgsRenderContext.fromMapSettings(self.canvas.mapSettings()) context.expressionContext().appendScope(QgsExpressionContextUtils.layerScope(layer)) r = None if layer.renderer(): r = layer.renderer().clone() r.startRender(context, layer.fields()) request = QgsFeatureRequest() request.setFilterRect(selectGeomTrans.boundingBox()) request.setFlags(QgsFeatureRequest.ExactIntersect) if r: request.setSubsetOfAttributes(r.usedAttributes(context), layer.fields()) else: request.setSubsetOfAttributes([]) closestFeatureId = 0 foundSingleFeature = False closestFeatureDist = sys.float_info.max for f in layer.getFeatures(request): context.expressionContext().setFeature(f) if r and not r.willRenderFeature(f, context): continue g = f.geometry() if contains: if not selectGeomTrans.contains(g): continue else: if not selectGeomTrans.intersects(g): continue if singleSelect: foundSingleFeature = True distance = g.distance(selectGeomTrans) if distance <= closestFeatureDist: closestFeatureDist = distance closestFeatureId = f.id() else: newFeatures.append(f.id()) if singleSelect and foundSingleFeature: newFeatures.append(closestFeatureId) if r: r.stopRender(context) return newFeatures
class GeometryTool(QgsMapTool): def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.dlg = GeometryShapesDialog() self.capturing = False self.startPoint = None self.endPoint = None self.rubberBand = None self.helperBand = None self.canvas = canvas cursor = QgsApplication.getThemeCursor( QgsApplication.Cursor.CapturePoint) self.setCursor(cursor) def flags(self): return QgsMapTool.EditTool def isEditTool(self): return True def reset(self): self.capturing = False self.startPoint = None self.endPoint = None if self.rubberBand is not None: self.canvas.scene().removeItem(self.rubberBand) if self.helperBand is not None: self.canvas.scene().removeItem(self.helperBand) self.rubberBand = None self.helperBand = None self.canvas.refresh() def start_capturing(self): """Capturing has started: setup the tool by initializing the rubber band and capturing mode""" # apply application settings for the rubber band settings = QSettings() settings.beginGroup('qgis/digitizing') line_width = settings.value('line_width', 1, type=int) fill_color = QColor(settings.value('fill_color_red', 255, type=int), settings.value('fill_color_green', 0, type=int), settings.value('fill_color_blue', 0, type=int), settings.value('fill_color_alpha', 31, type=int)) line_color = QColor(settings.value('line_color_red', 255, type=int), settings.value('line_color_green', 0, type=int), settings.value('line_color_blue', 0, type=int), settings.value('line_color_alpha', 199, type=int)) self.rubberBand = QgsRubberBand(self.canvas, _polygon) self.rubberBand.setColor(line_color) self.rubberBand.setFillColor(fill_color) self.rubberBand.setWidth(line_width) self.helperBand = QgsRubberBand(self.canvas, _polygon) self.helperBand.setColor(Qt.gray) self.helperBand.setFillColor(QColor(0, 0, 0, 0)) self.helperBand.setWidth(line_width) self.capturing = True def stop_capturing(self): """ Capturing will stop: adjust dimensions if needed and add feature to to the active layer. """ self.capturing = False rect = self.selection_rect() # fixme: need to find out why this sometimes happens if not rect: self.reset() return # fixme: use QGis project 'measurement units' in stead of project crs units title = 'Set size ({})'.format( QgsUnitTypes.toString(self.canvas.mapUnits())) self.dlg.setWindowTitle(title) self.dlg.width.setValue(rect.width()) self.dlg.height.setValue(rect.height()) self.dlg.show() result = self.dlg.exec_() if result: # check for a valid result from the dialog if self.dlg.width.value() <= 0 or self.dlg.height.value() <= 0: iface.messageBar().pushMessage( "Add feature", "Invalid dimensions (must be numeric and greater than zero)", level=_warning, duration=5) self.reset() return # adjust start and end points based on dimensions if self.startPoint.x() < self.endPoint.x(): self.endPoint.setX(self.startPoint.x() + self.dlg.width.value()) else: self.endPoint.setX(self.startPoint.x() - self.dlg.width.value()) if self.startPoint.y() < self.endPoint.y(): self.endPoint.setY(self.startPoint.y() + self.dlg.height.value()) else: self.endPoint.setY(self.startPoint.y() - self.dlg.height.value()) self.add_feature_to_layer() else: self.reset() def canvasReleaseEvent(self, event): if event.button() == Qt.LeftButton: # there must be an active polygon layer layer = self.canvas.currentLayer() if not layer or layer.type( ) != QgsMapLayer.VectorLayer or layer.geometryType() != _polygon: iface.messageBar().pushInfo("Add feature", "No active polygon layer") return if not self.capturing: self.start_capturing() self.startPoint = self.toMapCoordinates(event.pos()) self.endPoint = self.startPoint else: self.capture_position(event) self.stop_capturing() elif event.button() == Qt.RightButton: self.reset() def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.reset() def canvasMoveEvent(self, event): if self.capturing: self.capture_position(event) self.show_rubberband() if self.canvas.underMouse(): rect = self.selection_rect() if rect is not None: QToolTip.showText( self.canvas.mapToGlobal(self.canvas.mouseLastXY()), self.tooltip_text(rect), self.canvas) def capture_position(self, event): """ Record the position of the mouse pointer and adjust if keyboard modifier is pressed :type event: qgis.gui.QgsMapMouseEvent """ # adjust dimension on the fly if Shift is pressed if QApplication.keyboardModifiers() == Qt.ShiftModifier: end_point = QgsPointXY(self.toMapCoordinates(event.pos())) rect = QgsRectangle(self.startPoint, end_point) # return if start and endpoint are the same if rect.width() + rect.height() == 0: self.endPoint = self.toMapCoordinates(event.pos()) return if rect.width() > rect.height(): # make height (y) same as width in the correct direction if self.startPoint.y() < end_point.y(): end_point.setY(self.startPoint.y() + rect.width()) else: end_point.setY(self.startPoint.y() - rect.width()) else: # make width (x) same as height in the correct direction if self.startPoint.x() < end_point.x(): end_point.setX(self.startPoint.x() + rect.height()) else: end_point.setX(self.startPoint.x() - rect.height()) self.endPoint = end_point else: self.endPoint = self.toMapCoordinates(event.pos()) def show_rubberband(self): """ Draw to 'rubber band' to the map canvas as a preview of the shape *To be implemented by child class* """ pass def add_feature_to_layer(self): """Adds the just created shape to the active layer as a feature""" layer = self.canvas.currentLayer() feature = QgsFeature(layer.fields()) feature.setGeometry(self.transformed_geometry(layer)) if layer.fields().count(): ff = iface.getFeatureForm(layer, feature) if version_info[0] >= 3: ff.setMode(QgsAttributeEditorContext.AddFeatureMode) ff.accepted.connect(self.reset) ff.rejected.connect(self.reset) ff.show() else: layer.addFeature(feature) self.reset() def geometry(self): """ Returns the actual shape as a QgsGeometry object in the project CRS *To be implemented by child class* :rtype: qgis.core.QgsGeometry """ pass def transformed_geometry(self, layer): """ Takes a layer and returns the geometry shape as a QgsGeometry object in the that layer's CRS :param layer: target layer for transformation :type layer: qgis.core.QgsMapLayer :return: geometry in target layer CRS :rtype: qgis.core.QgsGeometry """ geometry = self.geometry() if version_info[0] >= 3: source_crs = QgsProject.instance().crs() tr = QgsCoordinateTransform(source_crs, layer.crs(), QgsProject.instance()) else: if hasattr(self.canvas, "mapSettings"): source_crs = self.canvas.mapSettings().destinationCrs() else: source_crs = self.canvas.mapRenderer().destinationCrs() tr = QgsCoordinateTransform(source_crs, layer.crs()) if source_crs != layer.crs(): geometry.transform(tr) return geometry def selection_rect(self): """ Returns the area between start and endpoint as a QgsRectangle in MapCoordinates :rtype: qgis.core.QgsRectangle """ if self.startPoint is None or self.endPoint is None: return None elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y( ) == self.endPoint.y(): return None return QgsRectangle(self.startPoint, self.endPoint) def tooltip_text(self, rect): pass def activate(self): self.statusBar = iface.mainWindow().statusBar() self.statusBar.showMessage( "Hold SHIFT to lock the ratio for perfect squares and circles") super(GeometryTool, self).activate() # fixme: use for further cleanup? def deactivate(self): self.statusBar.clearMessage() self.reset() super(GeometryTool, self).deactivate()
class ObstacleAreaJigCreateArea(QgsMapTool): def __init__(self, canvas, areaType): QgsMapTool.__init__(self, canvas) self.mCanvas = canvas self.areaType = areaType self.annotation = None self.rubberBand = QgsRubberBand(canvas, QGis.Point) self.rubberBand.setColor(Qt.red) self.rubberBand.setWidth(10) self.rubberBandClick = QgsRubberBand(canvas, QGis.Point) self.rubberBandClick.setColor(Qt.green) self.rubberBandClick.setWidth(3) self.obstaclesLayerList = QgisHelper.getSurfaceLayers(SurfaceTypes.Obstacles) self.demLayerList = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM) self.mRubberBand = None self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mCursor = Qt.ArrowCursor self.mFillColor = QColor( 254, 178, 76, 63 ) self.mBorderColour = QColor( 254, 58, 29, 100 ) self.mRubberBand0.setBorderColor( self.mBorderColour ) self.polygonGeom = None self.drawFlag = False self.mSnapper = QgsMapCanvasSnapper(canvas) self.resultPolylineArea = PolylineArea() # self.constructionLayer = constructionLayer self.menuString = "" self.isPrimaryPolylineStarted = False self.primaryPolyline = PolylineArea() def createContextMenu(self, areaType, isStarted = False): menu = QMenu() # h = QHBoxLayout(menu) # c = QCalendarWidget() # h.addWidget(c) if areaType == ProtectionAreaType.Primary: actionEnter = QgisHelper.createAction(menu, "Enter", self.menuEnterClick) actionCancel = QgisHelper.createAction(menu, "Cancel", self.menuCancelClick) actionArc = QgisHelper.createAction(menu, "Arc", self.menuArcClick) actionUndo = QgisHelper.createAction(menu, "Undo", self.menuUndoClick) menu.addAction( actionEnter ) menu.addAction( actionCancel ) menu.addAction( actionArc ) menu.addAction( actionUndo ) elif areaType == ProtectionAreaType.Secondary: if not isStarted: actionEnter = QgisHelper.createAction(menu, "Enter", self.menuEnterClick) actionCancel = QgisHelper.createAction(menu, "Cancel", self.menuCancelClick) actionUndo = QgisHelper.createAction(menu, "Undo", self.menuUndoClick) actionPrimatyPolylineStart = QgisHelper.createAction(menu, "Strat INNER edge of the secondary area", self.menuPrimaryStartClick) actionPrimatyPolylineEnd = QgisHelper.createAction(menu, "End INNER edge of the secondary area", self.menuPrimaryEndClick) menu.addAction( actionEnter ) menu.addAction( actionCancel ) menu.addAction( actionUndo ) menu.addAction( actionPrimatyPolylineStart ) menu.addAction( actionPrimatyPolylineEnd ) actionPrimatyPolylineStart.setEnabled(not self.isPrimaryPolylineStarted) actionPrimatyPolylineEnd.setEnabled(self.isPrimaryPolylineStarted) else: actionPrimatyPolylineStart = QgisHelper.createAction(menu, "Strat INNER edge of the secondary area", self.menuPrimaryStartClick) actionPrimatyPolylineEnd = QgisHelper.createAction(menu, "End INNER edge of the secondary area", self.menuPrimaryEndClick) menu.addAction( actionPrimatyPolylineStart ) menu.addAction( actionPrimatyPolylineEnd ) actionPrimatyPolylineStart.setEnabled(not self.isPrimaryPolylineStarted) actionPrimatyPolylineEnd.setEnabled(self.isPrimaryPolylineStarted) return menu def menuPrimaryStartClick(self): self.primaryPolyline = PolylineArea() self.isPrimaryPolylineStarted = True # self.menuString = "Enter" def menuPrimaryEndClick(self): self.isPrimaryPolylineStarted = False # self.menuString = "Enter" def menuEnterClick(self): self.menuString = "Enter" def menuCancelClick(self): self.menuString = "Cancel" def menuArcClick(self): self.menuString = "Arc" def menuUndoClick(self): self.menuString = "Undo" def reset(self): self.Point = None def canvasPressEvent( self, e ): define._messageLabel.setText("") self.menuString = "" pointBackground = e.pos() # self.Point = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas) self.Point, self.pointID, self.layer= self.snapPoint(e.pos()) self.selectedLayerFromSnapPoint = None if ( self.mRubberBand == None ): self.resultPolylineArea = PolylineArea() self.mRubberBand0.reset( QGis.Polygon ) # define._canvas.clearCache () self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) self.mRubberBand0.setFillColor( QColor(255, 255, 255, 100) ) self.mRubberBand0.setBorderColor( QColor(0, 0, 0) ) if ( e.button() == Qt.LeftButton ): if self.Point == None: self.mRubberBand.addPoint( self.toMapCoordinates( e.pos() ) ) self.resultPolylineArea.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) if self.isPrimaryPolylineStarted: self.primaryPolyline.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) else: self.mRubberBand.addPoint( self.Point ) self.resultPolylineArea.Add(PolylineAreaPoint(self.Point)) if self.isPrimaryPolylineStarted: self.primaryPolyline.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) else: menu = None if self.areaType == ProtectionAreaType.Secondary and len(self.resultPolylineArea) == 0: menu = self.createContextMenu(self.areaType, True) menu.exec_( define._canvas.mapToGlobal(e.pos() )) return if ( self.mRubberBand.numberOfVertices() > 2 ): self.polygonGeom = self.mRubberBand.asGeometry() else: return # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, polygonGeom, e ) menu = self.createContextMenu(self.areaType) menu.exec_( define._canvas.mapToGlobal(e.pos() )) if self.menuString == "Cancel" or self.menuString == "Arc": return elif self.menuString == "Undo": if ( self.mRubberBand.numberOfVertices() > 0 ): self.mRubberBand = None QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) self.resultPolylineArea[self.resultPolylineArea.Count - 2].bulge = 0.0 self.resultPolylineArea.pop(self.resultPolylineArea.Count - 1) if self.isPrimaryPolylineStarted and len(self.primaryPolyline) > 0: self.primaryPolyline.pop(self.primaryPolyline.Count - 1) for pt in self.resultPolylineArea.method_14(): self.mRubberBand.addPoint(pt) return elif self.menuString == "Enter": # if self.areaType == ProtectionAreaType.Secondary: # if self.resultPolylineArea.Count != 4: # define._messageLabel.setText("The count of point of Secondary Area must be 4.") # return self.mRubberBand.reset( QGis.Polygon ) self.mRubberBand0.reset( QGis.Polygon ) # define._canvas.clearCache () self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand0.setFillColor( QColor(255, 255, 255, 100) ) self.mRubberBand0.setBorderColor( QColor(0, 0, 0) ) for pt in self.resultPolylineArea.method_14(): self.mRubberBand0.addPoint(pt) # self.mRubberBand0.addGeometry(self.polygonGeom, None) n = self.mRubberBand0.numberOfVertices() self.mRubberBand0.show() self.mRubberBand = None area = None if self.areaType == ProtectionAreaType.Primary: area = PrimaryObstacleArea(self.resultPolylineArea) elif self.areaType == ProtectionAreaType.Secondary: if len(self.resultPolylineArea) == 4: area = SecondaryObstacleArea(self.resultPolylineArea[0].Position, self.resultPolylineArea[1].Position, self.resultPolylineArea[3].Position, self.resultPolylineArea[2].Position, MathHelper.getBearing(self.resultPolylineArea[0].Position, self.resultPolylineArea[1].Position)) else: if self.primaryPolyline.Count < 2: define._messageLabel.setText("The PrimaryLine in Secondary Area must exist.") return if self.isPrimaryPolylineStarted: define._messageLabel.setText("You must finish the input of PrimaryLine.") return area = SecondaryObstacleAreaWithManyPoints(self.resultPolylineArea, self.primaryPolyline) self.emit(SIGNAL("outputResult"), area, self.mRubberBand0) n = 0 def canvasMoveEvent( self, e ): self.rubberBand.reset(QGis.Point) # snapPoint = QgisHelper.snapPoint(e.pos(), self.mSnapper , define._canvas, True) snapPoint, snapPointID, layer = self.snapPoint(e.pos(), True) if snapPoint != None: self.rubberBand.addPoint(snapPoint) self.rubberBand.show() if ( self.mRubberBand == None ): return if ( self.mRubberBand.numberOfVertices() > 0 ): if self.menuString != "Undo": self.mRubberBand.removeLastPoint( 0 ) else: self.menuString = "" point2 = None if snapPoint != None: self.mRubberBand.addPoint( snapPoint) point2 = snapPoint else: self.mRubberBand.addPoint( self.toMapCoordinates( e.pos() ) ) point2 = self.toMapCoordinates( e.pos() ) if self.menuString == "Arc": point0 = self.resultPolylineArea[self.resultPolylineArea.Count - 2].Position point1 = self.resultPolylineArea[self.resultPolylineArea.Count - 1].Position # point2 = self.mRubberBand.getPoint(self.mRubberBand.numberOfVertices() - 1) bulge = MathHelper.smethod_60(point0, point1, point2) self.resultPolylineArea[self.resultPolylineArea.Count - 2].bulge = bulge self.mRubberBand = None QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) for pt in self.resultPolylineArea.method_14(): self.mRubberBand.addPoint(pt) self.mRubberBand.addPoint(point2) 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 deactivate(self): self.rubberBand.reset(QGis.Point) QgsMapTool.deactivate(self) self.emit(SIGNAL("deactivated()"))
class DiviIdentifyTool(QgsMapToolIdentify): on_feature = pyqtSignal(object) on_activities = pyqtSignal(dict) on_raster = pyqtSignal(list) wgs84 = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) cursor = QCursor(QPixmap(["16 16 3 1", "# c None", "a c #000000", ". c #ffffff", ".###########..##", "...########.aa.#", ".aa..######.aa.#", "#.aaa..#####..##", "#.aaaaa..##.aa.#", "##.aaaaaa...aa.#", "##.aaaaaa...aa.#", "##.aaaaa.##.aa.#", "###.aaaaa.#.aa.#", "###.aa.aaa..aa.#", "####..#..aa.aa.#", "####.####.aa.a.#", "##########.aa..#", "###########.aa..", "############.a.#", "#############.##"]), 0, 0) def __init__(self, parent): self.parent = parent self.iface = parent.iface self.canvas = parent.iface.mapCanvas() self.indentifying = False self.currentFid = None self.geometry = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry) self.geometry.setColor(QColor('red')) self.geometry.setFillColor(QColor(255, 0, 0, 100)) self.geometry.setIconSize(7) self.geometry.setWidth(3) super(DiviIdentifyTool, self).__init__(self.canvas) def canvasReleaseEvent(self, event ): self.geometry.reset(QgsWkbTypes.PointGeometry) layer = self.iface.activeLayer() if layer is None: return if isinstance(layer, QgsRasterLayer): if layer.customProperty('DiviId') is None: #Selected layer is not from DIVI self.on_raster.emit( [] ) return point = self.iface.mapCanvas().getCoordinateTransform().toMapCoordinates( event.x(), event.y() ) self.identifyRaster( point, layer.customProperty('DiviId') ) self.geometry.addPoint( point ) return self.on_activities.emit( { 'attachments':[], 'comments':[], 'changes':[]} ) if layer.customProperty('DiviId') is None: #Selected layer is not from DIVI self.on_feature.emit( None ) return result = self.identify(event.x(), event.y(), [layer], QgsMapToolIdentify.ActiveLayer) if not result: #Clear activities panel and return if no feaure was found if self.indentifying: self.abortIdentification() self.on_feature.emit( None ) return self.parent.identification_dock.tvIdentificationResult.model().sourceModel().setLoading() feature = result[0].mFeature if feature.id()<0: #Added feature self.iface.messageBar().pushMessage(self.tr("Error"), self.tr("Selected feature is not saved."), level=QgsMessageBar.CRITICAL, duration=3) return self.geometry.setToGeometry(feature.geometry(), layer) if self.indentifying: self.abortIdentification() self.identifyVector( feature ) def activate(self): super(DiviIdentifyTool, self).activate() self.connector = self.parent.dockwidget.getConnector() self.canvas.setCursor(self.cursor) def deactivate(self): super(DiviIdentifyTool, self).deactivate() self.geometry.reset() self.action().setChecked(False) del self.connector def identifyVector(self, feature): self.indentifying = True if not self.parent.identification_dock.isVisible(): self.parent.identification_dock.show() self.parent.identification_dock.raise_() fid = self.parent.ids_map[self.parent.iface.activeLayer().id()][feature.id()] self.on_feature.emit( fid ) QgsMessageLog.logMessage(self.tr('Feature start identification: %d (diviID:%d)') % (feature.id(), fid), 'DIVI') if not self.indentifying: self.on_feature.emit( None ) return #Get activities for itemType in ('attachments', 'comments', 'changes'): data = getattr(self.connector, 'get_%s' % itemType)( fid ) or {} if self.indentifying: self.on_activities.emit( { itemType : data.get('data', []) } ) else: self.on_feature.emit( None ) return QgsMessageLog.logMessage(self.tr('Feature end identification: %d (diviID:%d)') % (feature.id(), fid), 'DIVI') self.indentifying = False def identifyRaster(self, point, layerid): canvas_crs = self.canvas.mapSettings().destinationCrs() if canvas_crs.authid() != "EPSG:4326": transform = QgsCoordinateTransform(canvas_crs, self.wgs84, QgsCoordinateTransformContext ()) point = transform.transform(point) result = self.connector.getRasterIdentification( layerid, point )['data'][0] if not isinstance(result, list): result = [result] self.on_raster.emit( result ) def abortIdentification(self): self.connector.abort() self.indentifying = False self.on_feature.emit( None ) def toggleMapTool(self, state): if state: self.canvas.setMapTool(self) else: self.canvas.unsetMapTool(self)
class AreaTool(QgsMapTool): """ Map tool class to select an area """ releasedSignal = pyqtSignal() def __init__(self, iface): """ Constructor :param iface: interface """ QgsMapTool.__init__(self, iface.mapCanvas()) self.__clear() def activate(self): """ When the action is selected """ QgsMapTool.activate(self) self.__rubber = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor("red") color.setAlphaF(0.6) self.__rubber.setBorderColor(color) color = QColor("orange") color.setAlphaF(0.3) self.__rubber.setFillColor(color) def deactivate(self): """ When the action is deselected """ self.__clear() QgsMapTool.deactivate(self) def __clear(self): """ To clear used variables """ self.__selecting = False self.__rubber = None self.first = None self.last = None self.geom = None def canvasMoveEvent(self, event): """ When the mouse is moved :param event: mouse event """ if self.__selecting: self.__rubber.reset() firstV2 = QgsPointV2(self.first) second = QgsPointV2(self.first.x(), event.mapPoint().y()) third = QgsPointV2(event.mapPoint()) fourth = QgsPointV2(event.mapPoint().x(), self.first.y()) lineV2 = QgsLineStringV2() lineV2.setPoints([firstV2, second, third, fourth, firstV2]) polygonV2 = QgsPolygonV2() polygonV2.setExteriorRing(lineV2) self.geom = QgsGeometry(polygonV2) self.__rubber.setToGeometry(self.geom, None) def canvasPressEvent(self, event): """ When the mouse is pressed :param event: mouse event """ self.__selecting = True self.first = event.mapPoint() def canvasReleaseEvent(self, event): """ When the mouse is clicked :param event: mouse event """ self.__selecting = False self.last = event.mapPoint() self.__rubber.reset() self.releasedSignal.emit()
class ApisMapToolEmitPolygonAndPoint(QgsMapTool, ApisMapToolMixin): mappingFinished = pyqtSignal(QgsGeometry, QgsGeometry, QgsCoordinateReferenceSystem) def __init__(self, canvas): QgsMapTool.__init__(self, canvas) self.canvas = canvas self.rubberBand = None self.tempRubberBand = None self.vertexMarker = None self.capturedPoints = [] self.derivedPoint = None self.capturing = False self.setCursor(Qt.CrossCursor) def canvasReleaseEvent(self, event): if event.button() == Qt.LeftButton: if not self.capturing: self.startCapturing() self.addVertex(event.pos()) elif event.button() == Qt.RightButton: point = self.getDerivedPoint() polygon = self.getCapturedPolygon() self.stopCapturing() if point != None and polygon != None: pointGeom = self.getPointGeometry(point) polygonGeom = self.getPolygonGeometry(polygon) if pointGeom != None and polygonGeom != None: self.mappingFinished.emit(pointGeom, polygonGeom, self.canvas.mapSettings().destinationCrs()) else: self.clearScene() else: self.clearScene() def canvasMoveEvent(self, event): if self.tempRubberBand != None and self.capturing: mapPt = self.transformCoordinates(event.pos()) self.tempRubberBand.movePoint(mapPt) def keyPressEvent(self, event): if event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete: self.removeLastVertex() event.ignore() if event.key() == Qt.Key_Escape: self.stopCapturing() self.clearScene() if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: point = self.getDerivedPoint() polygon = self.getCapturedPolygon() self.stopCapturing() if point != None and polygon != None: pointGeom = self.getPointGeometry(point) polygonGeom = self.getPolygonGeometry(polygon) if pointGeom != None and polygonGeom != None: self.mappingFinished.emit(pointGeom, polygonGeom, self.canvas.mapSettings().destinationCrs()) else: self.clearScene() else: self.clearScene() def startCapturing(self): self.clearScene() self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon) self.rubberBand.setWidth(2) self.rubberBand.setFillColor(QColor(220, 0, 0, 120)) self.rubberBand.setBorderColor(QColor(220, 0, 0)) self.rubberBand.setLineStyle(Qt.DotLine) self.rubberBand.show() self.tempRubberBand = QgsRubberBand(self.canvas, QGis.Polygon) self.tempRubberBand.setWidth(2) self.tempRubberBand.setFillColor(QColor(0, 0, 0, 0)) self.tempRubberBand.setBorderColor(QColor(220, 0, 0)) self.tempRubberBand.setLineStyle(Qt.DotLine) self.tempRubberBand.show() self.vertexMarker = QgsVertexMarker(self.canvas) self.vertexMarker.setIconType(1) self.vertexMarker.setColor(QColor(220, 0, 0)) self.vertexMarker.setIconSize(16) self.vertexMarker.setPenWidth(3) self.vertexMarker.show() self.capturing = True def clearScene(self): if self.vertexMarker: self.canvas.scene().removeItem(self.vertexMarker) self.vertexMarker = None if self.rubberBand: self.canvas.scene().removeItem(self.rubberBand) self.rubberBand = None if self.tempRubberBand: self.canvas.scene().removeItem(self.tempRubberBand) self.tempRubberBand = None def stopCapturing(self): if self.vertexMarker and self.rubberBand and self.rubberBand.numberOfVertices() < 3: self.canvas.scene().removeItem(self.vertexMarker) self.vertexMarker = None if self.rubberBand and self.rubberBand.numberOfVertices() < 3: self.canvas.scene().removeItem(self.rubberBand) self.rubberBand = None if self.tempRubberBand: self.canvas.scene().removeItem(self.tempRubberBand) self.tempRubberBand = None self.capturing = False self.capturedPoints = [] self.derivedPoint = None self.canvas.refresh() def addVertex(self, canvasPoint): mapPt = self.transformCoordinates(canvasPoint) self.rubberBand.addPoint(mapPt) self.capturedPoints.append(mapPt) bandSize = self.rubberBand.numberOfVertices() if bandSize > 2: rubGeom = self.rubberBand.asGeometry() cpGeom = rubGeom.centroid() if not rubGeom.contains(cpGeom): cpGeom = rubGeom.pointOnSurface() #nearestCp = rubGeom.nearestPoint(cpGeom) self.vertexMarker.setCenter(cpGeom.asPoint()) self.derivedPoint = cpGeom.asPoint() self.vertexMarker.show() self.tempRubberBand.reset(QGis.Polygon) firstPoint = self.rubberBand.getPoint(0, 0) self.tempRubberBand.addPoint(firstPoint) self.tempRubberBand.movePoint(mapPt) self.tempRubberBand.addPoint(mapPt) def removeLastVertex(self): if not self.capturing: return bandSize = self.rubberBand.numberOfVertices() tempBandSize = self.tempRubberBand.numberOfVertices() numPoints = len(self.capturedPoints) if bandSize < 1 or numPoints < 1: return self.rubberBand.removePoint(-1) if bandSize > 1: if tempBandSize > 1: point = self.rubberBand.getPoint(0, bandSize - 2) self.tempRubberBand.movePoint(tempBandSize - 2, point) else: self.tempRubberBand.reset(QGis.Polygon) bandSize = self.rubberBand.numberOfVertices() if bandSize < 3: self.vertexMarker.hide() else: rubGeom = self.rubberBand.asGeometry() cpGeom = rubGeom.centroid() if not rubGeom.contains(cpGeom): cpGeom = rubGeom.pointOnSurface() #nearestCp = rubGeom.nearestPoint(cpGeom) self.vertexMarker.setCenter(cpGeom.asPoint()) self.derivedPoint = cpGeom.asPoint() self.vertexMarker.show() del self.capturedPoints[-1] def getCapturedPolygon(self): polygon = self.capturedPoints if len(polygon) < 3: return None else: return polygon def getDerivedPoint(self): point = self.derivedPoint if point == None: return None else: return point def getPointGeometry(self, geom): p = QgsGeometry.fromPoint(geom) if p.isGeosValid() and not p.isGeosEmpty(): return p else: return None def getPolygonGeometry(self, geom): p = QgsGeometry.fromPolygon([geom]) if p.isGeosValid() and not p.isGeosEmpty(): return p else: return None
class ApisMapToolEmitPointAndSquare(QgsMapTool, ApisMapToolMixin): # when mapping finished signal emitted that carries the Point and a Polygon Geometry (in Map Coordinates) mappingFinished = pyqtSignal(QgsGeometry, QgsGeometry, QgsCoordinateReferenceSystem) def __init__(self, canvas, diagonal=200): QgsMapTool.__init__(self, canvas) self.canvas = canvas self.vertexMarker = None self.rubberBand = None self.capturedPoint = None self.derivedPolygon = [] self.capturing = False # self.setLayers(pointLayer, polygonLayer) self.setDiagonal(diagonal) self.setCursor(Qt.CrossCursor) def canvasReleaseEvent(self, event): if event.button() == Qt.LeftButton: if not self.capturing: self.startCapturing() self.setVertex(event.pos()) elif event.button() == Qt.RightButton: point = self.getCapturedPoint() polygon = self.getDerivedPolygon() self.stopCapturing() if point != None and polygon != None: self.mappingFinished.emit(self.getPointGeometry(point), self.getPolygonGeometry(polygon), self.canvas.mapSettings().destinationCrs()) def keyPressEvent(self, event): if event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete: #self.removeLastVertex() event.ignore() if event.key() == Qt.Key_Escape: self.stopCapturing() self.clearScene() if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: point = self.getCapturedPoint() polygon = self.getDerivedPolygon() self.stopCapturing() if point != None and polygon != None: self.mappingFinished.emit(self.getPointGeometry(point), self.getPolygonGeometry(polygon), self.canvas.mapSettings().destinationCrs()) def startCapturing(self): self.clearScene() self.vertexMarker = QgsVertexMarker(self.canvas) self.vertexMarker.setIconType(1) self.vertexMarker.setColor(QColor(220, 0, 0)) self.vertexMarker.setIconSize(16) self.vertexMarker.setPenWidth(3) self.vertexMarker.show() self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon) self.rubberBand.setWidth(2) self.rubberBand.setFillColor(QColor(220, 0, 0, 120)) self.rubberBand.setBorderColor(QColor(220, 0, 0)) self.rubberBand.setLineStyle(Qt.DotLine) self.rubberBand.show() self.capturing = True def clearScene(self): if self.vertexMarker: self.canvas.scene().removeItem(self.vertexMarker) self.vertexMarker = None if self.rubberBand: self.canvas.scene().removeItem(self.rubberBand) self.rubberBand = None def stopCapturing(self): self.capturing = False self.capturedPoint = None self.derivedPolygon = [] self.canvas.refresh() def setVertex(self, canvasPoint): mapPt = self.transformCoordinates(canvasPoint) # set/update vertexMarker Position self.vertexMarker.setCenter(mapPt) self.capturedPoint = mapPt # update rubberBand self.updateRubberBand() def updateRubberBand(self): if self.capturedPoint and self.rubberBand: # calculate Points self.derivedPolygon = self.calculateSquare(self.capturedPoint) self.rubberBand.reset(QGis.Polygon) for mapPt in self.derivedPolygon: self.rubberBand.addPoint(mapPt) def getCapturedPoint(self): point = self.capturedPoint if point == None: return None else: return point def getDerivedPolygon(self): polygon = self.derivedPolygon if polygon == None: return None else: return polygon def getPointGeometry(self, geom): return QgsGeometry.fromPoint(geom) def getPolygonGeometry(self, geom): return QgsGeometry.fromPolygon([geom]) def updateDiagonal(self, diagonal): self.setDiagonal(diagonal) # update Rubberband self.updateRubberBand()