Création automatisée de lignes perpendiculaires entre une couche de points et une couche de lignes

10

J'utilise QGIS et je recherche un script, ou un plugin, qui peut créer un grand nombre de lignes perpendiculaires d'une couche de points aux lignes d'une couche de lignes distinctes.

Jusqu'à présent, j'ai essayé d'utiliser la fonction Hub Distance dans MMQGIS (transformer les lignes en points puis connecter les points au hub le plus proche) et l'outil respectif des géoalgorithmes QGIS. Aucun n'a fonctionné. Les deux prennent plus de 2 heures et créent soit des lignes de tout le calque, soit des lignes qui ne sont pas perpendiculaires ou connectées aux points.

Dans l'image, vous pouvez voir l'état actuel du projet. Les lignes perpendiculaires doivent aller des points à la ligne la plus proche. En fin de compte, je voudrais utiliser des points d'intersection avec une ligne entre les points et les frontières du pays pour créer un tampon de polygones à 4 côtés de deux polygones de profondeur. Je mentionne cela au cas où il existe un moyen plus simple de le faire. entrez la description de l'image ici entrez la description de l'image ici

Je sais qu'il existe des articles sur la façon de créer des lignes perpendiculaires, mais aucun d'eux n'a résolu mon problème.

Monodie
la source
1
@ Germán Carrillo Cette question n'est pas un double exact de la question existante "Tracer des lignes perpendiculaires dans PyQGIS?" ( gis.stackexchange.com/questions/59169/… ) parce que la réponse n'utilise pas la méthode 'le plus procheSegmentWithContext' dans une boucle pour explorer chaque interaction entre les points et la ligne d'entités pour prendre la distance minimale pour créer une couche de mémoire de ligne. C'est impossible car cette réponse n'utilise que des points. Veuillez le revoir.
xunilk
1
Je trouve toujours que l'autre réponse constitue une bonne base pour résoudre cette question. Le PO aurait dû mentionner dans la question initiale qu'il était au courant des postes connexes ET nous dire pourquoi ils ne travaillaient pas pour lui. Néanmoins, bonne réponse, merci d'avoir posté!
Germán Carrillo

Réponses:

7

Le script suivant a automatisé la création de lignes perpendiculaires entre une couche de points et une couche de lignes. Les segments perpendiculaires (caractéristiques d'une couche de mémoire) créés vont des points à la caractéristique la plus proche de la couche de ligne.

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)

Je l'ai essayé avec une situation très similaire à celle présentée dans la question:

entrez la description de l'image ici

Après avoir exécuté le code sur la console Python de QGIS, il a été obtenu:

entrez la description de l'image ici

xunilk
la source
A merveilleusement travaillé. Je vais devoir le nettoyer un peu car je reçois des inadaptations comme dans votre exemple, mais sinon cela n'a pris que quelques secondes et semble parfait. Merci beaucoup.
Monody
4

Voici le même code que dans la réponse acceptée, ajusté uniquement pour fonctionner avec 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
la source