Ejemplo n.º 1
0
    def build_markers(self, signature):
        markers = []
        rb = QgsRubberBand(self._canvas)
        rb.setColor(Qt.red)
        rb.setWidth(1)
        max_col = 0
        max_line = 0
        for point in signature['points']:
            col = point['col']
            if col > max_col:
                max_col = col
            line = point['line']
            if line > max_line:
                max_line = line

            markers.append(self.build_marker(col, line))
            rb.addPoint(QgsPointXY(col, -line))
        rb.closePoints()
        markers.append(rb)
        return (markers, QgsPointXY(max_col, -max_line))
Ejemplo n.º 2
0
class PolygonMapTool(QgsMapToolEmitPoint):
    """This class holds a map tool to create a polygon from points got by clicking
        on the map window. Points are stored in a list of point geometries, which is returned to
        the main plugin for use."""
    def __init__(self, canvas):
        self.canvas = canvas
        QgsMapToolEmitPoint.__init__(self, self.canvas)
        # rubberband class gives the user visual feedback of the drawing
        self.rubberBand = QgsRubberBand(self.canvas, True)
        # setting up outline and fill color: both red
        self.rubberBand.setColor(QColor(235, 36, 21))
        # RGB color values, last value indicates transparency (0-255)
        self.rubberBand.setFillColor(QColor(255, 79, 66, 140))
        self.rubberBand.setWidth(3)
        self.points = []
        # a flag indicating when a single polygon is finished
        self.finished = False
        self.poly_bbox = False
        self.double_click_flag = False
        self.reset()

    def reset(self):
        """Empties the canvas and the points gathered thus far"""
        self.rubberBand.reset(True)
        self.poly_bbox = False
        self.points.clear()

    def keyPressEvent(self, e):
        """Pressing ESC resets the canvas. Pressing enter connects the polygon"""
        if (e.key() == 16777216):
            self.reset()
        if (e.key() == 16777220):
            self.finishPolygon()

    def canvasDoubleClickEvent(self, e):
        self.double_click_flag = True
        self.finishPolygon()

    def canvasReleaseEvent(self, e):
        """Activated when user clicks on the canvas. Gets coordinates, draws
        them on the map and adds to the list of points."""
        if self.double_click_flag:
            self.double_click_flag = False
            return

        # if the finished flag is activated, the canvas will be must be reset
        # for a new polygon
        if self.finished:
            self.reset()
            self.finished = False

        self.click_point = self.toMapCoordinates(e.pos())

        self.rubberBand.addPoint(self.click_point, True)
        self.points.append(self.click_point)
        self.rubberBand.show()

    def finishPolygon(self):
        """Activated when by user or when the map window is closed without connecting
            the polygon. Makes the polygon valid by making first and last point
            the same. This is reflected visually. Up until now the user has been
            drawing a line: a polygon is created and shown on the map."""
        # nothing will happen if the code below has already been ran
        if self.finished:
            return
        # connecting the polygon is valid if there's already at least 3 points
        elif len(self.points) > 2:
            first_point = self.points[0]
            self.points.append(first_point)
            self.rubberBand.closePoints()
            self.rubberBand.addPoint(first_point, True)
            self.finished = True
            # a polygon is created and added to the map for visual purposes
            map_polygon = QgsGeometry.fromPolygonXY([self.points])
            self.rubberBand.setToGeometry(map_polygon)
            # get the bounding box of this new polygon
            self.poly_bbox = self.rubberBand.asGeometry().boundingBox()
        else:
            self.finished = True

    def getPoints(self):
        """Returns list of PointXY geometries, i.e. the polygon in list form"""
        self.rubberBand.reset(True)
        return self.points

    def getPolyBbox(self):
        return self.poly_bbox
