diff schema/isrs_functions.sql @ 2563:dc4fae4bdb8f

Expose axis snapping tolerance to users
author Tom Gottfried <tom@intevation.de>
date Fri, 08 Mar 2019 19:15:47 +0100
parents 73c8762cee60
children 974122125a76
line wrap: on
line diff
--- a/schema/isrs_functions.sql	Fri Mar 08 18:57:58 2019 +0100
+++ b/schema/isrs_functions.sql	Fri Mar 08 19:15:47 2019 +0100
@@ -47,6 +47,7 @@
 -- Uses the table waterway.distance_marks_virtual to map ISRS location codes
 -- to their geo-location.
 -- Distance marks are assumed to be near the axis.
+-- Returns the axis geometry transformed to the best matching UTM zone.
 CREATE OR REPLACE FUNCTION ISRSrange_axis(
     stretch isrsrange,
     tolerance float
@@ -135,32 +136,28 @@
     LANGUAGE plpgsql
     STABLE PARALLEL SAFE;
 
--- Clip an area to a stretch given by a pair of ISRS location codes.
--- Uses ISRSrange_axis() to retrieve the respective clipped axis used to find
--- perpendicular direction at geo-locations of ISRS codes.
+-- Clip an area to a stretch given by a geometry representing an axis (e.g.
+-- the output of ISRSrange_axis()).
+-- Clipping is done by cutting the area in perpendicular direction at
+-- the ends of the given axis.
 -- The area passed as argument is assumed to intersect with the axis
 -- (use e.g. waterway area or fairway dimensions).
 -- If a multipolygon is passed, the union of the polygons intersecting with the
--- relevant part of the axis is used for clipping.
+-- axis is used for clipping.
 CREATE OR REPLACE FUNCTION ISRSrange_area(
-    stretch isrsrange,
+    axis geometry,
     area geometry
 ) RETURNS geometry
 AS $$
     WITH
-        axis_substring AS (
-            SELECT ISRSrange_axis(stretch, 5) AS line),
-        utm_zone AS (
-            SELECT best_utm(stretch) AS z),
         area_subset AS (
             -- In case area is a multipolygon, process the union of those
             -- polygons, which intersect with the axis. The union is to avoid
             -- problems with invalid/self-intersecting multipolygons
             SELECT ST_Union(a_dmp.geom) AS area
-                FROM axis_substring, utm_zone, LATERAL (
-                    SELECT ST_MakeValid(ST_Transform(geom, z)) AS geom
-                        FROM ST_Dump(area)) AS a_dmp
-                WHERE ST_Intersects(a_dmp.geom, axis_substring.line)
+                FROM (SELECT ST_MakeValid(ST_Transform(geom, ST_SRID(axis)))
+                        FROM ST_Dump(area)) AS a_dmp (geom)
+                WHERE ST_Intersects(a_dmp.geom, axis)
             ),
         rotated_ends AS (
             SELECT ST_Collect(ST_Scale(
@@ -168,11 +165,11 @@
                         (ST_X(p1) - ST_X(p2)) / 2,
                         (ST_Y(p1) - ST_Y(p2)) / 2),
                     ST_Point(d, d), p1)) AS blade
-                FROM axis_substring, area_subset,
-                    LATERAL (SELECT i, ST_PointN(line, i) AS p1
+                FROM (SELECT i, ST_PointN(axis, i) AS p1
                         FROM (VALUES (1), (-1)) AS idx (i)) AS ep,
-                    ST_Rotate(ST_PointN(line, i*2), pi()/2, p1) AS ep2 (p2),
+                    ST_Rotate(ST_PointN(axis, i*2), pi()/2, p1) AS ep2 (p2),
                     ST_Makeline(p1, p2) AS e (e),
+                    area_subset,
                     LATERAL (SELECT (ST_MaxDistance(p1, area) / ST_Length(e))
                             * 2) AS d (d)),
         range_area AS (
@@ -183,8 +180,7 @@
         -- From the polygons returned by the last CTE, select only those
         -- around the clipped axis
         SELECT ST_Multi(ST_Transform(ST_Union(range_area.geom), ST_SRID(area)))
-            FROM axis_substring, range_area
-            WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001),
-                axis_substring.line)
+            FROM range_area
+            WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), axis)
     $$
     LANGUAGE sql;