170 lines
6.5 KiB
TeX
170 lines
6.5 KiB
TeX
\documentclass{article}
|
|
|
|
\usepackage[L7x,T1]{fontenc}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[lithuanian]{babel}
|
|
\usepackage{hyperref}
|
|
\usepackage{minted}
|
|
\usepackage{tikz}
|
|
\usetikzlibrary{positioning}
|
|
|
|
\title{Žemėlapių naršyklės ir elektroninės paslaugos\\ \vspace{4mm}
|
|
Galutinis semestro egzaminas}
|
|
|
|
\author{Motiejus Jakštys}
|
|
|
|
\date{\today}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
|
|
\section{Įžanga}
|
|
|
|
Kaip pasufleruota užduotyje, pagrindinė problema yra bandymas atvaizduoti per
|
|
daug duomenų vienu metu. Problemos sprendimas dvilypis: vartotojo sąsajoje ir
|
|
"serverinėje" implementacijoje.
|
|
|
|
Kaip pasufleruota užduotyje, sprendimas dvilypis: vartotojo sąsaja ir serverinis komponentas.
|
|
|
|
\section{Sprendimas}
|
|
|
|
Kadangi problema labai opi smulkiuose masteliuose, pirmiausia nuspręskime, kaip
|
|
žemėlapį vaizduoti smulkiame mastelyje. Tai atsispindės ir GUI/UX, ir
|
|
serveriniame sprendime.
|
|
|
|
\subsection{Funkcionalumo keitimas, GUI/UX keitimas}
|
|
\label{sec:ux}
|
|
|
|
Jei vienoje vietoje (pvz., per 5\% ekrano ploto) yra daugiau, nei du objektai,
|
|
juos agreguoti ir vietoj pačių objektų rodyti skaičių, kiek tame plote yra
|
|
objektų. Tada priartinus tuos objektus jie natūraliai atsiskirs.
|
|
|
|
Tai implementuojant reikia apgalvoti šiokias tokias išimtis: pvz., jei ekrane
|
|
rodoma iš viso mažiau, nei X objektų (tarkime, 42), tuomet agregacijos daryti
|
|
nereikia, ir rodyti viską taip, kaip buvo "senuoju būdu". Taip užtikriname, kad
|
|
objektus, kad ir kaip arti vienas kito esančius, visada galėsime pamatyti
|
|
pakankamai priartinę. Algoritmą, kaip tai padaryti, aprašome
|
|
skyriuje~\ref{sec:backend}.
|
|
|
|
\subsection{Žemėlapio vizualizacijos modifikavimo/optimizavimo priemonės}
|
|
\label{sec:api}
|
|
|
|
Šioje sekcijoje aprašome API dalį: į ką pakeisti milžinišką GeoJSON objektą,
|
|
kad galėtume jį atvaizduoti?
|
|
|
|
Pirmiausia, vartotojas į serverį turi siųsti savo matomo žemėlapio koordinates
|
|
({\em extent}). Tada pagal tai serveris nusprendžia, kuriuos duomenis grąžinti
|
|
tiesiogiai, kuriuos -- agreguotus. Taip kai kurie taškai lieka originalūs, o
|
|
kai kurie dingsta, ir vietoje jų atsiranda "agreguoti".
|
|
|
|
Agreguoti taškai -- GeoJSON objektai, tačiau su papildomu atributu, kad tai yra
|
|
"virtualūs" taškai, ir nurodantys, kiek objektų savyje "slepia". Pvz.
|
|
|
|
\begin{minted}{json}
|
|
{
|
|
"type": "Feature",
|
|
"geometry": {
|
|
"type": "Point",
|
|
"coordinates": [24.3 55.68]
|
|
},
|
|
"properties": {
|
|
"aggregated": true,
|
|
"aggregate_count": 10
|
|
}
|
|
}
|
|
\end{minted}
|
|
|
|
Paspaudus ant agreguoto komponento būtų patogu, jei atsirastų kitas langas su
|
|
visais "slepiamais" komponentais, arba žemėlapis taip prisiartintų, kad
|
|
pasirodytų visi to agreguoto vidiniai slepiami objektai.
|
|
|
|
Grąžinus tik matomą dalį duomenų, serveris visada atsiųs pakankamai mažą kiekį
|
|
GeoJSON objektų, kurie tikrai neapkraus naršyklės; taip vartotojo sąsaja bus
|
|
sėkmingai naudotina ir smulkiuose, ir stambiuose masteliuose.
|
|
|
|
\subsection{Esamų servisų modifikavimo ir/ar naujų kūrimo priemonės, įvardinant
|
|
konkrečius servisus tipus/sprendimus ir juos trumpai pagrindžiant}
|
|
|
|
Dėstytojo nurodymu, ArcGIS Online pakeičiame PostGIS duombaze ir serveriniu
|
|
({\em back-end}) komponentu; žr. architektūros diagramą~\ref{fig:arch}.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\begin{tikzpicture}[thick]
|
|
\node at (0,4)[rectangle,draw=black,fill=yellow!20] (browser) {Naršyklė};
|
|
\node at (0,2)[rectangle,draw=black,fill=blue!20] (backend) {Serverinis komponentas};
|
|
\node at (0,0)[rectangle,draw=black,fill=blue!20] (gis) {PostGIS};
|
|
\draw [->] (browser) to (backend);
|
|
\draw [->] (backend) to (gis);
|
|
\end{tikzpicture}
|
|
\caption{Architektūros diagrama}
|
|
\label{fig:arch}
|
|
\end{figure}
|
|
|
|
Pakeitę ArcGIS į PostGIS, atsikratome dirbtinio 2000 objektų ribojimo ir
|
|
aplikacijoje galime pasiimti tiek duomenų, kiek reikia. Šioje užduotyje taip
|
|
pat tariame, kad visi, kas įrašinėja objektus, juos rašo į duombazę naudojant
|
|
GIS įrangą, ir įrašymu mums rūpintis nereikia.
|
|
|
|
Liko neišspręsta viena problema: kaip, turint tūkstančius objektų ir vartotojo
|
|
"langą" (extent) grąžinti tinkamus PostGIS objektus? Logiką galima dėti į dvi
|
|
vietas: arba duomenų bazę, arba pačią programą.
|
|
|
|
\subsubsection{Duomenų bazė}
|
|
\label{sec:db}
|
|
|
|
Programuoti skirstymo duomenų bazėje yra paprasčiau, nei serveriniame
|
|
komponente. Pavyzdinis, gana naivus, algoritmas, kurį galima parašyti naudojant
|
|
plpgsql:
|
|
|
|
\begin{itemize}
|
|
\item parinkti objektus, esančius rėme ({\em extent}).
|
|
\item padalinti rėmą į reikiamą skaičių dalių (aprašyta~\ref{sec:ux}). Rėmą
|
|
populiaru dalinti į šešiakampius arba kvadratus.
|
|
|
|
\item kiekvienai daliai grąžinti tikrus arba virtualius objektus
|
|
(aprašyta~\ref{sec:api}).
|
|
|
|
\item sukonstruoti GeoJSON objektą ir grąžinti vartotojui.
|
|
\end{itemize}
|
|
|
|
Nors išspręsti problemą duomenų bazėje yra paprasčiau kodo prasme, tačiau
|
|
duomenų bazės apkrovimas bus didesnis ir kils su naršančiųjų kiekiu. Todėl
|
|
ateityje, jei duomenų arba vartotojų bus dar daugiau, gali būti sunkiau
|
|
optimizuoti algoritmus; naudojant tikrą programavimo kalbą (tarkime, C++ arba
|
|
Go) daug paprasčiau optimizuoti ir užtikrinti norimą servisą augant vartotojų
|
|
skaičiui.
|
|
|
|
\subsubsection{Serverinis komponentas}
|
|
\label{sec:backend}
|
|
|
|
Algoritmas gali būti panašus į aprašytą~\ref{sec:db}. Tačiau kaip gauti
|
|
duomenis?
|
|
|
|
Kadangi objektų kiekis -- tik dešimtys tūkstančių, visus duomenis lengvai
|
|
galima laikyti atmintyje ir serveriniame komponente analizę leisti su kiekviena
|
|
užklausa iš naujo. Duomenis atsisiųsti iš duomenų bazės galima reguliariai,
|
|
tarkime, kas kelias sekundes ar minutę: taip duomenų bazės apkrovimas bus
|
|
minimalus, ir nekils didėjant skaitytojų kiekiui (didės rašančiųjų kiekiui, bet
|
|
tokių paprastai būna daug mažiau).
|
|
|
|
Kaip minėta anksčiau, serveriniame komponente lengviau užtikrinti, kad servisas
|
|
veiks gerai ir su dideliais apkrovimais, ir nereikės didinti duomenų bazių
|
|
galingumo, kas paprastai yra brangiau ir/arba sudėtingiau, nei aplikacijos.
|
|
|
|
Jei apkrovimai smarkiai didėja, reikia analizuoti ir tobulinti algoritmą.
|
|
Kelios idėjos optimizacijai:
|
|
|
|
\begin{itemize}
|
|
|
|
\item apskaičiuoti generalizacijas iš anksto kiekvienam įmanomam masteliui
|
|
ir atėjus užklausai, tiesiog pasiimti jas iš atminties.
|
|
|
|
\item išankstinės optimizacijos, jei skaičiuojamos ne kiekvienos užklausos
|
|
metu, gali būti leidžiamos ir į duomenų bazę: taip DB apkrovimas
|
|
nesikeičia su naršančių vartotojų kiekiu.
|
|
|
|
\end{itemize}
|
|
|
|
\end{document}
|