Ejemplo n.º 3
0
class QGISRedMultiLayerSelection(QgsMapTool):
    def __init__(self, iface, canvas, action):
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        self.iface = iface
        self.setAction(action)
        self.myRubberBand = QgsRubberBand(self.canvas, 3)  # 3= Polygon
        mFillColor = QColor(255, 0, 0, 100)
        self.myRubberBand.setColor(mFillColor)
        self.myRubberBand.setWidth(2)
        self.myRubberBand.setLineStyle(2)

        self.rubberBand1 = None
        self.rubberBand2 = None

        self.reset()

    def deactivate(self):
        self.reset()
        self.myRubberBand.hide()
        QgsMapTool.deactivate(self)

    def activate(self):
        QgsMapTool.activate(self)

    """Methods"""

    def reset(self):
        self.initialPoint = None
        self.finalPoint = None
        self.isSelecting = False
        self.myRubberBand.reset(3)  # 3= Polygon

        if self.rubberBand1 is not None:
            self.iface.mapCanvas().scene().removeItem(self.rubberBand1)
        if self.rubberBand2 is not None:
            self.iface.mapCanvas().scene().removeItem(self.rubberBand2)

        self.mousePoints = []
        self.rubberBand1 = None
        self.rubberBand2 = None

    def createRubberBand(self, points):
        myPoints1 = []
        for p in points:
            myPoints1.append(QgsPoint(p.x(), p.y()))
        myPoints1.remove(myPoints1[-1])
        myPoints1.append(myPoints1[0])
        if self.rubberBand1 is not None:
            self.iface.mapCanvas().scene().removeItem(self.rubberBand1)
        self.rubberBand1 = QgsRubberBand(self.iface.mapCanvas(), False)
        self.rubberBand1.setToGeometry(QgsGeometry.fromPolyline(myPoints1),
                                       None)
        self.rubberBand1.setColor(QColor(240, 40, 40))
        self.rubberBand1.setWidth(1)
        self.rubberBand1.setLineStyle(Qt.SolidLine)

        myPoints2 = []
        myPoints2.append(QgsPoint(points[-2].x(), points[-2].y()))
        myPoints2.append(QgsPoint(points[-1].x(), points[-1].y()))
        myPoints2.append(QgsPoint(points[0].x(), points[0].y()))
        if self.rubberBand2 is not None:
            self.iface.mapCanvas().scene().removeItem(self.rubberBand2)
        self.rubberBand2 = QgsRubberBand(self.iface.mapCanvas(), False)
        self.rubberBand2.setToGeometry(QgsGeometry.fromPolyline(myPoints2),
                                       None)
        self.rubberBand2.setColor(QColor(240, 40, 40))
        self.rubberBand2.setWidth(1)
        self.rubberBand2.setLineStyle(Qt.DashLine)

    def showRectangle(self, initialPoint, finalPoint):
        self.myRubberBand.reset(3)
        if initialPoint.x() == finalPoint.x() or initialPoint.y(
        ) == finalPoint.y():
            return
        point1 = QgsPointXY(initialPoint.x(), initialPoint.y())
        point2 = QgsPointXY(initialPoint.x(), finalPoint.y())
        point3 = QgsPointXY(finalPoint.x(), finalPoint.y())
        point4 = QgsPointXY(finalPoint.x(), initialPoint.y())

        self.myRubberBand.addPoint(point1, False)
        self.myRubberBand.addPoint(point2, False)
        self.myRubberBand.addPoint(point3, False)
        self.myRubberBand.addPoint(point4, False)
        self.myRubberBand.closePoints()
        self.myRubberBand.show()

    def getRectangle(self):
        if self.initialPoint is None or self.finalPoint is None:
            return None
        elif self.initialPoint.x() == self.finalPoint.x(
        ) or self.initialPoint.y() == self.finalPoint.y():
            return None
        return QgsRectangle(self.initialPoint, self.finalPoint)

    """Events"""

    def canvasPressEvent(self, e):
        if e.button() == Qt.RightButton and len(self.mousePoints) > 0:
            poligon = QgsVectorLayer('Polygon', 'poly', "memory")
            pr = poligon.dataProvider()
            poly = QgsFeature()
            if len(self.mousePoints) > 3:
                self.mousePoints.remove(self.mousePoints[-1])
            poly.setGeometry(QgsGeometry.fromPolygonXY([self.mousePoints]))
            pr.addFeatures([poly])

            layers = self.canvas.layers()
            try:
                for layer in layers:
                    if layer.type() == QgsMapLayer.RasterLayer:
                        continue
                    modifiers = QApplication.keyboardModifiers()
                    if modifiers == Qt.ShiftModifier:
                        processing.run(
                            'qgis:selectbylocation', {
                                'INPUT': layer,
                                'PREDICATE': [0],
                                'INTERSECT': poligon,
                                'METHOD': 3
                            })  # Remove
                    elif modifiers == Qt.ControlModifier:
                        processing.run(
                            'qgis:selectbylocation', {
                                'INPUT': layer,
                                'PREDICATE': [0],
                                'INTERSECT': poligon,
                                'METHOD': 1
                            })  # Add
                    else:
                        processing.run(
                            'qgis:selectbylocation', {
                                'INPUT': layer,
                                'PREDICATE': [0],
                                'INTERSECT': poligon,
                                'METHOD': 0
                            })  # Set
            except Exception:
                self.iface.messageBar().pushMessage(
                    "Warning",
                    "Polygon not valid for selecting elements",
                    level=1,
                    duration=5)
            self.reset()
            poligon = None
            return
        elif e.button() == Qt.RightButton:
            self.canvas.unsetMapTool(self)
            self.deactivate()
            return
        # Rectangle
        if len(self.mousePoints) == 0:
            self.initialPoint = self.toMapCoordinates(e.pos())
            self.finalPoint = self.initialPoint
            self.isSelecting = True
            self.showRectangle(self.initialPoint, self.finalPoint)
        # Poliline
        point = self.toMapCoordinates(e.pos())
        self.mousePoints.append(point)
        if len(self.mousePoints) == 1:
            self.mousePoints.append(point)

    def canvasReleaseEvent(self, e):
        self.isSelecting = False
        rect = self.getRectangle()
        if rect is None:
            if len(self.mousePoints) > 0:
                self.createRubberBand(self.mousePoints)
        else:
            self.mousePoints = []
            layers = self.canvas.layers()
            for layer in layers:
                if layer.type() == QgsMapLayer.RasterLayer:
                    continue
                lRect = self.canvas.mapSettings().mapToLayerCoordinates(
                    layer, rect)
                modifiers = QApplication.keyboardModifiers()
                if modifiers == Qt.ShiftModifier:
                    layer.selectByRect(lRect, 3)  # Remove
                elif modifiers == Qt.ControlModifier:
                    layer.selectByRect(lRect, 1)  # Add
                else:
                    layer.selectByRect(lRect, 0)  # Set
            self.myRubberBand.hide()

    def canvasMoveEvent(self, e):
        point = self.toMapCoordinates(e.pos())
        if self.isSelecting:
            self.finalPoint = point
            self.showRectangle(self.initialPoint, self.finalPoint)
        elif len(self.mousePoints) > 0:
            self.mousePoints[-1] = point
            self.createRubberBand(self.mousePoints)
