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
Line 166: Line 166:
 
Abbildung 9: Start- und Entpunkte der Strassengeometrien erstellen
 
Abbildung 9: Start- und Entpunkte der Strassengeometrien erstellen
  
=== Weitere Routingspezifische Werte berechnen ===
+
== Weitere Routingspezifische Werte berechnen ==
 
Anschließend sollen die length-Werte berechnet werden.
 
Anschließend sollen die length-Werte berechnet werden.
 
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

Revision as of 07:03, 27 August 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: 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 (mit 8 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 Ä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). 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

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).

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

Die Daten der Tabelle „fridastreets“ haben folgende Struktur: Abbildung 6: Ursprüngliche Struktur der Frida-Daten

So weit so gut. 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

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).


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 (liegt im heruntegeladenen Ordner als x_y_einlesen.php).

<?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 "
";

6

 $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 Entpunkte der Strassengeometrien erstellen

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


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