domingo, 13 de enero de 2019

Crear polígono regular de área específica, a partir de puntos, con PyQGIS 3

La creación de polígonos ya ha sido tratada en Cómo producir buffers, alrededor de puntos, con diferentes números de lados en PyQGIS para la versión anterior de QGIS. Sin embargo, el criterio empleado allí fue el de la distancia buffer, es decir, desde el centro a cualquiera de sus vértices.

En este post se va a usar un criterio diferente: el área. Como se va a considerar un polígono regular de cinco lados se necesita la fórmula del área como función del radio; la cual se ha tomado de aquí. Para corroborar que el código funciona de la manera esperada se imprime la longitud del lado para un área control. El código completo es el siguiente:

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
import numpy as np

area = 2377641.2907378837 #considering a regular pentagon

#bufferLength obtained from area formula of regular pentagon
bufferLength = np.sqrt((2./5.)*(area/np.sin(72.*np.pi/180.)))

print (bufferLength) #value must be 1000 meters if area is equal to 2377641.2907378837 square meters

polygonSides = 5  #considering a regular pentagon

layer = qgis.utils.iface.activeLayer()
 
points = [ feat.geometry().asPoint() for feat in layer.getFeatures() ]
 
epsg = layer.crs().postgisSrid()
 
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
 
mem_layer = QgsVectorLayer(uri,
                           'pentagons',
                           'memory')
 
prov = mem_layer.dataProvider()
 
for i, point in enumerate(points):
    outFeat = QgsFeature()
 
    outFeat.setGeometry(QgsGeometry.fromMultiPolygonXY([[[ QgsPointXY(point[0] + np.sin(angle)*bufferLength, point[1] + np.cos(angle)*bufferLength)
                        for angle in np.linspace(0, 2*np.pi, polygonSides, endpoint = False) ]]]))

    outFeat.setAttributes([i])
    prov.addFeatures([outFeat])
 
QgsProject.instance().addMapLayer(mem_layer)

El vectorial de puntos que servirá de base para la generación de los polígonos se encuentra visualizado en la imagen siguiente:


Después de ejecutado el código anterior en la Python Console de QGIS se obtiene el resultado esperado de la imagen a continuación:


No hay comentarios: