Criação automatizada de linhas perpendiculares entre uma camada de pontos e uma camada de linhas

10

Estou usando o QGIS e estou procurando um script ou um plug-in que possa criar um grande número de linhas perpendiculares de uma camada de ponto a linhas em uma camada de linha separada.

Até agora, tentei usar a função Distância do Hub no MMQGIS (transformar as linhas em pontos e depois conectar os pontos ao hub mais próximo) e a respectiva ferramenta dos geoalgoritmos do QGIS. Nem funcionou. Ambos demoram mais de 2 horas e criam todas as linhas da camada ou linhas que não são perpendiculares ou conectadas aos pontos.

Na figura, você pode ver o status atual do projeto. As linhas perpendiculares devem correr dos pontos para a linha mais próxima. No final, eu gostaria de usar pontos de interseção com uma linha entre os pontos e as fronteiras do país para criar um buffer de polígonos de quatro lados com dois polígonos de profundidade. Menciono isso no caso de haver uma maneira mais fácil de fazer isso. insira a descrição da imagem aqui insira a descrição da imagem aqui

Eu sei que existem alguns posts sobre como criar linhas perpendiculares, mas nenhum deles resolveu meu problema.

Monody
fonte
1
@ Germán Carrillo Esta pergunta não é uma duplicata exata da pergunta existente "Desenhando linhas perpendiculares no PyQGIS?" ( gis.stackexchange.com/questions/59169/… ) porque a resposta não usa o método 'closestSegmentWithContext' em um loop para explorar cada interação entre pontos e linhas de recursos, para obter uma distância mínima para criar uma camada de memória de linhas. É impossível porque esta resposta usa apenas pontos. Por favor, revise-o novamente.
xunilk
1
Ainda acho a outra resposta uma boa base para resolver esta questão. O OP deveria ter mencionado na pergunta original que ele / ela estava ciente das postagens relacionadas E nos dizer por que elas não funcionaram para ele / ela. No entanto, boa resposta, obrigado por postar!
Germán Carrillo

Respostas:

7

O próximo script automatizou a criação de linhas perpendiculares entre uma camada de pontos e uma camada de linhas. Os segmentos perpendiculares (recursos de uma camada de memória) criados são executados desde os pontos até o recurso mais próximo da camada de linha.

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

p_lyr = layers[0]
l_lyr = layers[1]

epsg = p_lyr.crs().postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&field=distance:double(20,2)&index=yes"

dist = QgsVectorLayer(uri, 
                      'dist', 
                      'memory')

QgsMapLayerRegistry.instance().addMapLayer(dist)

prov = dist.dataProvider()

lines_features = [ line_feature for line_feature in l_lyr.getFeatures() ] 
points_features = [ point_feature for point_feature in p_lyr.getFeatures() ]

feats = []

for p in points_features:

    minDistPoint = min([l.geometry().closestSegmentWithContext( p.geometry().asPoint() ) for l in lines_features])[1]
    feat = QgsFeature()
    feat.setGeometry(QgsGeometry.fromPolyline([p.geometry().asPoint(), minDistPoint]))
    feat.setAttributes([points_features.index(p),feat.geometry().length()])
    feats.append(feat)

prov.addFeatures(feats)

Eu tentei com uma situação muito semelhante à apresentada na pergunta:

insira a descrição da imagem aqui

Após a execução do código no Python Console do QGIS, foi obtido:

insira a descrição da imagem aqui

xunilk
fonte
Trabalhou maravilhosamente. Vou ter que limpá-lo um pouco, pois tenho alguns desajustados, como no seu exemplo, mas, caso contrário, levou apenas alguns segundos e parece perfeito. Muito obrigado, muito mesmo.
Monody
4

Aqui está o mesmo código da resposta aceita, ajustado apenas para funcionar com o Python 3.x (ou QGIS v3.x):

from qgis.core import QgsProject

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

p_lyr = layers[0]
l_lyr = layers[1]

epsg = p_lyr.crs().postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&field=distance:double(20,2)&index=yes"

dist = QgsVectorLayer(uri,
                      'dist',
                      'memory')

QgsProject.instance().addMapLayer(dist)

prov = dist.dataProvider()

lines_features = [ line_feature for line_feature in l_lyr.getFeatures() ]
points_features = [ point_feature for point_feature in p_lyr.getFeatures() ]

feats = []

for p in points_features:

    minDistPoint = min([l.geometry().closestSegmentWithContext( p.geometry().asPoint() ) for l in lines_features])[1]
    feat = QgsFeature()
    feat.setGeometry(QgsGeometry.fromPolylineXY([p.geometry().asPoint(), minDistPoint]))
    feat.setAttributes([points_features.index(p),feat.geometry().length()])
    feats.append(feat)

prov.addFeatures(feats)
sys49152
fonte