7 votos

Obteniendo coordenadas de un clic de ratón en QGIS 3 (complemento de python)

Estoy tratando de obtener coordenadas de un clic de ratón en QGIS 3 y python 3 utilizando el generador de plugin.

He intentado utilizando la respuesta de esta publicación, y puedo lograr que las coordenadas se impriman en la consola de python en QGIS pero al mismo tiempo recibo el mensaje "'TypeError: 'QgsMapToolEmitPoint' object is not iterable" o "'QgsMapToolEmitPoint' object does not support indexing"

No recuerdo haber visto nunca un programa en python que produzca un error pero aún así logre calcular y producir el resultado deseado. El error de "not iterable" se remonta a la línea con el bucle "for point in ... " el error de "does not support indexing" se produce si por ejemplo hago x = pointTool[0]

Aquí hay una versión del código:

from qgis.gui import QgsMapToolEmitPoint 

def display_point(pointTool):
    #print(pointTool)
    cood = []
    for point in pointTool:
        cood.append(point)
    print(cood)

# una referencia a nuestro lienzo de mapas
canvas = iface.mapCanvas()

# esta herramienta de QGIS emite como QgsPoint después de cada clic en el lienzo del mapa
pointTool = QgsMapToolEmitPoint(canvas)

pointTool.canvasClicked.connect(display_point)

canvas.setMapTool(pointTool)

display_point(pointTool)

3voto

Keith Puntos 8

Tengo un poco de dificultad para obtener las coordenadas x, y de "canvasReleaseEvent". Por el momento, estoy escribiendo mi código en esa función ya que muestra las coordenadas x, y (simplemente declarando "x=point.x()" etc).

Creo que probaré el código de @xunilk y veré si eso sería más fácil.

https://webgeodatavore.github.io/pyqgis-samples/gui-group/QgsMapTool.html

# coding: utf-8
from PyQt4.QtCore import Qt
from qgis.gui import QgsMapTool
from qgis.utils import iface

class SendPointToolCoordinates(QgsMapTool):
    """ Permite obtener coordenadas al hacer clic en una capa.
    """
    def __init__(self, canvas, layer):
        """ Constructor.
        """
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas
        self.layer = layer
        self.setCursor(Qt.CrossCursor)

    def canvasReleaseEvent(self, event):
        point = self.toLayerCoordinates(self.layer, event.pos())

        print(point.x(), point.y())

layer, canvas = iface.activeLayer(), iface.mapCanvas()

send_point_tool_coordinates = SendPointToolCoordinates(
    canvas,
    layer
)
canvas.setMapTool(send_point_tool_coordinates)

1voto

Yada Puntos 9489

En QGIS 3 necesitas una función algo diferente. Siguiendo la versión de tu código, puede imprimir clics del mouse:

from qgis.gui import QgsMapToolEmitPoint 

def display_point(pointTool):
    try:
        print(pointTool.x(), pointTool.y())
    except AttributeError:
        pass

# una referencia a nuestro lienzo de mapa
canvas = iface.mapCanvas()

# esta herramienta de QGIS emite un QgsPoint después de cada clic en el lienzo de mapa
pointTool = QgsMapToolEmitPoint(canvas)

pointTool.canvasClicked.connect(display_point)

canvas.setMapTool(pointTool)

display_point(pointTool)

como se puede observar en la siguiente imagen:

enter image description here

1voto

ppg Puntos 16

En QGIS 3.16 lo hice de una manera simple. Creé un botón de complemento. Después de hacer clic en eso (1) puedo hacer clic en el mapa y obtener la coordenada como un self.iface.messageBar().pushMessage.Ingrese la descripción de la imagen aquí

from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.PyQt.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtWidgets import QTableView, QApplication
from urllib.request import urlopen
from qgis.core import *
from qgis.gui import *
from qgis.gui import QgsMapToolEmitPoint 
from qgis.utils import iface
from qgis.gui import QgsMapTool
# Inicializar recursos de Qt desde el archivo resources.py
from .resources import *
# Importar el código para el diálogo
from .webgis_connector_dialog import WebGISConnectorDialog
import os.path
import sys
import urllib3

