domingo, 24 de noviembre de 2019

Creando un "buffer" en diferentes direcciones sin solapamiento con el shapefile inicial utilizando PyQGIS 3

En esta pregunta de gis.stackexchange.com se solicita una manera de generar una especie de "buffer" en diferentes direcciones sin solapar la capa inicial y combinando todos los rasgos producidos. Como la capa base es rectangular, dadas las distancias verticales y horizontales que representan "las diferentes direcciones", es sencillo determinar esos rasgos porque sólo hay que calcular dos puntos para genererar cada uno de los cuatro objetos QgsRectangle que se requieren.

Los objetos de tipo QgsRectangle se convierten a WKT (Well Known Text) para generar una memory layer con estos rasgos. El código desarrollado 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
registry = QgsProject.instance()

layer = registry.mapLayersByName('square')
 
feats = [ feat for feat in layer[0].getFeatures() ]
 
epsg = layer[0].crs().postgisSrid()
 
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
 
mem_layer = QgsVectorLayer(uri,
                           'different_directions_buffer',
                           'memory')

prov = mem_layer.dataProvider()

xmin, ymin, xmax, ymax = feats[0].geometry().boundingBox().toRectF().getCoords()

d1 = 2000
d2 = 4000

geom = []

p1 = QgsPointXY(xmin - d2, ymax + d1)
p2 = QgsPointXY(xmin, ymin - d1)

geom.append(QgsRectangle(p1,p2).asWktPolygon())

p3 = QgsPointXY(xmin, ymax + d1)
p4 = QgsPointXY(xmax, ymax)

geom.append(QgsRectangle(p3,p4).asWktPolygon())

p5 = QgsPointXY(xmax, ymax + d1)
p6 = QgsPointXY(xmax + d2, ymin - d1)

geom.append(QgsRectangle(p5,p6).asWktPolygon())

p7 = QgsPointXY(xmin, ymin)
p8 = QgsPointXY(xmax, ymin - d1)

geom.append(QgsRectangle(p7,p8).asWktPolygon())

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

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromWkt(geom[i]))

prov.addFeatures(feats)
registry.addMapLayer(mem_layer)

El resultado de ejecución del código anterior para la capa denominada 'square' se observa en la imagen siguiente y resultó tal como se esperaba.


No hay comentarios: