Pruebe el siguiente ejemplo. Pegue en un nuevo editor en la consola de Python, seleccione una capa activa (debe ser una capa vectorial, ya que no hay ninguna salvaguarda en el script para manejar capas rasterizadas, etc.) y haga clic en ejecutar para probar.
class PrintSnappedPoint(QgsMapToolEmitPoint):
def __init__(self, canvas, transform=False):
self.canvas = canvas
QgsMapToolEmitPoint.__init__(self, self.canvas)
self.transform = transform
self.project = QgsProject.instance()
self.l = iface.activeLayer()
self.i = QgsSnapIndicator(self.canvas)
self.u = self.canvas.snappingUtils()
self.c = self.u.config()
self.c.setEnabled(True)
self.c.setMode(QgsSnappingConfig.AdvancedConfiguration)
self.s = QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.VertexFlag, 25.00,
QgsTolerance.Pixels)
self.c.setIndividualLayerSettings(self.l, self.s)
self.u.setConfig(self.c)
#Define source and destination crs's and instantiate QgsCoordinateTransform class
self.src_crs = self.project.crs()
#Best to change epsg code below to a local projected crs (e.g. UTM)
self.dst_crs = QgsCoordinateReferenceSystem('EPSG:3857')
self.x_form = QgsCoordinateTransform(self.src_crs, self.dst_crs, self.project)
def canvasMoveEvent(self, e):
m = self.u.snapToMap(e.pos())
self.i.setMatch(m)
def canvasPressEvent(self, e):
if self.i.match().type():
pointxy = self.i.match().point()
else:
pointxy = None
if pointxy:
if self.transform:
tr = self.x_form.transform(pointxy)
point = [tr.x(), tr.y()]
else:
point = [pointxy.x(), pointxy.y()]
print('Point snapped to vertex: {}'.format(point))
def deactivate(self):
self.s = QgsSnappingConfig.IndividualLayerSettings(False, QgsSnappingConfig.NoSnapFlag, 25.00,
QgsTolerance.Pixels)
self.c.setIndividualLayerSettings(self.l, self.s)
self.u.setConfig(self.c)
canvas = iface.mapCanvas()
#to transform snapped click-points, pass True as 2nd argument to constructor
T = PrintSnappedPoint(canvas, True)
canvas.setMapTool(T)
Edición basada en los comentarios:
He actualizado el código anterior para dar un ejemplo de uso de QgsCoordinateTransform
para transformar el punto de clic del proyecto a otro crs de su elección. En este ejemplo mi crs de proyecto es epsg:4326 así que transformo el punto de ese a epsg:3857. Sin embargo, yo recomendaría cambiar el código epsg del crs de destino a un crs local proyectado con precisión, como una zona UTM apropiada para su área.
Para utilizar la función de transformación, pase True como segundo argumento al constructor del PrintSnappedPoint
constructor de la clase. Si no se pasa un segundo argumento, el parámetro de transformación será por defecto False y los puntos ajustados se imprimirán según el crs del proyecto.
Los resultados esperados se muestran en el siguiente gif: