# HG changeset patch # User Tom Gottfried # Date 1559314722 -7200 # Node ID 453f15ba803096079c83e0c0b4cafeb770dd2129 # Parent ec1aec03676db6b1f97f0dc73be53b198837d09b Improve error handling in area generation Instead of hitting a NOT NULL constraint later on, raise an error if no candidate area for cutting is found. diff -r ec1aec03676d -r 453f15ba8030 pkg/imports/errors.go --- a/pkg/imports/errors.go Fri May 31 16:54:09 2019 +0200 +++ b/pkg/imports/errors.go Fri May 31 16:58:42 2019 +0200 @@ -72,6 +72,8 @@ return "No distance mark found for at least one given ISRS Location Code" case strings.Contains(recent, "isrsrange_axis"): return "No contiguous axis found between given ISRS Location Codes" + case strings.Contains(recent, "isrsrange_area"): + return "No area around axis between given ISRS Location Codes" } } return "Unexpected database error: " + err.Message diff -r ec1aec03676d -r 453f15ba8030 schema/isrs_functions.sql --- a/schema/isrs_functions.sql Fri May 31 16:54:09 2019 +0200 +++ b/schema/isrs_functions.sql Fri May 31 16:58:42 2019 +0200 @@ -165,16 +165,21 @@ area geometry ) RETURNS geometry AS $$ +DECLARE + area_subset geometry; + result_geom geometry; +BEGIN + -- 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) + INTO STRICT area_subset + 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) + HAVING ST_Union(a_dmp.geom) IS NOT NULL; + WITH - 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 (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( ST_Translate(e, @@ -185,18 +190,23 @@ FROM (VALUES (1), (-1)) AS idx (i)) AS ep, 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)) + LATERAL ( + SELECT (ST_MaxDistance(p1, area_subset) / ST_Length(e)) * 2) AS d (d)), range_area AS ( -- Split area by orthogonal lines at the ends of the clipped axis SELECT (ST_Dump(ST_CollectionExtract( - ST_Split(area, blade), 3))).geom - FROM area_subset, rotated_ends) + ST_Split(area_subset, blade), 3))).geom + FROM rotated_ends) -- 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))) + INTO result_geom FROM range_area - WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), axis) + WHERE ST_Intersects(ST_Buffer(range_area.geom, -0.0001), axis); + + RETURN result_geom; +END; $$ - LANGUAGE sql; + LANGUAGE plpgsql + STABLE PARALLEL SAFE; diff -r ec1aec03676d -r 453f15ba8030 schema/isrs_tests.sql --- a/schema/isrs_tests.sql Fri May 31 16:54:09 2019 +0200 +++ b/schema/isrs_tests.sql Fri May 31 16:58:42 2019 +0200 @@ -58,14 +58,21 @@ 5)), 'ISRSrange_axis returns a valid simple feature'); -SELECT ok( - ISRSrange_area(ISRSrange_axis(isrsrange( +SELECT throws_ok($$ + SELECT ISRSrange_area('LINESTRING(0 0, 1 1)', NULL) + $$, + 'P0002', NULL, + 'ISRSrange_area fails if no input area is given'); + +SELECT throws_ok($$ + SELECT ISRSrange_area(ISRSrange_axis(isrsrange( ('AT', 'XXX', '00001', '00000', 0)::isrs, ('AT', 'XXX', '00001', '00000', 1)::isrs), 5), - ST_SetSRID('POLYGON((0 1, 0 2, 1 2, 1 1, 0 1))'::geometry, 4326) - ) IS NULL, - 'ISRSrange_area returns NULL, if given area does not intersect with axis'); + ST_SetSRID('POLYGON((0 1, 0 2, 1 2, 1 1, 0 1))'::geometry, 4326)) + $$, + 'P0002', NULL, + 'ISRSrange_area fails, if given area does not intersect with axis'); SELECT results_eq($$ SELECT every(ST_DWithin( diff -r ec1aec03676d -r 453f15ba8030 schema/run_tests.sh --- a/schema/run_tests.sh Fri May 31 16:54:09 2019 +0200 +++ b/schema/run_tests.sh Fri May 31 16:58:42 2019 +0200 @@ -28,7 +28,7 @@ -c 'SET client_min_messages TO WARNING' \ -c "DROP ROLE IF EXISTS $TEST_ROLES" \ -f tap_tests_data.sql \ - -c "SELECT plan(64 + ( + -c "SELECT plan(65 + ( SELECT count(*)::int FROM information_schema.tables WHERE table_schema = 'waterway'))" \