a line is a full bend now

This commit is contained in:
Motiejus Jakštys 2021-02-20 14:10:34 +02:00
parent 973c78b0cf
commit 95baf98c8b
3 changed files with 25 additions and 13 deletions

1
IV/notes.txt Normal file
View File

@ -0,0 +1 @@
Definition of a bend: ends of the line should always be bends, otherwise not all line vertices are covered by bends (definition elsewhere).

View File

@ -17,20 +17,25 @@ insert into figures (name, way) values ('fig3',ST_GeomFromText('LINESTRING(0 0,1
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 ('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 ('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)'));
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')));
do $$ do $$
declare declare
bends geometry[]; bends geometry[];
begin begin
select detect_bends((select way from figures where name='fig3')) into bends; select detect_bends((select way from figures where name='fig3')) into bends;
perform assert_equals(3, array_length(bends, 1)); perform assert_equals(5, array_length(bends, 1));
perform assert_equals(4::bigint, (select count(1) from (select (st_dumppoints(detect_bends[1])).path from bends) a)); perform assert_equals('LINESTRING(0 0,12 0,13 4)', st_astext(bends[1]));
perform assert_equals('LINESTRING(12 0,13 4,20 2,20 0)', st_astext(bends[1])); perform assert_equals('LINESTRING(12 0,13 4,20 2,20 0)', st_astext(bends[2]));
perform assert_equals('LINESTRING(20 2,20 0,32 0,33 10)', st_astext(bends[2])); perform assert_equals('LINESTRING(20 2,20 0,32 0,33 10)', st_astext(bends[3]));
perform assert_equals('LINESTRING(32 0,33 10,38 16,43 15,44 10,44 0)',st_astext(bends[3])); perform assert_equals('LINESTRING(32 0,33 10,38 16,43 15,44 10,44 0)', st_astext(bends[4]));
perform assert_equals(3, array_length(detect_bends((select way from figures where name='fig3-1')), 1)); perform assert_equals(4, array_length(detect_bends((select way from figures where name='fig3-1')), 1));
select detect_bends((select way from figures where name='fig5')) into bends; select detect_bends((select way from figures where name='fig5')) into bends;
perform assert_equals(2, array_length(bends, 1)); perform assert_equals(3, array_length(bends, 1));
end $$ language plpgsql; end $$ language plpgsql;

View File

@ -16,7 +16,11 @@ declare
begin begin
pi = radians(180); pi = radians(180);
for p in (select (dp).geom from st_dumppoints(line) as dp) loop for p in (
(select (dp).geom from st_dumppoints(line) as dp order by (dp).path[1] asc)
union all
(select (dp).geom from st_dumppoints(line) as dp order by (dp).path[1] desc limit 1)
) loop
p3 = p2; p3 = p2;
p2 = p1; p2 = p1;
p1 = p; p1 = p;
@ -25,7 +29,11 @@ begin
end if; end if;
cur_sign = sign(pi - st_angle(p1, p2, p2, p3)); cur_sign = sign(pi - st_angle(p1, p2, p2, p3));
bend = st_linemerge(st_union(bend, st_makeline(p3, p2))); if bend is null then
bend = st_makeline(p3, p2);
else
bend = st_linemerge(st_union(bend, st_makeline(p3, p2)));
end if;
if prev_sign + cur_sign = 0 then if prev_sign + cur_sign = 0 then
if bend is not null then if bend is not null then
@ -36,10 +44,8 @@ begin
prev_sign = cur_sign; prev_sign = cur_sign;
end loop; end loop;
-- the last bend may be lost if there is no "final" inflection angle. -- the last bend may be lost if there is no "final" inflection angle. Add it.
-- to avoid that, return the last bend if the last accumulation has >3 if (select count(1) from ((select st_dumppoints(bend) as a)) b) >= 2 then
-- vertices.
if (select count(1) from ((select st_dumppoints(bend) as a)) b) >= 3 then
bends = bends || bend; bends = bends || bend;
end if; end if;
end end