2026-03-19 14:06:08 +01:00

104 lines
3.7 KiB
Python

# Import PyQt libs
from PyQt5.QtCore import (
pyqtSignal,
Qt,
)
from PyQt5.QtGui import QColor
# Import PyQgis libs
from qgis.core import (
QgsRectangle,
QgsPointXY,
QgsWkbTypes,
QgsCoordinateReferenceSystem,
QgsCoordinateTransform,
)
from qgis.gui import (
QgsMapTool,
QgsMapMouseEvent,
QgsRubberBand,
)
class RectangleFeatureTool(QgsMapTool):
signal = pyqtSignal()
def __init__(self, project, canvas):
super().__init__(canvas)
self.project = project
self.canvas = canvas
# initiate variable to calculate the extent
self.start_point = None
self.end_point = None
self.new_extent = None
# flag to check if the left mouse button was pressed
self.is_left_button_pressed = False
# create a rubber line object
# to display the geometry of the dragged object on the canvas
self.rubber_band = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
self.rubber_band.setColor(QColor(255, 0, 0, 50))
self.rubber_band.setWidth(2)
# Mouse button pressed.
def canvasPressEvent(self, event: QgsMapMouseEvent):
if event.button() == Qt.LeftButton:
self.start_point = self.toMapCoordinates(event.pos())
self.end_point = self.start_point
self.is_left_button_pressed = True
# The cursor moves across the screen.
def canvasMoveEvent(self, event: QgsMapMouseEvent):
# if the left mouse button is pressed
if self.is_left_button_pressed:
self.end_point = self.toMapCoordinates(event.pos())
# draw a rectangle on the canvas
self.showRect(self.start_point, self.end_point)
# The mouse button is released.
def canvasReleaseEvent(self, event: QgsMapMouseEvent):
# if the left mouse button was released
if event.button() == Qt.LeftButton:
if event.type() == 3:
# get the rectangle created from the click point and
# left mouse button release points
self.new_extent = self.rectangle()
self.signal.emit()
# toggle the flag, the left mouse button is no longer held down
self.is_left_button_pressed = False
self.rubber_band.reset() # remove rubber band from canvas
sourceCrs = QgsCoordinateReferenceSystem(self.project.crs())
destCrs = QgsCoordinateReferenceSystem(4326)
tr = QgsCoordinateTransform(sourceCrs, destCrs, self.project)
# Draw the rectangle on the canvas
def showRect(self, startPoint, endPoint):
# Reset the last drawn rectangle
self.rubber_band.reset(QgsWkbTypes.PolygonGeometry)
# Make sure the mouse has moved
if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
return
# Create the rectangle
point1 = QgsPointXY(startPoint.x(), startPoint.y())
point2 = QgsPointXY(startPoint.x(), endPoint.y())
point3 = QgsPointXY(endPoint.x(), endPoint.y())
point4 = QgsPointXY(endPoint.x(), startPoint.y())
self.rubber_band.addPoint(point1, False)
self.rubber_band.addPoint(point2, False)
self.rubber_band.addPoint(point3, False)
self.rubber_band.addPoint(point4, True) # true to update canvas
self.rubber_band.show()
def rectangle(self):
if self.start_point is None or self.end_point is None:
return None
elif self.start_point.x() == self.end_point.x() or self.start_point.y() == self.end_point.y():
return None
return QgsRectangle(self.start_point, self.end_point)
def deactivate(self):
# unload the map tool on the mouse
QgsMapTool.deactivate(self)
self.deactivated.emit()