Criar buffers quadrados em torno de pontos no QGIS com Python?

8

Eu tenho coordenadas x, y em lat / long e preciso criar células quadradas de 5x5 graus em torno delas, com as coordenadas lat / long sendo os centróides.

Minha primeira opção é criar um buffer em torno dos centróides com 1 segmento e uma distância de 1/2 (5 °) * sqrt (2) (deve multiplicar por sqrt (2) bc, a ferramenta usa o centróide no canto do quadrado como a distância do buffer, ao contrário do centróide até a borda), o que resulta em quadrados laterais ao redor dos meus pontos e gire cada recurso em 45 graus. Prefiro não fazer isso, pois a distância não é tão precisa e não sei como girar cada recurso de buffer individual rapidamente.

Minha segunda opção, que parece muito mais simples, é criar um buffer em torno dos centróides com a distância que eu preciso ((1/2) * 5 °) e usar algo como a ferramenta Feature to Envelope do ArcMap.

Vejo que alguém tem a mesma pergunta aqui e uma resposta foi fornecida, mas não tenho idéia de como fazê-lo programaticamente.

srha
fonte

Respostas:

19

Como você está pensando em seu último parágrafo, fazer isso programaticamente com o PyQGIS, não é muito difícil. Você pode experimentar o próximo código. No entanto, usei um shapefile e as coordenadas projetadas em metros (o buffer tem 1000 m). Você só precisaria fazer algumas alterações.

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)

Depois de executar o código acima no Python Console do QGIS, obtive:

insira a descrição da imagem aqui

Funciona.

Nota de edição:

O código a seguir apresenta na tabela de atributos uma coluna para a coordenada x, a coordenada y e o número de identificação de cada ponto.

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)

Após executar o novo código no Python Console do QGIS, o resultado foi:

insira a descrição da imagem aqui

xunilk
fonte
Obrigado pela sua resposta. Como eu modificaria isso para que os polígonos de saída finais incluam os atributos dos pontos?
srha 12/09/16
Quais pontos apontam?
xunilk 12/09
1
Essa é outra pergunta, no entanto, você tem a resposta na minha Nota de edição .
xunilk 12/09
2
Para qualquer pessoa que tente fazer isso no QGIS 3 (2,99 no momento da redação deste comentário), substitua QgsMapLayerRegistryna última linha por QgsProject. Para mais informações consulte este
Techie_Gus
1
-1 é o padrão para um buffer completamente circular. Usando 1 obtém um buffer de quatro lados, 2 obtém um buffer de oito lados (4 + 4), 3 obtém um buffer de doze lados (8 + 4) e assim por diante.
xunilk
4

O QGIS 3 fornece uma alternativa rápida e suja: - Vetor -> Ferramentas de geoprocessamento -> Buffer

Selecione sua camada de pontos como uma camada de entrada, verifique se o estilo da tampa final está definido como quadrado e a distância deve ser metade do comprimento pretendido do quadrado (para que um quadrado de 1 km por lado tenha uma distância de 500 m).

miln40
fonte
1

Para transformar pontos em quadrados, você pode tentar native:bufferprocessar o algoritmo com o END_CAP_STYLEparâmetro definido como 2(quadrado).

Atenção! Os resultados podem variar e dependem do sistema de coordenadas da camada de entrada. Por exemplo, se você usar o WGS 84 e definir a distância para 5000isso, resultará em uma linha quadrada de 5000 graus (não metros).

insira a descrição da imagem aqui

Testado com 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

Exemplo de uso:

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