pgRouting on Mac OS X 10.6.8

Some notes about how to build pgRouting on Mac OS X, in case I have to do this again in the future. 🙂 I’m writing this from my memory and I hope I did not forget something, but it should work similar to what I’ve described.

pgRouting adds geospatial routing functionality to a PostGIS / PostgreSQL geospatial database. So, as a preliminary requirement, we have to start with installing PostgreSQL and PostGIS.

I’ve done this using MacPorts, so

$ sudo port -d install postgresql90 postgresql90-server postgis

If you like, you can also install pgAdmin3 via MacPorts, an administration program to PostgreSQL

To create a database instance, after install do

$ sudo mkdir -p /opt/local/var/db/postgresql90/defaultdb
$ sudo chown postgres:postgres /opt/local/var/db/postgresql90/defaultdb
$ sudo su postgres -c '/opt/local/lib/postgresql90/bin/initdb -D /opt/local/var/db/postgresql90/defaultdb'

When executing the last command from above, I remember I had some trouble with the postgres user that was created during installation. Check that the postgres user account can be executed using the su command, e.g.

$ sudo su - postgres

If not, make sure that the postgres account has a valid shell

$ sudo dscl . -create /Users/postgres UserShell /bin/sh

Note that the installation has created a startup item for starting postgresql90-server with launchd. It is disabled by default. Execute the following command to start the server, and to cause the server to launch at startup:

$ sudo port load postgresql90-server

As an alternative to launchd, you can also start the database server using:

$ /opt/local/lib/postgresql90/bin/postgres -D /opt/local/var/db/postgresql90/defaultdb

or

$ /opt/local/lib/postgresql90/bin/pg_ctl -D /opt/local/var/db/postgresql90/defaultdb -l logfile start

After starting the server, you might want to look at /opt/local/var/log/postgresql90/postgres.log to check if the server is running OK.

Now, let’s try to install pgRouting.

The pgRouting package is also available from MacPorts, but only an older version 1.03. So, I just went to www.pgrouting.org and downloaded the latest source package pgrouting-1.05.tar.gz from 2010/11/22.

However, you won’t be available to successfully build from this archive (at least not on Mac OS X…)! Instead, you will end up with a couple of “undefined symbols” when linking.

For solving this, go to the pgRouting GitHub repository instead. This issue explains the cause why the linking fails on Mac OS X. Fortunately, this issue has already been fixed, so download a current snapshot from the repository and try to build this one instead.

First, you need to edit cmake/FindPostgreSQL.cmake. Add the include path /opt/local/include/postgresql90/server
and the library path /opt/local/lib/postgresql90 to the file so that cmake is able to locate your PostgreSQL installation.

Then build pgRouting with

$ cmake .
$ make
$ sudo make install

You should end up with something like this

[100%] Built target routing
Install the project...
-- Install configuration: ""
-- Installing: /opt/local/lib/postgresql90/librouting.so
-- Installing: /usr/share/pgrouting/routing_core.sql
-- Installing: /usr/share/pgrouting/routing_core_wrappers.sql
-- Installing: /usr/share/pgrouting/routing_topology.sql
-- Installing: /usr/share/pgrouting/matching.sql

Finally, I hope my memory still serves me right:

$ createdb -U postgres -E utf8 template_postgis
$ psql -U postgres -d template_postgis -f /opt/local/share/postgresql90/contrib/postgis-1.5/postgis.sql 
$ psql -U postgres -d template_postgis -f /opt/local/share/postgresql90/contrib/postgis-1.5/spatial_ref_sys.sql 
$ psql -U postgres -d template_postgis -f /usr/share/pgrouting/routing_core.sql 
$ psql -U postgres -d template_postgis -f /usr/share/pgrouting/routing_core_wrappers.sql 
$ psql -U postgres -d template_postgis -f /usr/share/pgrouting/routing_topology.sql 

Create a pgRouting enabled database using the new template_postgis template

$ createdb -U postgres -T template_postgis routing

That’s it! If you are new to pgRouting, you can find a good example about route calculation using pgRouting here.

Best way to merge color relief with shaded relief map

When creating a raster map featuring a shaded relief combined with elevation colors, then chances are that you are using the gdaldem tool to create both the hillshading (gdaldem hillshade) and the color relief map (gdaldem color-relief). But as soon as you have created both images, you might ask yourself how to combine both images into one. First, I want this to be reproducible in a script, so GIMP or Photoshop is not a viable option.

Let’s take a closer look at the results of some different methods I’ve tried out. The color relief and the hillshade relief images were created with the following commands:

$ gdalwarp -te 29 39 31 41 SRTM30.tif clip.tif
$ gdaldem color-relief clip.tif palette.cpt color.tif
$ gdaldem hillshade clip.tif hills.tif -z 3 -s 111120
Color relief
Hillshade


One option for combining these two images is the hsv_merge.py script from Frank Warmerdam. This script merges the two images in a way where the Hue and Saturation come from the color bands, and the Value comes from the panchromatic band.

But as stated here, “[this approach] works ok, but usually turns vegetation from a deep forest green to a minty pistachio green. This is because vegetation is very reflective in the IR band, which the pan band covers.” Let’s take a look at the result of hsv_merge.py:

$ ./hsv_merge.py color.tif hills.tif merged.tif
Result of hsv_merge.py


As you can see very clearly, the resulting image doesn’t match well with the original color relief in the lower green regions. I didn’t find this result satisfactory, so I looked into whether ImageMagick can be of help here.

A very simple operation would be

$ composite -blend 60 color.tif hills.tif output.tif

but the composite image looks, well, a bit gray (no surprise here):

Simple blend operation


A much better approach consists of two steps: adjusting the gamma level of the hillshade image so that the resulting gamma-corrected hillshade has the RGB value (128, 128, 128) in the plain areas, followed by a lighting composition. I’ve used the “overlay” method below, but you can also experiment with the other lighting methods available.

$ convert -gamma .5 hills.tif hills_gamma.tif
$ convert color.tif hills_gamma.tif -compose Overlay -composite output.tif
Gamma-corrected hillshade
Result


Looks good doesn’t it? Note that the colors of the composite image match very well with the original color relief image.

Finally, note that applying any ImageMagick conversion leads to loosing the georeferencing in the TIFF image. To keep the georeferencing information, you can save the GeoTIFF metadata to a file, and then copy the metadata into a new image:

$ listgeo clip.tif > meta.txt
$ geotifcp -g meta.txt output.tif final.tif 

After this, final.tif should be georeferenced (you can check this with gdalinfo).