Ejemplo n.º 4
0
class DeleteTool(QgsMapTool):
    def __init__(self, data_dock, params):
        QgsMapTool.__init__(self, data_dock.iface.mapCanvas())

        self.iface = data_dock.iface
        """:type : QgisInterface"""
        self.data_dock = data_dock
        """:type : DataDock"""
        self.params = params

        self.elev = -1
        self.vertex_marker = QgsVertexMarker(self.canvas())

        # Stroke
        self.rubber_band = QgsRubberBand(self.data_dock.iface.mapCanvas())
        self.rubber_band.setColor(QColor(255, 0, 0, 255))
        self.rubber_band.setWidth(2)

        self.mouse_clicked = False
        self.snapper = None

        self.clicked_pt = None

        self.snap_results = None
        self.adj_links_fts = None

        self.selected_node_ft = None
        self.selected_node_ft_lay = None
        self.mouse_pt = None
        self.pump_valve_selected = False
        self.pump_or_valve = None
        self.pump_valve_ft = None
        self.adj_junctions = None
        self.delta_vec = None

        self.adj_pipes_fts_d = {}

    def canvasPressEvent(self, event):

        # if self.snap_results is None:
        #     return

        if event.button() == Qt.RightButton:
            self.mouse_clicked = False
            self.clicked_pt = None

        if event.button() == Qt.LeftButton:
            self.mouse_clicked = True
            self.clicked_pt = self.toMapCoordinates(event.pos())

    def canvasMoveEvent(self, event):

        self.mouse_pt = self.toMapCoordinates(event.pos())

        elev = raster_utils.read_layer_val_from_coord(self.params.dem_rlay,
                                                      self.mouse_pt, 1)
        if elev is not None:
            self.elev = elev
            self.data_dock.lbl_elev_val.setText("{0:.2f}".format(self.elev))

        # Mouse not clicked
        if not self.mouse_clicked:

            match = self.snapper.snapToMap(self.mouse_pt)
            if match.isValid():

                self.snap_results = match
                # snapped_pt = self.snap_results[0].snappedVertex

                self.snapped_pipe_id = match.featureId()
                snapped_vertex = match.point()
                self.snapped_vertex_nr = match.vertexIndex()

                self.vertex_marker.setCenter(
                    QgsPointXY(snapped_vertex.x(), snapped_vertex.y()))
                self.vertex_marker.setColor(QColor(255, 0, 0))
                self.vertex_marker.setIconSize(10)
                self.vertex_marker.setIconType(
                    QgsVertexMarker.ICON_CIRCLE)  # or ICON_CROSS, ICON_X
                self.vertex_marker.setPenWidth(3)
                self.vertex_marker.show()
            else:
                self.snap_results = None
                self.selected_node_ft = None
                self.vertex_marker.hide()

        # Mouse clicked: draw rectangle
        else:
            if self.snap_results is None:
                end_point = self.toMapCoordinates(event.pos())
                self.show_rect(self.clicked_pt, end_point)

    def canvasReleaseEvent(self, event):

        if not self.mouse_clicked:
            return
        if event.button() == Qt.LeftButton:
            self.mouse_clicked = False

            # Snapped: one element selected
            if self.snap_results is not None:

                selected_node_ft_lay, selected_node_ft = vector_utils.findSnappedNode(
                    self.snapper, self.snap_results, self.params)

                # A node ha been snapped
                if selected_node_ft_lay is not None:
                    self.delete_element(selected_node_ft_lay, selected_node_ft)

                # A link has been snapped
                else:
                    snapped_ft = vector_utils.get_feats_by_id(
                        self.snap_results.layer(),
                        self.snap_results.featureId())
                    snapped_layer = self.snap_results.layer()
                    self.delete_element(snapped_layer, snapped_ft[0])

            # Not snapped: rectangle
            else:
                rubber_band_rect = self.rubber_band.asGeometry().boundingBox()

                self.rubber_band.reset()

                self.delete_elements(self.params.valves_vlay, rubber_band_rect)
                self.delete_elements(self.params.pumps_vlay, rubber_band_rect)
                self.delete_elements(self.params.pipes_vlay, rubber_band_rect)
                self.delete_elements(self.params.tanks_vlay, rubber_band_rect)
                self.delete_elements(self.params.reservoirs_vlay,
                                     rubber_band_rect)
                self.delete_elements(self.params.junctions_vlay,
                                     rubber_band_rect)

            # Refresh
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.junctions_vlay)
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.reservoirs_vlay)
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.tanks_vlay)
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.pipes_vlay)
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.pumps_vlay)
            symbology.refresh_layer(self.iface.mapCanvas(),
                                    self.params.valves_vlay)

    def activate(self):

        cursor = QCursor()
        cursor.setShape(Qt.ArrowCursor)
        self.iface.mapCanvas().setCursor(cursor)

        layers = {
            self.params.junctions_vlay: QgsSnappingConfig.Vertex,
            self.params.reservoirs_vlay: QgsSnappingConfig.Vertex,
            self.params.tanks_vlay: QgsSnappingConfig.Vertex,
            self.params.pipes_vlay: QgsSnappingConfig.VertexAndSegment
        }
        self.snapper = NetworkUtils.set_up_snapper(layers,
                                                   self.iface.mapCanvas(),
                                                   self.params.snap_tolerance)
        self.snapper.toggleEnabled()

        # Editing
        if not self.params.junctions_vlay.isEditable():
            self.params.junctions_vlay.startEditing()
        if not self.params.reservoirs_vlay.isEditable():
            self.params.reservoirs_vlay.startEditing()
        if not self.params.tanks_vlay.isEditable():
            self.params.tanks_vlay.startEditing()
        if not self.params.pipes_vlay.isEditable():
            self.params.pipes_vlay.startEditing()
        if not self.params.pumps_vlay.isEditable():
            self.params.pumps_vlay.startEditing()
        if not self.params.valves_vlay.isEditable():
            self.params.valves_vlay.startEditing()

    def deactivate(self):
        self.data_dock.btn_delete_element.setChecked(False)
        self.canvas().scene().removeItem(self.vertex_marker)

    def isZoomTool(self):
        return False

    def isTransient(self):
        return False

    def isEditTool(self):
        return True

    def show_rect(self, start_point, end_point):

        self.rubber_band.reset()
        if start_point.x() == end_point.x() or start_point.y() == end_point.y(
        ):
            return

        point1 = QgsPointXY(start_point.x(), start_point.y())
        point2 = QgsPointXY(start_point.x(), end_point.y())
        point3 = QgsPointXY(end_point.x(), end_point.y())
        point4 = QgsPointXY(end_point.x(), start_point.y())
        point5 = QgsPointXY(start_point.x(), start_point.y())

        self.rubber_band.addPoint(point1, False)
        self.rubber_band.addPoint(point2, False)
        self.rubber_band.addPoint(point3, False)
        self.rubber_band.addPoint(point4, False)
        self.rubber_band.closePoints(True)  # true to update canvas
        self.rubber_band.show()

    def delete_elements(self, layer, rectangle):

        try:
            QApplication.setOverrideCursor(Qt.WaitCursor)
            feats = layer.getFeatures()
            for feat in feats:
                if rectangle.contains(feat.geometry().boundingBox()):
                    self.delete_element(layer, feat)

        finally:
            QApplication.restoreOverrideCursor()

    def delete_element(self, layer, feature):

        # If node
        if layer == self.params.junctions_vlay or \
                        layer == self.params.reservoirs_vlay or \
                        layer == self.params.tanks_vlay:

            # The node is a junction
            if layer == self.params.junctions_vlay:

                adj_links_fts = NetworkUtils.find_adjacent_links(
                    self.params, feature.geometry())

                # Only pipes adjacent to node: it's a simple junction
                if not adj_links_fts['pumps'] and not adj_links_fts['valves']:

                    # Delete node
                    NodeHandler.delete_node(self.params, layer, feature)

                    # Delete adjacent pipes
                    adj_pipes = NetworkUtils.find_adjacent_links(
                        self.params, feature.geometry())
                    for adj_pipe in adj_pipes['pipes']:
                        LinkHandler.delete_link(self.params.pipes_vlay,
                                                adj_pipe)

                # The node is part of a pump or valve
                else:

                    if adj_links_fts['pumps']:
                        LinkHandler.delete_link(self.params,
                                                self.params.pumps_vlay,
                                                feature)

                    elif adj_links_fts['valves']:
                        LinkHandler.delete_link(self.params,
                                                self.params.valves_vlay,
                                                feature)

            # The node is a reservoir or a tank
            elif layer == self.params.reservoirs_vlay or \
                            layer == self.params.tanks_vlay:

                adj_pipes = NetworkUtils.find_adjacent_links(
                    self.params, feature.geometry())['pipes']

                NodeHandler._delete_feature(self.params, layer, feature)

                for adj_pipe in adj_pipes:
                    LinkHandler.delete_link(self.params,
                                            self.params.pipes_vlay, adj_pipe)

        # If pipe
        elif layer == self.params.pipes_vlay:

            if self.snap_results is not None:
                vertex = feature.geometry().closestVertexWithContext(
                    self.snap_results.point())
                vertex_dist = vertex[0]
                if vertex_dist < self.params.min_dist:
                    # Delete vertex
                    LinkHandler.delete_vertex(self.params,
                                              self.params.pipes_vlay, feature,
                                              vertex[1])
                else:
                    # Delete whole feature
                    LinkHandler.delete_link(self.params, layer, feature)
            else:
                LinkHandler.delete_link(self.params, layer, feature)
