The OS X Spatial Stack

I've been doing a bunch of spatial analysis and exploration recently. Where I previously would have used a Debian or Ubuntu server (or VM) to experiment, I'm now using Snow Leopard exclusively.

However, it's not all roses. As with most things, there are many paths to installing and configuring software, not all of them complementary. What follows is my experience installing and configuring various tools and their dependencies. I've attempted to install as few duplicate dependencies as possible (preferring Apple-provided versions) and to simplify the overall experience in order that individual elements may be upgraded independently.

Xcode

First, download and install Xcode 3.2.1. The defaults are fine.

Homebrew

Next, install homebrew. I've found that homebrew is significantly lighter and easier than MacPorts for installing additional open source software, as it re-uses system versions of libraries wherever possible.

Part of the homebrew philosophy is:

OS X is designed to minimise sudo use, you only need it for real root-level stuff. You know your /System and /usr are as clean and pure as the day you bought your Mac because you didn't sudo. Sleep better at night! ... Lets face it; Homebrew is not installing anything system-critical. Apple already did that.

Homebrew is typically installed in /usr/local, so:

$ sudo mkdir -p /usr/local
$ sudo chown -R `whoami` /usr/local

(If you already had MySQL installed in /usr/local, fix it: sudo chown -R mysql:mysql /usr/local/mysql.)

Now, install homebrew:

$ cd /usr/local
$ curl -L http://github.com/mxcl/homebrew/tarball/master | tar xz --strip 1 -C .

Homebrew-provided Libraries

While we're working with homebrew, let's install a dependencies that we'll need later.

pkg-config is necessary to cleanly compile PIL:

$ brew install pkg-config

You'll want to make sure that /usr/local/bin is in your $PATH so that homebrew-installed binaries will get run.

KyngChaos Frameworks and Binaries

The KyngChaos Wiki is the holy grail for OS X spatial downloads, as everything is cleanly packaged, up-to-date, and very well organized.

From the Unix Compatibility Frameworks page, you'll want to download and install:

These will install to /Library/Frameworks and will set up pointers to their corresponding Python packages in /Library/Python/2.6/site-packages/.

From the Qgis page, you'll want the most up-to-date Qgis installer (non-standalone). If you intend to open Spatialite data sources, you may need to install a more up-to-date version of the SQLite3 Framework than is included in the GDAL Complete package (this is generally applicable; if you want/need to live on the bleeding edge, install frameworks individually).

From the PostgreSQL page, download and install the newest versions of the following:

Mapnik

Thanks to Dane Springmeyer and others, Mapnik is now available as a framework. This means fewer homebrew dependencies, a simple upgrade path, and compatibility with 32-bit QGIS Python plugins. To install it, grab a Snow Leopard build from the Mapnik OSX Downloads page and run both the Mapnik Framework and Mapnik Python 2.6 System installers.

If you'd previously installed Mapnik from source, you should remove it from your system before running the installer:

$ rm -rf /Library/Python/2.6/site-packages/mapnik
$ rm -rf /usr/local/lib/mapnik
$ rm /usr/local/lib/libmapnik.dylib

You can also remove boost and icu with homebrew if nothing else is using them:

$ brew uninstall boost
$ brew uninstall icu

Quantumnik

Quantumnik is a QGIS plugin that allows Mapnik to be used for rendering. In addition, it will map many QGIS styles to Mapnik styles and provides an interface for editing them. In short, it's an excellent way to prototype your maps before starting up a batch rendering job.

