From 5a076c32d3b9f58f7db2b5cfbfeb5b5d61455dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Wed, 19 May 2021 22:57:46 +0300 Subject: [PATCH] return whether self_crossings mutated the bends --- tests.sql | 14 +++++++++----- wm.sql | 9 ++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tests.sql b/tests.sql index 0903db2..f33ab0b 100644 --- a/tests.sql +++ b/tests.sql @@ -46,8 +46,8 @@ insert into demo_inflections2 select name, generate_subscripts(ways, 1), unnest( -- SELF-LINE CROSSING drop table if exists selfcrossing, demo_selfcrossing3; -create table selfcrossing (name text, ways geometry[]); -insert into selfcrossing select name, self_crossing(ways) from inflections; +create table selfcrossing (name text, ways geometry[], mutated boolean); +insert into selfcrossing select name, (self_crossing(ways)).* from inflections; create table demo_selfcrossing3 (name text, i bigint, way geometry); insert into demo_selfcrossing3 select name, generate_subscripts(ways, 1), unnest(ways) from selfcrossing; @@ -88,9 +88,11 @@ end $$ language plpgsql; do $$ declare + mutated boolean; vcrossings geometry[]; begin - select self_crossing((select ways from inflections where name='fig6')) into vcrossings; + select (self_crossing((select ways from inflections where name='fig6'))).* into vcrossings, mutated; + perform assert_equals(true, mutated); perform assert_equals( 'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)', (select st_astext( @@ -98,7 +100,8 @@ begin ) from (select unnest(vcrossings) way) a) ); - select self_crossing((select ways from inflections where name='fig6-rev')) into vcrossings; + select (self_crossing((select ways from inflections where name='fig6-rev'))).* into vcrossings, mutated; + perform assert_equals(true, mutated); perform assert_equals( 'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)', (select st_astext( @@ -106,7 +109,8 @@ begin ) from (select unnest(vcrossings) way) a) ); - select self_crossing((select ways from inflections where name='fig6-combi')) into vcrossings; + select (self_crossing((select ways from inflections where name='fig6-combi'))).* into vcrossings, mutated; + perform assert_equals(true, mutated); perform assert_equals( 'LINESTRING(84 137,91 149,114 154,120 135,125 129,141 129,147 122,164 137,171 149,194 154,200 135,205 129,221 129,227 122)', (select st_astext( diff --git a/wm.sql b/wm.sql index 4aa2776..0d25b94 100644 --- a/wm.sql +++ b/wm.sql @@ -165,7 +165,10 @@ $$ language plpgsql; -- self_crossing eliminates self-crossing from the bends, following the -- article's section "Self-line Crossing When Cutting a Bend". drop function if exists self_crossing; -create function self_crossing(INOUT bends geometry[]) as $$ +create function self_crossing( + INOUT bends geometry[], + OUT mutated boolean +) as $$ declare i int4; j int4; @@ -182,6 +185,7 @@ declare multi geometry; begin pi = radians(180); + mutated = false; -- go through the bends and find one where sum of inflection angle is >180 for i in 1..array_length(bends, 1) loop @@ -227,6 +231,9 @@ begin continue when st_numgeometries(multi) = 2 and (st_contains(bends[j], a) or st_contains(bends[j], b)); + -- stars are aligned, we are changing the bend + mutated = true; + -- Sincere apologies to someone who will need to debug the block below. -- To understand it, I suggest you take a pencil and paper, draw a -- self-crossing bend (fig6 from the article works well), and figure out