Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 DOKUMENTATION Interaktiver Stadtplan: Routing-Modul 1 EINFÜHRUNG........................................................................................................ 2 1.1 1.2 1.3 1.4 2 Aufgabenstellung ....................................................................................... 2 Projektbeschreibung................................................................................... 2 Grobes Design............................................................................................ 2 Zeitplan ...................................................................................................... 2 DURCHFÜHRUNG.................................................................................................. 3 2.1 Daten .......................................................................................................... 3 2.1.1 2.1.2 2.2 2.3 3 Benutzeroberfläche .................................................................................... 6 main.svg ..................................................................................................... 6 click.js ........................................................................................................ 6 fenster.js ..................................................................................................... 8 left.php ....................................................................................................... 9 dijkstra.php................................................................................................. 9 Testbeispiel 1 ........................................................................................... 17 Testbeispiel 2 ........................................................................................... 20 AUFGETRETENE PROBLEME.............................................................................. 21 5.1 5.2 6 4 4 5 5 TESTBEISPIELE .................................................................................................. 17 4.1 4.2 5 Allgemeines A*-Algorithmus based on Dijkstra Pseudocode Definition der Variablen KOMMENTIERTER QUELLCODE .......................................................................... 6 3.1 3.2 3.3 3.4 3.5 4 3 3 Eingabe- und Ausgabeparameter ............................................................... 4 Algorithmus ............................................................................................... 4 2.3.1 2.3.2 2.3.3 2.3.4 2.4 Tabelle 1: graz_node Tabelle 1: graz_arc Rechenfehler im PHP-Skript.................................................................... 21 Server-Timeout ........................................................................................ 22 SCHLUSSWORT ................................................................................................... 22 1 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 1 Einführung 1.1 Aufgabenstellung Im Rahmen der Konstruktionsübung sollen frei wählbare Bereiche der Vorlesung Multimediale Informationssysteme praktisch umgesetzt werden. Das Ziel ist ein multimediales Informationssystem. Für das vorliegende Projekt wurde das Routing-Modul eines interaktiven Stadtplanes von Graz für die Anwendung im Internet programmiert. 1.2 Projektbeschreibung Auf der Basis einer Straßendatenbank von Graz wurde ein Routingmodul erstellt; sprich es ist möglich, einen Startpunkt und einen Endpunkt einzugeben und sich den "kürzesten" Weg berechnen zu lassen. Dieser Weg wird in Text als auch in Vektorform als Ergebnis dargestellt. 1.3 Grobes Design Der Algorithmus zur kürzesten Weg Suche wurde in PHP implementiert. Für die Visualisierung wurde SVG und Java Script verwendet. 1.4 Zeitplan Geschätzt Tatsächlich benötigt Installation/Konfiguration der Entwicklungsumgebung: 5h 3h SVG, JavaScript, PHP lernen 20 h 15 h Programmieren Dijkstra 15 h 24 h Design Webseiten 5h 4h Einbinden in Projekt 25 h 20 h Testen 5h 3h Dokumentation 5h 10 h Präsentationsvorbesprechung 3h 5h 83 84 Arbeitsphase Summe 2 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 2 Durchführung 2.1 Daten Das Routing-Modul basiert auf einer Microsoft Access Datenbank welche sämtliche Knoten der Stadt Graz und deren Koordinaten sowie Distanzen zwischen den Nachbarknoten enthält. Zu Beginn der Entstehungsphase des Projektes wurde überlegt die Datenbank in XML zu verfassen, da jedoch ein Datenbankzugriff mittels ODBC leichter realisierbar (Abfrage mit PHP) war, wurde die Idee wieder verworfen. Die Datenbank weist folgende Struktur auf: 2.1.1 Tabelle 1: graz_node Die Tabelle graz_node enthält die Koordinaten sämtlicher Knoten der Stadt Graz. Die Knoten ID ist eindeutig. GRAZ_ID Y X Eindeutige Knoten ID Y Koordinate [m] X Koordinate [m] Wertebereich: 1..8888 Wertebereich: Ymin = 551.000,7 Ymax = 570.233,6 Wertebereich: Xmin = 290.266,9 Xmax = 307.640,2 2.1.2 Tabelle 1: graz_arc Die Tabelle graz_arc enthält sämtliche Nachbarschaftsbeziehungen zwischen den Knoten. Will man z.B. alle Nachbarn (zwischen Nachbarn müssen Verbindungen existieren) des Knoten 66 herausfinden, muss sowohl die Spalte FNODE_ als auch die Spalte TNODE_ durchsucht werden. Die Nachbarschaftsbeziehungen sind nicht doppelt verspeichert, ist z.B. der Knoten 43 Nachbar des Knoten 66, wird man entweder die Kombinaten FNODE_= 66, TNODE_= 43 oder die Kombination FNODE_= 43, TNODE_= 66 – nicht jedoch beide – vorfinden. In der Spalte LENGTH ist die Distanz zwischen den jeweiligen Nachbarn verspeichert. Weitere Spalten in der Tabelle wurden für das Routing-Modul nicht verwendet. FNODE_ FROM Knoten Wertebereich: 1..8888 TNODE_ LENGTH TO Knoten Distanz Wertebereich: 1..8888 Wertebereich: dmin = 2,58 dmax = 3938,14 3 […] Weitere Spalten wurden für das Routing-Modul nicht verwendet. Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 2.2 Eingabe- und Ausgabeparameter Eingabeparameter des Routing-Moduls sind der Start- und der Zielknoten der zu bestimmenden Route, ausgegeben wird in alphanumerischer Form die kürzeste Route zwischen Start- und Zielpunkt in Form einer Knotenliste und als Ergänzung die zurückgelegte Distanz. Außerdem wird die Route graphisch als Polylinie mit dem graphischen Stadtplan des Basismoduls (ISG) überlagert. 2.3 Algorithmus 2.3.1 Allgemeines Das Herz eines jeden Routing-Moduls ist der Such-Algorithmus. Von ihm hängt alles ab, er muss schnell und effizient arbeiten. Um dies optimal umsetzen zu können haben wir den A*-Algorithmus based on Dijkstra verwendet: 2.3.2 A*-Algorithmus based on Dijkstra Zu einem gegebenen zusammenhängenden Graphen wird der kürzeste Weg zwischen einem Startknoten und einem Zielknoten ermittelt. Die Kanten in diesem Graphen repräsentieren mögliche Verbindungen und sind nach der Weglänge gewichtet. Zusätzlich arbeitet der Algorithmus mit einer plausiblen Abschätzung der Weglänge zwischen jedem Knoten v und dem Zielknoten, die ebenfalls aus dem Kartenmaterial gewonnen werden muss. Mit der Genauigkeit dieser Heuristik kann die Genauigkeit des Ergebnisses beeinflusst werden: Wird die Entfernung überschätzt, wird die Wegesuche beschleunigt, es findet sich aber nicht garantiert der kürzeste Weg. Wird die Entfernung unterschätzt, dauert die Suche zunehmend länger, aber es findet sich garantiert der kürzeste Weg. Der Algorithmus wird in jedem Falle einen Weg finden, wenn einer existiert. Im Vergleich zum leichter verständlichen Dijkstra-Algorithmus, wird hier die Suche durch die Abschätzung auf einen Teil der Gesamtmenge aller Knoten fokussiert. Während bei Dijkstra zunächst alle Knoten des Graphen als "zu untersuchen" in eine Liste eingetragen werden, berücksichtigt der A*-Algorithmus nur vielversprechende Knoten des Graphen und untersucht dafür zunächst die Knoten mit der geringsten geschätzten Distanz zum Zielknoten.1 1 Quelle: http://www.irf.uni-dortmund.de/seminar/schlette/stdt_0.htm 4 Gander, Mayrhofer, Raffold 2.3.3 INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Pseudocode Der A*-Algorithmus kann folgendermaßen in Pseudocode umgesetzt werden2: d(s):=0; T ← {s}; f(s):=h(s); FOR v∈V\{s} DO d(v):=∞; f(v):=∞; END FOR WHILE T≠{} DO u:=v∈T with min. f(v); P ← P+{u}; T ← T\{u}; FOR v∈N(u) DO IF v∉T ∧ v∉P THEN d(v):=d(u)+c(u,v); p(v):=u; f(v):=d(v)+h(v); T ← T+{v}; END IF IF v∈T ∧ d(u)+c(u,v)<d(v) THEN d(v):=d(u)+c(u,v); p(v):=u; f(v):=d(v)+h(v); END IF IF v∈P ∧ d(u)+c(u,v)<d(v) THEN d(v):=d(u)+c(u,v); p(v):=u; f(v):=d(v)+h(v); P ← P\{u}; T ← T+{u}; END IF END FOR END WHILE 2.3.4 Definition der Variablen Variable 2 Beschreibung T Liste der temporären Knoten P Liste der permanenten Knoten (schon besucht) N Liste der Nachbarsknoten eines Knoten s Startknoten h Luftdistanz vom aktuellen Knoten zum Zielknoten u Aktueller Knoten f Zurückgelegte Distanz + Luftdistanz d Liste der bisher gefundenen realen Distanzen zum aktuellen Knoten c Distanz vom aktuellen Knoten zum Nachbarknoten Quelle: Institut für Geodäsie, Abteilung für theoretische Geodäsie 5 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 2.4 Benutzeroberfläche Während sich der Großteil unseres Moduls – die Routingfunktion – im Verborgenen abspielt, muss die Benutzeroberfläche nur geringen Anforderungen gewachsen sein. Dem Benutzer wird ermöglicht, einen Start- und Zielpunkt graphisch durch Mausklick (klick – ziehen – klick) auf den Stadtplan auszuwählen. Durch klick auf den Routing-Button wird der Suchalgorithmus gestartet und anschließend alphanumerisch in Form einer Knotenliste ausgegeben. Außerdem besteht die Möglichkeit die berechnete Route graphisch durch Überlagerung einer Polylinie mit dem Grazer Stadtplan zu visualisieren. 3 Kommentierter Quellcode 3.1 main.svg [...] </g> <text id="start" x="40" y="635" style="font-size:15"> Startpunkt</text> <text id="ziel" x="350" y="635" style="font-size:15"> Zielpunkt</text> </svg> Die main.svg gehört eigentlich zum Basismodul, allerdings haben wir – der Einfachheit halber – 2 Zeilen am Ende des Skripts hinzugefügt. Es schreibt Startpunkt und Zielpunkt an den unteren Rand der Stadtkarte. 3.2 click.js function coord_start(evt) { //auslesen der Bildkoordinaten aus SVG xm=evt.getClientX(); ym=evt.getClientY(); //Hook auf SVG Dokument dokument=evt.getTarget().getOwnerDocument(); //Nur dann weitermachen, wenn Klick in Karte if (xm>20){ if (xm<620){ if (ym>20){ if (ym<620){ //Bestimmen der Aktuellen Kartenauflösung res = get_resolution(); //Bestimmen, welche Bildkacheln geladen sind var bild = dokument.getElementById('b1').getAttribute('xlink:href'); for (var i= 1; i<=bild.length; i++) { if (bild.substr(i,1) == "z") { 6 Gander, Mayrhofer, Raffold { } INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 var pos1 = i; } if (bild.substr(i,1) =="_") } spalte=bild.substring(pos1+1,i); zeile=bild.substring(i+1,bild.length-4); //gesamte Kartenausdehnung b_ymin=553480; b_xmax=305900; //Festlegen des Bildmaßstabes if (res == "images_high"){ bild_meter = 13907/48; } if (res == "images_middle"){ bild_meter = 13907/24; } if (res == "images_low"){ bild_meter = 13907/12; } //Karten auf 0 Verschieben xm=xm-20; ym=ym-20; //Bildkoordinaten runden y=Math.round(b_ymin+spalte*bild_meter+xm*bild_meter/150,0); x=Math.round(b_xmax-zeile*bild_meter-ym*bild_meter/150,0); //Zusammenbauen der Übergabewertes wert_str="Startpunkt:"+y+"_"+x; } //Schreiben des Wertes ins SVG Dokument dokument.getElementById('start').getFirstChild().setData(wert_str); }}}} function coord_ziel(evt) { xm=evt.getClientX(); ym=evt.getClientY(); dokument=evt.getTarget().getOwnerDocument(); if (xm>20){ if (xm<620){ if (ym>20){ if (ym<620){ res = get_resolution(); var bild = dokument.getElementById('b1').getAttribute('xlink:href'); for (var i= 1; i<=bild.length; i++) { if (bild.substr(i,1) == "z") { var pos1 = i; } if (bild.substr(i,1) =="_") { spalte=bild.substring(pos1+1,i); zeile=bild.substring(i+1,bild.length-4); } 7 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 } b_ymin=553480; b_xmax=305900; if (res == "images_high"){ bild_meter = 13907/48; } if (res == "images_middle"){ bild_meter = 13907/24; } if (res == "images_low"){ bild_meter = 13907/12; } xm=xm-20; ym=ym-20; y=Math.round(b_ymin+spalte*bild_meter+xm*bild_meter/150,0); x=Math.round(b_xmax-zeile*bild_meter-ym*bild_meter/150,0); wert_str="Zielpunkt:"+y+"_"+x; dokument.getElementById('ziel').getFirstChild().setData(wert_str); }}}} } Diese Javascript-Datei besteht aus zwei Functions welche zum Auslesen der Bildkoordinaten des Start- bzw. Zielpunktes in der Karte dienen um sie dann später an den Routing-Algorithmus zu übergeben. Kommentiert wurde nur eine Function, da beide völlig ident ablaufen, bis auf den Unterschied, dass einmal Bildkoordinaten des Startpunktes und einmal jene des Zielpunkt bestimmt werden. Bei einem Klick in die Karte (SVG-Grafik) wird ein Koordinatenpaar (xm, ym) an die click.js übergeben. Dieses wird überprüft und weiterverwendet, wenn der Bereich gültig ist. Im Anschluss wird die Kartenauflösung bestimmt, d.h. in welcher Zoomstufe der Klick erfolgt ist. Dies ist wichtig, um den richtigen Bildmaßstab festlegen zu können. Außerdem werden die maßstäblich veränderten Koordinaten noch zu Ganzzahlen gerundet und dann in der Form x-Koordinate_y-Koordinate in der Variable wert_str an das SVG-Dokument übergeben. 3.3 fenster.js [...] function start_Routing(){ var hilf = window.parent.frames[1].document; dokument=hilf.embeds["karte"].getSVGDocument(); var start = dokument.getElementById('start').getFirstChild().getData(); var ziel = dokument.getElementById('ziel').getFirstChild().getData(); var start_coord=start.substring(11,start.length); var ziel_coord=ziel.substring(10,ziel.length); document.routing.coordinates.value=start_coord+"_"+ziel_coord; [...] 8 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Dieses Skript wird für mehrere Module verwendet. Für das Routing-Modul ist nur die Function start_Routing() relevant. Diese wird aufgerufen, wenn im linken Frame (left.php) ein Klick auf den Button Routing erfolgt. Sie hat die Aufgabe, die vorhin von der click.js in das SVG-Dokument geschriebenen Koordinaten in ein hidden field der left.php zu schreiben. Aus diesem versteckten Feld können die Koordinaten dann in die dijkstra.php übergeben und zur Berechnung der Route verwendet werden. 3.4 left.php [...] <form name="routing" method="get" action="database/dijkstra.php"> <p> <input name="Routing_start" type="submit" value="Routing" onClick="start_Routing()"style="width=100"> <input type="hidden" name="coordinates"> </p> </form> [...] Das Skript left.php beinhaltet den gesamten linken Frame im interaktiven Stadtplan. Für das Routing-Modul ist nur ein kleiner Teil relevant in dem die Schaltfläche Routing und das hidden field definiert wird. 3.5 dijkstra.php <html> <head> <title>Routing mittels A*</title> <LINK REL=STYLESHEET TYPE="text/css" HREF="../styles.css" TITLE="Stylesheet"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <script src="../javascript/routen.js" type="text/javascript"></script> </head> <body> <p> <script language="php"> /*Auslesen der Knoten und Daten aus Formular übernehmen*/ $Ziele = explode("_",$coordinates); /*Rechteck um Startpunkt legen - Suche im Umkreis*/ $ystart_min=$Ziele[0]-200; $ystart_max=$Ziele[0]+200; $xstart_min=$Ziele[1]-200; $xstart_max=$Ziele[1]+200; $yziel_min=$Ziele[2]-200; 9 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 $yziel_max=$Ziele[2]+200; $xziel_min=$Ziele[3]-200; $xziel_max=$Ziele[3]+200; /*Datenbankparameter*/ $DSN="dijkstra"; $Benutzer="Administrator"; $Kennwort=""; /*Verbindung mit der Datenbank*/ $verbindung=odbc_connect($DSN, $Benutzer, $Kennwort); /*Suche nach Knoten mit passenden Koordinaten für den Startpunkt und speichern der Daten in Array*/ $sql="SELECT * FROM graz_node WHERE Y<'$ystart_max' AND Y>'$ystart_min' AND X<'$xstart_max' AND X>'$xstart_min'"; $ergebnis=odbc_exec($verbindung, $sql); $i=0; while (odbc_fetch_row($ergebnis)) { $start_knoten[$i]=odbc_result($ergebnis, "GRAZ_ID"); $start_knotenx[$i]=odbc_result($ergebnis, "X"); $start_knoteny[$i]=odbc_result($ergebnis, "Y"); $i=$i+1; } $Knoten[1]=round($start_knoten[0],0); if ($i>1) { $hilf=500; for ($i=0;$i<=count($start_knoten);$i++) { $dx=($Ziele[0]-$start_knoteny[$i])^2; $dy=($Ziele[1]-$start_knotenx[$i])^2; $tempdistanz=sqrt($dx-$dy); if ($tempdistanz<$hilf) { $hilf=$tempdistanz; $Knoten[1]=round($start_knoten[$i],0); } } } /*Suche nach Knoten mit passenden Koordinaten für den Zielpunkt und speichern der Daten in Array*/ $sql="SELECT * FROM graz_node WHERE Y<'$yziel_max' AND Y>'$yziel_min' AND X<'$xziel_max' AND X>'$xziel_min'"; $ergebnis=odbc_exec($verbindung, $sql); $j=0; while (odbc_fetch_row($ergebnis)) { $ziel_knoten[$j]=odbc_result($ergebnis, "GRAZ_ID"); $ziel_knotenx[$j]=odbc_result($ergebnis, "X"); $ziel_knoteny[$j]=odbc_result($ergebnis, "Y"); $j=$j+1; 10 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 } $Knoten[2]=round($ziel_knoten[0],0); if ($j>1) { $hilf=500; for ($j=0;$j<=count($ziel_knoten);$j++) { $dx=($Ziele[2]-$ziel_knoteny[$j])^2; $dy=($Ziele[3]-$ziel_knotenx[$j])^2; $tempdistanz=sqrt($dx-$dy); if ($tempdistanz<$hilf) { $hilf=$tempdistanz; $Knoten[2]=round($ziel_knoten[$j],0); } } } odbc_close($verbindung); /*Ende Auslesen der Knoten für Routing*/ /*Startbedinungen, Knoten müssen vorhanden sein*/ if ($i==0 OR $j==0) { echo("Keine Knoten gefunden!"); } else { /*Login in die Access Datenbank*/ $DSN ="dijkstra"; $Benutzer ="Administrator"; $Kennwort =""; $verbindung = odbc_connect ($DSN, $Benutzer, $Kennwort); $sql ="SELECT * FROM graz_arc"; $ergebnis = odbc_exec($verbindung, $sql); /*Initialisieren der Zählvariable*/ $i=1; /*Einlesen der FNODE, TNODE und LENGTH Arrays*/ $FNODE_TEMP = odbc_result($ergebnis, "FNODE_"); $FNODE = array(1 => $FNODE_TEMP); $TNODE_TEMP = odbc_result($ergebnis, "TNODE_"); $TNODE = array(1 => $TNODE_TEMP); $LENGTH_TEMP = odbc_result($ergebnis, "LENGTH"); $LENGTH = array(1 => $LENGTH_TEMP); while (odbc_fetch_row($ergebnis)) { $i=i+1; $FNODE_TEMP = odbc_result($ergebnis, "FNODE_"); array_push($FNODE,$FNODE_TEMP); $TNODE_TEMP = odbc_result($ergebnis, "TNODE_"); array_push($TNODE,$TNODE_TEMP); $LENGTH_TEMP = odbc_result($ergebnis, "LENGTH"); 11 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 array_push($LENGTH,$LENGTH_TEMP); } if ($i==0) { echo "Keine entsprechenden Datensätze gefunden!!!"; } $sql ="SELECT * FROM graz_node"; $ergebnis = odbc_exec($verbindung, $sql); /*Initialisieren der Zählvariable*/ $i=1; /*Einlesen der ID, XKOO und YKOO Arrays*/ $ID_TEMP = odbc_result($ergebnis, "GRAZ_ID"); $ID = array(1 => $ID_TEMP); $YKOO_TEMP = odbc_result($ergebnis, "Y"); $YKOO = array(1 => $YKOO_TEMP); $XKOO_TEMP = odbc_result($ergebnis, "X"); $XKOO = array(1 => $XKOO_TEMP); while (odbc_fetch_row($ergebnis)) { $i=i+1; $ID_TEMP = odbc_result($ergebnis, "GRAZ_ID"); array_push($ID,$ID_TEMP); $YKOO_TEMP = odbc_result($ergebnis, "Y"); array_push($YKOO,$YKOO_TEMP); $XKOO_TEMP = odbc_result($ergebnis, "X"); array_push($XKOO,$XKOO_TEMP); } if ($i==0) { echo "Keine entsprechenden Datensätze gefunden!!!"; } /*Umwandeln von ID, FNODE udn TNODE auf Integer Werte*/ for ($i=1;$i<=count($ID);$i++) { $ID[$i]=intval($ID[$i]); } for ($i=1;$i<=count($FNODE);$i++) { $FNODE[$i]=intval($FNODE[$i]); $TNODE[$i]=intval($TNODE[$i]); } /*Übergabe von Start- Zielknoten*/ $Start=$Knoten[1]; $Ziel=$Knoten[2]; /*Alle Temporären ID's werden auf FALSE gesetzt, P Array erstellt und Vorgänger Array erstellt*/ 12 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 for($i=1;$i<=count($ID);$i++) { $T[$i]=0; $P[$i]=0; $pre[$i]=0; } /*Startknoten im temporären Array ist TRUE*/ $T[$Start]=1; /*Initialisierung von f-Array und d-Array, setzte alle Elemente ausser Start auf unendlich*/ for($i=1;$i<=count($ID);$i++) { $d[$i]=-1; $f[$i]=-1; if($i==$Start) { $d[$i]=0; $dx=$XKOO[$Ziel]-$XKOO[$Start]; $dy=$YKOO[$Ziel]-$YKOO[$Start]; $f[$i]=sqrt(($dx)*($dx)+($dy)*($dy)); } } /*Beginn der Routing Schleife*/ $startwhile=1; if ($Start==$Ziel) { $startwhile=0; } while($startwhile==1) { /*Suche des Knoten mit TRUE im temporären Array mit minimalem f(v)*/ $z=1; for($i=1;$i<=count($ID);$i++) { if ($T[$i]==1) { $aktu[$z]=$i; $aktf[$z]=$f[$i]; $z=$z+1; } } $minf=$aktf[1]; for($i=1;$i<=count($aktf);$i++) { If ($aktf[$i]<=$minf and $aktf[$i]>=0 and $T[$aktu[$i]]==1) { $minf=$aktf[$i]; $u=$aktu[$i]; } } /*Wenn aktueller Knoten = Zielknoten -> Abbruchsbedingung*/ 13 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 if ($u==$Knoten[2]) { $startwhile=0; } /*Wenn aktueller Knoten <> Zielknoten -> Routing wird fortgesetzt*/ if ($u!=$Knoten[2]) { $P[$u]=1; $T[$u]=0; /*Suche der Nachbarsknoten von u*/ $z=1; for($i=1;$i<=count($FNODE);$i++) { if ($FNODE[$i]==$u) { $nachbar[$z]=$TNODE[$i]; $nachdist[$z]=$LENGTH[$i]; $z=$z+1; } if ($TNODE[$i]==$u) { $nachbar[$z]=$FNODE[$i]; $nachdist[$z]=$LENGTH[$i]; $z=$z+1; } } /*Für alle Nachbarknoten von u wird folgednes ausgeführt*/ for($i=1;$i<=count($nachbar);$i++) { /*Für alle Knoten nicht Element aus T und nicht Element aus P wird folgendes ausgeführt*/ if ($T[$nachbar[$i]]==0 and $P[$nachbar[$i]]==0) { $d[$nachbar[$i]]=$d[$u]+$nachdist[$i]; $pre[$nachbar[$i]]=$u; zum Zielknoten*/ /*h ist Luftdistanz vom aktuellen Nachbarknoten $dx=$XKOO[$Ziel]-$XKOO[$nachbar[$i]]; $dy=$YKOO[$Ziel]-$YKOO[$nachbar[$i]]; $h=sqrt(($dx)*($dx)+($dy)*($dy)); $f[$nachbar[$i]]=$d[$nachbar[$i]]+$h; $T[$nachbar[$i]]=1; } /*Für alle Knoten Element aus T und d(u)+c(u,v) < d(v) wird folgendes ausgeführt*/ if ($T[$nachbar[$i]]==1 and $d[$u]+$nachdist[$i]<$d[$nachbar[$i]]) { 14 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 $d[$nachbar[$i]]=$d[$u]+$nachdist[$i]; $pre[$nachbar[$i]]=$u; $dx=$XKOO[$Ziel]-$XKOO[$nachbar[$i]]; $dy=$YKOO[$Ziel]-$YKOO[$nachbar[$i]]; $h=sqrt(($dx)*($dx)+($dy)*($dy)); //echo "X=",$XKOO[$nachbar[$i]]," Y=",$YKOO[$nachbar[$i]]," XZ=",$XKOO[$Ziel]," YZ=",$YKOO[$Ziel]."<br>"; //echo "Luftdistanz vom Knoten ",$nachbar[$i]," zum Knoten ",$Ziel," ist ",$h."<br>"; $f[$nachbar[$i]]=$d[$nachbar[$i]]+$h; } /*Für alle Knoten Element aus P und d(u)+c(u,v) < d(v) wird folgendes ausgeführt*/ if ($P[$nachbar[$i]]==1 and $d[$u]+$nachdist[$i]<$d[$nachbar[$i]]) { $d[$nachbar[$i]]=$d[$u]+$nachdist[$i]; $pre[$nachbar[$i]]=$u; $dx=$XKOO[$Ziel]-$XKOO[$nachbar[$i]]; $dy=$YKOO[$Ziel]-$YKOO[$nachbar[$i]]; $h=sqrt(($dx)*($dx)+($dy)*($dy)); $f[$nachbar[$i]]=$d[$nachbar[$i]]+$h; /*Löschen des aktuellen Knoten aus dem P Array und Hinzufügen des aktuellen Knoten zum T Array*/ } $P[$u]=0; $T[$u]=1; } /*Löschen der Nachbararrays und Nachbardistanzarrays*/ } unset($nachbar); unset($nachdist); } /*Auslesen der Route aus der Vorgänger-Liste*/ $vorgaenger=$Knoten[2]; $i=0; while($pre[$vorgaenger]!=$Knoten[1]) { $i=$i+1; $zwischenknoten[$i]=$pre[$vorgaenger]; $vorgaenger=$zwischenknoten[$i]; } /*Umkehren der Route, Start -> Ziel*/ $zwischenknoten_sortiert=array_reverse($zwischenknoten); /*Alphanumerische Ausgabe der Route*/ 15 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 echo "<h3>Routing Ergebnis</h3>"; echo "Startknoten: ",$Start."<br>"; for ($i=0;$i<=count($zwischenknoten_sortiert)-1;$i++) { echo $i," = ",$zwischenknoten_sortiert[$i]."<br>"; } echo "Zielknoten: ",$Ziel."<br><br>"; /*Erstellen von Koordinatenarrays der Start-, Zwischen- und Zeilknoten*/ $koord_arrayx[0]=round($XKOO[$Start],0)-40; $koord_arrayy[0]=round($YKOO[$Start],0); for ($i=0;$i<=count($zwischenknoten_sortiert)-1;$i++) { $koord_arrayx[$i+1]=round($XKOO[$zwischenknoten_sortiert[$i]],0)-40; $koord_arrayy[$i+1]=round($YKOO[$zwischenknoten_sortiert[$i]],0); } $koord_arrayx[$i+1]=round($XKOO[$Ziel],0)-40; $koord_arrayy[$i+1]=round($YKOO[$Ziel],0); /*Suche der minimalen und maximalen x/y Koordinaten*/ $xmin=$koord_arrayx[0]; $xmax=$koord_arrayx[0]; $ymin=$koord_arrayy[0]; $ymax=$koord_arrayy[0]; for ($i=0; $i<=count($koord_arrayx)-1; $i++) { if ($koord_arrayx[$i] < $xmin) { $xmin=$koord_arrayx[$i]; } if ($koord_arrayx[$i] > $xmax) { $xmax=$koord_arrayx[$i]; } if ($koord_arrayy[$i] < $ymin) { $ymin=$koord_arrayy[$i]; } if ($koord_arrayy[$i] > $ymax) { $ymax=$koord_arrayy[$i]; } } /*Graphische Darstellung der Route als überlagerte Polylinie*/ echo ("Gesamtdistanz: "); echo (round($f[$Ziel],0)." m <br><br>"); echo"<a href=\"javascript:ZeichnePolyLinie('pl1','styMarkRot',"; echo($ymin.",".$ymax.",".$xmin.",".$xmax); for ($i=0;$i<=count($koord_arrayy)-1;$i++) { echo ",".$koord_arrayy[$i].",".$koord_arrayx[$i]; } echo ")\">Zeige Route</a>"; } 16 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 </script> </p> <p><a href="../left.php">Neue Route</a></p> </body> </html> Das Skript dijkstra.php ist das Herz des Routing-Moduls. Es werden folgende Operationen durchgeführt: - Auslesen der Koordinaten von Start- und Zielknoten aus dem hidden field in der left.php - Berechnung des Knotens welcher sich in unmittelbarer Nähe zu den ausgelesenen Koordinaten befindet, dazu wird ein Quadrat von 400 m Seitenlänge um den „Klickpunkt“ gelegt, alle Knoten innerhalb des Quadrates mittels SQLDatenbankabfrage gesucht und jener Knoten mit dem kürzesten Abstand ausgewählt. Ergebnis ist ein eindeutiger Start- und Zielknoten. - Einlesen von FNODE, TNODE, LENGTH, ID, XKOO und YKOO in Arrays mittels SQL Abfrage und ODBC Datenbankverbindung - Umwandeln von ID, FNODE und TNODE in Integerwerte da sie nach dem Auslesen eine Dezimalstelle mit dem Wert 0 erhalten haben - Initialisieren der Variablen für den Routing-Algorithmus - Eigentlicher Routingalgorithmus - Auslesen der gefundenen Route aus der Vorgänger-Liste - Alphanumerische Ausgabe der Route und der Gesamtdistanz - Erstellen von Koordinatenarrays für Start-, Zwischen- und Zielknoten - Suche der maximalen und minimalen x/y-Koordinaten - Graphische Darstellung der Route durch Überlagerung einer Polylinie mit der Stadtkarte. Dafür werden SVG-Elemente in JavaScript gezeichnet. Diese Funktion wird auch von anderen Modulen verwendet, deshalb wurde nur ein einziges Skript dafür erstellt, routen.js. 4 Testbeispiele 4.1 Testbeispiel 1 Als erstes Testbeispiel soll die kürzeste Route zwischen der Rechbauerstraße Alte Technik und der Inffeldgasse gefunden werden. 17 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Dazu wird in der Karte die Maus zum Startpunkt bewegt, geklickt (ohne die Maustaste loszulassen), dann zum Zielpunkt bewegt und dann die Maustaste erst losgelassen. Unterhalb der Karte sieht man dass die Koordinaten des Start- und Zielpunktes übernommen wurden. 18 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Ein Klick auf Routing startet die Berechnung der Route. Sobald die kürzeste Route gefunden wurde, wird im linken Frame die Route und die zurückgelegte Distanz alphanumerisch ausgegegeben, will man sich die Route graphisch anzeigen lassen muss man auf Zeige Route klicken. Es wird automatisch die beste Zoomstufe gewählt. 19 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Mit Klick auf Neue Route kann eine neue Berechnung durchgeführt werden. 4.2 Testbeispiel 2 Nun vielleicht ein Beispiel mit einer längeren Route, Ecke Keplerstraße-Bahnhofgürtel zur Inffeldstraße. 20 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Route gefunden. 5 Aufgetretene Probleme Abgesehen von mehreren kleineren Schwierigkeiten bei der Umsetzung des A*-Algorithmus in PHP sowie der graphischen Ausgabe der Route in SVG sind folgende „gröbere“ Schwierigkeiten aufgetreten. 5.1 Rechenfehler im PHP-Skript Anscheinend hat PHP Probleme mit der Ausführung von mathematischen Operationen. Es gilt die Entfernung zweier Punkte in einem kartesischen Koordinatensystem zu berechnen. Folgende Formel ist wurde deshalb folgendermaßen in PHP umgesetzt: s= (x2 − x1 )2 + ( y 2 − y1 )2 [...] $dx=$XKOO[$Ziel]-$XKOO[$nachbar[$i]]; $dy=$YKOO[$Ziel]-$YKOO[$nachbar[$i]]; $h=sqrt(($dx)*($dx)+($dy)*($dy)); [...] 21 Gander, Mayrhofer, Raffold INTERAKTIVER STADTPLAN GRAZ ROUTING-MODUL Multimediale Informationssysteme WS 2002/2003 Bei Koordinatenwerten in der Größenordnung von 30.000 m bis 50.000 m verrechnet sich das Skript im Dezimeterbereich. Da der Rechenfehler in dieser Größenordnung jedoch keine Rolle für die Routenberechnung spielt wurde auf eine Suche nach einer Lösung des Problems verzichtet. 5.2 Server-Timeout Längere Routen haben eine längere Rechenzeit zur Folge. Deshalb stießen wir oft auf das Problem dass der Server nach 30 Sekunden das PHP-Skript aufgrund eines Timeouts abgebrochen hat. Nachdem wir nach längerem Suchen den entsprechenden Eintrag in der php.ini von 30 Sekunden auf 300 Sekunden erhöht hatten gabs keine Probleme mehr. 6 Schlusswort In Anbetracht dessen, dass wir vorher noch nie mit Internet-Programmierung konfrontiert wurden, war diese Konstruktionsübung eine große Herausforderung für uns. Da wir Geodäten eine größere Gruppe bilden durften war es etwas leichter, wir konnten Probleme miteinander diskutieren und behandeln. So war es auch unvermeidbar dass oft gruppenübergreifend gearbeitet wurde. Trotzdem war es nicht leicht das Projekt vollständig zu realisieren und mehr als einmal haben wir stundenlang am selben Problem gearbeitet, aber nun ist es für uns eine Genugtuung, das vollendete Werk auf dem Bildschirm leuchten zu sehen. „Die bis zum Erreichen des Ziels verbleibende Arbeit steigert sich mit dem Herannahen des Abgabetermins. “ 3 3 Quelle: Murphy’s Computergesetze http://siriux.net/docs/humor/murphy/computer.html 22