3 votos

Actualizar la columna de área después de los cambios en QGIS

Estoy utilizando QGIS y POSTGIS, por ejemplo para calcular automáticamente el área de un nuevo polígono creado. Lo hago con el siguiente código:

CREATE OR REPLACE FUNCTION calc_area()
RETURNS trigger AS
$BODY$
BEGIN
NEW.fla_ha := st_area(NEW.geom)/10000;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER area_calculate BEFORE INSERT OR UPDATE ON nutzungen
    FOR EACH ROW EXECUTE PROCEDURE calc_area();

Definición del problema:

¿Cómo puedo cambiar mi disparador, de modo que las ediciones en la geometría de un polígono existente (nuevo vértice ...) se reconocerá y el valor de área de edad se sobrescribe.

Si utilizo ACTUALIZACIÓN en combinación con un AFTER-TRIGGER me actualiza toda la columna fla_ha y no la fila concreta:

CREATE OR REPLACE FUNCTION "area_new"()
RETURNS trigger AS
$BODY$BEGIN
UPDATE nutzungen SET fla_ha=ST_AREA(NEW.geom)/10000;
END;$BODY$
LANGUAGE plpgsql VOLATILE

ALTER FUNCTION "area_new"()
OWNER TO postgres;

5voto

Dr Herbie Puntos 2966

Su desencadenante original contiene un error:

CREATE TRIGGER area_calculate **BEFORE** INSERT OR UPDATE ON nutzungen

Esto significa que estás desencadenantes llama a la función en geom antes de se actualiza la geometría. Sustituye el trigger llamando a lo siguiente:

DROP TRIGGER area_calculate;
CREATE TRIGGER area_calculate AFTER INSERT OR UPDATE ON nutzungen
    FOR EACH ROW EXECUTE PROCEDURE calc_area();

En cuanto a la calc_area() no es necesario cambiarle el nombre. CREATE OR REPLACE significa que al ejecutar el script de creación de la nueva función, ésta sustituir la antigua.

1voto

kevinc Puntos 143

Su primera afirmación es correcta en lo que está tratando de lograr - al menos probando en mi servidor PostgreSQL 9.3. Permítanme explicar:

  • El gatillo dispara BEFORE los cambios se aplican a la tabla.
  • En este estado, ya tiene información sobre el OLD contenido de la fila y el NEW del contenido de la fila (es decir, el aspecto que tendrá la fila tras los cambios implícitos en el UPDATE se habrá aplicado), dado que se dispara durante un UPDATE para un INSERT Por supuesto, sólo el NEW existe información.
  • En NEW el contenido aún no se ha escrito en la tabla, por lo que puede ser interceptado.
  • Por lo tanto, al establecer NEW.fla_ha=st_area(NEW.geom)/10000 , toqueteas la información de la fila que aún no se ha aplicado a la tabla.
  • Por RETURN NEW le devuelve la fila completa, personalizada según su función, que se aplica a la tabla, es decir, incluido el cálculo de st_area.

Con un AFTER no funciona como cabría esperar porque los cambios ya se han aplicado pihásicamente a la fila de la tabla. Así que cualquier intercepción en el NEW simplemente no se tiene en cuenta. La dirección NEW existe en este contexto para su posterior evaluación, pero los cambios que se realicen en él ya no se aplicarán a la tabla.

Espero que esto lo aclare.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X