Ola a toda a lista,

Tenho uma tabela de *incendios* (com geometria de polígonos) onde se
encontram os perímetros de incêndios florestais.
Outra *admin* (com geometria de polígonos) com as divisões administrativas.
E uma terceira *resumo* (alfanumérica) onde quero que o seguinte disparador
guarde a superfície afectada por incêndio e município.

Até aqui tudo bem, o problema vem quando faça um UPDATE de um
determinado incêndio, alterando a sua geometria/superfície, o disparador
deve eliminar previamente os registos originados pelo INSERT e recalcular
a superfície afectada por incêndio e município. Não sei como eliminar os
registos desactualizados baseando-me no codigo de incendio (fire_code).

-----------------------------------------------------
-- tabela incendios
CREATE TABLE sch_temp.incendios (gid SERIAL PRIMARY KEY, fir_code BIGINT);
SELECT AddGeometrycolumn ('sch_temp','incendios','geom',23030,'POLYGON',2);

-- tabela municipios
CREATE TABLE sch_temp.municipios (adm_code INT, adm_name VARCHAR(50));
SELECT AddGeometrycolumn ('sch_temp','municipios','geom',23030,'POLYGON',2);
INSERT INTO sch_temp.municipios(adm_code,adm_name, geom) VALUES(101,'Muni
a', ST_GeomFromText('SRID=23030;POLYGON((725000 4430000,730000
4430000,730000 4425000,725000 4430000))'));
INSERT INTO sch_temp.municipios(adm_code,adm_name, geom) VALUES(102,'Muni
b', ST_GeomFromText('SRID=23030;POLYGON((725000 4430000,730000
4425000,725000 4425000,725000 4430000))'));

-- tabela resumo
CREATE TABLE sch_temp.resumo (id SERIAL PRIMARY KEY, fir_code BIGINT,
adm_code INT, adm_area BIGINT);

-- disparador
CREATE OR REPLACE FUNCTION funcao_incendios() RETURNS trigger AS
$fire_by_admin$
DECLARE
fire BIGINT;
BEGIN
--fire = NEW.fire_code;   -- <-- RAIZ DO PROBLEMA
IF (TG_OP = 'DELETE') THEN
DELETE FROM sch_temp.resumo
WHERE fir_code = fire;
ELSIF (TG_OP = 'UPDATE') OR (TG_OP = 'INSERT') THEN
--DELETE FROM sch_temp.resumo
--WHERE fir_code = fire;
INSERT INTO sch_temp.resumo(fir_code, adm_code, adm_area) (
SELECT t2.fir_code, t1.adm_code,
sum(ST_Area(ST_Intersection(t1.geom,t2.geom)))
FROM sch_temp.municipios AS t1, sch_temp.incendios AS t2
WHERE (t1.geom && t2.geom)
AND ST_Intersects(t1.geom,t2.geom)
GROUP BY t2.fir_code, t1.adm_code);
END IF;
RETURN NULL;
END;
$fire_by_admin$ LANGUAGE plpgsql;

CREATE TRIGGER funcao_incendios
AFTER INSERT OR UPDATE OR DELETE ON sch_temp.incendios
FOR EACH ROW EXECUTE PROCEDURE funcao_incendios();

-- insert
INSERT INTO sch_temp.incendios(fir_code, geom) VALUES(1,
ST_GeomFromText('SRID=23030;POLYGON((726000 4429000,729000 4429000,729000
4426000,726000 4426000,726000 4429000))'));
SELECT * FROM sch_temp.resumo;

-- resultado observado e esperado
/*fir_code,adm_code,adm_area
1;1;101;4500000
2;1;102;4500000*/

-- update
UPDATE sch_temp.incendios SET geom =
ST_GeomFromText('SRID=23030;POLYGON((727000 4429000,729100 4429000,729100
4427000,727000 4429000))') WHERE gid = 1;
SELECT * FROM sch_temp.resumo;

-- resultado observado
/*fir_code,adm_code,adm_area
1;1;101;4500000  <- este registe devia ser eliminado, vem do INSERT
2;1;102;4500000  <- este registe devia ser eliminado, vem do INSERT
3;1;101;2100000*/

-- resultado esperado
/*fir_code,adm_code,adm_area
3;1;101;2100000*/

-- eliminar todo o anterior
/*DROP TRIGGER IF EXISTS funcao_incendios ON sch_temp.incendios;
SELECT DropGeometryColumn('sch_temp','incendios','geom');
SELECT DropGeometryColumn('sch_temp','municipios','geom');
DROP TABLE sch_temp.resumo;
DROP TABLE sch_temp.municipios;
DROP TABLE sch_temp.incendios;*/
-----------------------------------------------------

Obrigado,

Eloi Ribeiro
GIS Analyst
39,45º -4,40º
http://eloiribeiro.wordpress.com
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a