DEV Community

Cover image for How to build and serve custom simplified maps with OpenMapTiles
Noan for Zenika

Posted on

How to build and serve custom simplified maps with OpenMapTiles

If you need to display a map on your website and do not plan to use online mapping services such as MapTiler or Mapbox, you may want to use OpenMapTiles to generate and serve custom tiles. This approach is also useful when you are not interested in all the features a map can display.
In this tutorial, we will create a map featuring only water, such as coastlines, lakes and rivers.
This tutorial was tested on Ubuntu 24.04.

Prerequisites

  • Osmium: a tool used to process OpenStreetMap data.
  • The OpenMapTiles repository cloned on your computer.
  • Docker, to run the OpenMapTiles containers.
  • The build-essential package (to run the make command).

1. Download the source data

OpenStreetMap provides an up-to-date export of the entire planet.

Pay attention to the licenses of the tools and data used. For OpenStreetMap and OpenMapTiles, proper attribution must be displayed on your map, for example: © OpenMapTiles © OpenStreetMap contributors

The planet.osm.pbf file is about 85GB. This is very large and can take hours to process even you are when only interested in the water data. During development, it is recommended to use an extract from GeoFabrik covering a smaller region that you know well.
In my case, I used the file bretagne.osm.pbf and then the file france.osm.pbf. They can be processed in a few seconds or minutes.

A .osm.pbf file is a compressed format for OpenStreetMap data, if you decompress it with the command osmium cat <your-region>.osm.pbf --output <your-region>.osm you will find that the .osm file is an XML file listing nodes, ways, and polygons. The documentation for this format is available on the OpenStreetMap wiki

2. Extract the relevant data

Since we are only interested in water data, the process can be sped up by reducing the input file size. Let's filter out everything that is not related to water:

osmium tags-filter <your-region>.osm.pbf  rw/waterway rw/water -o water.osm.pbf
Enter fullscreen mode Exit fullscreen mode

3. Generate the vector tiles

At the root of the OpenMapTiles repository, edit the file openmaptiles.yaml to comment out all layers except those related to water:

tileset:
  layers:
    - layers/water/water.yaml
    - layers/waterway/waterway.yaml
    # All other layers are commented out
    # - layers/landcover/landcover.yaml
    # - layers/landuse/landuse.yaml
    # - layers/mountain_peak/mountain_peak.yaml
    # - layers/park/park.yaml
    # - layers/boundary/boundary.yaml
    # - layers/aeroway/aeroway.yaml
    # - layers/transportation/transportation.yaml
    # - layers/building/building.yaml
    # - layers/water_name/water_name.yaml
    # - layers/transportation_name/transportation_name.yaml
    # - layers/place/place.yaml
    # - layers/housenumber/housenumber.yaml
    # - layers/poi/poi.yaml
    # - layers/aerodrome_label/aerodrome_label.yaml
  name: OpenMapTiles
  version: 3.15.0
  id: openmaptiles
  description: "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org"
  ...
Enter fullscreen mode Exit fullscreen mode

Next, edit the .env file to specify the zoom levels to generate:

...
# Which zooms to generate with make generate-tiles-pg
MIN_ZOOM=0
MAX_ZOOM=10
...
Enter fullscreen mode Exit fullscreen mode

Move the water.osm.pbf you generated earlier into the data/ directory

mkdir openmaptiles/data/
mv water.osm.pbf openmaptiles/data/
Enter fullscreen mode Exit fullscreen mode

Now run OpenMapTiles to generate the tiles:

cd openmaptiles
./quickstart.sh water
Enter fullscreen mode Exit fullscreen mode

Under the hood, this process will:

  1. Populate a PostGIS database with map features. Note that the database already contains Natural Earth data for low zoom levels. At low zoom levels, coastlines in the resulting map will come frome Natural Earth data.
  2. Create views and functions in this database responsible for querying each layer for each zoom level.
  3. Query the PostGIS database to create a file named tiles.mbtiles. It is a SQLite database containing vector tile data for each (x, y, z) coordinate.

4. Serve the tiles

make start-tileserver
Enter fullscreen mode Exit fullscreen mode

And visit http://localhost:8080

Preview of the water map on localhost:8080

Or if you want to serve the tiles on a server without the whole OpenMapTiles project

# Make sure you have Node.js version 18.17.0 or later installed
npm install -g tileserver-gl
tileserver-gl --file tiles.mbtiles
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial, we have introduced techniques for generating simple vector maps: where to retrieve the data, how it can be filtered with Osmium, how OpenMapTiles processes it to generate vector tiles, and finally how tileserver-gl can serve them (although it is not production-ready on its own).

From here, you may then want to style your map with Maputnik, explore the user interactions provided by MapLibre, or dig deeper into the transformations performed by OpenMapTiles for each layer.

Top comments (0)