Creación automatizada de líneas perpendiculares entre una capa de puntos y una capa de líneas.

10

Estoy usando QGIS y estoy buscando un script, o un complemento, que pueda crear una gran cantidad de líneas perpendiculares desde una capa de puntos a líneas en una capa de línea separada.

Hasta ahora, he intentado utilizar la función Distancia de eje en MMQGIS (convirtiendo las líneas en puntos y luego conectando los puntos al centro más cercano) y la herramienta respectiva de los geoalgoritmos de QGIS. Ninguno funcionó. Ambos tardan más de 2 horas y crean líneas en todas las capas o líneas que no son perpendiculares o conectadas a los puntos.

En la imagen, puede ver el estado actual del proyecto. Las líneas perpendiculares deben correr desde los puntos hasta la línea más cercana. Al final, me gustaría usar puntos de intersección con una línea entre los puntos y las fronteras del país para crear un búfer de polígonos de 4 lados que tenga dos polígonos de profundidad. Menciono esto en caso de que haya una manera más fácil de hacerlo. ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Sé que hay algunas publicaciones sobre cómo crear líneas perpendiculares, pero ninguna de ellas resolvió mi problema.

Canción funeral
fuente
1
@ Germán Carrillo Esta pregunta no es un duplicado exacto de la pregunta existente "¿Dibujar líneas perpendiculares en PyQGIS?" ( gis.stackexchange.com/questions/59169/… ) porque la respuesta no utiliza el método'arestSegmentWithContext 'en un bucle para explorar cada interacción entre puntos y líneas de características para tomar la distancia mínima para crear una capa de memoria de línea. Es imposible porque esta respuesta solo usa puntos. Por favor, revísalo de nuevo.
xunilk
1
Todavía encuentro la otra respuesta como una buena base para resolver esta pregunta. El OP debería haber mencionado en la pregunta original que él / ella estaba al tanto de las publicaciones relacionadas Y decirnos por qué no funcionaron para él / ella. Sin embargo, buena respuesta, ¡gracias por publicar!
Germán Carrillo

Respuestas:

7

Siguiente script creación automatizada de líneas perpendiculares entre una capa de puntos y una capa de línea. Los segmentos perpendiculares (entidades de una capa de memoria) creados se ejecutan desde los puntos hasta la entidad más cercana de la capa de línea.

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)

Lo probé con una situación muy similar a la presentada en la pregunta:

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

xunilk
fuente
Trabajó maravillosamente. Tendré que limpiarlo un poco a medida que obtenga algunos inadaptados como en su ejemplo, pero de lo contrario solo me tomó segundos y se ve perfecto. Muchas muchas gracias.
Monody
4

Aquí está el mismo código que en la respuesta aceptada, solo ajustado para funcionar con Python 3.x (o 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
fuente