comparison schema/isrs_tests.sql @ 2398:8481e6266691

Fix corner case in area generation from stretch In case orthogonal lines of arbitrary length at the ends of the axis between two given distance marks cross the axis (e.g. because it describes a tight turn), the result of ST_Buffer with endcap=flat is not well defined. Test data have been amended to include such a case as well as appropriate data to test correctness of a fix. The fix includes construction of the afore mentioned orthogonal lines, splitting the given area by these lines and constructing the end result from those parts of the splitted area that intersect with the clipped axis. Due to numerical inaccuracy, the parts might overlap slightly and eventually cross the clipped axis where they should only touch. Therefore, a small buffer was introduced before testing intersection and intersecting parts are dissolved using ST_Union (which is necessary to revert splits inside the resulting polygon anyhow).
author Tom Gottfried <tom@intevation.de>
date Wed, 27 Feb 2019 18:00:35 +0100
parents 7936b46a88d4
children 48495bd3081d
comparison
equal deleted inserted replaced
2397:b95234702ee9 2398:8481e6266691
40 ('AT', 'XXX', '00001', '00000', 1)::isrs), 40 ('AT', 'XXX', '00001', '00000', 1)::isrs),
41 ST_SetSRID('POLYGON((0 1, 0 2, 1 2, 1 1, 0 1))'::geometry, 4326) 41 ST_SetSRID('POLYGON((0 1, 0 2, 1 2, 1 1, 0 1))'::geometry, 4326)
42 ) IS NULL, 42 ) IS NULL,
43 'ISRSrange_area returns NULL, if given area does not intersect with axis'); 43 'ISRSrange_area returns NULL, if given area does not intersect with axis');
44 44
45 \set test_area 'POLYGON((-1 1, 2 1, 2 -1, -1 -1, -1 1))'
46 SELECT ok( 45 SELECT ok(
47 ST_DWithin( 46 ST_DWithin(
48 (SELECT geom FROM waterway.distance_marks_virtual 47 (SELECT geom FROM waterway.distance_marks_virtual
49 WHERE location_code = ('AT', 'XXX', '00001', '00000', 0)::isrs), 48 WHERE location_code = ('AT', 'XXX', '00001', '00000', 0)::isrs),
50 ST_Boundary(ISRSrange_area(isrsrange( 49 ST_Boundary(ISRSrange_area(isrsrange(
51 ('AT', 'XXX', '00001', '00000', 0)::isrs, 50 ('AT', 'XXX', '00001', '00000', 0)::isrs,
52 ('AT', 'XXX', '00001', '00000', 1)::isrs), 51 ('AT', 'XXX', '00001', '00000', 1)::isrs),
53 ST_SetSRID(:'test_area'::geometry, 52 (SELECT ST_Collect(CAST(area AS geometry))
54 4326)))::geography, 53 FROM waterway.waterway_area))),
55 1) 54 1)
56 AND 55 AND
57 ST_DWithin( 56 ST_DWithin(
58 (SELECT geom FROM waterway.distance_marks_virtual 57 (SELECT geom FROM waterway.distance_marks_virtual
59 WHERE location_code = ('AT', 'XXX', '00001', '00000', 1)::isrs), 58 WHERE location_code = ('AT', 'XXX', '00001', '00000', 1)::isrs),
60 ST_Boundary(ISRSrange_area(isrsrange( 59 ST_Boundary(ISRSrange_area(isrsrange(
61 ('AT', 'XXX', '00001', '00000', 0)::isrs, 60 ('AT', 'XXX', '00001', '00000', 0)::isrs,
62 ('AT', 'XXX', '00001', '00000', 1)::isrs), 61 ('AT', 'XXX', '00001', '00000', 1)::isrs),
63 ST_SetSRID(:'test_area'::geometry, 62 (SELECT ST_Collect(CAST(area AS geometry))
64 4326)))::geography, 63 FROM waterway.waterway_area))),
65 1), 64 1),
66 'Resulting polygon almost ST_Touches points corresponding to stretch'); 65 'Resulting polygon almost ST_Touches points corresponding to stretch');
67 66
67 \set test_area 'POLYGON((-1 1, 2 1, 2 -1, -1 -1, -1 1))'
68 SELECT ok( 68 SELECT ok(
69 2 = ST_NumGeometries( 69 2 = ST_NumGeometries(
70 ISRSrange_area( 70 ISRSrange_area(
71 isrsrange( 71 isrsrange(
72 ('AT', 'XXX', '00001', '00000', 0)::isrs, 72 ('AT', 'XXX', '00001', '00000', 0)::isrs,