#1 Mon 18 November 2024 14:31
- Tartof
- Juste Inscrit !
- Date d'inscription: 2 Jul 2023
- Messages: 1
QGIS: Deplacement automatique de sommet de lignes
Bonjour, j'essaie de mettre au point un script Python (si vous avez d'autres moyens d'arriver à mes fins, ça me va aussi).
J'ai donc un jeu de 3 couches, une couche ligne 'L', une couche point 'A' et une autre couche point 'B'.
Une partie des sommets des segments de L sont accrochés sur A
B est une version à jour de A, certains points ne sont plus au même endroit
Il est possible de faire une correspondance entre les points de A et B via l'ID. Chaque point de B dispose d'un ID identique à un point de A
J'aimerais déplacer les sommets de L qui sont accrochés à A vers le point B correspondant. Je débute en Python et je ne vois pas comment faire autrement. Auriez-vous des idées ?
Hors ligne
#2 Tue 19 November 2024 09:33
- Gabi63
- Juste Inscrit !
- Date d'inscription: 3 Apr 2016
- Messages: 3
Re: QGIS: Deplacement automatique de sommet de lignes
Bonjour,
Selon l'écart entre les points de la couche B il peut-être possible d'utiliser l'outil "accrocher des géométries à la couche" avec la tolérance adaptée.
Si les assemblages de points sont trop proche il faudra en effet, à ma connaissance, passer par un script python.
.
Si tu débutes en python pyQGIS n'est pas une librairie que je te conseille (très verbeuse mais très puissante à mon gout). Je me suis donc permis d'assembler un script rapide de mémoire qui n'est surement pas optimisé. Des fonctions natives de QGIS permettent surement de faire cette action directement en creusant bien. Fais moi savoir si ça ne fonctionne pas de la manière souhaitée ou si tu souhaites des explications plus détaillées.
Code à exécuter dans la console python de QGIS (ctrl+alt+p ou extension -> console python puis afficher l'éditeur (la feuille avec le stylo rouge dans la console)) :
Je conseille de dupliquer la couche de ligne en amont de l’exécution, au cas où.
Code:
a_name = "A" # Layer name in QGIS b_name = "B" l_name = "L" fld_id = "id" # Id field to join B and A # Load layer # QGIS layer name must not be duplicated layer_a = QgsProject.instance().mapLayersByName(a_name)[0] layer_b = QgsProject.instance().mapLayersByName(b_name)[0] layer_l = QgsProject.instance().mapLayersByName(l_name)[0] # Build spatial index in case a large number of line is available index = QgsSpatialIndex(layer_l.getFeatures()) with edit(layer_l): for feature in layer_a.getFeatures(): geom = feature.geometry() # Get candidates based on bounding box. candidate_ids = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(candidate_ids) # Fetch candidates lines = [f for f in layer_l.getFeatures(request)] # Assuming a point from A intersect only one line if len(lines) > 1: raise Exception("Too many candidates") elif len(lines) == 0: # Skip this geom continue else: # For one match # Find the vertex to move line = lines[0] vertex, vtx_idx, _, _, _ = line.geometry().closestVertex(geom.asPoint()) # Find the corresponding B point exp = f"{fld_id} = {feature[fld_id]}" request = QgsFeatureRequest().setFilterExpression(exp) # Assuming one match feature = [f for f in layer_b.getFeatures(request)][0] point_b = feature.geometry().asPoint() new_line = line.geometry().asPolyline() new_line[vtx_idx] = point_b # Update geometry new_geom = QgsGeometry().fromPolyline([QgsPoint(v) for v in new_line]) line.setGeometry(new_geom) layer_l.updateFeature(line)
Dernière modification par Gabi63 (Tue 19 November 2024 09:57)
Hors ligne