To install Quantumnik, start up QGIS, enable the Plugin Installer in the Plugin Manager, choose Fetch Python Plugins, add a new repository (http://qgis.dbsgeo.com/), find it in the list, and check the box to enable it.

Python

We'll start with the easy stuff and easy_install the following:

$ easy_install Flickr.API
$ easy_install ipython
$ easy_install nik2img
$ easy_install Nikweb
$ easy_install nose
$ easy_install numscons
$ easy_install readline
$ easy_install TileCache

PIL

PIL is the Python Imaging Library. Download the current source kit and extract it to /usr/local/src:

$ cd /usr/local/src
$ tar zxf ~/Downloads/Imaging-1.1.6.tar.gz
$ cd Imaging-1.1.6/

Since you previously installed pkg-config, building it is straightforward:

$ python setup.py install

matplotlib

matplotlib is a plotting library for Python. It can be used both programmatically and interactively.

Download the source distribution from SourceForge and extract it to /usr/local/src:

$ cd /usr/local/src
$ tar zxf ~/Downloads/matplotlib-0.99.1.2.tar.gz
$ cd matplotlib-0.99.1.1/ # why yes, this is a mistake in the pkg

Again, this is straightforward:

$ python setup.py install

matplotlib includes the Basemap Toolkit, which makes it easier to work with cartographic data.

Download the source distribution from SourceForge and extract it to /usr/local/src. While you're at it, download natgrid from the same place.

$ cd /usr/local/src
$ tar zxf ~/Downloads/basemap-0.99.4.tar.gz
$ tar zxf ~/Downloads/natgrid-0.1.tar.gz

Basemap needs to know where GEOS was installed:

$ cd basemap-0.99.4/
$ GEOS_DIR=/Library/Frameworks/GEOS.framework/unix python setup.py install

natgrid is straightforward:

$ cd natgrid-0.1/
$ python setup.py install

numpy / scipy

numpy and scipy are the Pythonic chainsaws for scientific computing. numpy will mostly install out-of-the-box, but we'll install it from source.

Before we can build them, we need to install a Fortran compiler from AT&T Research: http://r.research.att.com/gfortran-4.2.3.dmg

Download source distributions of numpy and scipy from SourceForge(numpy, scipy) and extract them to /usr/local/src:

$ cd /usr/local/src
$ tar zxf ~/Downloads/numpy-1.3.0.tar.gz
$ tar zxf ~/Downloads/scipy-0.7.1.tar.gz

Build and install numpy:

$ cd numpy-1.3.0/
$ LDFLAGS="-lgfortran -arch x86_64" FFLAGS="-arch x86_64" \
    python setup.py install

Build and install scipy:

$ cd scipy-0.7.1/
$ LDFLAGS="-lgfortran -arch x86_64" FFLAGS="-arch x86_64" \
    python setup.py install

Note: the GDAL installer from KyngChaos bundles a version of numpy in /Library/Frameworks/GDAL.framework/Versions/1.6/Python/site-packages/numpy/, so if you run into weirdness, it's probably safe to delete that one.

Note: scipy recommends installing fftw for fast Fourier transformations; I was unable to get scipy to build when it was installed (using homebrew), so I'm omitting that step.

Cascadenik

Cascadenik is a pre-processor that converts CSS-like syntax into Mapnik XML configuration files. It supports handy shorthand such as ".thing[zoom > 12] { ... }" for targeting standard slippy zoom levels and generally makes it easier to maintain map styles. nik2img supports Cascadenik styling natively, making it easier to create and tweak styles (otherwise you'll need to run cascadenik-compile.py manually).

First, check out Cascadenik from Google Code:

$ cd /usr/local/src
$ svn co http://mapnik-utils.googlecode.com/svn/trunk/serverside/cascadenik

Next, build and install it:

$ cd cascadenik
$ python setup.py install

It will automatically download and install cssutils for you before making cascadenik-compile.py and cascadenik-style.py available in your $PATH.

OpenStreetMap

When working with data from OpenStreetMap, osm2pgsql and Osmosis are critical.

To install osm2pgsql, check it out from OSM's subversion repository and use make to build and install it, linking against the KyngChaos framework:

$ cd /usr/local/src
$ svn co http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/ 
$ cd osm2pgsql
$ PATH=$PATH:/Library/Frameworks/GEOS.framework/unix/bin/ \
    CFLAGS="-I/Library/Frameworks/PROJ.framework/unix/include" \
    LDFLAGS="-L/Library/Frameworks/PROJ.framework/unix/lib/" \
    make

You'll have to install it by hand to /usr/local:

$ install -m 0755 osm2pgsql /usr/local/bin
$ install default.style /usr/local/share/osm2pgsql

default.style is the standard map of OSM tags to database columns; you'll need it when you run an import, even if the defaults are fine.

Osmosis is a filter-driven tool for processing large volumes of OSM XML.

To begin, download the latest version of Osmosis.

Extract it to /usr/local:

$ cd /usr/local
$ tar zxf ~/Downloads/osmosis-latest-bin.tar.gz

Now, create a symlink to the binary:

$ ln -s /usr/local/osmosis-0.36/bin/osmosis /usr/local/bin/osmosis

PostgreSQL Additions

At present, the KyngChaos distribution of PostgreSQL does not include the intarray module (you can check /usr/local/pgsql/share/contrib to see if it's been added). osm2pgsql uses this module to create updatable Postgres OSM mirrors (meaning that you can stay up-to-date by applying planet diffs).

This means that we need to build it ourselves. First, download the source tarball corresponding to the version you already have installed. Next, extract it to /usr/local/src:

$ cd /usr/local/src
$ tar zxf ~/Downloads/postgresql-8.4.5.tar.bz2

Configure Postgres:

$ cd postgres-8.4.5
$ ./configure

Change to the intarray contrib directory and make it:

$ cd contrib/intarray
$ export PATH=/usr/local/pgsql/bin:$PATH
$ export USE_PGXS=1
$ make
$ sudo make install

(This same process can be repeated for other extensions that you desire.)

With intarray now installed, you can enable the database of your choosing (osm in this case):

$ sudo -u postgres psql -d osm -f /usr/local/pgsql/share/contrib/_int.sql

GUI Utilities

For graphical management of spatial data beyond what Qgis can handle, I usually use Base (for SQLite databases) and pgAdmin (for PostgreSQL databases).

Congratulations!

You now have a working spatial stack on OS X! There are certainly things missed here, but I'll try to keep this up-to-date as I discover new tools and simpler methods (and in response to your comments, dear reader).