pgRouting, OpenStreetMap, and QGIS

Thu 14 October 2010

I mentioned a few posts back that there was a great resource for downloading OpenStreetMap data, and that it was relatively easy to import osm data into PostgreSQL/PostGIS for use with pgRouting to calculate shortest paths and various other network-based operations. In this post, I’ll outline the steps required to get all this up and going, and provide a quick example to show how this can be combined with QGIS to visualise the computed shortest path directly.

Firstly, we need to install all the required packages. I’m assuming you already have PostgreSQL and PostGIS installed, but if not, have a look here for a quick guide to getting things set up (Note that the latest version of PostgreSQL is now 8.4).

sudo apt-get install postgresql-server-dev-8.4 libboost-graph-dev

If you don’t have them already, you might also need tools for building the required software packages, as well as subversion and cmake.

sudo apt-get install build-essential subversion cmake

To be able to run the driving distance algorithms we need CGAL:

sudo apt-get install libcgal*

And the traveling sales person algorithm requires GAUL:

tar -xzf gaul-devel-0.1850-0.tar.gz cd gaul-devel-0.1850-0/
./configure --disable-slang
sudo make install
sudo ldconfig

Now it’s time to download, build, and install pgRouting. If you don’t have subversion, or you don’t want to have the latest trunk version of pgRouting, you can also download it manually.

svn checkout pgrouting
cd pgrouting/
cmake -DWITH_TSP=ON -DWITH_DD=ON . make
sudo make install

Once we’ve got that installed and ready to go, we need to set up PostgreSQL so that it ‘trusts’ local database connections.

sudo gedit /etc/postgresql/8.4/main/pg_hba.conf

Scroll to the bottom, and make sure you change the METHOD to ‘trust’.

local   all         all                               trust

And now that we’ve made these changes, we need to restart PostgreSQL

sudo /etc/init.d/postgresql-8.4 restart

Next we simply create a routing database to store our data in…

createdb -U postgres routing createlang -U postgres plpgsql routing

…add the PostGIS functions…

psql -U postgres -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql routing
psql -U postgres -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql routing

…add all the pgRouting functions…

psql -U postgres -f /usr/share/postlbs/routing_core.sql routing
psql -U postgres -f /usr/share/postlbs/routing_core_wrappers.sql routing
psql -U postgres -f /usr/share/postlbs/routing_topology.sql routing

…including the traveling salesman functions…

psql -U postgres -f /usr/share/postlbs/routing_tsp.sql routing
psql -U postgres -f /usr/share/postlbs/routing_tsp_wrappers.sql routing

…and finally the driving distance functions.

psql -U postgres -f /usr/share/postlbs/routing_dd.sql routing
psql -U postgres -f /usr/share/postlbs/routing_dd_wrappers.sql routing

We now have a fully working pgRouting database ready to be populated with data! So in order to do that relatively painlessly, we first install the osm2pgrouting tool, which will help us import our osm data directly into our pgRouting database with the correct structure and everything.

svn checkout osm2pgrouting
cd osm2pgrouting/

Once that’s finished building, we can go ahead and download our osm data from See this previous post for details. For this example, I’ll be using the osm data for Ireland

bzip2 -d ireland.osm.bz2

Once we have that downloaded and extracted, we’re ready to import the osm data into our database using the osm2pgrouting tool

./osm2pgrouting -file /home/cfarmer/Downloads/ireland.osm -conf mapconfig.xml -dbname routing -user postgres -clean

Once that is finished (could take a long time) we’re ready to query the network (Note that the values 52343 and 39219 represent network node ids)…

psql -U postgres routing
select * from shortest_path
    ('select gid as id,
        length::double precision as cost
        from ways',
    52343, 39219, false, false);

…to produce something like this:

vertex_id | edge_id |        cost
    52343 |   78055 |   0.217641978736602
    52341 |   78052 |  0.0230665826613562
    52342 |   78053 |  0.0839311516838216
    20390 |   28717 |   0.166809293071158
    20389 |   28716 |   0.493120178133836
    20388 |   28715 |   0.271165901884914
    20387 |  112841 |   0.101669458767093
    14183 |   22893 |   0.106433172954507

Assuming your database is structured as pgRouting expects (which it should be if you’ve used osm2pgrouting), you can use the some of the functions which return geometries for use with other PostGIS functions:

select * from dijkstra_sp('ways', 52343, 39219);
id  |  gid   |          the_geom
  1 |  78055 | 0105000020E610000001000...
  2 |  78052 | 0105000020E610000001000...
  3 |  78053 | 0105000020E610000001000...
  4 |  28717 | 0105000020E610000001000...
  5 |  28716 | 0105000020E610000001000...
  6 |  28715 | 0105000020E610000001000...
  7 | 112841 | 0105000020E610000001000...
  8 |  22893 | 0105000020E610000001000...

These queries are all fine and dandy, and can easily be used to calculate the distances of shortest paths etc, but what I really want to do is visualise this output in a GIS so I can get an idea of what these shortest paths looks like. In another previous post, I mentioned how we could visualise spatial SQL queries directly in QGIS from both the Python console, and using a handy plugin. We can do the same thing here using pgRouting to produce a lovely spatial representation of our shortest path query:


And there you go, a full fledged routing library built right into our database!

Helpful Tip

Networks OpenStreeMap Databases QGIS FOSS GIS How-To


recent visitors