Mercurial > gemma
annotate schema/updates/1469/01.fix_isrsrange_area.sql @ 5559:ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Since ST_MakeValid() might return a collection of lower-to-equal dimension
geometries, distill only the polygons from it. This should prevent
respective errors when trying to save the result to a column of type
MultiPolygon.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Thu, 02 Dec 2021 12:37:33 +0100 |
parents | |
children |
rev | line source |
---|---|
5559
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
1 CREATE OR REPLACE FUNCTION ISRSrange_area( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
2 axis geometry, |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
3 area geometry |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
4 ) RETURNS geometry |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
5 AS $$ |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
6 DECLARE |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
7 area_subset geometry; |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
8 result_geom geometry; |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
9 BEGIN |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
10 -- In case area is a multipolygon, process the union of those |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
11 -- polygons, which intersect with the axis. The union is to avoid |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
12 -- problems with invalid/self-intersecting multipolygons |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
13 SELECT ST_Union(a_dmp.geom) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
14 INTO STRICT area_subset |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
15 FROM (SELECT ST_MakeValid(ST_Transform(geom, ST_SRID(axis))) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
16 FROM ST_Dump(area)) AS a_dmp (geom) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
17 WHERE ST_Intersects(a_dmp.geom, axis) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
18 HAVING ST_Union(a_dmp.geom) IS NOT NULL; |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
19 |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
20 WITH |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
21 rotated_ends AS ( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
22 SELECT ST_Collect(ST_Scale( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
23 ST_Translate(e, |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
24 (ST_X(p1) - ST_X(p2)) / 2, |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
25 (ST_Y(p1) - ST_Y(p2)) / 2), |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
26 ST_Point(d, d), p1)) AS blade |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
27 FROM (SELECT i, ST_PointN(axis, i) AS p1 |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
28 FROM (VALUES (1), (-1)) AS idx (i)) AS ep, |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
29 ST_Rotate(ST_PointN(axis, i*2), pi()/2, p1) AS ep2 (p2), |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
30 ST_Makeline(p1, p2) AS e (e), |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
31 LATERAL ( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
32 SELECT (ST_MaxDistance(p1, area_subset) / ST_Length(e)) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
33 * 2) AS d (d)), |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
34 range_area AS ( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
35 -- Split area by orthogonal lines at the ends of the clipped axis |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
36 SELECT (ST_Dump(ST_CollectionExtract( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
37 ST_Split(area_subset, blade), 3))).geom |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
38 FROM rotated_ends) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
39 -- From the polygons returned by the last CTE, select only those |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
40 -- around the clipped axis |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
41 SELECT ST_Multi(ST_CollectionExtract(ST_MakeValid(ST_Transform( |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
42 ST_Union(range_area.geom), ST_SRID(area))), 3)) |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
43 INTO result_geom |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
44 FROM range_area |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
45 WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), axis); |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
46 |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
47 RETURN result_geom; |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
48 END; |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
49 $$ |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
50 LANGUAGE plpgsql |
ce9a9a1bf92f
Make invalid output of ISRSrange_area() less likely, next try
Tom Gottfried <tom@intevation.de>
parents:
diff
changeset
|
51 STABLE PARALLEL SAFE; |