Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#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: 5

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

 

Pied de page des forums

Powered by FluxBB