patternsqlMinor
Trigger to automatically calculate area when adding polygon in PostGIS
Viewed 0 times
triggerautomaticallyaddingcalculatewhenpostgispolygonarea
Problem
I need help with writing a trigger to automatically update and insert into a column the area of a polygon being created using PostgreSQL/PostGIS and QGIS.
This is what I have but it's not updating when I add new features.
This is what I have but it's not updating when I add new features.
CREATE OR REPLACE FUNCTION calc_area()
RETURNS trigger AS
$BODY$
BEGIN
NEW.area_ha := ROUND((st_area(NEW.geom::geography)/10000)::numeric,2);
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER area_calculate AFTER INSERT OR UPDATE ON public."Guyana_Coastal_Zone"
FOR EACH ROW EXECUTE PROCEDURE calc_area();Solution
This is not a very good idea, and there is no need to do this. Just create a functional index.
I would create the index on the unrounded version.
Then a query like this:
will use the index. Alternatively, you can create a
Shy of that, if you really want to store the computed column on the row your trigger needs to be
The return value of a row-level trigger fired AFTER or a statement-level trigger fired BEFORE or AFTER is always ignored; it might as well be null. However, any of these types of triggers might still abort the entire operation by raising an error.
CREATE INDEX ON table ( ROUND( (ST_Area(geom)/1000)::numeric ,2 ) );I would create the index on the unrounded version.
CREATE INDEX ON table ( ST_Area(geom) );Then a query like this:
SELECT * ON table WHERE ST_Area(geom) > x;will use the index. Alternatively, you can create a
MATERIALIZED VIEW. Generally, it's not a good idea to cache the result of a calculation on the table.Shy of that, if you really want to store the computed column on the row your trigger needs to be
BEFORE INSERT OR UPDATE. I really wish returning non-null in AFTER would generate a warning, but it's in the docs (emphasis added):The return value of a row-level trigger fired AFTER or a statement-level trigger fired BEFORE or AFTER is always ignored; it might as well be null. However, any of these types of triggers might still abort the entire operation by raising an error.
Code Snippets
CREATE INDEX ON table ( ROUND( (ST_Area(geom)/1000)::numeric ,2 ) );CREATE INDEX ON table ( ST_Area(geom) );SELECT * ON table WHERE ST_Area(geom) > x;Context
StackExchange Database Administrators Q#161774, answer score: 3
Revisions (0)
No revisions yet.