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 07 December 2020 14:57

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

TRIGGER avec condition

Bonjour,

Je travail à la mise en place d'un trigger permettant de "remonter" un info dans une table en se basant sur un foonction spatial et une "clause" attributaire.

Je m'explique : j'ai 2 tables stockées sous POSTGIS / POSTGRES:
- Table poste_source qui contient le nom du poste source
- Table Rsx_hta qui contient les réseaux partant du poste source.

Je souhaite faire remonter de façon automatique dans la table Rsx_hta le nom du poste_source d'où part le réseau. Avec comme critère les règles suivantes :
1 - il faut que le point et la ligne aient leurs deux géométries se touchent en leur contours extérieurs. Utilsation de la fonction ST_touches
2 - il faut que le champs nom_poste dans la table Rsx_hta soit vide ou null . Utilisation du SELECT WHERE / AND / OR

J'ai donc écrit le code suivant :

Code:

CREATE OR REPLACE FUNCTION remonte_poste_source ()
RETURNS "trigger" AS $$
    BEGIN
        NEW.nom_poste= (SELECT nom

FROM public.rsx_hta, public.postes_source 


WHERE 

(st_touches( public.rsx_hta.geom,public.postes_source.geom)  AND  nom_poste = '' )

OR 

(st_touches( public.rsx_hta.geom,public.postes_source.geom)  AND  nom_poste IS NULL )) ;
        RETURN NEW;
    END;
$$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER remonte_poste_source
BEFORE INSERT OR UPDATE ON public.rsx_hta 
FOR EACH ROW EXECUTE PROCEDURE remonte_poste_source ();

Le soucis est que si je commence à tracer du Rsx qui part du poste_1 et que je passe ensuite à du réseau qui part du poste_2 le trigger me remonte toujours la valeur "poste_1" même si le réseau part du poste_2. cf photo en pièce jointe.

J'ai tracé dans l'ordre chronologique en commençant par la 6. 6 et 7 sont "justes" par contre 8 remonte poste_1 alors qu'il n'a aucune geométrie commune avec... La bonne valeur serait poste_2.

Je n'arrive pas à isoler mon erreur

Merci de votre aide.

Bonne journée.

Vincent

Dernière modification par Vincent-SIABS (Mon 07 December 2020 15:30)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#2 Tue 08 December 2020 11:45

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: TRIGGER avec condition

Bonjour,

Attention avec st_touches: à la précision près, elle peut retourner false alors que les geom se touchent.
Pour passer à travers ces pb de précision, st_dwithin(geom1, geom2, precision) marche très bien.

Ensuite, vous faites une jointure (st_touches) sur tous les éléments de la table vs l'autre table or il faut joindre l'élément courant de poste_source (NEW.geom) avec les geom de rsx_hta:

Code:

st_touches( public.rsx_hta.geom,NEW.geom)

Enfin, la clause peut etre simplifiée en

Code:

st_touches( public.rsx_hta.geom,NEW.geom)  AND length(coalesce(nom_poste, '')) = 0

Nicolas

Hors ligne

 

#3 Tue 08 December 2020 13:32

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: TRIGGER avec condition

Bonjour,

Merci de votre aide.

J'ai pris en compte vos corrections et ré-ecrit le trigger comme suit :

Code:

CREATE OR REPLACE FUNCTION remonte_poste_source ()
RETURNS "trigger" AS $$
    BEGIN
        NEW.nom_poste= (SELECT postes_source.nom, rsx_hta.nom_poste

FROM public.rsx_hta, public.postes_source 


WHERE (st_touches( public.rsx_hta.geom,NEW.geom)  AND length(coalesce(nom_poste, '')) = 0) ;
        RETURN NEW;
    END;
$$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER remonte_poste_source
BEFORE INSERT OR UPDATE ON public.rsx_hta 
FOR EACH ROW EXECUTE PROCEDURE remonte_poste_source ();

Mais il y a un soucis. En effet on appel une table NEW qui "n'existe pas" : st_touches( public.rsx_hta.geom,NEW.geom)

Dans l'ordre chronologique les postes_source sont dessinés en premier puis ensuite je trace le rsx_hta qui en part. Donc en fait c'est la géométrie "nouvelle" de rsx_hta qui doit ressortir de la requête et non celle du postes_source non ?

Encore merci pour votre aide et piste de recherche.

Cordialement,

Hors ligne

 

#4 Tue 08 December 2020 13:51

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: TRIGGER avec condition

Après correction le trigger fonctionne.

Le code :

Code:

CREATE OR REPLACE FUNCTION remonte_poste_source ()
RETURNS "trigger" AS $$
    BEGIN
        NEW.nom_poste= (SELECT p.nom

FROM public.postes_source as p


WHERE (st_touches( p.geom,NEW.geom)  AND length(coalesce(new.nom_poste, '')) = 0) );
        RETURN NEW;
    END;
$$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER remonte_poste_source
BEFORE INSERT OR UPDATE ON public.rsx_hta 
FOR EACH ROW EXECUTE PROCEDURE remonte_poste_source ();

Encore merci pour votre aide !

Bonne journée.

Vincent

Dernière modification par Vincent-SIABS (Wed 09 December 2020 15:00)

Hors ligne

 

#5 Tue 08 December 2020 14:19

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: TRIGGER avec condition

Vous pouvez faire plus direct dans le code de la fonction trigger (plus clean aussi):

La table public.rsx_hta ne doit pas etre référencée dans ce code: le trigger agit sur elle et déclenche pour chaque ligne, représentée par NEW.
Il faut juste référencer l'autre table sur laquelle vous voulez faire la requete:


Code:

NEW.nom_poste= p.nom
            FROM public.postes_source p 
            WHERE (st_touches( p.geom,NEW.geom)  AND length(coalesce(p.nom_poste, '')) = 0) ;

Nicolas

Hors ligne

 

#6 Tue 08 December 2020 14:21

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: TRIGGER avec condition

oups erreur dsl

Dernière modification par Vincent-SIABS (Tue 08 December 2020 14:25)

Hors ligne

 

#7 Tue 08 December 2020 14:25

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: TRIGGER avec condition

ah oui bien vu je vais m'être à jour mon post précédent.

et merci pour l'écriture plus clean ;-)

Hors ligne

 

Pied de page des forums

Powered by FluxBB