test harness

This commit is contained in:
Motiejus Jakštys 2021-05-15 00:31:41 +03:00
parent 493d43f6b8
commit 98af154526
6 changed files with 120 additions and 14 deletions

View File

@ -228,3 +228,24 @@
url={https://github.com/motiejus/wm}, url={https://github.com/motiejus/wm},
urldate={2021-05-19}, urldate={2021-05-19},
} }
@online{openstreetmap,
author={OpenStreetMap contributors},
title={Project that creates and distributes free world's geographic data},
url={https://www.openstreetmap.org},
urldate={2021-05-15},
}
@online{nzt,
author={Nacionalinė Žemės Tarnyba Prie Žemės Ūkio Ministerijos},
title={Atviri Duomenys},
url={http://nzt.lt/go.php/lit/Atviri-duomenys},
urldate={2021-05-15},
}
@online{openmapwm,
author={Tomas Straupis},
title={Test harness for Wang--M{\"u}ller algorithm},
url={https://dev.openmap.lt/webgl/wm.html},
urldate={2021-05-15},
}

View File

@ -909,11 +909,20 @@ When debug mode is turned off (that is, \textsc{dbgname} is left unspecified),
\subsection{Merging pieces of the river into one} \subsection{Merging pieces of the river into one}
% TODO Example river geometries were sourced from OpenStreetMap\cite{openstreetmap}
and NŽT\cite{nzt}. Rivers in both data sources are stored in shorter line
segments, and multiple segments (usually hundreds or thousands for significant
rivers) define one full river. While it is convenient to store and edit, these
segments are not explicitly related to each other. This poses a problem for
simplification algorithms, which manipulate on full linear features at a time:
full river geometries, but not their parts.
NOTE: explain how different river segments are merged into a single line. This Since these rivers do not have an explicit relationship to connect them
is not explained in the {\WM} paper, but is a necessary prerequisite. This is together, they were connected using heuristics: if two line segments share a
implemented in \textsc{aggregate-rivers.sql}. name and are within 500 meters from each other, then they form a single river.
For all line simplification algorithms, all rivers need to be combined, and
this way proved to be reasonably effective. Source code for this operation can
be found in listings~\onpage{lst:aggregate-rivers.sql}.
\subsection{Bend scaling and dimensions} \subsection{Bend scaling and dimensions}
\label{sec:bend-scaling-and-dimensions} \label{sec:bend-scaling-and-dimensions}
@ -1002,7 +1011,7 @@ but with bends colored as polygons: each color is a distinctive bend.
\centering \centering
\includegraphics[width=\textwidth]{fig8-definition-of-a-bend} \includegraphics[width=\textwidth]{fig8-definition-of-a-bend}
\caption{similar to figure 8 in \cite{wang1998line}: detected bends are \caption{Similar to figure 8 in \cite{wang1998line}: detected bends are
highlighted.} highlighted.}
\label{fig:fig8-definition-of-a-bend} \label{fig:fig8-definition-of-a-bend}
@ -1031,7 +1040,7 @@ when a single vertex is moved outwards the end of the bend.
\includegraphics[width=\textwidth]{fig5-gentle-inflection-after} \includegraphics[width=\textwidth]{fig5-gentle-inflection-after}
\caption{After applying the inflection rule.} \caption{After applying the inflection rule.}
\end{subfigure} \end{subfigure}
\caption{figure 5 in \cite{wang1998line}: gentle inflections at the ends of \caption{Figure 5 in \cite{wang1998line}: gentle inflections at the ends of
the bend.} the bend.}
\label{fig:fig5-gentle-inflection} \label{fig:fig5-gentle-inflection}
\end{figure} \end{figure}
@ -1347,7 +1356,8 @@ isolated bends are exaggerated, and some small bends are removed.
\label{fig:salvis-wm-220-250k} \label{fig:salvis-wm-220-250k}
\end{figure} \end{figure}
% TODO: expand % TODO: expand section and remove clear-page.
\clearpage
\subsection{Generalization result comparison with national spatial data sets} \subsection{Generalization result comparison with national spatial data sets}
@ -1355,9 +1365,28 @@ isolated bends are exaggerated, and some small bends are removed.
\subsection{Testing results online} \subsection{Testing results online}
% TODO: [Siūlau įdėti nuorodą į web app, kur būtų galima interaktyviai An on-line tool\cite{openmapwm} has been developed to test incoming parameters
% pastestuoti rezultatus. Jeigu planuotum dėti, tuomet galima nedidelį poskyrį to {\WM} algorithm. A user should select a river of interest, enter the
% pridėti Testing Results] \textsc{dhalfcircle} parameter and click "Submit". The simplified line feature
will be overlaid on top of the map.
Figure~\ref{fig:openmap-wm-good} illustrates the end result that looks
reasonably well. Figure~\ref{fig:openmap-wm-bad} illustrates that the algorithm
produces poorly simplified results for some geometries.
\begin{figure}[ht]
\centering
\includegraphics[width=\textwidth]{openmap-wm-good.png}
\caption{Example on-line test tool for {\WM} algorithm.}
\label{fig:openmap-wm-good}
\end{figure}
\begin{figure}[ht]
\centering
\includegraphics[width=.5\textwidth]{openmap-wm-bad.png}
\caption{Another example from the on-line test tool.}
\label{fig:openmap-wm-bad}
\end{figure}
\section{Conclusions} \section{Conclusions}
\label{sec:conclusions} \label{sec:conclusions}

BIN
IV/openmap-wm-bad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
IV/openmap-wm-good.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

View File

@ -10,7 +10,7 @@ BEGIN { FS="[(); ]" }
x2 += 1; x2 += 1;
d2 = sprintf("\\newcommand{\\isolationThreshold}{%.1f}",$7); d2 = sprintf("\\newcommand{\\isolationThreshold}{%.1f}",$7);
} }
/scale constant float default / { /scale2 constant float default / {
x3 += 1; x3 += 1;
d3 = sprintf("\\newcommand{\\exaggerationEnthusiasm}{%.1f}",$7); d3 = sprintf("\\newcommand{\\exaggerationEnthusiasm}{%.1f}",$7);
} }

View File

@ -417,7 +417,9 @@ begin
return st_split(st_snap(input, blade, 0.00000001), blade); return st_split(st_snap(input, blade, 0.00000001), blade);
end $$ language plpgsql; end $$ language plpgsql;
-- wm_exaggerate_bend2 is the second version of bend exaggeration. Uses
-- non-linear interpolation by point azimuth. Slower, but produces nicer
-- exaggerated geometries.
drop function if exists wm_exaggerate_bend2; drop function if exists wm_exaggerate_bend2;
create function wm_exaggerate_bend2( create function wm_exaggerate_bend2(
INOUT bend geometry, INOUT bend geometry,
@ -425,7 +427,7 @@ create function wm_exaggerate_bend2(
desired_size float desired_size float
) as $$ ) as $$
declare declare
scale constant float default 1.2; -- exaggeration enthusiasm scale2 constant float default 1.2; -- exaggeration enthusiasm
midpoint geometry; -- midpoint of the baseline midpoint geometry; -- midpoint of the baseline
points geometry[]; points geometry[];
startazimuth float; startazimuth float;
@ -459,7 +461,7 @@ begin
if diffazimuth > 90 then if diffazimuth > 90 then
diffazimuth = 180 - diffazimuth; diffazimuth = 180 - diffazimuth;
end if; end if;
sss = ((scale-1) * (diffazimuth / 90)^0.5); sss = ((scale2-1) * (diffazimuth / 90)^0.5);
point = st_transform( point = st_transform(
st_project( st_project(
st_transform(point, 4326)::geography, st_transform(point, 4326)::geography,
@ -472,6 +474,60 @@ begin
end loop; end loop;
end $$ language plpgsql; end $$ language plpgsql;
-- wm_exaggerate_bend exaggerates a given bend. Uses naive linear
-- interpolation. Faster than wm_exaggerate_bend2, but result visually looks
-- worse.
drop function if exists wm_exaggerate_bend;
create function wm_exaggerate_bend(
INOUT bend geometry,
size float,
desired_size float
) as $$
declare
scale constant float default 1.2; -- exaggeration enthusiasm
midpoint geometry; -- midpoint of the baseline
splitbend geometry; -- bend split across its half
bendm geometry; -- bend with coefficients to prolong the lines
points geometry[];
begin
if size = 0 then
raise 'invalid input: zero-area bend';
end if;
midpoint = st_lineinterpolatepoint(st_makeline(
st_pointn(bend, 1),
st_pointn(bend, -1)
), .5);
while size < desired_size loop
splitbend = wm_st_split(bend, st_lineinterpolatepoint(bend, .5));
-- Convert bend to LINESTRINGM, where M is the fraction by how
-- much the point will be prolonged:
-- 1. draw a line between midpoint and the point on the bend.
-- 2. multiply the line length by M. Midpoint stays intact.
-- 3. the new set of lines form a new bend.
-- Uses linear interpolation; can be updated to gaussian or similar;
-- then interpolate manually instead of relying on st_addmeasure.
bendm = st_collect(
st_addmeasure(st_geometryn(splitbend, 1), 1, scale),
st_addmeasure(st_geometryn(splitbend, 2), scale, 1)
);
points = array((
select st_scale(
st_makepoint(st_x(geom), st_y(geom)),
st_makepoint(st_m(geom), st_m(geom)),
midpoint
)
from st_dumppoints(bendm)
order by path[1], path[2]
));
bend = st_setsrid(st_makeline(points), st_srid(bend));
size = wm_adjsize(bend);
end loop;
end $$ language plpgsql;
-- wm_adjsize calculates adjusted size for a polygon. Can return 0. -- wm_adjsize calculates adjusted size for a polygon. Can return 0.
drop function if exists wm_adjsize; drop function if exists wm_adjsize;
create function wm_adjsize(bend geometry, OUT adjsize float) as $$ create function wm_adjsize(bend geometry, OUT adjsize float) as $$