class MeasureAreaTool(QgsMapTool): finished = pyqtSignal() def __init__(self, canvas, msglog): super().__init__(canvas) self.canvas = canvas self.msglog = msglog self.start_point = self.middle_point = self.end_point = None self.rubber_band = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry) self.rubber_band.setColor(QColor(255, 0, 0, 100)) self.rubber_band.setWidth(3) self.rubber_band_points = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry) self.rubber_band_points.setIcon(QgsRubberBand.ICON_CIRCLE) self.rubber_band_points.setIconSize(10) self.rubber_band_points.setColor(QColor(255, 0, 0, 150)) crs = self.canvas.mapSettings().destinationCrs() self.area_calc = QgsDistanceArea() self.area_calc.setSourceCrs(crs, QgsProject.instance().transformContext()) self.area_calc.setEllipsoid(crs.ellipsoidAcronym()) self.reset() def reset(self): """ Reset log message and rubber band""" self.msglog.logMessage("") self.start_point = self.end_point = None self.rubber_band.reset(QgsWkbTypes.PolygonGeometry) self.rubber_band_points.reset(QgsWkbTypes.PointGeometry) def canvasPressEvent(self, event): pass def canvasReleaseEvent(self, event): transform = self.canvas.getCoordinateTransform() point = transform.toMapCoordinates(event.pos().x(), event.pos().y()) if self.start_point and event.button() == Qt.RightButton: multipoint = self.rubber_band.asGeometry() area = self.area_calc.measureArea(multipoint) anglemsg = QMessageBox(self.parent()) anglemsg.finished.connect(self.deactivate) anglemsg.setWindowTitle("Measure area tool") anglemsg.setText("Area: {} ".format( self.area_calc.formatArea(area, 3, QgsUnitTypes.AreaSquareMeters, True))) anglemsg.exec() self.finish() elif self.start_point: self.rubber_band.addPoint(point) self.rubber_band_points.addPoint(point) else: self.start_point = point self.rubber_band.addPoint(self.start_point) self.rubber_band_points.addPoint(self.start_point) def canvasMoveEvent(self, e): if self.start_point and not self.end_point: transform = self.canvas.getCoordinateTransform() point = transform.toMapCoordinates(e.pos().x(), e.pos().y()) self.rubber_band.movePoint(point) multipoint = self.rubber_band.asGeometry() area = self.area_calc.measureArea(multipoint) self.msglog.logMessage("") self.msglog.logMessage( "Current area: {} ".format( self.area_calc.formatArea(area, 3, QgsUnitTypes.AreaSquareMeters, True)), "Measure Area:", 0) def keyPressEvent(self, event): """ When escape key is pressed, line is restarted """ if event.key() == Qt.Key_Escape: self.reset() def finish(self): self.reset() self.finished.emit()