Routino
A Routino egy útvonaltervező szoftver, mely OSM adatok felhasználásával képes a legrövidebb, vagy a leggyorsabb utat kiszámítani két pont között. A szoftvert C nyelven írták, emellett a webes felületét CGI scriptek segítségével teszi dinamikussá.
Az OSM adatokat fel kell dolgozni, még az első használat előtt. Támogatott formátumok: XML, PBF, O5M. Az előfeldolgozást csak egyszer kell végrehajtani az OSM adatokon. Az útvonaltervezés eredménye kimenthető HTML, illetve GPX formátumban is.
Az útvonaltervező figyelembe veszi az utakra való korlátozásokat is (például.: sebesség, súly, méretkorlátozás), illetve a KRESZ korlátozásait is (például.: egyszerűbb tiltások a kanyarodásra, egy irányú az utca).
A programot jelenleg legtöbben saját weboldalukba beépítve, útvonaltervezésre használják, általában egy régióra lekorlátozva. Emellett, amióta kiegészült egy függvénykönyvtárral, lehetővé tették az asztali alkalmazások számára is az útvonaltervezést, kibővítve a felhasználhatósági kört.
Tartalomjegyzék
Telepítés
Linux
Előfeltételek A program előfeltételeit célszerű telepíteni először
apt-get install gcc make libc6-dev libz-dev libbz2-dev
apt-get install libwww-perl liburi-perl libjson-pp-perl #These are optional
Telepítés A telepítéshez ez után le kell töltenünk a Routino weboldaláról a forráskódot, majd azt kibontva, le kell fordítanunk, majd be kell másolni az Apache webszerver mappájába.
make
cp -a web /var/www/routino
chown -R www-data:www-data /var/www/routino
Ezek után az OSM adatokat fel kell dolgozni:
cd /var/www/routino/data
../bin/planetsplitter --errorlog [Tetszőleges OSM fájl neve].osm.bz2
Miután megvolt, válasszuk ki, hogy OpenLayers vagy Leaflet felületen szeretnénk-e használni a Routino-t, és futtassuk ezt le:
cd /var/www/routino/www/[openlayers vagy leaflet]
sh -x install.sh
Ezek után még egy lépés hátra van, az apache /etc/apache2/sites-enabled/000-default
fájljába ezeket a sorokat hozzá kell adni:
<Directory /var/www/routino>
AllowOverride Options=MultiViews,ExecCGI FileInfo Limit
</Directory>
Konfigurálás
Szerkesszük az alábbi fájlt: /var/www/routino/www/routino/mapprops.js
- A
library
változó értékével tudjuk módosítani, hogy az OpenLayers vagy a Leaflet felületet próbálja-e meg betölteni. - A
westedge
eastedge
southedge
northedge
zoomout
zoomin
változókkal értelemszerűen a térkép mozgásterét tudjuk korlátozni, illetve a minimum és a maximum zoom értékeket. - A
mapdata
változóban tudjuk megadni, hogy melyik Tileserver-ről szedje le a térkép Tile-okat. Az alapértelmezett Tileserver jelenleg megfelelő lesz.
Windows
Bizonyos korlátozásokkal elérhető a Routino Windowson is, és a telepítése is egy bonyolultabb folyamat, a legegyszerűbb, ha követjük a Routino által leírt lépéseket.
Algoritmusok
Előfeldolgozás
Ahhoz, hogy kellően gyors, és hatékony legyen az útvonalkeresés, az OSM adatokat feldolgozzuk, és eltároljuk egy lokális adatbázisban. A csomópontok közül a legtöbbet töröljük, és az érdekes csomópontokat hagyjuk meg. Ezután az izolált területeket töröljük.
A csomópontok megtartásának szabályai:
- 3 vagy több útvonalszakaszt köt össze.
- 2 útvonalszakaszt köt össze, de a két útvonalszakasznak más tulajdonságai vannak.
- 2 útvonalszakaszt köt össze, de az útvonalszakaszok közt megváltoztak az útvonaltervezési korlátozások.
A fentebbi szabályokat felhasználva a csomópontok törlését annyiszor ismételhetjük, amíg csak a legfontosabb csomópontok maradnak már csak meg. Ezeket a csomópontokat szuper-csomópontnak nevezzük, és a szuper-csomópontokat szuper-utak kötik össze.
Útkeresés
- A kezdőponttól útvonalat keresünk a legközelebbi szuper-csomóponthoz.
- A végponttól útvonalat keresünk a legközelebbi szuper-csomóponthoz.
- Az 1. és a 2. szuper-csomópont közt megkeressük a szuper-útvonalat.
- A 3. pontban talált szuper-útvonalak mindegyikére megkeresi a legrövidebb utat a szuper-útvonal kezdő és végpontja között.
Az útvonal keresési algoritmust az A* algoritmussal (vagy legalábbis egy ehhez nagyon hasonlító algoritmussal) oldották meg. Ez az algoritmus a kezdő csomóponttól a legkisebb érték (legrövidebb, vagy leggyorsabb út) kiszámítására törekszik minden csomóponthoz.
A 4. pontban lévő útvonalakat viszont a Dijkstra algoritmussal keresi meg.
Webes felület
Útvonaltervező
Az útvonaltervező felület alapvetően 3 fülre van bontva, melyeken csoportosítva érhetőek el a funkciók.
Beállítások
Itt lehet kiválasztani az utazás kezdő és végpontjait, illetve a közbeeső állomások pontjait is itt lehet megadni, emellett van lehetőségünk az utazás fajtáját kiválasztani, illetve a preferenciákat módosítani, a sebességkorlátokat módosítani, illetve meg lehet adni súly, vagy méretbeli korlátozásokat.
Eredmény
Az útvonaltervezés instrukciói, a távolsága, és az időtartama itt jelenik meg, ezenkívül van lehetőségünk ezt az útvonalat megjeleníteni egy új lapon HTML, szöveges, vagy akár GPX formátumban is.
Adatok
Innen érhető el az adatvizualizációs felület, illetve megjeleníthetőek benne az adatokkal kapcsolatos statisztikák.
Adat vizualizáció
Vizualizáló
Itt lehet megjeleníttetni a Routino által eltárolt információkat a térképen, mint például a szuper-utakat, korlátozásokat, csomópontokat.
Útvonaltervező
Innen vissza lehet menni az útvonaltervező interfészre.
Adatok
Az útvonaltervezőnél lévő adatok fülre hasonlít, ugyanazokat az adatokat/statisztikákat lehet itt is megjeleníteni.
Fejlesztés
Webes felületre
A webes felület elérhető Leaflet, illetve OpenLayers térképmegjelenítőkben is, ezért érdemes a gyárilag kapott webes interfészt használni, azt személyre szabni (CSS), átvariálni a kezelőfelületét, és beleépíteni a honlapunkba, ahol szeretnénk használni az útvonaltervezés funkciót. Amennyiben egyáltalán nem használnánk a gyárilag kapott webes felületet, írhatunk saját megjelenítőt, a lentebbi két opció által.
A programot használva
A fordítás után létrejött egy router nevű futtatható állomány, mellyel parancssori argumentumok segítségével tervezhetünk útvonalat, és azt HTML, szöveges, vagy GPX formátumban fájlba menthetjük, vagy akár kiírhatjuk a képernyőre. Használat:
Usage: router [--version]
[--help | --help-profile | --help-profile-xml |
--help-profile-json | --help-profile-perl ]
[--dir=<dirname>] [--prefix=<name>]
[--profiles=<filename>] [--translations=<filename>]
[--exact-nodes-only]
[--quiet | [--loggable] [--logtime] [--logmemory]]
[--output-html]
[--output-gpx-track] [--output-gpx-route]
[--output-text] [--output-text-all]
[--output-none] [--output-stdout]
[--profile=<name>]
[--transport=<transport>]
[--shortest | --quickest]
--lon1=<longitude> --lat1=<latitude>
--lon2=<longitude> --lon2=<latitude>
[ ... --lon99=<longitude> --lon99=<latitude>]
[--reverse] [--loop]
[--heading=<bearing>]
[--highway-<highway>=<preference> ...]
[--speed-<highway>=<speed> ...]
[--property-<property>=<preference> ...]
[--oneway=(0|1)] [--turns=(0|1)]
[--weight=<weight>]
[--height=<height>] [--width=<width>] [--length=<length>]
Példa a használatra:
./router --shortest --lon1=19.45000 --lat1=47.17563 --lon2=19.09424 --lat2=47.33138 --dir=../data --output-stdout --output-text
A függvénykönyvtárat használva
A Routino 3.0 megjelenése óta külön függvénykönyvtárként is elérhető az útvonaltervező szolgáltatás. Kétféle library is készült hozzá, a libroutino
és a libroutino-slim
. Az interfészük teljesen megegyezik, viszont a slim változat kevesebb memóriát fogyaszt, cserébe lassabb is. A teljes leírása az API-nak elérhető itt. A használatát egy egyszerű példaprogrammal bemutatom itt, megtalálhatóak benne a legfontosabb függvények, hogy hogyan kell használni, és hogy az eredményen hogyan lehet végigiterálni:
#include <iostream>
#include <cstdlib>
#include <routino.h>
int main (int argc, char *argv[])
{
Routino_Database *t_routinoDB = Routino_LoadDatabase("/var/www/routino/data", NULL); //Betöltjük az adatbázist
if(!t_routinoDB) { std::cout << "Could not find database" << std::endl; return 1; }
Routino_ParseXMLProfiles("/var/www/routino/data/profiles.xml"); //Felolvassuk a Profiles XML-t
Routino_ParseXMLTranslations("/var/www/routino/data/translations.xml"); //Felolvassuk a fordításokat
Routino_Profile *t_profile = Routino_GetProfile("motorcar"); //Kiválasztjuk az utazási módot: autó
if(!t_profile) { std::cout << "Could not find profile" << std::endl; return 1; }
Routino_Translation *t_translation = Routino_GetTranslation("hu"); //Kiválasztjuk a nyelvet: magyar
if(Routino_ValidateProfile(t_routinoDB, t_profile) != 0) { std::cout << "Not valid profile" << std::endl; return 1; } //Ellenőrizzük, hogy érvényes-e a profil
Routino_Waypoint **t_waypoints = (Routino_Waypoint**)calloc(sizeof(Routino_Waypoint*), 2); //Lefoglaljuk a helyet a kezdő és a végpontnak
t_waypoints[0] = Routino_FindWaypoint(t_routinoDB, t_profile, 47.17563, 19.45000); //Beállítjuk a kezdőpontot
t_waypoints[1] = Routino_FindWaypoint(t_routinoDB, t_profile, 47.33138, 19.09424); //Beállítjuk a végpontot
if(!t_waypoints[0]) { std::cout << "Could not find starting point" << std::endl; return 1; }
if(!t_waypoints[1]) { std::cout << "Could not find ending point" << std::endl; return 1; }
int t_routingOptions = 0;
t_routingOptions |= ROUTINO_ROUTE_QUICKEST; //A legrövidebb úton menjünk
t_routingOptions |= ROUTINO_ROUTE_LIST_TEXT_ALL; //Szövegesen írja ki az utcaneveket
Routino_Output *t_output = Routino_CalculateRoute(t_routinoDB, t_profile, t_translation, t_waypoints, 2, t_routingOptions, NULL); //Kiszámítjuk az útvonalat
Routino_Output *t_iter = t_output;
while(t_iter) //Amíg végig nem érünk az útvonal pontjain, kiírjuk a koordinátáit, és az utca nevét
{
std::cout << ( t_iter->lon * 180 ) / 3.14 << " " << ( t_iter->lat * 180 ) / 3.14;
if(t_iter->name)
std::cout << " " << t_iter->name;
std::cout << std::endl;
t_iter = t_iter->next;
}
Routino_DeleteRoute(t_output); //Felszabadítjuk a memóriából az útvonalat
Routino_UnloadDatabase(t_routinoDB); //Felszabadítjuk a memóriából az adatbázist
Routino_FreeXMLProfiles(); //Felszabadítjuk a memóriából a betöltött profilokat
Routino_FreeXMLTranslations(); //Felszabadítjuk a memóriából a betöltött nyelveket
for(int waypoint=0;waypoint<2;waypoint++)
free(t_waypoints[waypoint]);
free(t_waypoints); //Töröljük az általunk foglalt területeket
}