viernes, 14 de julio de 2017

Snapping puntos de un rasgo a otro en un vectorial tipo polígono mediante PyQGIS

Una forma para realizar esto es generando primero todo los vértices para cada rasgo debido a que el método 'moveVertex' de QgsVectorLayer tiene como parametros un QgsPoint del rasgo destino (target) y el id del rasgo fuente (source) y el id del vértice en dicho rasgo. Tales vértices se almacenan en una memory layer de puntos.

El código completo se añade 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
registry = QgsMapLayerRegistry.instance()

layer = registry.mapLayersByName('again')

feats = [ feat for feat in layer[0].getFeatures() ]

polygons = [ feat.geometry().asPolygon() for feat in feats ]

num_vertex_feats = [ len(polygon[0]) - 1 for polygon in polygons ] 

idx = [ [i,j] for i, num in enumerate(num_vertex_feats) for j in range(num) ]

points = [ feats[i].geometry().vertexAt(j) for i, num in enumerate(num_vertex_feats) for j in range(num) ]

epsg = layer[0].crs().postgisSrid()

uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer&field=i:integer&field=j:integer&field=x:real&field=y:real""&index=yes"

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

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(len(points)) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i, idx[i][0], idx[i][1], points[i][0], points[i][1]])
    feat.setGeometry(QgsGeometry.fromPoint(points[i]))

prov.addFeatures(feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Ejecutado el código anterior para el vectorial tipo polígono de la imagen siguiente, se obtiene la referida memory layer de puntos donde en su tabla de atributos se incluye toda la información para hacer el snapping.


El cuadro siguiente resume toda la información para hacer el snapping que nos interesa:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
target
id: 1, i: 0, j: 1, x: 408268.114929, y: 4441699.98256
source
id: 4, i: 1, j: 0, x: 412427.500504, y: 4439668.65472
target
id: 2, i: 0, j: 2, x: 402561.051, y: 4437637.32688
source
id: 6, i: 1, j: 2, x: 414362.098446, y: 4432220.45265
target
id: 5, i: 1, j: 1, x: 433804.807761, y: 4432607.37223
source
id: 9, i: 2, j: 2, x: 433321.158276, y: 4433671.4011

Las líneas de código a continuación permiten ejecutar el primer snapping:

1
2
3
4
5
6
7
8
9
registry = QgsMapLayerRegistry.instance()

layer = registry.mapLayersByName('again')

layer[0].startEditing()

layer[0].moveVertex(408268.114929, 4441699.98256, 1, 0)

layer[0].commitChanges()

cuyo resultado es el siguiente:



Para el segundo snapping se tiene:

1
2
3
4
5
6
7
8
9
registry = QgsMapLayerRegistry.instance()

layer = registry.mapLayersByName('again')

layer[0].startEditing()

layer[0].moveVertex(402561.051, 4437637.32688, 1, 2)

layer[0].commitChanges()

y para el tercer y último:

1
2
3
4
5
6
7
8
9
registry = QgsMapLayerRegistry.instance()

layer = registry.mapLayersByName('again')

layer[0].startEditing()

layer[0].moveVertex(433804.807761, 4432607.37223, 2, 2)

layer[0].commitChanges()

El resultado final es:


No hay comentarios: