|
-- This wraps `topology.ST_ChangeEdgeGeom` |
|
-- with a retry-different-tolerance |
|
CREATE OR REPLACE FUNCTION SimplifyEdgeGeom(atopo varchar, anedge int, maxtolerance float8) |
|
RETURNS float8 AS $$ |
|
DECLARE |
|
tol float8; |
|
sql varchar; |
|
BEGIN |
|
tol := maxtolerance; |
|
LOOP |
|
sql := 'SELECT topology.ST_ChangeEdgeGeom(' || quote_literal(atopo) || ', ' || anedge |
|
|| ', ST_Simplify(geom, ' || tol || ')) FROM ' |
|
|| quote_ident(atopo) || '.edge WHERE edge_id = ' || anedge; |
|
BEGIN |
|
RAISE DEBUG 'Running %', sql; |
|
EXECUTE sql; |
|
RETURN tol; |
|
EXCEPTION |
|
WHEN OTHERS THEN |
|
RAISE WARNING 'Simplification of edge % with tolerance % failed: %', anedge, tol, SQLERRM; |
|
tol := round( (tol/2.0) * 1e8 ) / 1e8; -- round to get to zero quicker |
|
IF tol = 0 THEN raise |
|
--EXCEPTION |
|
notice '%', SQLERRM; END IF; |
|
END; |
|
END LOOP; |
|
end |
|
$$ LANGUAGE 'plpgsql' STABLE STRICT; |
|
|
|
create table intersect_area_rainfall(id serial, area_id int, rainfall text, geom geometry(polygon, 4326)); |
|
WITH intersection AS (SELECT |
|
"area"."id" "area_id", "rainfall"."rainfall", |
|
ST_MULTI(ST_INTERSECTION("rainfall"."geom", "area"."geom")) AS "geom" |
|
FROM simple_locations_area area, location_profile_rainfall rainfall, simple_locations_areatype areatype |
|
WHERE ST_INTERSECTS("rainfall"."geom", "area"."geom") |
|
AND "area"."kind_id" = "areatype"."id" |
|
AND "areatype"."slug" = 'district' |
|
), |
|
dump_geometries AS ( |
|
SELECT "area_id", "rainfall", (ST_DUMP(geom)).geom AS geom FROM intersection |
|
) |
|
INSERT INTO intersect_area_rainfall (area_id, rainfall, geom) |
|
select area_id, rainfall, geom from dump_geometries; |
|
|
|
-- Create a temporary topology |
|
-- and suitable table |
|
|
|
SELECT topology.CreateTopology('rainfall_area_topology', 32756); |
|
drop table if exists rainfall_topology; |
|
CREATE TABLE if not exists rainfall_topology(intersect_area_rainfall_id int, area_id int, rainfall text); |
|
-- The layer ID here should be 1 |
|
SELECT topology.AddTopoGeometryColumn('rainfall_area_topology', 'public', 'rainfall_topology', 'topo', 'POLYGON'); |
|
|
|
|
|
-- This should work if your postgis version is 3.2+ |
|
|
|
INSERT INTO rainfall_topology (intersect_area_altitude_id, area_id, rainfall, topo) |
|
select |
|
id, |
|
area_id, |
|
rainfall, |
|
topology.toTopoGeom(ST_Transform(geom, 32756), 'rainfall_area_topology', 1, 10) from intersect_area_altitude |
|
|
|
|
|
|
|
select SUM(SimplifyEdgeGeom('rainfall_area_topology', edge_id, 200)) from rainfall_area_topology.edge; |
|
drop table if exists topology_rainfall_200; |
|
create table topology_rainfall_200 as select area_id, rainfall, topo::geometry from rainfall_topology; |
|
|
|
|
|
-- Replace the rainfallforarea records with the simplified ones |
|
truncate location_profile_rainfallforarea; |
|
insert into location_profile_rainfallforarea (rainfall, geom, area_id) |
|
select rainfall, (ST_DUMP(ST_TRANSFORM(topo, 4326))).geom, area_id from topology_rainfall_200; |
|
-- We no longer need this table |
|
truncate location_profile_rainfall; |
|
-- This zeroes out decimal points. No effect on table size on server, but |
|
-- reduces size for on-disk representation. |
|
update location_profile_rainfallforarea set geom = ST_QuantizeCoordinates(geom, 3); |
|
|
|
|
|
|
|
-- Clean up |
|
|
|
--select topology.DropTopology('rainfall_area_topology'); |