wip -- debugging

This commit is contained in:
Motiejus Jakštys 2021-05-19 22:57:47 +03:00 committed by Motiejus Jakštys
parent 144ea894d0
commit f30354290f
3 changed files with 122 additions and 83 deletions

View File

@ -246,7 +246,7 @@ and the implementation.
\centering \centering
\begin{tabular}{|c|c|c|c|c|c|c|} \begin{tabular}{|c|c|c|c|c|c|c|}
\hline \hline
Degrees & $30^\circ$ & $45^\circ$ & $90^\circ$ & $180^\circ$ & $360^\circ$ \\ Degrees & $30^\circ$ & $45^\circ$ & $90^\circ$ & $180^\circ$ & $360^\circ$ \\
\hline \hline
Radians & $\nicefrac{\pi}{6}$ & $\nicefrac{\pi}{4}$ & $\nicefrac{\pi}{2}$ & $\pi$ & $2\pi$ \\ Radians & $\nicefrac{\pi}{6}$ & $\nicefrac{\pi}{4}$ & $\nicefrac{\pi}{2}$ & $\pi$ & $2\pi$ \\
\hline \hline
@ -316,7 +316,6 @@ provides more technical details. Here are some non-obvious characteristics that
are necessary when writing code to detect the bends: are necessary when writing code to detect the bends:
\begin{itemize} \begin{itemize}
\item End segments of each line should also belong to bends. That way, all \item End segments of each line should also belong to bends. That way, all
segments belong to 1 or 2 bends. segments belong to 1 or 2 bends.
@ -394,7 +393,8 @@ vertices to the next bend instead of one.
To find and fix the gentle bends' inflections requires to run the algorithm in To find and fix the gentle bends' inflections requires to run the algorithm in
both directions; if implemented as documented, the steps will fail to match both directions; if implemented as documented, the steps will fail to match
some bends that should be mutated. This implementation does it in the following way: some bends that should be mutated. This implementation does it in the following
way:
\begin{enumerate} \begin{enumerate}
\item Run the algorithm from beginning to the end. \item Run the algorithm from beginning to the end.

188
tests.sql
View File

