-
-
Notifications
You must be signed in to change notification settings - Fork 368
How to: v1.x
pgRouting v1.x
- Is no longer supported
- This page is Historical
Table of Contents:
- Build pgRouting for Windows
- Converting OSM-Files into PostgreSQL-Scripts
- Diagnostic Tools
- How to show the route with Mapserver
- Working with OpenStreetMap data
- Working with Shapefiles
- Collection of useful SQL commands
- Network data validation
- Author: René Westerholt (edited by Daniel Kastl)
- License: Creative Commons
Warning
This manual page is a checklist of what is needed to build a Windows binary
for pgRouting. It was written some time ago, so it might be outdated.
-
Environment
- MinGW 5.0.3 (install to E:/Build/mingw)
- MSYS-1.0.11 (install to E:/Build/msys) http://www.baldanders.info/spiegel/remark/archives/000209.shtml
- pthread-win32-2.7.0
Download prebuild-dll-2-7-0-release from ftp://sources.redhat.com/pub/pthreads-win32/
cp /include/*.h /mingw/include
cp /lib/libpthreadGC2.a /mingw/lib/libpthread.a
- CMake
Use latest version(2.4.7)
#./configure --prefix=E:/Build/msys/1.0/local
#make
#make install
Or you can use Windows installer.
- Boost
Use previous version (1.33.1) because of v2 problem
#bjam -sTOOLS=mingw "-sBUILD=release <runtime-link>static <threading>multi <native-wchar_t>on" --prefix=/e/Build/msys/1.0/local install
#mv /usr/local/include/boost-1_33_1/boost /usr/local/include/boost
#rmdir /usr/local/include/boost-1_33_1
If you don't need CGAL library (driving distance functionality), pgRouting uses only Boost headers. So you needs download Boost headers(1.33.1 or later), and extract it.
- Gaul
Use latest version(0.1849-0)
#./configure --enable-slang=no
edit /util/Makefile
DEFS = -DHAVE_CONFIG_H
-> DEFS = -DHAVE_CONFIG_H -DBUILDING_DLL
edit /src/Makefile
DEFS = -DHAVE_CONFIG_H
-> DEFS = -DHAVE_CONFIG_H -DBUILDING_DLL
INCLUDES = -I../util/ -I../../util/
-> INCLUDES = -I../util -I../../util
edit /tests/Makefile
DEFS = -DHAVE_CONFIG_H
-> DEFS = -DHAVE_CONFIG_H -DBUILDING_DLL
INCLUDES = -I../util/ -I../../util/ -I../src/ -I../../src/ -I/usr/include/slang/
-> INCLUDES = -I../util -I../../util -I../src -I../../src -I/usr/include/slang/
#make
#make install
- CGAL
Use latest version(3.2.1)
#./install_cgal --prefix=/usr/local/cgal --with-BOOST --BOOST_INCL_DIR=/usr/local/include --BOOST_LIB_DIR=/usr/local/lib --without-autofind -ni /mingw/bin/g++
#cp /usr/local/cgal/include/CGAL/config/i686_MINGW32NT-5.1_g++-3.4.2/CGAL/compiler_config.h /usr/local/cgal/include/CGAL/compiler_config.h
#cp /usr/local/cgal/lib/i686_MINGW32NT-5.1_g++-3.4.2/libCGAL.a /usr/local/cgal/lib/libCGAL.a
#cp /usr/local/cgal/lib/i686_MINGW32NT-5.1_g++-3.4.2/libCGAL.so /usr/local/cgal/lib/libCGAL.so
- pgRouting
#cmake -G"MSYS Makefiles" -DWITH_TSP=ON -DWITH_DD=ON .
- Edit CMakeCache.txt
Boost_INCLUDE_DIR:PATH=Boost_INCLUDE_DIR-NOTFOUND
-> Boost_INCLUDE_DIR:PATH=E:/Build/msys/1.0/local/include
CGAL_INCLUDE_DIR:PATH=CGAL_INCLUDE_DIR-NOTFOUND
-> CGAL_INCLUDE_DIR:PATH=E:/Build/msys/1.0/local/cgal/include
CGAL_LIBRARIES:FILEPATH=CGAL_LIBRARIES-NOTFOUND
-> CGAL_LIBRARIES:FILEPATH=E:/Build/msys/1.0/local/cgal/lib
GAUL_LIBRARIES:FILEPATH=GAUL_LIBRARIES-NOTFOUND
-> GAUL_LIBRARIES:FILEPATH=E:/Build/msys/1.0/local/lib
- Edit core\src\CMakeFiles\routing.dir\flags.make
Adjust (ie. "C") and to your system environment!
C_FLAGS = -Drouting_EXPORTS -O2 -g \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/. \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/core \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/core/src \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/tsp \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/tsp/src \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/driving_distance \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/driving_distance/src \
-I/boost \
-I/<drive>/<my path>/msys/1.0/local/include \
-IC:/PROGRA~1/PostgreSQL/8.2/include/server \
-IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32
CXX_FLAGS = -Drouting_EXPORTS -O2 -g
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/. \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/core \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/core/src \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/tsp \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/tsp/src \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/driving_distance \
-I/<drive>/<my path>/msys/1.0/local/src/pgrouting/pgrouting/extra/driving_distance/src \
-I/boost \
-I/<drive>/<my path>/msys/1.0/local/include \
-IC:/PROGRA~1/PostgreSQL/8.2/include/server \
-IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32
- Edit core\src\CMakeFiles\routing.dir\build.make
Adjust (ie. "C") and to your system environment!
routing_EXTERNAL_OBJECTS = \
Edit last line as follows (not make clean!!!)
cd /<drive>/<my path>/pgrouting/core/src && /<drive>/<my path>/mingw/bin/g++.exe $(routing_OBJECTS) $(routing_EXTERNAL_OBJECTS) \
-L/<drive>/<my path>/msys/1.0/local/lib \
-LC:/PROGRA~1/PostgreSQL/8.2/lib \
-lpostgres -shared -o ../../lib/librouting.dll \
-Wl,--out-implib,../../lib/librouting.dll.a \
-Wl,--major-image-version,0,--minor-image-version,0
- Edit extra\tsp\src\CMakeFiles\routing_tsp.dir\flags.make
C_FLAGS = -Drouting_tsp_EXPORTS -g -O2 -IE:/Build/msys/1.0/local/include -I/E/Build/msys/1.0/local/src/pgrouting/pgrouting/core/src -IC:/PROGRA~1/PostgreSQL/8.2/include/server -IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32
CXX_FLAGS = -Drouting_tsp_EXPORTS -g -O2 -IE:/Build/msys/1.0/local/include -I/E/Build/msys/1.0/local/src/pgrouting/pgrouting/core/src -IC:/PROGRA~1/PostgreSQL/8.2/include/server -IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32 -DBUILDING_DLL
- Edit extra\tsp\src\CMakeFiles\routing_tsp.dir\build.make
routing_tsp_EXTERNAL_OBJECTS = \
Edit last line as follows
cd /E/Build/msys/1.0/local/src/pgrouting/pgrouting/extra/tsp/src && /e/Build/mingw/bin/g++.exe $(routing_tsp_OBJECTS) $(routing_tsp_EXTERNAL_OBJECTS) -LE:/Build/msys/1.0/local/lib -LC:/PROGRA~1/PostgreSQL/8.2/lib -lpostgres -lgaul -lgaul_util -lm -shared -o ../../../lib/librouting_tsp.dll -Wl,--out-implib,../../../lib/librouting_tsp.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--export-all-symbols
- Edit extra\driving_distance\src\CMakeFiles\routing_dd.dir\flags.make
C_FLAGS = -Drouting_dd_EXPORTS -g -O2 -IE:/Build/msys/1.0/local/include -I/E/Build/msys/1.0/local/src/pgrouting/pgrouting/core/src -I/E/Build/msys/1.0/local/cgal/include -IC:/PROGRA~1/PostgreSQL/8.2/include/server -IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32
CXX_FLAGS = -Drouting_dd_EXPORTS -g -O2 -IE:/Build/msys/1.0/local/include -I/E/Build/msys/1.0/local/src/pgrouting/pgrouting/core/src -I/E/Build/msys/1.0/local/cgal/include -IC:/PROGRA~1/PostgreSQL/8.2/include/server -IC:/PROGRA~1/PostgreSQL/8.2/include/server/port/win32
- Edit extra\driving_distance\src\CMakeFiles\routing_dd.dir\build.make
routing_dd_EXTERNAL_OBJECTS = \
Edit last line as follows
cd /E/Build/msys/1.0/local/src/pgrouting/pgrouting/extra/driving_distance/src && /e/Build/mingw/bin/g++.exe $(routing_dd_OBJECTS) $(routing_dd_EXTERNAL_OBJECTS) -LE:/Build/msys/1.0/local/lib -LE:/Build/msys/1.0/local/cgal/lib -LC:/PROGRA~1/PostgreSQL/8.2/lib -lCGAL -lpostgres -shared -o ../../../lib/librouting_dd.dll -Wl,--out-implib,../../../lib/librouting_dd.dll.a -Wl,--major-image-version,0,--minor-image-version,0
- Build pgRouting
#make
- Author: Westerholt (edited by Daniel Kastl)
If you desire to put some data for displaying as a WFS or WMS into your database you will assert, that most of the available tools for doing something like this are not very satisfying. The tool "osm2pgsql" has the fault, that only attributes that are necessary for rendering the map, are imported into your database. If you want to have the attribute "surface" (for example) in your database, this wouldn't be imported by osm2pgsql.
The tool "osm2pgrouting" works well with creating a routing topology, but it's not useful for the problem aforementioned. "osmosis" is another tool for importing data into a PostgreSQL database. But it creates a table structure that is very disastrous because it creates one row for each attribute that belongs to geometry. So, if your geometry has 5 attributes, there would be 5 rows with the structure: ID, Attribute. If you have a big amount of data, you will assert that this would be very uncomfortable.
Here are some new java programs are written by myself, that make it very easy to import data from OSM-Files into your PostgreSQL databases:
Download:
The use of the programs is as follows:
For nodes2postgis.jar:
java -jar nodes2postgis.jar map.osm
For lines2postgis.jar:
java -jar lines2postgis.jar map.osm
For latlon2google.jar:
java -jar latlon2google.jar yourTablename
The result of running those java-programs are .sql scripts that can be easily loaded in the SQL-Performer in PGAdmin III or even be executed on command-line as usually.
Note:
The program "latlon2google" converts the data in the declared table from
geographical reference system into the google projection.
- Author: Stephen Woodbridge (edited by Daniel Kastl)
- License: Creative Commons
pgRouting is a large black box for most users. When things are working nobody has a problem, but when it is not working as expected what do you do? One of the most common problems is issues with the routing data. I built the following tools that are easy to implement and use and can reveal a lot about your data. I assume that you are working with OpenLayers as you map viewer and we will build two visualization tools.
- View just the streets in the routing database
- View intersections and detect deadends
You can see these tools in action at http://imaptools.com/leaddog/routing/dd.html Zoom into a city, open the layer switcher and select "Just the Streets" and "Dead Ends".
Create a mapfile that displays the street segments from the routing database and add this as an optional base layer. You might want to add color oneway streets a different color, but in general, keep the display simple and probably single pixel lines. You might label the segments with their UID so you can go back to the database and query them in detail.
LAYER
NAME "Streets"
STATUS DEFAULT
TYPE LINE
CONNECTIONTYPE postgis
CONNECTION "user=postgres dbname=routing host=centos port=5432"
DATA "the_geom from (select gid, the_geom from st) as foo
using SRID=4326 using unique gid"
LABELITEM "gid"
MAXLABELSCALEDENOM 25000
CLASS
STYLE
COLOR 87 87 87
WIDTH 1
END
LABEL
FONT "arial"
TYPE TRUETYPE
ANGLE AUTO
SIZE 7
COLOR 1 1 1
END
END
END
symbol
name "one_way_from"
type truetype
font arial-bold
character ">"
gap -40
end
symbol
name "one_way_to"
type truetype
font arial-bold
character "<"
gap -40
end
LAYER
NAME "One_Way_Arrows"
STATUS DEFAULT
TYPE LINE
MAXSCALEDENOM 25000
CONNECTIONTYPE postgis
CONNECTION "user=postgres dbname=routing host=centos port=5432"
DATA "the_geom from (select gid, one_way, the_geom from st
where one_way is not null and length(one_way)>0) as foo
using SRID=4326 using unique gid"
CLASSITEM 'one_way'
CLASS
NAME 'From'
EXPRESSION "FT"
STYLE
SYMBOL "one_way_from"
COLOR 80 80 80
SIZE 8
END
END
CLASS
NAME 'To'
EXPRESSION "TF"
STYLE
SYMBOL "one_way_to"
COLOR 80 80 80
SIZE 8
END
END
END
Add a column cnt integer to the vertices_tmp table and update it with the count of segments that reference that node. Maybe something like this:
alter table vertices_tmp add column cnt integer;
update vertices_tmp set cnt=0;
update vertices_tmp set cnt=cnt+1 where streets.source=id;
update vertices_tmp set cnt=cnt+1 where streets.target=id;
Now create a mapfile layer for points and display the vertices_tmp
LAYER
NAME "deadends"
TYPE POINT
CONNECTIONTYPE "postgis"
CONNECTION ...
DATA ...
CLASSEXPRESSION "cnt"
CLASS
EXPRESSION "cnt=1"
STYLE
SYMBOL "circle"
SIZE 5
COLOR 255 0 0
END
END
CLASS
EXPRESSION "cnt>2"
STYLE
SYMBOL "circle"
SIZE 3
COLOR 0 255 0
END
END
END
This will display red dots at dead ends and green dots as good connections be segments. If you have a lot of red dots between segments that should be joined, you probably need to rebuild your vertices_tmp table with a larger tolerance.
It is very hard to debug a large black box like a router without having some tools that can give you some better insight as to what is going on.
- Author: Camptocamp/ pgDijkstra (edited by Daniel Kastl)
- License: Creative Commons
The shortest path function (i.e. "dijkstra_sp()") can be used inside Mapserver to draw the shortest path directly:
LAYER
NAME "europe"
TYPE LINE
STATUS DEFAULT
CONNECTIONTYPE postgis
CONNECTION "user=postgres host=localhost dbname=geo"
DATA "the_geom from (SELECT the_geom, gid from
dijkstra_sp('bahnlinien_europa_polyline', 2629, 10171)) AS
foo using unique gid using srid=-1"
TEMPLATE "t"
CLASS
NAME "0"
STYLE
SYMBOL "circle"
SIZE 10
COLOR 50 50 100
END
END
END
Notice, however, that this function will be called at each map display, computing the shortest path every time.
A better approach would be to generate the shortest path in a temporary table.
- Author: Kai Behncke (edited by Daniel Kastl)
- License: Creative Commons
In that case as an example from Osnabrück ... (in lower Saxony(Germany))
Getting your own OpenStreetMap-Routing-data is not the easiest step in the world. Do you know that you need data with a real topology?
In general, Shapefiles should have one, but be very careful with OSM-Shapefiles. For most thing they work very nice, you get them e.g. from here: http://download.geofabrik.de/osm/
But please don`t use these Shapefiles (and shp2pgsql) for a routing and have a look at that discussion:
http://lists.postlbs.org/pipermail/pgrouting-users/2009-April/000096.html
Many thanks to Daniel KASTL who brought the needed information:
... shp2pgsql imports the geometry correctly, but the topology function will not work with how OSM represents their ways, because ways consist (can consist) of more than one edge often.
osm2pgrouting cares about this and splits a way into more edges if they cross each other. It then automatically does the assign_vertex topology script and adds a few more tables to keep information about road types and classes.
To get your own data you need to work with .osm (XML) files.
Please download the .osm-data from lower Saxony (Niedersachsen.osm.bz2), e.g. from here:
http://download.geofabrik.de/osm/europe/germany/
And then install osmosis, a very nice tool to work with osm-data, The wiki-site for osmosis you find here:
http://wiki.openstreetmap.org/wiki/Osmosis
You need to extract the data from Osnabrück out of Lower Saxony, it works like that:
osmosis --read-xml niedersachsen.osm --bb left=7.917 right=8.1694 \
top=52.3537 bottom=52.3537 --write-xml osnabrueck.osm
Now, you have the "real"-OSM-XML-Data from Osnabrück but without a topology.
For that, you need the tool "osm2pgrouting". After you have loaded the .osm-File in the database via osm2pgrouting, the table-structure should look like:
- Author: Kai Behncke (edited by Daniel Kastl)
- License: Creative Commons
Nearly a standard are the well-known ESRI-Shapefiles that consist of -at least - a .dbf-File, a .shp-File and a .shx-File.
These files mostly have already a topology.
If you have installed postgresql a tool called "shp2pgsql" will exist on your computer. You can transform your data into the sql-format doing:
shp2pgsql /home/mydata/roads.shp newtable >/home/mydata/roads.sql“
For test-purposes you can take data from British Columbia (nrn_rrn_bc_shp_en.zip).
You get it from the GeoBase <http://geobase.ca/geobase/en/data/nrn/index.html>
_
"National Road Network" dataset.
Please be aware: Don`t use OpenStreetMap-Shapefiles, as thew will create some problems because of their structure.
That sql-file that was created by shp2pgsql you need to bring in your routing-database.
- Author: Daniel Kastl
- License: Creative Commons
SELECT
count(gid) AS links,
sum(a.cost) AS cost,
sum(length) AS length
FROM shortest_path(
'SELECT gid AS id,
source::integer,
target::integer,
length::double precision AS cost
FROM <TABLE A>
WHERE <...>,
false,
false
) AS a LEFT JOIN <TABLE B> ON (a.gid = gid)
Note:
If you have some SQL commands to share, that are useful for pgRouting,send an email to project@pgrouting.org for further information.
- Author: Kaib Behncke (edited by Daniel Kastl)
- License: Creative Commons
An important thing is to test if your data work properly for routing. If you are more or less fit to UMN MapServer you can easily do some tests. First of all many thank to Stephen WOODBRIDGE for that idea.
You need to type the following commands on your vertices_tmp-table
alter table vertices_tmp add column cnt integer;
update vertices_tmp set cnt=0;
update vertices_tmp set cnt=cnt+1 from ways where ways.source=vertices_tmp.id;
update vertices_tmp set cnt=cnt+1 from ways where ways.target=vertices_tmp.id;
This will display red dots at dead ends and green dots as good connections be segments.
You can visualize it with the UMN MapServer, just take a mapfile like:
MAP
NAME 'mymap'
STATUS ON
#EXTENT 3427065.200000 5788323.530000 3443999.370000 5800691.660000
#EXTENT 7.9189 52.2102 8.1716 52.3467
EXTENT 880000 6840000 915000 6860000
IMAGECOLOR 255 255 255
SIZE 700 700
SYMBOLSET '/your_path/symbols/symbols.sym'
FONTSET '/your_path/fonts/fonts.list'
WEB
TEMPLATE 'template.html'
IMAGEPATH '/your_path/tmp/'
IMAGEURL '/tmp/'
METADATA
'WMS_TITLE' 'Gastronomap_routing'
'WMS_FEATURE_INFO_MIME_TYPE' 'text/html'
'WMS_ONLINERESOURCE' 'http://localhost/cgi-bin/mapserv?map=/your_path/routing.map'
'WMS_SRS' "EPSG:900913"
END
END
PROJECTION
'init=epsg:900913'
END
LAYER
OFFSITE 255 255 255
#LABELITEM 'name'
TOLERANCE 20
NAME 'streets'
TYPE LINE
STATUS DEFAULT
CONNECTIONTYPE postgis
CONNECTION 'user=postgres password=postgres dbname=routing host=localhost port=5432'
DATA 'the_geom from ways as foo using unique gid using SRID=900913'
CLASSITEM 'gid'
TEMPLATE 'ausgabe.phtml'
METADATA
'WMS_TITLE' 'streets'
'WMS_SRS' "EPSG:900913"
'WMS_INCLUDE_ITEMS' 'all'
END
CLASS
TEXT ([gid],[source],[target])
EXPRESSION /./
STYLE
WIDTH 1
COLOR 0 0 0
END
LABEL
TYPE TRUETYPE
ANTIALIAS TRUE
FONT 'arial'
COLOR 0 0 0
BACKGROUNDCOLOR 240 240 240
POSITION cc
MINSIZE 8
MAXSIZE 12
BUFFER 2
END
END
END
LAYER
OFFSITE 255 255 255
#LABELITEM 'name'
TOLERANCE 20
NAME 'dead_ends'
TYPE POINT
STATUS DEFAULT
CONNECTIONTYPE postgis
CONNECTION 'user=postgres password=postgres dbname=routing host=localhost port=5432'
DATA 'the_geom from vertices_tmp as foo using unique id using SRID=900913'
CLASSITEM 'cnt'
TEMPLATE 'ausgabe.phtml'
METADATA
'WMS_TITLE' 'dead_ends'
'WMS_SRS' "EPSG:900913"
'WMS_INCLUDE_ITEMS' 'all'
END
CLASS
Text ([id])
EXPRESSION /1/
STYLE
SYMBOL 'tent'
SIZE 11
COLOR 255 0 0
END
LABEL
TYPE TRUETYPE
ANTIALIAS TRUE
FONT 'arial'
COLOR 255 0 0
BACKGROUNDCOLOR 240 240 240
POSITION cr
MINSIZE 8
MAXSIZE 12
BUFFER 2
END
END
CLASS
TEXT ([id])
EXPRESSION /./
STYLE
SYMBOL 'tent'
SIZE 11
COLOR 0 0 255
END
LABEL
TYPE TRUETYPE
ANTIALIAS TRUE
FONT 'arial'
COLOR 0 0 255
BACKGROUNDCOLOR 240 240 240
POSITION cr
MINSIZE 8
MAXSIZE 12
BUFFER 2
END
END
END
END
If you open your MapServer-testing-apllication via: http://localhost/cgi-bin/mapserv?map=/var/www/gastronomap_wms/gastronomap_routing.map
and you zoom in you get something like:
Everything fine with the data ! :-)
But if it looks like:
Definitely something went wrong........