Difference between revisions of "Anleitung für Routing (Pgrouting) und UMN MapServer mit den Freien Geodaten aus Osnabrück (Frida)"

From OSGeo
Jump to navigation Jump to search
 
(44 intermediate revisions by 2 users not shown)
Line 7: Line 7:
 
Weitere hilfreiche Quellen:
 
Weitere hilfreiche Quellen:
  
Mailinglist von umn-mapserver.de:
+
[http://freegis.org/pipermail/mapserver-de/2006-August/002433.html Mailinglist von umn-mapserver.de] (mit 14 Antworten)
http://freegis.org/pipermail/mapserver-de/2006-August/002433.html (mit 14 Antworten)
 
  
Englischsprachige Mailinglist des UMN MapServers:
+
[http://lists.umn.edu/cgi-bin/wa?A2=ind0612&L=mapserver-users&T=0&F=&S=&P=30653 Englischsprachige Mailinglist des UMN MapServers] (mit 8 Antworten)
http://lists.umn.edu/cgi-bin/wa?A2=ind0612&L=mapserver-users&T=0&F=&S=&P=30653
+
 
(mit 8 Antworten)
+
[http://www.selbstverwaltungbundesweit.de/mapserver/modules.php?name=Forums&file=viewtopic&t=331 Forum auf umn-mapserver-community.de] (mit 25 Antworten)
  
Forum auf umn-mapserver-community.de:
 
http://www.selbstverwaltungbundesweit.de/mapserver/modules.php?name=Forums&file=viewtopic&t=331
 
  
 
Diese Anleitung ist für Windows XP geschrieben, funktioniert (mit den entsprechenden
 
Diese Anleitung ist für Windows XP geschrieben, funktioniert (mit den entsprechenden
Line 24: Line 21:
 
Folgende Umgebung wurde installiert:
 
Folgende Umgebung wurde installiert:
  
Das ms4w-Paket (2.2.3)
+
* Das ms4w-Paket (2.2.3)
PostgreSQL 8.2.4 mit PostGIS-Aufsatz 1.1
+
* PostgreSQL 8.2.4 mit PostGIS-Aufsatz 1.1
 +
 
  
 
Wie gehen wir nun vor?  
 
Wie gehen wir nun vor?  
Line 34: Line 32:
 
Installieren Sie pgrouting am Besten in das Verzeichnis C:\Programme\PostgreSQL\8.2
 
Installieren Sie pgrouting am Besten in das Verzeichnis C:\Programme\PostgreSQL\8.2
 
(siehe Abbildung 1).
 
(siehe Abbildung 1).
 
 
  
 
'''Abbildung 1: Installation von PgRouting'''  
 
'''Abbildung 1: Installation von PgRouting'''  
Line 45: Line 41:
 
Wir verwenden dafür die Freien Geodaten aus dem von der Intevation GmbH initiierten
 
Wir verwenden dafür die Freien Geodaten aus dem von der Intevation GmbH initiierten
 
Projekt „Frida“ (http://frida.intevation.org/) (siehe Abbildung 2).
 
Projekt „Frida“ (http://frida.intevation.org/) (siehe Abbildung 2).
 +
 +
''' Abbildung 2: Homepage der Frida-Daten'''
 +
 +
[[Image:frida.png|Homepage der Frida-Daten]]
 +
 +
 
Laden Sie sich hier folgende Daten herunter: frida-1.0.1-shp-joined.tar.gz
 
Laden Sie sich hier folgende Daten herunter: frida-1.0.1-shp-joined.tar.gz
 
und entpacken Sie diese.
 
und entpacken Sie diese.
Line 51: Line 53:
 
PostgreSQL/PostGIS-Datenbank zu lesen.
 
PostgreSQL/PostGIS-Datenbank zu lesen.
 
Also geben wir auf der Kommandozeile z.B. folgendes ein (siehe auch Abbildung 3):
 
Also geben wir auf der Kommandozeile z.B. folgendes ein (siehe auch Abbildung 3):
Shp2pgsql D:\frida\strassen-joined.shp fridastreets routingdb > D:\frida\strassen-joined.sql
+
Shp2pgsql D:\frida\strassen-joined.shp fridastreets routingdb > D:\frida\strassen-joined.sql
Abbildung 3: Shape in SQL-Format umwandeln
+
 
 +
'''Abbildung 3: Shape in SQL-Format umwandeln'''
 +
 
 +
[[Image:frida_umwandlung.png|Shape in SQL-Format umwandeln]]
  
 
== Datenbank anlegen ==
 
== Datenbank anlegen ==
Line 58: Line 63:
 
pgAdmin III).
 
pgAdmin III).
 
Diese Datenbank nennen wir hier mal „routingdb“ (Abbildung 4).
 
Diese Datenbank nennen wir hier mal „routingdb“ (Abbildung 4).
 +
 +
'''Abbildung 4: Anlegen einer Datenbank mit PgAdminIII'''
 +
 +
[[Image:newdb.png|Anlegen einer Datenbank mit PgAdminIII]]
  
 
Anschließend dann muss die Datei strassen-joined.sql in die Datenbank eingelesen
 
Anschließend dann muss die Datei strassen-joined.sql in die Datenbank eingelesen
 
werden.
 
werden.
 
Gegen Sie also auf Kommandozeile folgendes ein:
 
Gegen Sie also auf Kommandozeile folgendes ein:
psql -U postgres -f D:/frida/strassen-joined.sql routingdb
+
psql -U postgres -f D:/frida/strassen-joined.sql routingdb
Abbildung 5: Befehl zum Einlesen der SQL-Datei in die Datenbank
+
 
 +
'''Abbildung 5: Befehl zum Einlesen der SQL-Datei in die Datenbank'''
 +
 
 +
[[Image:routingeinlesen.png|Befehl zum Einlesen der SQL-Datei in die Datenbank]]
 +
 
 +
Die Daten der Tabelle „fridastreets“ haben folgende Struktur (siehe Abbildung 6):
  
Die Daten der Tabelle „fridastreets“ haben folgende Struktur:
+
'''Abbildung 6: Ursprüngliche Struktur der Frida-Daten'''
Abbildung 6: Ursprüngliche Struktur der Frida-Daten
+
 
 +
[[Image:struktur.png|Ursprüngliche Struktur der Frida-Daten]]
  
So weit so gut.
 
 
Die Datenbank ist zu diesem Zeitpunkt allerdings noch nicht in der Lage Routen zu
 
Die Datenbank ist zu diesem Zeitpunkt allerdings noch nicht in der Lage Routen zu
 
berechnen. Das wollen wir ändern.
 
berechnen. Das wollen wir ändern.
 
Dafür führen wir folgende Befehle aus:
 
Dafür führen wir folgende Befehle aus:
psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing.sql routingdb
+
psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing.sql routingdb
 
sowie anschließend:
 
sowie anschließend:
psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing_postgis.sql
+
psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing_postgis.sql routingdb
routingdb
+
 
Abbildung 7: Routingfunktionen werden in Datenbank gebracht
+
'''Abbildung 7: Routingfunktionen werden in Datenbank gebracht'''
 +
 
 +
[[Image:routing_postgis_eingelesen.png|Routingfunktionen werden in Datenbank gebracht]]
  
 
Ok, die Datenbank ist für Routing im Grunde präpariert. Das bedeutet aber noch lange
 
Ok, die Datenbank ist für Routing im Grunde präpariert. Das bedeutet aber noch lange
Line 88: Line 104:
 
vorliegen (siehe Abbildung 8).
 
vorliegen (siehe Abbildung 8).
  
 +
'''Abbildung 8: Tabellenstruktur für verschiedene Funktionen von pgRouting'''
 +
 +
[[Image:tabellen_ueberischt.png|Tabellenstruktur für verschiedene Funktionen von pgRouting]]
  
 
== Daten mittels PHP-Skript einlesen ==
 
== Daten mittels PHP-Skript einlesen ==
Line 93: Line 112:
 
Nachdem diese Spalten angelegt worden sind geht es darum automatisiert die Werte von
 
Nachdem diese Spalten angelegt worden sind geht es darum automatisiert die Werte von
 
x1,y1,x2,y2 einzulesen.
 
x1,y1,x2,y2 einzulesen.
Dafür wurde folgendes PHP-Skript geschrieben (liegt im heruntegeladenen Ordner als
+
Dafür wurde folgendes PHP-Skript geschrieben:
x_y_einlesen.php).
 
  
 
  <?php
 
  <?php
Line 167: Line 185:
 
Als Bestätigung erscheint beim Aufruf des Skriptes etwa folgendes Fenster (Abb. 9), in
 
Als Bestätigung erscheint beim Aufruf des Skriptes etwa folgendes Fenster (Abb. 9), in
 
welchem in diesem Falle alle 12323 Einträge bestätigt werden.
 
welchem in diesem Falle alle 12323 Einträge bestätigt werden.
Abbildung 9: Start- und Entpunkte der Strassengeometrien erstellen
+
 
 +
'''Abbildung 9: Start- und Endpunkte der Strassengeometrien erstellen'''
 +
 
 +
[[Image:startpunkt.PNG|Start- und Endpunkte der Strassengeometrien erstellen]]
 +
 
 +
Neben der oben beschrieben Möglichkeit die Daten mit PHP einzulesen, befüllt auch das folgende SQL-Kommando die Tabelle:
 +
update roads set x1=X(StartPoint(the_geom)), y1=Y(StartPoint(the_geom)), x2=X(EndPoint(the_geom)), y2=Y(EndPoint(the_geom)), 
 +
length=length(the_geom);
 +
 
 +
Wichtig: In neuen Versionen von PostGIS (ab 1.3.x) muss allen Funktionen ein 'ST_' vorangestellt werden.
  
 
== Weitere Routingspezifische Werte berechnen ==
 
== Weitere Routingspezifische Werte berechnen ==
Line 173: Line 200:
 
Das geht ganz einfach mit folgendem SQL-Befehl in der routingdb-Datenbank (Abbildung
 
Das geht ganz einfach mit folgendem SQL-Befehl in der routingdb-Datenbank (Abbildung
 
10):
 
10):
UPDATE fridastreets set length=length(the_geom);
+
UPDATE fridastreets set length=length(the_geom);
Abbildung 10: length-Berechnung
+
 
 +
 
 +
'''Abbildung 10: length-Berechnung'''
  
 +
[[Image:length.PNG|Start- und Endpunkte der Strassengeometrien erstellen]]
  
 
Jetzt fehlt aber noch etwas.......
 
Jetzt fehlt aber noch etwas.......
 
Um die Werte für source und target zu errechnen benutzen wir eine vorgefertige Funktion:
 
Um die Werte für source und target zu errechnen benutzen wir eine vorgefertige Funktion:
SELECT assign_vertex_id('fridastreets', 5);
+
SELECT assign_vertex_id('fridastreets', 5);
 
Die Zahl ist letztlich variabel. Die Zahl 5 steht für einen Distanzraum, in welchem Knoten
 
Die Zahl ist letztlich variabel. Die Zahl 5 steht für einen Distanzraum, in welchem Knoten
 
die selbe Vertexid erhalten.
 
die selbe Vertexid erhalten.
Line 187: Line 217:
 
die Funktion absenden.
 
die Funktion absenden.
 
Das ganze dauert dann ein Weilchen, irgendwann sind die Einträge dann aber getätigt
 
Das ganze dauert dann ein Weilchen, irgendwann sind die Einträge dann aber getätigt
Abbildung 11: Source/target-Werte berechnen
+
 
 +
 
 +
'''Abbildung 11: Source/target-Werte berechnen'''
 +
 
 +
[[Image:Assign_vertex_routing.PNG|Source/target-Werte berechnen]]
  
 
== Routingvisualisierung ==
 
== Routingvisualisierung ==
Line 194: Line 228:
 
Unter http://files.orkney.jp/pgrouting/sample/pgRouting-sampleapp.tar.bz kann man sich
 
Unter http://files.orkney.jp/pgrouting/sample/pgRouting-sampleapp.tar.bz kann man sich
 
diesbezügliche Dateien herunterladen.
 
diesbezügliche Dateien herunterladen.
Diese Dateien wurden etwas verändert. Sie liegen im Ordner als routing.map
+
Diese Dateien wurden etwas verändert und können [http://www.selbstverwaltung-bundesweit.de/mapserver/routinganleitung.zip hier] als routing.map bzw. phtmls/routing_os_frida.phtml heruntergeladen werden.
bzw. phtmls/routing_os_frida.phtml
+
 
 
Die Datei routing.map ist eigentlich ganz einfach.
 
Die Datei routing.map ist eigentlich ganz einfach.
 
Defaultmäßig werden die Frida-Daten über folgenden Eintrag visualisiert:
 
Defaultmäßig werden die Frida-Daten über folgenden Eintrag visualisiert:
Line 225: Line 259:
 
         END
 
         END
 
   END
 
   END
END
+
END
Abbildung 12: Darstellung der Frida-Geometrien im UMN MapServer
 
  
 +
 +
'''Abbildung 12: Darstellung der Frida-Geometrien im UMN MapServer'''
 +
 +
[[Image:Frida_strassen.PNG|Source/Darstellung der Frida-Geometrien]]
  
 
Der Layer über welchen letztlich die Ausgabe der Route dargestellt wird nennt sich „path“.
 
Der Layer über welchen letztlich die Ausgabe der Route dargestellt wird nennt sich „path“.
 +
 
  LAYER
 
  LAYER
 
   NAME "path"
 
   NAME "path"
Line 250: Line 288:
 
Mittels dieses Codes wird die Angabe zum Map-Objekt getätigt und ein statischer Extent
 
Mittels dieses Codes wird die Angabe zum Map-Objekt getätigt und ein statischer Extent
 
definiert, dieser kann über die Variable $delta leicht verändert werden:
 
definiert, dieser kann über die Variable $delta leicht verändert werden:
 +
 
  $delta=0;
 
  $delta=0;
 
  $map_file=MAPFILE;
 
  $map_file=MAPFILE;
Line 270: Line 309:
 
Entscheidend ist der Aufruf der Funktion „shortest_path_astar2_as_geometry_internal_id“
 
Entscheidend ist der Aufruf der Funktion „shortest_path_astar2_as_geometry_internal_id“
 
(welcher nur dann gelingt, wenn die Tabelle die entsprechend angelegte Struktur besitzt).
 
(welcher nur dann gelingt, wenn die Tabelle die entsprechend angelegte Struktur besitzt).
 +
 
  $ll_x = $rectobj->minx;
 
  $ll_x = $rectobj->minx;
 
     $ll_y = $rectobj->miny;
 
     $ll_y = $rectobj->miny;
Line 280: Line 320:
 
     $l->set('data', $sql);
 
     $l->set('data', $sql);
 
     $l->set('status', MS_ON);
 
     $l->set('status', MS_ON);
 +
 
Die Funktion selber ist definiert in der Datei routing_postgis.sql und wurde ja von uns in
 
Die Funktion selber ist definiert in der Datei routing_postgis.sql und wurde ja von uns in
 
die Datenbank eingelesen.
 
die Datenbank eingelesen.
Line 293: Line 334:
 
Achtung: Die Zahlen stehen aber nicht für die gid in der Tabelle sondern für den Wert der
 
Achtung: Die Zahlen stehen aber nicht für die gid in der Tabelle sondern für den Wert der
 
source- oder aber target-spalte (siehe Werte der Kolpingstr. in Abb. 13).
 
source- oder aber target-spalte (siehe Werte der Kolpingstr. in Abb. 13).
Abbildung 13: Source/target-Werte der Kolpingstr.
+
 
 +
 
 +
'''Abbildung 13: Source/target-Werte der Kolpingstr.'''
 +
 
 +
 
 +
[[Image:datenmodell.PNG|Source/target-Werte der Kolpingstr.]]
  
  
Line 299: Line 345:
 
shortest_path_astar2_as_geometry_internal_id wird dann „on_the_fly“ die entsprechende
 
shortest_path_astar2_as_geometry_internal_id wird dann „on_the_fly“ die entsprechende
 
Route erstellt und über den Layer „path“ im Mapfile ausgegeben (Abb. 14).
 
Route erstellt und über den Layer „path“ im Mapfile ausgegeben (Abb. 14).
Abbildung 14: Route mit pgRouting erstellt
+
 
 +
'''Abbildung 14: Route mit pgRouting erstellt'''
 +
 
 +
 
 +
[[Image:endbild.PNG|Route mit pgRouting erstellt]]
  
 
Fragen zu dieser Thematik bitte an die Mailinglist von
 
Fragen zu dieser Thematik bitte an die Mailinglist von
Line 306: Line 356:
 
http://www.umn-mapserver-community.de
 
http://www.umn-mapserver-community.de
 
bzw. http://pgrouting.postlbs.org
 
bzw. http://pgrouting.postlbs.org
 +
 +
Diese Anleitung wurde von [[User:Kai Behncke | Kai Behncke]] und [[User:Peter_panther | Florian Thürkow]] erstellt.
 +
Ergänzung von [[User:Nhermann | Nicol Hermann]]

Latest revision as of 10:35, 12 November 2007

Einführung

Mittels dieser Anleitung soll Ihnen etwas Hilfestellung beim Thema pgRouting und UMN MapServer gegeben werden. Die Anleitung basiert im Wesentlichen auf Know-how, welches auf der Homepage http://pgrouting.postlbs.org vermittelt wird.

Weitere hilfreiche Quellen:

Mailinglist von umn-mapserver.de (mit 14 Antworten)

Englischsprachige Mailinglist des UMN MapServers (mit 8 Antworten)

Forum auf umn-mapserver-community.de (mit 25 Antworten)


Diese Anleitung ist für Windows XP geschrieben, funktioniert (mit den entsprechenden Änderungen) natürlich auch auf Linux-Systemen. Für diese Anwendung sollten Sie Grundkenntnisse im Umgang mit dem UMN MapServer, PostgreSQL/PostGIS sowie PHP/Mapscript besitzen.

Folgende Umgebung wurde installiert:

  • Das ms4w-Paket (2.2.3)
  • PostgreSQL 8.2.4 mit PostGIS-Aufsatz 1.1


Wie gehen wir nun vor? Zunächst einmal laden Sie von der Seite http://pgrouting.postlbs.org den pgRouting 1.0.0a-win32-installer herunter. Anschließen ein Doppelklick auf das Paket. Die Installation läuft quasi von alleine.

Installieren Sie pgrouting am Besten in das Verzeichnis C:\Programme\PostgreSQL\8.2 (siehe Abbildung 1).

Abbildung 1: Installation von PgRouting

Installationsroutine von pgRouting

Daten

Anschließend brauchen wir natürlich Geodaten. Wir verwenden dafür die Freien Geodaten aus dem von der Intevation GmbH initiierten Projekt „Frida“ (http://frida.intevation.org/) (siehe Abbildung 2).

Abbildung 2: Homepage der Frida-Daten

Homepage der Frida-Daten


Laden Sie sich hier folgende Daten herunter: frida-1.0.1-shp-joined.tar.gz und entpacken Sie diese. Im ersten Schritt brauchen wir die „strassen-joined.shp“-Daten. Diese Daten benötigen wir allerdings im SQL-Format um diese in die anzulegende PostgreSQL/PostGIS-Datenbank zu lesen. Also geben wir auf der Kommandozeile z.B. folgendes ein (siehe auch Abbildung 3):

Shp2pgsql D:\frida\strassen-joined.shp fridastreets routingdb > D:\frida\strassen-joined.sql

Abbildung 3: Shape in SQL-Format umwandeln

Shape in SQL-Format umwandeln

Datenbank anlegen

Anschließend legen wir eine Datenbank mit PostGIS-Unterstützung an (z.B. mit dem Tool pgAdmin III). Diese Datenbank nennen wir hier mal „routingdb“ (Abbildung 4).

Abbildung 4: Anlegen einer Datenbank mit PgAdminIII

Anlegen einer Datenbank mit PgAdminIII

Anschließend dann muss die Datei strassen-joined.sql in die Datenbank eingelesen werden. Gegen Sie also auf Kommandozeile folgendes ein:

psql -U postgres -f D:/frida/strassen-joined.sql routingdb

Abbildung 5: Befehl zum Einlesen der SQL-Datei in die Datenbank

Befehl zum Einlesen der SQL-Datei in die Datenbank

Die Daten der Tabelle „fridastreets“ haben folgende Struktur (siehe Abbildung 6):

Abbildung 6: Ursprüngliche Struktur der Frida-Daten

Ursprüngliche Struktur der Frida-Daten

Die Datenbank ist zu diesem Zeitpunkt allerdings noch nicht in der Lage Routen zu berechnen. Das wollen wir ändern. Dafür führen wir folgende Befehle aus:

psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing.sql routingdb

sowie anschließend:

psql -U postgres -f C:\Programme\PostgreSQL\8.2\share\contrib\routing_postgis.sql routingdb

Abbildung 7: Routingfunktionen werden in Datenbank gebracht

Routingfunktionen werden in Datenbank gebracht

Ok, die Datenbank ist für Routing im Grunde präpariert. Das bedeutet aber noch lange nicht, dass sie nun auch diesbezüglich funktioniert. Für verschiedene Funktionen von pgRouting muss eine bestimmte Tabellenstruktur vorliegen. Neben der gid und der Geometrie (the_geom) müssen auch die Anfangskoordinaten (x1, y1 jeweils als eigene Spalte (Datentyp numerisch)) bzw Endkoordinaten (x2,y2 ebenso jeweils als eigene Spalte) vorliegen. Zudem muss die Tabellenspalte „length“ (numeric) sowie source und target (bigint) vorliegen (siehe Abbildung 8).

Abbildung 8: Tabellenstruktur für verschiedene Funktionen von pgRouting

Tabellenstruktur für verschiedene Funktionen von pgRouting

Daten mittels PHP-Skript einlesen

Nachdem diese Spalten angelegt worden sind geht es darum automatisiert die Werte von x1,y1,x2,y2 einzulesen. Dafür wurde folgendes PHP-Skript geschrieben:

<?php
$host = "localhost";
$port = "5432";
$dbname = "routingdb";
$user = "postgres";
$password = "postgres";
$con_string = "host=$host port=$port dbname=$dbname user=$user password=$password";
$con = pg_connect ($con_string);
//Hier der Code für das Ermitteln von x1 und y1
$id_check = "SELECT max(gid)as gid from roads";
$res_id_check = pg_query($con,$id_check);
$count = pg_result($res_id_check,"gid");
echo "Anzahl der Eintraegege in der DB: ".$count;
echo "
"; for ($x=1;$x<=$count;$x++) { $start = "SELECT astext(StartPoint(the_geom))as startpoint from roads where gid='$x'"; $res_start= pg_query($con,$start); $start_ergebnis = pg_result($res_start,"startpoint"); echo "Geometrie $x
"; echo "Anfangspunkte (x1,y1): ".$start_ergebnis; echo "
"; $array_01=array("POINT(",")"); $array_02=array("",""); for($r=0;$r<sizeof($array_01);$r++) { $start_ergebnis=str_replace($array_01[$r],$array_02[$r],$start_ergebnis); } $explode=explode(" ",$start_ergebnis); $x1=$explode[0]; $y1=$explode[1]; echo "
"; //Hier der Code für das Ermitteln von x2 und y2 $end = "SELECT astext(EndPoint(the_geom))as endpoint from roads where gid='$x'"; $res_end= pg_query($con,$end); $end_ergebnis = pg_result($res_end,"endpoint"); echo "Endpunkte (x2,y2): ".$end_ergebnis; echo "
"; echo "--------------"; echo "
"; $array_01=array("POINT(",")"); $array_02=array("",""); for($r=0;$r<sizeof($array_01);$r++) { $end_ergebnis=str_replace($array_01[$r],$array_02[$r],$end_ergebnis); } $explode=explode(" ",$end_ergebnis); $x2=$explode[0]; $y2=$explode[1]; //Hier werden dann die Werte in die Spalten geschrieben $werte_in_tabelle_schreiben="UPDATE roads SET x1='$x1',y1='$y1',x2='$x2',y2='$y2' where gid='$x'"; $res = pg_query($werte_in_tabelle_schreiben); } ?>

Das Skript funktioniert eigentlich ganz einfach. Es stellt eine Verbindung zur PostgreSQL/PostGIS-Datenbank her. Dann wird ermittelt wie viele Geometrie-Einträge insgesamt vorliegen und in einer Schleife werden Rechtswerte und Hochwerte der Vertices in die Tabelle gelesen. Das Skript dann einfach über einen Webserver (z.B. innerhalb des ms4w-Paketes) abschicken.

Wichtig: Es kann eine Weile dauern, bis alle Einträge in die Datenbenk geschrieben
sind.
Falls Sie mit dem ms4w-Paket arbeiten sollten Sie unbedingt die Werte in der
PHP-Konfigurationsdatei php.ini (C:\ms4w\Apache\cgi-bin) ändern.
In Zeile 255 sollte die execution-time hochgesetzt werden, z.B.:
max_execution_time=300;
.........damit auch die kompletten Datensätze eingelesen werden.

Als Bestätigung erscheint beim Aufruf des Skriptes etwa folgendes Fenster (Abb. 9), in welchem in diesem Falle alle 12323 Einträge bestätigt werden.

Abbildung 9: Start- und Endpunkte der Strassengeometrien erstellen

Start- und Endpunkte der Strassengeometrien erstellen

Neben der oben beschrieben Möglichkeit die Daten mit PHP einzulesen, befüllt auch das folgende SQL-Kommando die Tabelle:

update roads set x1=X(StartPoint(the_geom)), y1=Y(StartPoint(the_geom)), x2=X(EndPoint(the_geom)), y2=Y(EndPoint(the_geom)),   
length=length(the_geom);
Wichtig: In neuen Versionen von PostGIS (ab 1.3.x) muss allen Funktionen ein 'ST_' vorangestellt werden.

Weitere Routingspezifische Werte berechnen

Anschließend sollen die length-Werte berechnet werden. Das geht ganz einfach mit folgendem SQL-Befehl in der routingdb-Datenbank (Abbildung 10):

UPDATE fridastreets set length=length(the_geom);


Abbildung 10: length-Berechnung

Start- und Endpunkte der Strassengeometrien erstellen

Jetzt fehlt aber noch etwas....... Um die Werte für source und target zu errechnen benutzen wir eine vorgefertige Funktion:

SELECT assign_vertex_id('fridastreets', 5);

Die Zahl ist letztlich variabel. Die Zahl 5 steht für einen Distanzraum, in welchem Knoten die selbe Vertexid erhalten. Die Funktion erwartet allerdings, dass die Spaltennamen nicht source bzw. target sondern source_id & target_id heissen. Natürlich könnten wir die Funktion jetzt modifizieren. Schneller geht’s aber, wenn wir die Spalten mal eben umbenennen, anschließend dann die Funktion absenden. Das ganze dauert dann ein Weilchen, irgendwann sind die Einträge dann aber getätigt


Abbildung 11: Source/target-Werte berechnen

Source/target-Werte berechnen

Routingvisualisierung

Anschließend ändern Sie source_id zu „source“ und „target_id“ zu „target“. Ok, dann brauchen wir noch ein PHP/Mapscript-Skript sowie ein passendes Mapfile. Unter http://files.orkney.jp/pgrouting/sample/pgRouting-sampleapp.tar.bz kann man sich diesbezügliche Dateien herunterladen. Diese Dateien wurden etwas verändert und können hier als routing.map bzw. phtmls/routing_os_frida.phtml heruntergeladen werden.

Die Datei routing.map ist eigentlich ganz einfach. Defaultmäßig werden die Frida-Daten über folgenden Eintrag visualisiert:

LAYER
 NAME "roads"
 TYPE LINE
 CONNECTION "user=postgres password=postgres dbname=routingdb host=localhost port=5432"
 CONNECTIONTYPE postgis
 DATA "the_geom from fridastreets"
 STATUS DEFAULT
#LABELITEM 'strname'
CLASSITEM 'strtypid'
   CLASS
        EXPRESSION '1'
        STYLE
      COLOR       255 0 0
      END
   END
 CLASS
        EXPRESSION '3'
        STYLE
              COLOR       255 255 0
        END
 END
 CLASS
        EXPRESSION /./
        STYLE
              COLOR       200 200 200
        END
 END
END


Abbildung 12: Darstellung der Frida-Geometrien im UMN MapServer

Source/Darstellung der Frida-Geometrien

Der Layer über welchen letztlich die Ausgabe der Route dargestellt wird nennt sich „path“.

LAYER
  NAME "path"
  CONNECTION "user=postgres password=postgres dbname=frida host=localhost port=5432"
  CONNECTIONTYPE postgis
 STATUS ON
  TYPE LINE
  CLASS
   NAME "path"
      STYLE
      SYMBOL 'circle'
COLOR 255 0 0
SIZE 8
      END
  END
END

Dieser wird dann über PHP/Mapscript aktiviert. Schauen Sich sich mal den Quellcode von routing_os_frida.phtml mal an. Mittels dieses Codes wird die Angabe zum Map-Objekt getätigt und ein statischer Extent definiert, dieser kann über die Variable $delta leicht verändert werden:

$delta=0;
$map_file=MAPFILE;
$map=ms_newMapObj($map_file);
$l=$map->getLayerByName("path");
if($l) {
 if($l && $start!=0 && $end!=0) {
 $cx1=3429000;
 $cy1=5787000;
 $cx2=3444000;
 $cy2=5800000;
   if($cx1!=0 && $cy1!=0 && $cx2!=0 && $cy2!=0 &&
      $cx1!=$cx2 && $cy1!=$cy2) {
     $minx = min($cx1,$cx2)-$delta;
     $miny = min($cy1,$cy2)-$delta;
     $maxx = max($cx1,$cx2)+$delta;
     $maxy = max($cy1,$cy2)+$delta;
     $map->setextent($minx,$miny,$maxx,$maxy);

Entscheidend ist der Aufruf der Funktion „shortest_path_astar2_as_geometry_internal_id“ (welcher nur dann gelingt, wenn die Tabelle die entsprechend angelegte Struktur besitzt).

$ll_x = $rectobj->minx;
   $ll_y = $rectobj->miny;
   $ur_x = $rectobj->maxx;
   $ur_y = $rectobj->maxy;
   $sql="the_geom from (select gid, the_geom from ".
       "shortest_path_astar2_as_geometry_internal_id('fridastreets', ".
       $start.", ".$end.", ".$ll_x.", ".$ll_y.", ".$ur_x.", ".
       $ur_y.")) as g using unique gid using SRID=-1";
   $l->set('data', $sql);
   $l->set('status', MS_ON);

Die Funktion selber ist definiert in der Datei routing_postgis.sql und wurde ja von uns in die Datenbank eingelesen. Wichtig ist dann auch noch das Definieren der Start- bzw. Endpunkte. Dieses geht über numerische Werte in einem Formular:

<select name=start>
<option value=0 >Wähle....</option>
<option value=7649 >Dom</option>
<option value=291 >Im Hone</option>
<option value=7750 >Kolpingstrasse</option>
<option value=7313 >Martinistr.</option>

Achtung: Die Zahlen stehen aber nicht für die gid in der Tabelle sondern für den Wert der source- oder aber target-spalte (siehe Werte der Kolpingstr. in Abb. 13).


Abbildung 13: Source/target-Werte der Kolpingstr.


Source/target-Werte der Kolpingstr.


Anschließend in der Anwendung dann einfach mal 2 Punkte auswählen. Über die Funktion shortest_path_astar2_as_geometry_internal_id wird dann „on_the_fly“ die entsprechende Route erstellt und über den Layer „path“ im Mapfile ausgegeben (Abb. 14).

Abbildung 14: Route mit pgRouting erstellt


Route mit pgRouting erstellt

Fragen zu dieser Thematik bitte an die Mailinglist von http://www.umn-mapserver.de, oder in die Foren auf: http://www.umn-mapserver-community.de bzw. http://pgrouting.postlbs.org

Diese Anleitung wurde von Kai Behncke und Florian Thürkow erstellt. Ergänzung von Nicol Hermann