@ -1,5 +1,10 @@
\i wm.sql \i wm.sql
--do $$
--begin
-- SET AUTOCOMMIT TO ON;
--end $$ language plpgsql;
-- https://stackoverflow.com/questions/19982373/which-tools-libraries-do-you-use-to-unit-test-your-pl-pgsql -- https://stackoverflow.com/questions/19982373/which-tools-libraries-do-you-use-to-unit-test-your-pl-pgsql
CREATE OR REPLACE FUNCTION assert_equals(expected anyelement, actual anyelement) RETURNS void AS $$ CREATE OR REPLACE FUNCTION assert_equals(expected anyelement, actual anyelement) RETURNS void AS $$
begin begin
@ -46,89 +51,116 @@ insert into wm_figures (name, way) values ('fig6-combi',
insert into wm_figures (name, way) values('fig8', ST_GeomFromText('LINESTRING(173 12,174 10,180 8,186 8,186 13,191 11,189 6,201 5,203 11,216 16,216 6,222 7,229 3,236 2,239 6,243 8,248 6)')); insert into wm_figures (name, way) values('fig8', ST_GeomFromText('LINESTRING(173 12,174 10,180 8,186 8,186 13,191 11,189 6,201 5,203 11,216 16,216 6,222 7,229 3,236 2,239 6,243 8,248 6)'));
insert into wm_figures (name, way) values ('inflection-1',ST_GeomFromText('LINESTRING(110 24,114 20,133 20,145 15,145 0,136 8,123 10,114 10,111 2)')); insert into wm_figures (name, way) values ('inflection-1',ST_GeomFromText('LINESTRING(110 24,114 20,133 20,145 15,145 0,136 8,123 10,114 10,111 2)'));
insert into wm_figures (name, way) values ('multi-island',ST_GeomFromText('MULTILINESTRING((-15 10,-10 10,-5 11,0 11,5 11,10 10,11 9,13 10,15 9),(-5 11,-2 15,0 16,2 15,5 11))')); insert into wm_figures (name, way) values ('multi-island',ST_GeomFromText('MULTILINESTRING((-15 10,-10 10,-5 11,0 11,5 11,10 10,11 9,13 10,15 9),(-5 11,-2 15,0 16,2 15,5 11))'));
insert into wm_figures (name, way) values ('selfcrossing-1',ST_GeomFromText('LINESTRING(-27 180,-20 166,-21 142,-18 136,55 136,55 136,71 145,44 165,37 146,22 145,14 164,11 164,3 146,-12 146,-13 176,-18 184)'));
delete from wm_figures where name <> 'selfcrossing-1';
-- Run ST_SimplifyWM in debug mode, so `wm_debug` is populated. That table -- Run ST_SimplifyWM in debug mode, so `wm_debug` is populated. That table
-- is used for geometric assertions later in the file. -- is used for geometric assertions later in the file.
drop table if exists wm_demo; drop table if exists wm_demo;
create table wm_demo (name text, i bigint, way geometry); create table wm_demo (name text, i bigint, way geometry);
do $$
declare
v_state TEXT;
v_msg TEXT;
v_detail TEXT;
v_hint TEXT;
v_context TEXT;
begin
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, name) from wm_figures; insert into wm_demo (name, way) select name, ST_SimplifyWM(way, name) from wm_figures;
exception when others then
get stacked diagnostics
v_state = returned_sqlstate,
v_msg = message_text,
v_detail = pg_exception_detail,
v_hint = pg_exception_hint,
v_context = pg_exception_context;
raise notice E'Got exception:
state : %
message: %
detail : %
hint : %
context: %', v_state, v_msg, v_detail, v_hint, v_context;
end $$ language plpgsql;
-- wm_visuals holds visual aids for the paper. -- wm_visuals holds visual aids for the paper.
drop table if exists wm_visuals; --drop table if exists wm_visuals;
create table wm_visuals (name text, way geometry); --create table wm_visuals (name text, way geometry);
do $$ --do $$
declare fig6b1 geometry; -- declare fig6b1 geometry;
declare fig6b2 geometry; -- declare fig6b2 geometry;
begin --begin
select way from wm_debug where name='fig6' and stage='bbends' and gen=1 into fig6b1 limit 1 offset 0; -- select way from wm_debug where name='fig6' and stage='bbends' and gen=1 into fig6b1 limit 1 offset 0;
select way from wm_debug where name='fig6' and stage='bbends' and gen=1 into fig6b2 limit 1 offset 2; -- select way from wm_debug where name='fig6' and stage='bbends' and gen=1 into fig6b2 limit 1 offset 2;
insert into wm_visuals (name, way) values('fig6-baseline', st_makeline(st_startpoint(fig6b2), st_endpoint(fig6b2))); -- insert into wm_visuals (name, way) values('fig6-baseline', st_makeline(st_startpoint(fig6b2), st_endpoint(fig6b2)));
insert into wm_visuals (name, way) values('fig6-newline', st_makeline(st_endpoint(fig6b1), st_endpoint(fig6b2))); -- insert into wm_visuals (name, way) values('fig6-newline', st_makeline(st_endpoint(fig6b1), st_endpoint(fig6b2)));
end $$ language plpgsql; --end $$ language plpgsql;
--
do $$ --do $$
declare --declare
vbends geometry[]; -- vbends geometry[];
begin --begin
select array((select way from wm_debug where name='fig3' and stage='bbends')) into vbends; -- select array((select way from wm_debug where name='fig3' and stage='bbends')) into vbends;
perform assert_equals(5, array_length(vbends, 1)); -- perform assert_equals(5, array_length(vbends, 1));
perform assert_equals('LINESTRING(0 0,12 0,13 4)', st_astext(vbends[1])); -- perform assert_equals('LINESTRING(0 0,12 0,13 4)', st_astext(vbends[1]));
perform assert_equals('LINESTRING(12 0,13 4,20 2,20 0)', st_astext(vbends[2])); -- perform assert_equals('LINESTRING(12 0,13 4,20 2,20 0)', st_astext(vbends[2]));
perform assert_equals('LINESTRING(20 2,20 0,32 0,33 10)', st_astext(vbends[3])); -- perform assert_equals('LINESTRING(20 2,20 0,32 0,33 10)', st_astext(vbends[3]));
perform assert_equals('LINESTRING(32 0,33 10,38 16,43 15,44 10,44 0)', st_astext(vbends[4])); -- perform assert_equals('LINESTRING(32 0,33 10,38 16,43 15,44 10,44 0)', st_astext(vbends[4]));
perform assert_equals(4, array_length(detect_bends((select way from wm_figures where name='fig3-1')), 1)); -- perform assert_equals(4, array_length(detect_bends((select way from wm_figures where name='fig3-1')), 1));
select detect_bends((select way from wm_figures where name='fig5')) into vbends; -- select detect_bends((select way from wm_figures where name='fig5')) into vbends;
perform assert_equals(3, array_length(vbends, 1)); -- perform assert_equals(3, array_length(vbends, 1));
end $$ language plpgsql; --end $$ language plpgsql;
--
do $$ --do $$
declare --declare
vbends geometry[]; -- vbends geometry[];
vinflections geometry[]; -- vinflections geometry[];
begin --begin
select array((select way from wm_debug where name='fig5' and stage='cinflections')) into vinflections; -- select array((select way from wm_debug where name='fig5' and stage='cinflections')) into vinflections;
perform assert_equals('LINESTRING(0 39,19 52,27 77)', st_astext(vinflections[1])); -- perform assert_equals('LINESTRING(0 39,19 52,27 77)', st_astext(vinflections[1]));
perform assert_equals('LINESTRING(19 52,27 77,26 104,41 115,49 115,65 103,65 75,53 45)', st_astext(vinflections[2])); -- perform assert_equals('LINESTRING(19 52,27 77,26 104,41 115,49 115,65 103,65 75,53 45)', st_astext(vinflections[2]));
perform assert_equals('LINESTRING(65 75,53 45,63 15,91 0)', st_astext(vinflections[3])); -- perform assert_equals('LINESTRING(65 75,53 45,63 15,91 0)', st_astext(vinflections[3]));
--
-- inflections-1, the example in fix_gentle_inflections docstring -- -- inflections-1, the example in fix_gentle_inflections docstring
select array((select way from wm_debug where name='inflection-1' and stage='bbends')) into vbends; -- select array((select way from wm_debug where name='inflection-1' and stage='bbends')) into vbends;
select array((select way from wm_debug where name='inflection-1' and stage='cinflections')) into vinflections; -- select array((select way from wm_debug where name='inflection-1' and stage='cinflections')) into vinflections;
perform assert_equals(vbends[1], vinflections[1]); -- unchanged -- perform assert_equals(vbends[1], vinflections[1]); -- unchanged
perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 8,123 10,114 10)', st_astext(vinflections[2])); -- perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 8,123 10,114 10)', st_astext(vinflections[2]));
perform assert_equals('LINESTRING(123 10,114 10,111 2)', st_astext(vinflections[3])); -- perform assert_equals('LINESTRING(123 10,114 10,111 2)', st_astext(vinflections[3]));
end $$ language plpgsql; --end $$ language plpgsql;
--
do $$ --do $$
declare --declare
vcrossings geometry[]; -- vcrossings geometry[];
mutated boolean; -- mutated boolean;
begin --begin
select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6')))).* into vcrossings, mutated; -- select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6')))).* into vcrossings, mutated;
perform assert_equals(true, mutated); -- perform assert_equals(true, mutated);
perform assert_equals( -- perform assert_equals(
'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)', -- 'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)',
(select st_astext( -- (select st_astext(
st_linemerge(st_union(way)) -- st_linemerge(st_union(way))
) from (select unnest(vcrossings) way) a) -- ) from (select unnest(vcrossings) way) a)
); -- );
--
select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6-rev')))).* into vcrossings, mutated; -- select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6-rev')))).* into vcrossings, mutated;
perform assert_equals(true, mutated); -- perform assert_equals(true, mutated);
perform assert_equals( -- perform assert_equals(
'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)', -- 'LINESTRING(84 47,91 59,114 64,120 45,125 39,141 39,147 32)',
(select st_astext( -- (select st_astext(
st_translate(st_reverse(st_linemerge(st_union(way))), -60, 0) -- st_translate(st_reverse(st_linemerge(st_union(way))), -60, 0)
) from (select unnest(vcrossings) way) a) -- ) from (select unnest(vcrossings) way) a)
); -- );
--
select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6-combi' and gen=1)))).* into vcrossings, mutated; -- select (self_crossing(array((select way from wm_debug where stage='cinflections' and name='fig6-combi' and gen=1)))).* into vcrossings, mutated;
perform assert_equals(true, mutated); -- perform assert_equals(true, mutated);
perform assert_equals( -- perform assert_equals(
'MULTILINESTRING((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))', -- 'MULTILINESTRING((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( -- (select st_astext(
st_linemerge(st_union(way)) -- st_linemerge(st_union(way))
) from (select unnest(vcrossings) way) a) -- ) from (select unnest(vcrossings) way) a)
); -- );
--
end $$ language plpgsql; --end $$ language plpgsql;

