¿Crear buffers cuadrados alrededor de puntos en QGIS con Python?

8

Tengo coordenadas x, y en lat / long y necesito crear celdas cuadradas de 5x5 grados alrededor de ellas, siendo las coordenadas lat / long los centroides.

Mi primera opción es crear un búfer alrededor de los centroides con 1 segmento y una distancia de 1/2 (5 °) * sqrt (2) (debe multiplicarse por sqrt (2) bc, la herramienta usa el centroide en la esquina del cuadrado como la distancia del búfer, en oposición al centroide al borde), que da como resultado cuadrados laterales alrededor de mis puntos, luego gira cada entidad 45 grados. Prefiero no hacer esto ya que la distancia no es tan precisa y no sé cómo rotar cada función de búfer individual rápidamente.

Mi segunda opción, que parece mucho más simple, es crear un búfer alrededor de los centroides con la distancia que necesito ((1/2) * 5 °) y luego usar algo como la herramienta Característica para envolver de ArcMap.

Veo que alguien tiene la misma pregunta aquí y se proporcionó una respuesta, pero no tengo idea de cómo hacerlo mediante programación.

srha
fuente

Respuestas:

19

Como se preguntó en su último párrafo, hacer eso mediante programación con PyQGIS no es muy difícil. Puedes probar el siguiente código. Sin embargo, utilicé un archivo de formas y coordenadas proyectadas en metros (el búfer tiene 1000 m). Solo necesitaría hacer algunos cambios.

layer = iface.activeLayer()

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

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

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

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    new_feat = QgsFeature()
    new_feat.setAttributes([i])
    tmp_feat = feat.geometry().buffer(1000, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Después de ejecutar el código anterior en la Consola Python de QGIS, obtuve:

ingrese la descripción de la imagen aquí

Funciona.

Nota de edición:

El siguiente código introduce en la tabla de atributos una columna para la coordenada x, la coordenada y y el número de ID para cada punto.

layer = iface.activeLayer()

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

epsg = layer.crs().postgisSrid()

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

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

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    point = feat.geometry().asPoint()
    new_feat = QgsFeature()
    new_feat.setAttributes([i, point[0], point[1], feat.id()])
    tmp_feat = feat.geometry().buffer(1000, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Después de ejecutar el nuevo código en la Consola Python de QGIS, el resultado fue:

ingrese la descripción de la imagen aquí

xunilk
fuente
Gracias por su respuesta. ¿Cómo modificaría esto para que los polígonos de salida final incluyan los atributos de los puntos?
srha
¿Qué atributos de punto?
xunilk
1
Esta es otra pregunta, sin embargo, tiene la respuesta en mi Nota de edición .
xunilk
2
Para cualquiera que intente esto en QGIS 3 (2.99 al momento de escribir este comentario), reemplace QgsMapLayerRegistryen la última línea con QgsProject. Para obtener más información, vea esto
Techie_Gus
1
-1 es el valor predeterminado para un búfer completamente circular. Al usar 1 obtiene un buffer de cuatro lados, 2 obtiene un buffer de ocho lados (4 + 4), 3 obtiene un buffer de doce lados (8 + 4) y así sucesivamente.
xunilk
4

QGIS 3 ofrece una alternativa rápida y sucia: - Vector -> Herramientas de geoprocesamiento -> Buffer

Seleccione su capa de puntos como capa de entrada, asegúrese de que el estilo de la tapa final esté configurado en cuadrado y la distancia debe ser la mitad de la longitud del cuadrado deseado (por lo que un cuadrado de 1 km por lado debe tener una distancia de 500 m).

miln40
fuente
1

Para transformar puntos en cuadrados, puede probar el native:bufferalgoritmo de procesamiento con el END_CAP_STYLEparámetro establecido en 2(cuadrado).

¡Advertencia! Los resultados pueden variar y dependen del sistema de coordenadas de la capa de entrada. Por ejemplo, si usa WGS 84 y establece la distancia a 5000esto, se obtendrá una línea cuadrada de 5000 grados (no metros).

ingrese la descripción de la imagen aquí

Probado con pyQGIS 3.6.1:

def buffer(input, distance, output, before_processing_reproject_to_epsg_number=None):
    params = {'INPUT': input,
              'DISTANCE': distance,
              'END_CAP_STYLE': 2 , # - 0: Round - 1: Flat - 2: Square
              'DISSOLVE': False,
              'OUTPUT': output}
    feedback = qgis.core.QgsProcessingFeedback()
    alg_name = 'native:buffer'
    # print(processing.algorithmHelp(alg_name)) # tool tips
    result = processing.run(alg_name, params, feedback=feedback)
    return  result

Ejemplo de uso:

buffer_result = buffer(input=r'C:\input.shp', distance=5000, output=r'C:\output.shp')
print(buffer_result)
Camarada che
fuente