Ejemplo n.º 5
0
class SignatureTool(QgsMapTool):
    """
        On Double click it will callback with an array with a single pixel.
        On Single click without releasing it will draw a square and callback
        the starting and ending point in an array.
        On Single click with releasing it will start drawing a polygon and
        every subsequent single click will add a new vertex in the polygon.
        On Right click it will callback with an array with all the vertex in
        the polygon.
        On Escape it will clean up the array and start over.
    """
    def __init__(self, canvas, layer, callback):
        QgsMapTool.__init__(self, canvas)
        self._canvas = canvas
        self._layer = layer
        self._callback = callback
        self._pixels = []
        self._start_point = None
        self._mode = Mode.NONE
        self._rubber_band = QgsRubberBand(self._canvas)
        self._rubber_band.setColor(Qt.red)
        self._rubber_band.setWidth(1)
        self.parent().setCursor(Qt.CrossCursor)

    def getPoint(self, pos):
        x = pos.x()
        y = pos.y()
        return self._canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def getRowCol(self, point):
        # clicked position on screen to map coordinates
        data_provider = self._layer.dataProvider()
        extent = data_provider.extent()
        width = data_provider.xSize() if data_provider.capabilities() \
            & data_provider.Size else 1000
        height = data_provider.ySize() if data_provider.capabilities() \
            & data_provider.Size else 1000
        xres = extent.width() / width
        yres = extent.height() / height
        if extent.xMinimum() <= point.x() <= extent.xMaximum() and \
            extent.yMinimum() <= point.y() <= extent.yMaximum():
            col = int(floor((point.x() - extent.xMinimum()) / xres))
            row = int(floor((extent.yMaximum() - point.y()) / yres))
            return (row, col)
        else:
            return None

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self._pixels = []
            self.finish()

    def canvasMoveEvent(self, event):
        point = self.getPoint(event.pos())
        if self._mode is Mode.SQUARE:
            if not point.compare(self._start_point):
                self._rubber_band.reset()
                self._rubber_band.addPoint(self._start_point, False)
                self._rubber_band.addPoint(
                    QgsPointXY(self._start_point.x(), point.y()), False)
                self._rubber_band.addPoint(point, False)
                self._rubber_band.addPoint(
                    QgsPointXY(point.x(), self._start_point.y()), False)
                self._rubber_band.closePoints()
        elif self._mode is Mode.POLYGON:
            self._rubber_band.movePoint(
                self._rubber_band.numberOfVertices() - 1, point)

    def canvasReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            point = self.getPoint(event.pos())
            if self._mode is Mode.SQUARE:
                if self._start_point.compare(point):
                    self._mode = Mode.POLYGON
                    self._rubber_band.addPoint(point)
                    self._start_point = None
                else:
                    self._pixels = []
                    # The last vertex is repeated
                    for i in range(self._rubber_band.numberOfVertices() - 1):
                        self._pixels.append(
                            self.getRowCol(self._rubber_band.getPoint(0, i)))
                    self.finish()
            elif self._mode is Mode.POLYGON:
                self._rubber_band.addPoint(point)

    def canvasPressEvent(self, event):
        if event.button() == Qt.LeftButton:
            point = self.getPoint(event.pos())
            pixel = self.getRowCol(point)
            if self._mode is Mode.NONE:
                self._mode = Mode.SQUARE
                self._start_point = QgsPointXY(point.x(), point.y())
            elif self._mode is Mode.POLYGON:
                self._rubber_band.removePoint(
                    self._rubber_band.numberOfVertices() - 1)
            else:
                self._mode = Mode.POLYGON
            if pixel:
                self._rubber_band.addPoint(point)
                self._pixels.append(pixel)
        elif event.button() == Qt.RightButton:
            self.finish()

    def finish(self):
        self._canvas.unsetMapTool(self)
        self._rubber_band.reset()
        self._mode = Mode.NONE
        self._start_point = None
        if len(self._pixels) > 0:
            self._callback(self._layer.hiperqube_id(), self._pixels)
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, 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:
            if not self.active:
                self.active = True
                self.geometry_changed.emit(QgsGeometry(), False)
                self.rb.reset(QgsWkbTypes.PolygonGeometry)
            self.rb.addPoint(mouseEvent.mapPoint())
            if self.rb.numberOfVertices() > 2:
                self.geometry_changed.emit(self.rb.asGeometry(), False)
        elif mouseEvent.button() == Qt.RightButton:
            if self.rb.numberOfVertices() > 3:
                self.active = False
                self.rb.removeLastPoint()
                self.rb.closePoints(
                )  #Ensures that a polygon geometry is closed and that the last vertex equals the first vertex
                geo = self.rb.asGeometry()
                self.geometry_changed.emit(geo, True)
            else:
                self.rb.reset(QgsWkbTypes.PolygonGeometry)

    def canvasMoveEvent(self, mouseEvent):
        if self.rb.numberOfVertices() > 1 and self.active:
            self.rb.removeLastPoint()
            self.rb.addPoint(mouseEvent.mapPoint())
        pass