Ejemplo n.º 1
0
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()