commit 7bef5ba36acb6157600bfa7684028678d7fed806 (tree)
parent f42354800b2f3258cd8ce73b0b44600f1abc0d84
Author: Motiejus Jakštys <motiejus@uber.com>
Date: Mon, 22 Feb 2021 08:44:23 +0200
gentle inflection of a bend
Diffstat:
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/IV/tests.sql b/IV/tests.sql
@@ -16,11 +16,13 @@ create table figures (name text, way geometry);
insert into figures (name, way) values ('fig3',ST_GeomFromText('LINESTRING(0 0,12 0,13 4,20 2,20 0,32 0,33 10,38 16,43 15,44 10,44 0,60 0)'));
insert into figures (name, way) values ('fig3-1',ST_GeomFromText('LINESTRING(0 0,12 0,13 4,20 2,20 0,32 0,33 10,38 16,43 15,44 10,44 0)'));
insert into figures (name, way) values ('fig5',ST_GeomFromText('LINESTRING(0 39,19 52,27 77,26 104,41 115,49 115,65 103,65 75,53 45,63 15,91 0,91 0)'));
+insert into figures (name, way) values ('inflection-1',ST_GeomFromText('LINESTRING(129 45,131 56,130 82,128 99,147 104,149 89,147 68,141 52)'));
drop table if exists bends;
create table bends (way geometry);
insert into bends select unnest(detect_bends((select way from figures where name='fig3')));
insert into bends select unnest(detect_bends((select way from figures where name='fig5')));
+insert into bends select unnest(detect_bends((select way from figures where name='inflection-1')));
do $$
declare
diff --git a/IV/wm.sql b/IV/wm.sql
@@ -70,7 +70,59 @@ $$ language plpgsql;
-- fix_gentle_inflections moves bend endpoints following "Gentle Inflection at
-- End of a Bend" section.
+--
+-- The text does not specify how many vertices can be "adjusted"; it can
+-- equally be one or many. This function is adjusting many, as long as the
+-- commulative inflection angle is less than pi/6 (30 deg).
create or replace function fix_gentle_inflections(INOUT bends geometry[]) as $$
+declare
+ prev_bend geometry;
+ bend geometry;
+ p geometry;
+ p1 geometry;
+ p2 geometry;
+ p3 geometry;
begin
+ foreach bend in array bends loop
+ if prev_bend is null then
+ prev_bend = bend;
+ continue;
+ end if;
+
+ -- Predicate: two bends will always share an edge. Assuming (A,B,C,D,E,F)
+ -- is a bend:
+ -- C________D
+ -- / \
+ -- \________/ \_______/
+ -- A B E F
+ --
+ -- Then edges (A,B) and (E,F) are shared with the neighboring bends.
+ --
+ --
+ -- Assume this curve:
+ --
+ -- A______B
+ -- ---' `---.___. E
+ -- C D |
+ -- _I |
+ -- '---.________ |
+ -- H G'---+ F
+ --
+ -- After processing the curve following the definition of a bend, the bend
+ -- [A-G] would be detected. Assuming inflection point G and H are "small",
+ -- the bend would be extended by two edges to [A,I].
+ for p in (select geom from st_dumppoints(prev_bend) order by path[1] desc) loop
+ p3 = p2;
+ p2 = p1;
+ p1 = p;
+ if p3 is null then
+ continue;
+ end if;
+
+ -- (p2, p1) is shared with the current bend.
+ end loop;
+
+ prev_bend = bend;
+ end loop;
end
$$ language plpgsql;