11
wm.sql
View File

@ -1,5 +1,5 @@
\set ON_ERROR_STOP on --\set ON_ERROR_STOP on
SET plpgsql.extra_errors TO 'all'; --SET plpgsql.extra_errors TO 'all';
-- detect_bends detects bends using the inflection angles. No corrections. -- detect_bends detects bends using the inflection angles. No corrections.
drop function if exists detect_bends; drop function if exists detect_bends;
@ -251,6 +251,7 @@ begin
-- vertices, segments and stars are aligned, we are changing the bend -- vertices, segments and stars are aligned, we are changing the bend
mutated = true; mutated = true;
raise notice 'splitting bend %', j;
-- To understand the block below, I suggest you take a pencil and paper, -- To understand the block below, I suggest you take a pencil and paper,
-- draw a self-crossing bend (fig6 from the article works well), and -- draw a self-crossing bend (fig6 from the article works well), and
@ -273,6 +274,10 @@ begin
-- remove last vertex of the previous bend, because the last -- remove last vertex of the previous bend, because the last
-- segment is duplicated with the i'th bend. -- segment is duplicated with the i'th bend.
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1); bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
raise notice 'multi: %', st_astext(multi);
raise notice '2: removing first point from %', st_astext(st_geometryn(multi, st_numgeometries(multi)));
mutated = false;
--return; % continue debugging here
bends[i] = st_makeline( bends[i] = st_makeline(
st_pointn(bends[i], 1), st_pointn(bends[i], 1),
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0) st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
@ -458,6 +463,7 @@ begin
); );
end if; end if;
bends = detect_bends(lines[i], dbgname, stagenum); bends = detect_bends(lines[i], dbgname, stagenum);
bends = fix_gentle_inflections(bends, dbgname, stagenum); bends = fix_gentle_inflections(bends, dbgname, stagenum);
@ -473,6 +479,7 @@ begin
); );
end if; end if;
if mutated then if mutated then
lines[i] = st_linemerge(st_union(bends)); lines[i] = st_linemerge(st_union(bends));
stagenum = stagenum + 1; stagenum = stagenum + 1;