Skip to main content

Example: Antarctica Map

Map of McMurdo Sound in Antarctica

You need at least osm2pgsql version 1.7.0 for this example.

Typical maps on the web these days use the Mercator projection. And osm2pgsql uses that as the default projection, too. But osm2pgsql can handle basically any projection out there. It does this by leveraging the capabilities of the PROJ library. (Osm2pgsql must be compiled with PROJ support for this to work. This should be the case for most versions of osm2pgsql you encounter.)

In this example we’ll use an Antarctic polar stereographic projection (EPSG 3031), a special projection suitable for showing Antarctica.

Getting and Preparing the Data

Getting the data needed is easy, because Geofabrik offers an Antarctica extract for download: antarctica-latest.osm.pbf

Running Osm2pgsql

OpenStreetMap contains data about coastlines, ice shelf boundaries as well as research stations and other details in Antarctica. We use this here for a rough outline of the continent and some red dots where stations and other important features are. (See the OSM wiki for more information about special tags for Antarctica.)

As usual with OSM, the tagging is a bit inconsistent, some stations are tagged with place=hamlet or place=town, others as place=locality. But some glaciers are also tagged place=locality. This is certainly something that could be improved in OSM data as well as the osm2pgsql config script, but for our purposes here, this should be good enough.

Here is the style config. Note the projection = 3031 option on all the tables we define.

Download Lua config
local tables = {}

tables.places = osm2pgsql.define_node_table('places', {
    { column = 'tags', type = 'jsonb' },
    { column = 'place', type = 'text' },
    { column = 'name', type = 'text' },
    { column = 'geom', type = 'point', projection = 3031 },

tables.coastlines = osm2pgsql.define_way_table('coastlines', {
    { column = 'geom', type = 'linestring', projection = 3031 },

tables.ice_shelves = osm2pgsql.define_way_table('ice_shelves', {
    { column = 'geom', type = 'linestring', projection = 3031 },

-- These are the value of the "place" tag we are interested in.
local check_place = osm2pgsql.make_check_values_func({ 'hamlet', 'isolated_dwelling', 'locality', 'town', 'village' })

function osm2pgsql.process_node(object)
    local place =

    if check_place(place) then
            tags = object.tags,
            place = place,
            name =,
            geom = object:as_point()

function osm2pgsql.process_way(object)
    -- For historical reasons OSM has ways tagged "natural=coastline" inside
    -- Antarctica that are not coastlines. Those have the additional tag
    -- "coastline=bogus", which allows us to make an exception for them.
    if object.tags.natural == 'coastline' and object.tags.coastline ~= 'bogus' then
        tables.coastlines:insert({ geom = object:as_linestring() })
    if object.tags['glacier:edge'] == 'grounding_line' then
        tables.ice_shelves:insert({ geom = object:as_linestring() })

Map of Antarctica with stations