class PointTool(QgsMapTool):   
    def __init__(self, canvas):
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas 
        self.iface = iface

    def canvasPressEvent(self, event):
        pass

    def canvasMoveEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def canvasReleaseEvent(self, event):
        #Obtener el clic
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)
        x1=point[0]
        y1=point[1]
        link="'http://gisground2.ibbenbueren.intern?koordinate="+str(x1)+","+str(y1)+"'"
        #qgis.utils.iface.messageBar().pushMessage("hhhh", u"Gespeichert ist folgender Layer: "+link, duration=7)

        self.iface.messageBar().pushMessage("Enlace al WebGIS: http://webgis.ibbenbueren.intern?koordinate="+str(round(point[0],1))+","+str(round(point[1],1))+"", duration=7)

    def activate(self):
        pass

    def deactivate(self):
        pass

    def isZoomTool(self):
        return False

    def isTransient(self):
        return False

    def isEditTool(self):
        return True

class WebGISConnector:
    """Implementación del complemento QGIS."""

    def __init__(self, iface):
        self.iface = iface

    def __init__(self, iface):
        """Constructor.

        :param iface: Una instancia de interfaz que se pasará a esta clase
            que proporciona el gancho mediante el cual puede manipular la aplicación QGIS
            en tiempo de ejecución.
        :type iface: QgsInterface
        """
        # Guardar referencia a la interfaz de QGIS
        self.iface = iface
        # inicializar el directorio del complemento
        self.plugin_dir = os.path.dirname(__file__)
        # inicializar configuración regional
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'WebGISConnector_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declarar atributos de instancia
        self.actions = []
        self.menu = self.tr(u'Conector WebGIS')

        # Verificar si el complemento se inició por primera vez en la sesión actual de QGIS
        # Debe establecerse en initGui() para sobrevivir a las recargas del complemento
        self.first_start = None

    # Sin importancia PyMethodMayBeStatic
    def tr(self, message):
        """Obtener la traducción de una cadena utilizando la API de traducción de Qt.

        Implementamos esto nosotros mismos ya que no heredamos de QObject.

        :param message: Cadena para traducir.
        :type message: str, QString

        :returns: Versión traducida del mensaje.
        :rtype: QString
        """
        return QCoreApplication.translate('WebGISConnector', message)

    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Agregar un icono de barra de herramientas a la barra de herramientas.

        :param icon_path: Ruta al icono para esta acción. Puede ser una ruta de recurso
            (por ejemplo, ':/plugins/foo/bar.png') o una ruta de sistema de archivos normal.
        :type icon_path: str

        :param text: Texto que debe mostrarse en los elementos de menú para esta acción.
        :type text: str

        :param callback: Función que se llamará cuando se active la acción.
        :type callback: función

        :param enabled_flag: Un indicador que indica si la acción debe estar habilitada
            de forma predeterminada. Los valores predeterminados a Verdadero.
        :type enabled_flag: bool

        :param add_to_menu: Indicador de si la acción también debe
            agregarse al menú. El valor predeterminado es Verdadero.
        :type add_to_menu: bool

        :param add_to_toolbar: Indicador de si la acción también debe
            agregarse a la barra de herramientas. El valor predeterminado es Verdadero.
        :type add_to_toolbar: bool

        :param status_tip: Texto opcional que se mostrará en un popup cuando el puntero
            del mouse se coloque sobre la acción.
        :type status_tip: str

        :param parent: Widget principal para la nueva acción. Los valores predeterminados son Ninguno.
        :type parent: QWidget

        :param whats_this: Texto opcional para mostrar en la barra de estado cuando el
            puntero del mouse se coloque sobre la acción.

        :returns: La acción que se creó. Tenga en cuenta que la acción también es
            agregado a la lista de self.actions.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Agrega el icono del complemento a la barra de herramientas
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToWebMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Crea las entradas de menú y los iconos de la barra de herramientas dentro de la GUI de QGIS."""

        icon_path = ':/plugins/webgis_connector/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Conector WebGIS'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # se establecerá en Falso en run()
        self.first_start = True

    def unload(self):
        """Elimina la entrada de menú y el icono del complemento de la GUI de QGIS."""
        for action in self.actions:
            self.iface.removePluginWebMenu(
                self.tr(u'&Conector WebGIS'),
                action)
            self.iface.removeToolBarIcon(action)

    def run(self):
        """Método de ejecución que realiza todo el trabajo real"""

        # Crear el diálogo con elementos (después de la traducción) y mantener referencia
        # Solo crear GUI UNA VEZ en la devolución de llamada, para que solo se cargue cuando se inicie el complemento
        if self.first_start == True:
            self.first_start = False
            self.dlg = WebGISConnectorDialog()

        self.iface.messageBar().pushMessage("Por favor, haz clic en el mapa ahora...", duration=3)  
        tool = PointTool(iface.mapCanvas())
        iface.mapCanvas().setMapTool(tool)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X