#1 Wed 09 December 2020 11:05
- Vincent-SIABS
- Participant actif
- Date d'inscription: 20 Sep 2016
- Messages: 57
ST_startpoint / ST_endpoint
Bonjour,
Petite question sur une sélection via st_startpoint et st_endpoint.
J'ai une couche de ligne type linestring dans ma base.
Je souhaite remplir automatiquement un attribut de la nouvelle ligne crée en me basant sur un attribut de la ligne déjà existante à laquelle se "rattache" la nouvelle.
En gros je trace ma ligne B avec son champs DATA "vide". Cette ligne B se rattache à la ligne A déjà existante avec son chmps DATA remplit par la valeur A_text.
J'ai dans ma tête la requête suivante :
Si point de départ de ligne_B = point de fin de ligne_A alors met à jour le champ DATA de ligne_B avec la valeur de DATA ligne_A
J'arrive à faire sortir les valeurs de st_startpoint et st_endpoint dans ma table mais après je "but" sur le "=" je pense à un ST_within mais je n'arrive pas à imbriquer le tout comme il faut.
Pour le moment j'arrive à "sortir le point de départ et d'arriver pour chaque ligne via la requête ci-dessous
Code:
select id, geom, ST_startpoint (geom) as n_dpt, st_endpoint(geom) as n_end FROM ma_table_ligne
S jamais quelqu'un à une piste ou une idée je suis preneur !
Merci à vous et bonne journée.
Vincent
Dernière modification par Vincent-SIABS (Wed 09 December 2020 11:26)
Hors ligne
#2 Wed 09 December 2020 11:40
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1549
Re: ST_startpoint / ST_endpoint
Bonjour,
st_within ne marche pas dans ce cas: c'est plutot st_touches, ou st_dwithin avec une distance toute petite.
Nicolas
Hors ligne
#3 Wed 09 December 2020 13:35
- Vincent-SIABS
- Participant actif
- Date d'inscription: 20 Sep 2016
- Messages: 57
Re: ST_startpoint / ST_endpoint
Bon j'avance ! En isolant une geométrie particulière la requête ci-dessous fonctionne :
Code:
SELECT id, geom, ST_AsText(geom), st_astext(st_startpoint(geom)) as dpt, st_astext(st_endpoint(geom)) as fin FROM ma_table_ligne where st_touches(ST_STARTPOINT(geom),'geom_d'une_une_ligne_particulière')
Reste maintenant à faire la même formule mais en remplaçant la géométrie particulière par un cas general et là ça se corse :-(
Merci en tout cas pour l'aide !
Dernière modification par Vincent-SIABS (Wed 09 December 2020 14:01)
Hors ligne
#4 Wed 09 December 2020 17:57
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1549
Re: ST_startpoint / ST_endpoint
Si c'est dans un trigger, et que je comprends bien ce que vous voulez faire, il suffit juste de rechercher la ligne dont le startpoint touche le endpoint de la ligne courante (NEW). (ceci à condition que la numérisation prenne en compte le sens des lignes. Sinon, il faut chercher sur startpoint et endpoint).
Dans le code de la fonction du trigger:
Code:
NEW.data = ma_table_ligne.data from ma_table_ligne m where st_touches(st_endpoint(NEW.geom), st_startPoint(m.geom));
Si la numérisation ne snape pas bien les sommets entre les lignes, on peut utiliser st_dwithin a une certaine précision:
Code:
NEW.data = ma_table_ligne.data from ma_table_ligne m where st_dwithin(st_endpoint(NEW.geom), st_startPoint(m.geom), 0.001);
Et si la table ma_table_ligne est volumineuse, vous pouvez créer un index spatial sur st_startpoint(m.geom): ca s'appelle un index fonctionnel et c'est bien pratique.
Nicolas
Hors ligne
#5 Thu 10 December 2020 08:57
- Vincent-SIABS
- Participant actif
- Date d'inscription: 20 Sep 2016
- Messages: 57
Re: ST_startpoint / ST_endpoint
Bonjour,
Un grand merci pour votre aide !
La fonction fonctionne mais me retourne le message suivant :
Code:
Erreur PostGIS lors de l'ajout d'entité : ERREUR: le contrôle a atteint la fin de la procédure trigger sans RETURN
J'ai l'impression qu'il ne trouve rien correspondant à la requête. J'ai tenté en inversant l'odre de st_startpoint et st_endpoint rien n'a changé tout comme utiliser le ST_Dwithin à la place du ST_touches.
J'ai aussi tenté une requête plus large qui concerne toute la geom voir ci-dessous, mais ça n'a rien donné. Toujours le même message d'erreur.
Code:
WHERE st_dwithin(ST_startpoint(new.geom),r.geom,0.01);
Code:
CREATE OR REPLACE FUNCTION remonte_champs_data_table_ligne () RETURNS "trigger" AS $$ BEGIN NEW.data=m.data FROM ma_table_ligne m WHERE st_dwithin(ST_startpoint(new.geom),st_endPoint(m.geom),0.01); END; $$ LANGUAGE 'plpgsql'VOLATILE; CREATE TRIGGER remonte_champs_data_table_ligne BEFORE INSERT OR UPDATE ON public.ma_table_ligne FOR EACH ROW EXECUTE PROCEDURE remonte_champs_data_table_ligne ();
La numerisation topologique est activée avec une tolérance de 5 pixels. J'ai tenté de modifier la tolérance à 1 pixel et / ou la précision de ST_within à 0.5 / 1 / 5/ 10 rien ne change. Le trigger retourne toujours le message ci-dessus.
Grâce à vous je suis proche très proche mais ça coince encore.
Un immense merci.
Dernière modification par Vincent-SIABS (Thu 10 December 2020 09:11)
Hors ligne
#6 Thu 10 December 2020 09:12
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1549
Re: ST_startpoint / ST_endpoint
Bonjour,
j'ai envie de dire: c'est marqué dessus
les messages PG sont clairs et il est important de les lire:
"ERREUR: le contrôle a atteint la fin de la procédure trigger sans RETURN"
Il manque un return NEW dans la fonction
Nico
Hors ligne
#7 Thu 10 December 2020 09:16
- Vincent-SIABS
- Participant actif
- Date d'inscription: 20 Sep 2016
- Messages: 57
Re: ST_startpoint / ST_endpoint
Shame on me …
ça fonctionne maintenant (bien sûr me direz vous ;-) )
Merci beaucoup pour le temps passer à me "sortir" de ma galère.
Bonne journée.
Vincent
Hors ligne