From b97531447c4a0d8b0e7c4d3c672b49984c304305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Fri, 26 Feb 2021 18:19:23 +0200 Subject: [PATCH] fix gentle inflections -- both tests pass --- IV/tests.sql | 28 ++++++++++++++-------------- IV/wm.sql | 25 +++++++++++++++++++++---- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/IV/tests.sql b/IV/tests.sql index 0e61339..8b2f35c 100644 --- a/IV/tests.sql +++ b/IV/tests.sql @@ -43,20 +43,20 @@ end $$ language plpgsql; drop table if exists inflections; create table inflections (name text, way geometry); ---insert into inflections select 'fig3', unnest(fix_gentle_inflections(detect_bends((select way from figures where name='fig3')))); +insert into inflections select 'fig3', unnest(fix_gentle_inflections(detect_bends((select way from figures where name='fig3')))); insert into inflections select 'fig5', unnest(fix_gentle_inflections(detect_bends((select way from figures where name='fig5')))); ---insert into inflections select 'inflection-1', unnest(fix_gentle_inflections(detect_bends((select way from figures where name='inflection-1')))); +insert into inflections select 'inflection-1', unnest(fix_gentle_inflections(detect_bends((select way from figures where name='inflection-1')))); -- FIX BEND INFLECTIONS ---do $$ ---declare --- vbends geometry[]; --- vinflections geometry[]; ---begin --- select detect_bends((select way from figures where name='inflection-1')) into vbends; --- select fix_gentle_inflections(vbends) into vinflections; --- --- perform assert_equals(vbends[1], vinflections[1]); -- unchanged --- perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 5,123 7,114 7)', st_astext(vinflections[2])); --- perform assert_equals('LINESTRING(123 7,114 7,111 2)', st_astext(vinflections[3])); ---end $$ language plpgsql; +do $$ +declare + vbends geometry[]; + vinflections geometry[]; +begin + select detect_bends((select way from figures where name='inflection-1')) into vbends; + select fix_gentle_inflections(vbends) into vinflections; + + perform assert_equals(vbends[1], vinflections[1]); -- unchanged + perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 5,123 7,114 7)', st_astext(vinflections[2])); + perform assert_equals('LINESTRING(123 7,114 7,111 2)', st_astext(vinflections[3])); +end $$ language plpgsql; diff --git a/IV/wm.sql b/IV/wm.sql index e5fd175..5ab7326 100644 --- a/IV/wm.sql +++ b/IV/wm.sql @@ -76,10 +76,21 @@ $$ language plpgsql; -- commulative inflection angle small (see variable below). create or replace function fix_gentle_inflections(INOUT bends geometry[]) as $$ declare + len int4; bends1 geometry[]; + bends2 geometry[]; begin + len = array_length(bends, 1); + bends1 = fix_gentle_inflections1(bends); - bends1 = array_reverse(fix_gentle_inflections1(array_reverse(bends1))); + for i in 1..len loop + bends2[i] = st_reverse(bends1[len-i+1]); + end loop; + bends2 = fix_gentle_inflections1(bends2); + + for i in 1..len loop + bends[i] = st_reverse(bends2[len-i+1]); + end loop; end $$ language plpgsql; @@ -134,13 +145,19 @@ begin exit when array_length(phead, 1) < 3; -- if inflection angle between ptail[1:3] "large", stop processing this bend - exit when abs(st_angle(phead[1], phead[2], phead[3]) - pi) > small_angle; + if abs(st_angle(phead[1], phead[2], phead[3]) - pi) > small_angle then + --raise notice 'quitting % because angle between % % %', st_astext(ptail), st_astext(phead[1]), st_astext(phead[2]), st_astext(phead[3]); + exit; + end if; -- distance from head's first vertex should be larger than from second vertex - exit when st_distance(ptail, phead[2]) < st_distance(ptail, phead[3]); + if st_distance(ptail, phead[2]) < st_distance(ptail, phead[3]) then + --raise notice 'quitting % because distance', st_astext(ptail); + exit; + end if; -- detected a gentle inflection. Move head of the tail to the tail of head - raise notice 'fixing a gentle inflection of angle %', degrees(abs(st_angle(phead[1], phead[2], phead[3]) - pi)); + --raise notice 'fixing a gentle inflection of angle %', degrees(abs(st_angle(phead[1], phead[2], phead[3]) - pi)); bends[i] = st_removepoint(bends[i], 0); bends[i-1] = st_addpoint(bends[i-1], phead[3]);