En el post anterior se adaptó un plugin plantilla, tipo botón checkeable, para producir rectángulos por dragado del Map Canvas en QGIS 3. Ahora, se va a adaptar la misma plantilla pero para producir círculos por dragado del Map Canvas. El código completo colocado en el archivo template.py se muestra a continuación. Sin embargo, para que funcione adecuadamente se requieren otras modificaciones que se detallan más adelante.
""" /*************************************************************************** Test A QGIS plugin Plugin for testing things ------------------- begin : 2015-01-28 copyright : (C) 2015-2017 by German Carrillo, GeoTux email : gcarrillo@linuxmail.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ """ import os, math # Import the PyQt and QGIS libraries from qgis.core import (QgsApplication, QgsRasterLayer, QgsRaster, QgsPointXY, QgsPoint, QgsCircle, QgsGeometry, QgsRectangle, QgsProject, QgsVectorLayer, QgsFeature) from qgis.gui import QgsMapToolEmitPoint, QgsRubberBand from PyQt5.QtCore import QObject, QTimer, Qt from PyQt5.QtWidgets import ( QMessageBox, QAction, QMenu, QActionGroup, QWidgetAction, QToolTip) from PyQt5.QtGui import ( QIcon ) class Test: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.tooltipRaster = TooltipRasterMapTool( self.iface ) def initGui(self): # Create action that will start plugin configuration self.action = QAction( QIcon( os.path.dirname(os.path.realpath(__file__)) + "/icon_default.png" ), "Making Circles", self.iface.mainWindow() ) # connect the action to the run method self.action.triggered.connect( self.run ) self.action.setCheckable( True ) self.iface.mapCanvas().mapToolSet.connect( self.mapToolWasSet ) # Add toolbar button to the Plugins toolbar self.iface.addToolBarIcon(self.action) # Add menu item to the Plugins menu self.iface.addPluginToMenu("&Tooltip for Raster Values", self.action) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu( "&Tooltip for Raster Values", self.action ) self.iface.removeToolBarIcon(self.action) # run method that performs all the real work def run(self, checked): if checked: self.iface.mapCanvas().setMapTool( self.tooltipRaster ) else: self.iface.mapCanvas().unsetMapTool( self.tooltipRaster ) def mapToolWasSet( self, newTool ): if type(newTool) != TooltipRasterMapTool: self.action.setChecked( False ) class TooltipRasterMapTool(QgsMapToolEmitPoint): def __init__(self, iface): self.iface = iface self.canvas = self.iface.mapCanvas() QgsMapToolEmitPoint.__init__(self, self.canvas) self.start_point = None self.end_point = None self.rubber_band = QgsRubberBand(self.canvas, True) self.rubber_band.setColor(Qt.red) self.rubber_band.setOpacity(0.7) def canvasPressEvent(self, e): self.start_point = self.toMapCoordinates(e.pos()) self.end_point = self.start_point def canvasMoveEvent(self, e): if self.start_point: end_point = self.toMapCoordinates(e.pos()) self.rubber_band.reset() q = self.get_circ_par(self.start_point, end_point) h = QgsCircle(q[0], q[1]).toPolygon().asWkt() self.rubber_band.setToGeometry(QgsGeometry.fromWkt(h), None) def canvasReleaseEvent(self, e): self.end_point = self.toMapCoordinates(e.pos()) r = self.get_circle() self.rubber_band.reset() self.start_point = None self.end_point = None circ_feat = r #definng Status Bar statusBar = self.iface.mainWindow().statusBar() #selecting elements in Status Bar elements = statusBar.children() #selecting widget in Status Bar with ESPG EPSG = elements[1].children()[10] EPSG = EPSG.text().split(':') uri = "Polygon?crs=epsg:" + EPSG[1] + "&field=id:integer""&index=yes" mem_layer = QgsVectorLayer(uri, 'circle', 'memory') prov = mem_layer.dataProvider() feat = QgsFeature() feat.setAttributes([0]) feat.setGeometry(QgsGeometry.fromWkt(circ_feat)) prov.addFeatures([feat]) QgsProject.instance().addMapLayer(mem_layer) def get_circ_par(self, startPoint, endPoint): par = [QgsPoint(startPoint.x(), startPoint.y()), math.sqrt((startPoint.x() - endPoint.x())**2 + (startPoint.y() - endPoint.y())**2)] return par def get_circle(self): dist = math.sqrt((self.start_point.x() - self.end_point.x())**2 + (self.start_point.y() - self.end_point.y())**2) circ = QgsCircle(QgsPoint(self.start_point), dist).toPolygon().asWkt() return circ
La carpeta completa de la plantilla (template) se guarda con el nombre de makingcircles en la ruta de plugins de QGIS 3. El archivo template.py que tiene el código anterior se renombra como making_circles.py. Para que lo procese de la manera esperada se hace la modificación siguiente en el __init__py.
. . . def classFactory(iface): # load Test class from file making_circles.py from .making_circles import Test return Test(iface)
También necesitamos la modificación siguiente en el metadata.txt para que el nombre del plugin sea procesado como se espera. Una modificación similar también fue realizada en el código fuente (making_circles.py) al inicio del método 'initGui'.
; the next section is mandatory [general] name=Making Circles plugin description=For Making Circles . . .
Finalmente, se produce un icono personalizado 24x24 (con el mismo nombre) para identificarlo de manera precisa. La ejecución del plugin se observa en la imagen a continuación.
No hay comentarios:
Publicar un comentario