domingo, 12 de enero de 2020

Clase plantilla con QDialog para crear puntos

En el post anterior se introdujo una Clase plantilla con QDialog para visualizar las coordenadas del Map Canvas de QGIS con un click del ratón. En este post se va a aprovechar la generación de estas coordenadas para producir memory layers de puntos con una función especial conectada a un QPushButton.

El QDialog incluye un objeto del tipo QgsProjectionSelectionWidget que permite asignar automáticamente la proyección del proyecto al iniciar el QDialog o cambiarla manualmente si es necesario. El código completo se presenta a continuación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from PyQt5.QtCore import Qt
from qgis.gui import QgsMapToolEmitPoint

class Dlg(QDialog):

    def __init__(self):
        QDialog.__init__(self)
        self.layout = QGridLayout(self)
        self.label1 = QLabel('Coordinates of map')
        self.line_edit = QLineEdit()
        self.line_edit.setFixedWidth(350)
        self.sel_proj = QgsProjectionSelectionWidget()
        proj = QgsProject.instance().crs().postgisSrid()
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(proj)
        self.sel_proj.setCrs(crs)
        self.btn1 = QPushButton('Create Point', self)

        # Save reference to the QGIS interface
        self.iface = iface
        
        # a reference to our map canvas
        self.canvas = self.iface.mapCanvas() 
        # this QGIS tool emits as QgsPoint after each click on the map canvas
        self.pointTool = QgsMapToolEmitPoint(self.canvas)

        self.layout.addWidget(self.label1, 0, 0)
        self.layout.addWidget(self.line_edit, 1, 0)
        self.layout.addWidget(self.sel_proj, 2, 0)
        self.layout.addWidget(self.btn1, 3, 0)

        self.pointTool.canvasClicked.connect(self.display_point)
        self.canvas.setMapTool(self.pointTool)
        
        self.btn1.clicked.connect(self.create_point)

    def display_point(self, point, button):
        # report map coordinates from a canvas click
        coords = "{}, {}".format(point.x(), point.y())
        self.line_edit.setText(str(coords))
    
    def create_point(self):
        
        pt = self.line_edit.text().split(',')
        
        try:
            x = float(pt[0])
            y = float(pt[1])
            point = QgsPointXY(x,y)

            epsg = self.sel_proj.crs().postgisSrid()
            
            uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

            mem_layer = QgsVectorLayer(uri,
                                       'point',
                                       'memory')

            prov = mem_layer.dataProvider()

            feat = QgsFeature()
            feat.setAttributes([0])
            feat.setGeometry(QgsGeometry.fromPointXY(point))
            prov.addFeatures([feat])
            QgsProject.instance().addMapLayer(mem_layer)

        except ValueError:
            pass

w = Dlg()
w.setWindowTitle('Point Creator')
w.setWindowFlags(Qt.WindowStaysOnTopHint)
w.show()

En la imagen siguiente se observa el QDialog, con sus elementos Qt correspondientes, que genera el código anterior. Una vez ejecutado en la Python Console se han hecho varios clicks del ratón en la zona del ráster; seguido posteriormente de un click en el botón 'Create Point' para producirlos.


No hay comentarios: