Example: Antarctica Map
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.
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 = object.tags.place
if check_place(place) then
tables.places:insert({
tags = object.tags,
place = place,
name = object.tags.name,
geom = object:as_point()
})
end
end
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() })
end
if object.tags['glacier:edge'] == 'grounding_line' then
tables.ice_shelves:insert({ geom = object:as_linestring() })
end
end