diff --git a/.gitignore b/.gitignore index 169e129..278cd92 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ __pycache__ .tmp/ *.pyc *.pyg +*.vrb *.inc.tex _minted-*/ *.qgz diff --git a/Makefile b/Makefile index d7403eb..7abb764 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,8 @@ RIVERFILTER = Visinčia|Šalčia|Nemunas # Max figure size (in meters) is when it's width is TEXTWIDTH_CM on scale 1:25k SCALEDWIDTH = $(shell awk '/^TEXTWIDTH_CM/{print 25000/100*$$3}' layer2img.py) -ARCHIVABLES = $(filter-out slides-2021-03-29.txt,$(shell git ls-files .)) -SLIDES = slides-2021-03-29.pdf - +SLIDES_IN = slides-2021-03-29.txt slides-2021-06-02.tex +SLIDES = slides-2021-03-29 slides-2021-06-02 LISTINGS = aggregate-rivers.sql wm.sql extract-and-generate FIGURES = \ @@ -22,6 +21,9 @@ FIGURES = \ selfcrossing-1 \ isolated-1-exaggerated +FIGURES_SLIDES += isolated-1-before \ + isolated-1-after + RIVERS = \ salvis-25k \ salvis-2x50k \ @@ -38,6 +40,9 @@ RIVERS = \ salvis-wm-overlaid-250k-zoom \ salvis-wm220 +RIVERS_SLIDES += salvis-dp64overlaid-2x50k \ + salvis-dpchaikin64overlaid-2x50k + ################################################################################ # FIGURES ################################################################################ @@ -103,6 +108,15 @@ isolated-1-exaggerated_1SELECT = wm_debug where name='isolated-1' AND stage='afi isolated-1-exaggerated_2SELECT = wm_debug where name='isolated-1' AND stage='afigures' AND gen=1 isolated-1-exaggerated_1COLOR = orange +isolated-1-before_1SELECT = wm_debug where name='isolated-1' AND stage='afigures' AND gen=1 +isolated-1-before_2SELECT = wm_debug where name='isolated-1' AND stage='afigures' AND gen=2 +isolated-1-before_2LINESTYLE = invisible +isolated-1-before_WIDTHDIV = 2 +isolated-1-after_1SELECT = wm_debug where name='isolated-1' AND stage='afigures' AND gen=2 +isolated-1-after_1COLOR = orange +isolated-1-after_WIDTHDIV = 2 + + ################################################################################ # 250K ################################################################################ @@ -135,6 +149,8 @@ label_grpk10 = GRPK 1:\numprint{10000} label_grpk50 = GRPK 1:\numprint{50000} label_vwchaikin64 = $(label_vw64) and Chaikin label_dpchaikin64 = $(label_dp64) and Chaikin +label_vwchaikin64lt = $(label_vw64) ir Chaikin +label_dpchaikin64lt = $(label_dp64) ir Chaikin legend_ = lower left legend_tr = lower right legend_tl = lower center @@ -179,6 +195,22 @@ salvis-25k_WIDTHDIV = 1 salvis-2x50k_1SELECT = wm_visuals where name='salvis-grpk10' salvis-2x50k_WIDTHDIV = 2 +salvis-dp64overlaid-2x50k_1SELECT = wm_visuals where name='salvis-grpk10' +salvis-dp64overlaid-2x50k_1LABEL = $(label_grpk10) +salvis-dp64overlaid-2x50k_2SELECT = wm_visuals where name='salvis-dp64' +salvis-dp64overlaid-2x50k_2LABEL = $(label_dp64) +salvis-dp64overlaid-2x50k_2COLOR = orange +salvis-dp64overlaid-2x50k_QUADRANT = tl +salvis-dp64overlaid-2x50k_LEGEND = $(legend_tl) + +salvis-dpchaikin64overlaid-2x50k_1SELECT = wm_visuals where name='salvis-grpk10' +salvis-dpchaikin64overlaid-2x50k_1LABEL = $(label_grpk10) +salvis-dpchaikin64overlaid-2x50k_2SELECT = wm_visuals where name='salvis-dpchaikin64' +salvis-dpchaikin64overlaid-2x50k_2COLOR = orange +salvis-dpchaikin64overlaid-2x50k_2LABEL = $(label_dpchaikin64lt) +salvis-dpchaikin64overlaid-2x50k_QUADRANT = tl +salvis-dpchaikin64overlaid-2x50k_LEGEND = $(legend_tl) + salvis-dp64-2x50k_1SELECT = wm_visuals where name='salvis-dp64' salvis-dp64-2x50k_WIDTHDIV = 2 @@ -220,14 +252,16 @@ $(1).pdf: layer2img.py Makefile $(2) ) endef -$(foreach fig,$(FIGURES),$(eval $(call FIG_template,$(fig),.faux_test))) -$(foreach fig,$(RIVERS), $(eval $(call FIG_template,$(fig),.faux_visuals))) +$(foreach fig,$(FIGURES), $(eval $(call FIG_template,$(fig),.faux_test))) +$(foreach fig,$(FIGURES_SLIDES),$(eval $(call FIG_template,$(fig),.faux_test))) +$(foreach fig,$(RIVERS), $(eval $(call FIG_template,$(fig),.faux_visuals))) +$(foreach fig,$(RIVERS_SLIDES), $(eval $(call FIG_template,$(fig),.faux_visuals))) ################################# # The thesis, publishable version ################################# -mj-msc-full.pdf: mj-msc.pdf version.inc.tex $(ARCHIVABLES) ## Thesis for publishing +mj-msc-full.pdf: mj-msc.pdf version.inc.tex $(filter-out $(SLIDES_IN),$(shell git ls-files .)) ## Thesis for publishing cp $< .tmp-$@ for f in $^; do \ if [ "$$f" = "$<" ]; then continue; fi; \ @@ -250,7 +284,7 @@ visuals: .faux_visuals # Generate visuals for paper (fast) test-rivers: .faux_test-rivers ## Rivers tests (slow) .PHONY: slides -slides: $(SLIDES) +slides: $(addsuffix .pdf,$(SLIDES)) .PHONY: refresh-rivers refresh-rivers: refresh-rivers-10.sql refresh-rivers-50.sql refresh-rivers-250.sql ## Refresh river data from national datasets @@ -307,6 +341,14 @@ vars.inc.tex: vars.awk wm.sql Makefile slides-2021-03-29.pdf: slides-2021-03-29.txt pandoc -t beamer -i $< -o $@ +slides-2021-06-02.pdf: slides-2021-06-02.tex \ + amalgamate1.png \ + isolated-1-before.pdf isolated-1-after.pdf \ + salvis-dp64overlaid-2x50k.pdf \ + salvis-dpchaikin64overlaid-2x50k.pdf \ + $(wilcard *logo.pdf) + latexmk -shell-escape -pdf $< + dump-debug_wm.sql.xz: docker exec -ti wm-mj pg_dump -Uosm osm -t wm_devug | xz -v > $@ @@ -330,7 +372,7 @@ clean: ## Clean the current working directory $(shell git ls-files -o mj-msc*) \ $(addsuffix .pdf,$(FIGURES)) \ $(addsuffix .pdf,$(RIVERS)) \ - $(SLIDES) + $(addsuffix .pdf,$(SLIDES)) .PHONY: clean-tables clean-tables: ## Remove tables created during unit or rivers tests diff --git a/github-wm.png b/github-wm.png new file mode 100644 index 0000000..d431331 Binary files /dev/null and b/github-wm.png differ diff --git a/osi-logo.pdf b/osi-logo.pdf new file mode 100644 index 0000000..8604941 Binary files /dev/null and b/osi-logo.pdf differ diff --git a/postgis-logo.png b/postgis-logo.png new file mode 100644 index 0000000..3470189 Binary files /dev/null and b/postgis-logo.png differ diff --git a/postgresql-logo.pdf b/postgresql-logo.pdf new file mode 100644 index 0000000..ff6a0d7 Binary files /dev/null and b/postgresql-logo.pdf differ diff --git a/slides-2021-06-02.tex b/slides-2021-06-02.tex new file mode 100644 index 0000000..bc0f824 --- /dev/null +++ b/slides-2021-06-02.tex @@ -0,0 +1,426 @@ +\documentclass[14pt]{beamer} +\usetheme{default} +\usepackage[L7x,T1]{fontenc} +\usepackage[lithuanian]{babel} +\usepackage{graphics} +\usepackage{biblatex} +\usepackage{tabularx} +\usepackage[labelfont={color=vupurple},labelformat=empty,justification=centering]{caption} +\usepackage{tikz} +\usepackage{minted} +\usepackage{subcaption} + + +\definecolor{vulightgrey}{RGB}{220,220,220} +\definecolor{vudarkgrey}{RGB}{65,65,65} +\definecolor{vupurple}{RGB}{123,0,63} +\definecolor{darkgreen}{RGB}{32,96,32} +\setbeamercolor{title}{fg=vupurple} +\setbeamercolor{frametitle}{fg=vupurple} +\setbeamercolor{abstract title}{fg=vupurple} +\setbeamercolor{item}{fg=vupurple} +\setbeamercolor{navigation symbols dimmed}{fg=vulightgrey} +\setbeamercolor{navigation symbols}{fg=vulightgrey} +\setbeamercolor{normal text}{fg=vudarkgrey} + +\usefonttheme{serif} + +\AtBeginEnvironment{minted}{% + \renewcommand{\fcolorbox}[4][]{#4}} +\usetikzlibrary{shapes.geometric,arrows,positioning} + +\newcommand{\DP}{Douglas \& Peucker} +\newcommand{\VW}{Visvalingam--Whyatt} +\newcommand{\WM}{Wang--M{\"u}ller} + +\mode{ + \setbeamertemplate{navigation symbols}{ + \insertslidenavigationsymbol + \insertframenavigationsymbol + \hspace{0.2cm} + \begin{minipage}[c]{0.5cm} + \vspace{-0.1cm} + {\strut\insertframenumber{}/\inserttotalframenumber\strut} + \end{minipage} + } +} + +\newcommand{\twocols}[2] +{ + \begin{columns}[c] + \begin{column}{0.45\textwidth} + #1 + \end{column} + %\hspace{0pt} \vrule{} + \begin{column}{0.55\textwidth} + #2 + \end{column} + \end{columns} +} + +%% ============================================================================= + +\title{ + \Large\textsc{wang–müller algoritmo realizacija + kartografinei upių generalizacijai} + +} +\author{\small \bf Motiejus Jakštys \\[4ex] + \includegraphics[height=4em]{vu} +} + +\date{\small 2021-06-02} + + +\begin{document} + + +\AtBeginSection[] +{ + \begin{frame} + \frametitle{Turinys} + \tableofcontents[currentsection] + \end{frame} +} + +\begin{frame} +\titlepage +\end{frame} + +%\begin{frame} +% \begin{abstract} +% +% Dabartiniai linijų simplifikavimo algoritmai netinka upėms. Šis darbas +% realizuoja {\WM} algoritmą. Jis geriau tinka upėms. +% +% \end{abstract} +%\end{frame} + +\section{Problema} + +\begin{frame}{Linijų paprastinimo algoritmų problemos} + \twocols{ + \begin{figure}[ht] + \includegraphics[width=\textwidth]{salvis-dp64overlaid-2x50k} + \includegraphics[width=\textwidth]{salvis-dpchaikin64overlaid-2x50k} + \end{figure} + }{ + \begin{itemize} + \item Nepritaikyti gamtiniams objektams: upėms, krantų linijoms. + \item Prarandami raiškūs gamtinių objektų elementai: vingiai, kilpos. + \end{itemize} + } +\end{frame} + +\section{Uždaviniai} + +\begin{frame}{Uždaviniai: algoritmų vertinimas} + \twocols{ + \includegraphics[width=\textwidth]{amalgamate1} + }{ + \begin{itemize} + \item Įvertinti prieinamus linijų paprastinimo algoritmus. + \item Įvardinti prieinamų algoritmų problemas. + \end{itemize} + } +\end{frame} + + +\begin{frame}{Uždaviniai: {\WM} realizacija} + \twocols{ + \begin{figure}[ht] + \includegraphics[width=\textwidth]{wang125-2} + \caption{{\WM} siūlomas metodas.} + \end{figure} + + }{ + \begin{itemize} + \item Apibrėžti algoritmo techninės realizacijos metodiką. + \item Teoriškai ir techniškai realizuoti algoritmą. + \item Išbandyti su skirtingais duomenų rinkiniais. + \item Palyginti su valstybiniais duomenų rinkiniais. + \end{itemize} + } +\end{frame} + +\section{Aktualumas} + +\begin{frame}[fragile]{Aktualumas: praplečiama teorija} + \begin{columns}[c] + \begin{column}{.3\textwidth} + \begin{figure}[ht] + \includegraphics[width=\textwidth]{selfcrossing-1} + \end{figure} + \end{column} + \begin{column}{.7\textwidth} + \begin{itemize} + + \item Praplečia išplėsti kartografinės teorijos žinias apie gamtinių + objektų ribų generalizavimą atsižvelgiant į jų raiškumą. + + \item {\WM} straipsnis sprendimų nedetalizuoja taip, kad būtų + galima pritaikyti. Šis darbas tai padaro. + + \end{itemize} + \end{column} + \end{columns} +\end{frame} + +\begin{frame}{Aktualumas: panaudojimas} + \begin{columns}[c] + \begin{column}{.3\textwidth} + \begin{figure}[ht] + \includegraphics[width=\textwidth]{github-wm} + \end{figure} + \end{column} + \begin{column}{.7\textwidth} + \begin{itemize} + + \item Papildomas atviro kodo sprendimas automatiniam generalizavimo + uždaviniams. + + \item Pritaikomas kartografų. + + \end{itemize} + \end{column} + \end{columns} +\end{frame} + + +\section{Metodika} + +\begin{frame}{Techninė implementacija: aplinka} + \begin{columns}[c] + \begin{column}{.3\textwidth} + \begin{figure}[ht] + \begin{subfigure}[b]{\textwidth} + \centering + \includegraphics[width=.7\textwidth]{postgis-logo} + \end{subfigure} + \\[1ex] + \begin{subfigure}[b]{\textwidth} + \centering + \includegraphics[width=.5\textwidth]{postgresql-logo} + \end{subfigure} + \\[1ex] + \begin{subfigure}[b]{\textwidth} + \centering + \includegraphics[width=.6\textwidth]{osi-logo} + \end{subfigure} + \end{figure} + \end{column} + \begin{column}{.7\textwidth} + + \begin{itemize} + \item Realizacija kurta PostGIS. + + \item PostGIS yra PostgreSQL duomenų bazės papildinys darbui su GIS. + + \item Atviro kodo nemokama programinė įranga. + + \item PostGIS sprendimai veikia iš praktiškai bet kokios programavimo + kalbos, todėl yra universalūs. + + \end{itemize} + + \end{column} + \end{columns} +\end{frame} + + +\begin{frame}[fragile]{Techninė implementacija: algoritmas} + \begin{minted}[fontsize=\small]{sql} +CREATE FUNCTION ST_SimplifyWM( + geom geometry, + dhalfcircle float, +) RETURNS geometry AS $$ +... +END $$ LANGUAGE plpgsql; + \end{minted} + + \vspace{2em} + + \textsc{dhalfcircle}: pusskritulio skersmuo. Analogiško ir didesnio ploto + linkių, nei šis pusapskritimis, nepaprastina. + +\end{frame} + +\begin{frame}{Algoritmo realizacijos procesas} + \tikzset{ + startstop/.style={trapezium,text centered,minimum height=2em, + trapezium left angle=70,trapezium right angle=110,draw=black,fill=red!20}, + proc/.style={rectangle,minimum height=2em,text centered,draw=black, + fill=orange!20}, + decision/.style={diamond,minimum height=2em,text centered,aspect=3, + draw=black,fill=green!20}, + arrow/.style={thick,->,>=stealth}, + } + \begin{figure} + \centering + \scalebox{.35}{ + \begin{tikzpicture}[node distance=2cm,auto] + \node (start) [startstop] {Nuskaityti \textsc{linestring}}; + \node (detect) [proc,below of=start] {Aptikti linkius}; + \node (inflections) [proc,below of=detect] {Sutvarkyti nežymius išlinkimus}; + \node (selfcrossing) [proc,below of=inflections] {Pašalinti save kertančias vietas}; + \node (mutated1) [decision,below of=selfcrossing] {Koreguotas?}; + \node (bendattrs) [proc,below of=mutated1] {Apskaičiuoti linkio savybes}; + \node (exaggeration) [proc,below of=bendattrs] {Didinti linkį}; + \node (mutated2) [decision,below of=exaggeration] {Koreguotas?}; + \node (elimination) [proc,below of=mutated2] {Pašalinti linkį}; + \node (mutated3) [decision,below of=elimination] {Koreguotas?}; + \node (stop) [startstop,below of=mutated3] {Pabaiga}; + + \coordinate [right of=mutated1,node distance=5cm] (mutated1y) {}; + \coordinate [right of=mutated2,node distance=5cm] (mutated2y) {}; + \coordinate [right of=mutated3,node distance=5cm] (mutated3y) {}; + + \draw [arrow] (start) -- (detect); + \draw [arrow] (detect) -- (inflections); + \draw [arrow] (inflections) -- (selfcrossing); + \draw [arrow] (selfcrossing) -- (mutated1); + \draw [arrow] (mutated1) -| node [near start] {Taip} (mutated1y) |- (detect); + \draw [arrow] (mutated1) -- node[anchor=west] {Ne} (bendattrs); + \draw [arrow] (bendattrs) -- (exaggeration); + \draw [arrow] (exaggeration) -- (mutated2); + \draw [arrow] (mutated2) -| node [near start] {Taip} (mutated2y) |- (detect); + \draw [arrow] (mutated2) -- node[anchor=west] {Ne} (elimination); + \draw [arrow] (mutated3) -| node [near start] {Taip} (mutated3y) |- (detect); + \draw [arrow] (mutated3) -- node[anchor=west] {Ne} (stop); + \draw [arrow] (elimination) -- (mutated3); + \end{tikzpicture} + } + \end{figure} +\end{frame} + +\begin{frame}{Automatiniai testai padeda tęstinumui} + \tikzset{ + arrow/.style={thick,->,>=stealth}, + } + \begin{figure} + \begin{tikzpicture}[auto] + \onslide<1->{ + \node (before) []{ + \includegraphics[width=.4\textwidth]{isolated-1-before.pdf} + }; + } + \onslide<2->{ + \node(after) [right=2cm of before.east]{ + \includegraphics[width=.4\textwidth]{isolated-1-after.pdf} + }; + } + \onslide<2->{ + \draw[arrow] (before) -- node[anchor=south] {\footnotesize Programa} (after); + } + \end{tikzpicture} + \end{figure} + \onslide<3->{ + \begin{itemize} + \item<3-> Iš duomenų ir rezultato sukuriamas testas. + \item<4-> Testai patikrina, ar programa veikia teisingai. + \item<4-> Išsaugomas tęstinumas ją keičiant. + \end{itemize} + } +\end{frame} + +\section{Įgyvendinimas} + +\begin{frame}{Pasiruošimas} + \begin{itemize} + \item Pagalbinių funkcijų ir lentelių paruošimas. + \item Upių sujungimas. + \end{itemize} +\end{frame} + +\begin{frame}{Algoritmo etapai} + \begin{itemize} + \item Linkių aptikimas ir sutvarkymas. + \item Linkių keitimo operatoriai: eliminavimas ir didinimas. + \item Jungimas neimplementuotas. + \end{itemize} +\end{frame} + +\section{Rezultatai} + +\begin{frame}{GRPK10 ir {\WM}} + \includegraphics[width=\textwidth]{salvis-wm75--grpk10-1x50k} +\end{frame} + +\begin{frame}{GRPK10, GRPK50 ir {\WM}} + \includegraphics[width=\textwidth]{salvis-wm75-grpk50-grpk10-1x50k} +\end{frame} + +\begin{frame}{GRPK250 ir {\WM}} + \begin{figure}[h!] + \centering + \begin{subfigure}[b]{.49\textwidth} + \includegraphics[width=\textwidth]{salvis-grpk250-2x} + \caption{GRPK250.} + \end{subfigure} + \hfill + \begin{subfigure}[b]{.49\textwidth} + \centering + \includegraphics[width=\textwidth]{salvis-wm220} + \caption{{\WM}.} + \end{subfigure} + \end{figure} +\end{frame} + +\begin{frame}{{\DP}} + \includegraphics[width=\textwidth]{salvis-wm75-dp64-grpk10-1x50k} +\end{frame} + +\begin{frame}{{\DP}+Chaikin} + \includegraphics[width=\textwidth]{salvis-wm75-dpchaikin64-grpk10-1x50k} +\end{frame} + +\begin{frame}{Išbandymas internete} + \centering + \includegraphics[width=.75\textwidth]{openmap-wm-good.png} + \includegraphics[width=.3\textwidth]{openmap-wm-bad.png} + + {\tiny https://dev.openmap.lt/webgl/wm.html} +\end{frame} + +\begin{frame}{Faktai} + \begin{itemize} + \item $>1000$ eilučių procedūrinio SQL. + \item $\sim500$ eilučių Python, Awk, GNU Make. + \item Susidomėjimas atsirado iš karto (web versija). + \end{itemize} +\end{frame} + +\section{Išvados ir pasiūlymai ateičiai} + +\begin{frame}{Išvados} + \begin{itemize} + \item Klasikiniai algoritmai išanalizuoti, problemos aprašytos. + \item Aprašytas metodas {\WM} realizacijai. + + \item Realizuotas: + \href{https://github.com/motiejus/wm}{github.com/motiejus/wm}. + + \item Šalčia--Visinčia rezultatai palyginti su: + \begin{itemize} + \item {\VW} (+Chaikin). + \item {\DP} (+Chaikin). + \item GRPK50. + \item GRPK250. + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}{Pasiūlymai ateičiai} + \begin{itemize} + \item Implementuoti kobinavimo operatorių. + \item Rasti ir aprašyti geresnius kriterijus izoliuotiems linkiams. + \item Pagerinti algoritmo laiko ir atminties sąnaudas. + \item Pilnesnė kartografinė generalizacija, įskaitant topologiją. + \end{itemize} +\end{frame} + +\begin{frame}{Ačiū} + \url{https://github.com/motiejus/wm} +\end{frame} + +\end{document} diff --git a/wang125-2.png b/wang125-2.png new file mode 100644 index 0000000..5c794a7 Binary files /dev/null and b/wang125-2.png differ