This note is about building a web map tile server using OpenStreetMap data and the Mapnik stack.
osm2pgsql is a tool for importing data from OpenStreetMap database extracts into PostgreSQL. By default, it imports into Spherical Mercator (900913) and that is great if you want to build a web map tile server that serves tiles in Spherical Mercator projection. If however you want to use a custom projection to enhance the display of geometry in a specific region, you can import using a custom projection.
For this example I will use EPSG:3573, a projection that vastly improves visualization of geography in the Arctic. To do the import, you can modify your osm2pgsql import command to include a reprojection (-E
):
$ sudo docker run -d --name postgres-nunavut -P openfirmware/postgres-osm
// wait about 30 seconds for the container to be ready to use
$ mkdir ~/osm
$ cd ~/osm
$ wget http://download.geofabrik.de/north-america/canada/nunavut-latest.osm.pbf
$ sudo docker run -i -t --rm --link postgres-nunavut:pg -v ~/osm:/osm openfirmware/osm2pgsql -c 'osm2pgsql --create --slim --cache 2000 --number-processes 2 -E 3573 --database $PG_ENV_OSM_DB --username $PG_ENV_OSM_USER --host pg --port $PG_PORT_5432_TCP_PORT /osm/nunavut-latest.osm.pbf'
This will set up a PostgreSQL docker container that contains the OSM extract data for the Canadian territory of Nunavut. The geometry will be in EPSG:3573 projection.
The next step is to set up your Mapnik renderer to use that as the database. I am using a fork of openstreetmap-carto with TileMill and I can adjust the database settings in project.yaml
by changing the following:
osm2pgsql: &osm2pgsql
type: "postgis"
dbname: "gis"
key_field: ""
geometry_field: "way"
extent: "-20037508,-20037508,20037508,20037508"
to:
osm2pgsql: &osm2pgsql
type: "postgis"
host: "192.168.1.100"
port: "32000"
user: "osm"
dbname: "gis"
key_field: ""
geometry_field: "way"
extent: "-20037508,-20037508,20037508,20037508"
I change the host and port to point to the Docker container that is running PostgreSQL. The next step is to tell Mapnik that the OpenStreetMap data in the database is not in Spherical Mercator. Edit the same file and find the following:
extents84: &extents84
extent: *world
srs-name: "WGS84"
srs: "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
Change it to:
extents84: &extents84
extent: *world
srs-name: "WGS84"
srs: "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
extents3573: &extents3573
extent: *world
srs-name: "EPSG:3573"
srs: "+proj=laea +lat_0=90 +lon_0=-100 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
Then do a find and replace for "*extents" and replace it with "*extents3573" but only for the OSM layers — you can tell them apart from the shapefiles as they have "*osm2pgsql" as their datasource.
Now you should have a Mapnik ready to style OSM data in your custom projection.
Here is a preview of Nunavut data in TileMill with bathymetry data from NaturalEarth Data.