sábado, 1 de agosto de 2020

Cómo producir rejillas (grid) hexagonales mediante PyQGIS 3

En un post anterior se introdujo un código para producir rejillas hexagonales mediante la versión previa de PyQGIS, es decir, con Python 2. Aunque las diferencias no son muchas, puede ser abrumador tratar de hacerlo funcionar si no nos familiarizamos previamente con las nuevas clases de PyQGIS 3.

A diferencia de las rejillas cuadradas, el punto de comienzo (punto de referencia del primer hexágono) en las filas de los hexagonos debe ser movido, según la fila, para que se ajusten adecuadamente con la de abajo. Los desplazamientos horizontal y vertical han sido determinados con base en consideraciones geométricas de los polígonos hexagonales.

El código completo, para generar una rejilla hexagonal (lado 1000 m) con 8 filas y 10 columnas (EPSG:32612), se incluye a continuación. El punto de referencia fue (354972.451507, 4473426.04508).

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
import numpy as np
 
bufferLength = 1000
polygonSides = 6
 
inc_x = 2 * bufferLength * np.cos(np.pi*30/180)
inc_y = inc_x * np.cos(np.pi*30/180)
 
p1 = QgsPointXY(354972.451507, 4473426.04508)
 
points = []
 
x = p1.x() + inc_x/2
y = p1.y()
 
rows = 8
cols = 10
     
for i in range(rows):
    for j in range(cols):
        point = QgsPointXY(x, y)
        points.append(point)
        x += inc_x
    y -= inc_y
    ver = i%2
 
    if ver ==0:
        h = 0
    else:
        h = inc_x/2
    x = p1.x() + h
 
epsg = 32612
 
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
 
mem_layer = QgsVectorLayer(uri,
                           'hexgrid',
                           'memory')
 
prov = mem_layer.dataProvider()
 
for i, point in enumerate(points):
    outFeat = QgsFeature()
 
    outFeat.setGeometry(QgsGeometry.fromPolygonXY([[ QgsPointXY(point[0] + np.sin(angle)*bufferLength, point[1] + np.cos(angle)*bufferLength)
                        for angle in np.linspace(0, 2*np.pi, polygonSides + 1, endpoint = True) ]]))
     
    outFeat.setAttributes([i])
    prov.addFeatures([outFeat])
 
QgsProject.instance().addMapLayer(mem_layer)

Después de ejecutado en la Python Console de Qgis se obtiene lo siguiente:


En el Map Canvas de QGIS 3 se observa el punto de referencia (en rojo) usado para generar la rejilla. Sólo falta hacer más prolijo el resultado cortando la memory layer generada para evitar los trozos “salientes” por fila y columna. Además, es necesario indicar el punto de comienzo de la rejilla en lugar del punto de referencia del primer hexágono; temas del próximo post.

No hay comentarios: