Pages: 1
- Sujet précédent - Trigger PostgreSQL/PostGIS : découper des lignes sur des polygones - Sujet suivant
#1 Thu 14 December 2023 13:11
- idjepacreutz
- Juste Inscrit !
- Date d'inscription: 14 Dec 2023
- Messages: 2
Trigger PostgreSQL/PostGIS : découper des lignes sur des polygones
Bonjour,
J'essaie de créer un trigger dans notre base de données PostgreSQL/PostGIS afin de découper les géométries linéaires d'une couche segment sur les polygones d'une couche communes à chaque mise à jour du champ geom (dont sur les opérations INSERT et UPDATE), et de mettre à jour des champs qui contiennent les codes INSEE des différents niveaux de collectivité (tous déjà stockés commune par commune).
Le fonctionnement voulu est celui-ci :
- INSERT : la nouvelle entitĂ© doit ĂȘtre dĂ©coupĂ©e sur les limites de la couche communes, et chaque ligne rĂ©sultant de cette opĂ©ration doit avoir les attributs du polygone dans lequel elle est contenue
- UPDATE : l'entitĂ© prĂ©existant doit continuer d'exister (conservation de l'id et de la date de crĂ©ation de l'entitĂ©), mais avec sa nouvelle gĂ©omĂ©trie (dĂ©coupĂ©e sur les communes), et de nouveaux attributs si nĂ©cessaire. Les nouvelles entitĂ©s issues du dĂ©coupage doivent ĂȘtre insĂ©rĂ©es dans la mĂȘme table.
J'ai du mal Ă obtenir le bon retour depuis la fonction PL/pgSQL, mon code ci-dessous met bien Ă jour l'entitĂ© existante (attributs et gĂ©omĂ©trie), mais les entitĂ©s qui sont supposĂ©es ĂȘtre insĂ©rĂ©es ne le sont pas. J'ai essayĂ© de nombreuses combinaisons de RETURN diffĂ©rentes, sans succĂšs. Quelqu'un aurait un conseil ?
Code:
CREATE OR REPLACE FUNCTION split_segments_on_communes_and_update_collectivities_codes()
RETURNS TRIGGER AS
$BODY$
DECLARE
rec RECORD;
BEGIN
FOR rec IN
SELECT c.insee_com AS insee_com,
'0' || c.insee_dep AS insee_dep,
c.insee_reg AS insee_reg,
c.code_epci AS code_epci,
(ST_Dump(ST_Intersection(NEW.geom, c.geom))).geom AS geom,
(ST_Dump(ST_Intersection(NEW.geom, c.geom))).path[0] AS "path",
NEW.id_statut,
NEW.propriete,
NEW.author,
NEW.create_date
FROM donnees_externes.commune c
WHERE ST_Intersects(NEW.geom, c.geom)
LOOP
IF rec."path" = 1 OR rec."path" IS NULL THEN
NEW.geom = rec.geom;
NEW.code_reg = rec.insee_reg;
NEW.code_dep = rec.insee_dep;
NEW.code_epci = rec.code_epci;
NEW.code_commune = rec.insee_com;
ELSE
INSERT INTO reference.segment (geom,
id_statut,
propriete,
code_epci,
code_dep,
code_reg,
author,
create_date,
code_commune)
VALUES (
rec.geom,
NEW.id_statut,
NEW.propriete,
rec.code_epci,
rec.insee_dep,
rec.insee_reg,
NEW.author,
NEW.create_date,
rec.insee_com);
END IF;
END LOOP;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER split_segments_on_communes_and_update_collectivities_codes
BEFORE INSERT
OR UPDATE OF geom
ON reference.segment
FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE split_segments_on_communes_and_update_collectivities_codes();Hors ligne
#2 Tue 19 December 2023 17:33
- idjepacreutz
- Juste Inscrit !
- Date d'inscription: 14 Dec 2023
- Messages: 2
Re: Trigger PostgreSQL/PostGIS : découper des lignes sur des polygones
Le problÚme était dans l'utilisation de `path` dans cette ligne : `(ST_Dump(ST_Intersection(NEW.geom, c.geom))).path[0] AS "path"`.
VoilĂ la bonne maniĂšre de faire :
Code:
WITH parts AS (
SELECT c.insee_com AS insee_com,
'0' || c.insee_dep AS insee_dep,
c.insee_reg AS insee_reg,
c.code_epci AS code_epci,
(ST_Dump(ST_Intersection(NEW.geom, c.geom))).geom AS geom,
NEW.id_statut,
NEW.propriete,
NEW.author,
NEW.create_date
FROM donnees_externes.commune c
WHERE ST_Intersects(NEW.geom, c.geom)
)
SELECT *,
ROW_NUMBER() OVER () AS "path"
FROM partsEt la fonction complĂšte :
Code:
CREATE OR REPLACE FUNCTION reference.split_segments_on_communes_and_update_collectivities_codes()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
rec RECORD;
newgeom geometry;
BEGIN
FOR rec IN
WITH parts AS (
SELECT c.insee_com AS insee_com,
'0' || c.insee_dep,
c.insee_reg AS insee_reg,
c.code_epci AS code_epci,
(ST_Dump(ST_Intersection(NEW.geom, c.geom))).geom AS geom
FROM donnees_externes.commune c
WHERE ST_Intersects(NEW.geom, c.geom)
)
SELECT *,
ROW_NUMBER() OVER () AS "path"
FROM parts
LOOP
IF ST_GeometryType(rec.geom) != 'ST_Point' THEN
IF rec."path" = 1 THEN
NEW.geom := rec.geom;
NEW.code_reg := rec.insee_reg;
NEW.code_dep := rec.insee_dep;
NEW.code_epci := rec.code_epci;
NEW.code_commune := rec.insee_com;
ELSE
INSERT INTO reference.segment (geom,
id_statut,
propriete,
code_epci,
code_dep,
code_reg,
author,
create_date,
code_commune)
VALUES (
rec.geom,
NEW.id_statut,
NEW.propriete,
rec.code_epci,
rec.insee_dep,
rec.insee_reg,
NEW.author,
NEW.create_date,
rec.insee_com);
END IF;
END IF;
END LOOP;
RETURN NEW;
END;
$function$
;Dernière modification par idjepacreutz (Tue 19 December 2023 17:33)
Hors ligne
#3 Tue 19 December 2023 19:32
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1566
Re: Trigger PostgreSQL/PostGIS : découper des lignes sur des polygones
Bonsoir,
Attention, en ne faisant pas de "order by" dans la CTE "parts", la valeur de path peut etre différente suivant les appels à cette fonction.
Nicolas
Hors ligne
Pages: 1
- Sujet précédent - Trigger PostgreSQL/PostGIS : découper des lignes sur des polygones - Sujet suivant

