Wasm Labs

Deploy your Maps service with Protomaps and Wasm Workers Server

By Angel M Miguel
At 2023 / 03 15 mins reading
A screenshot of a browser showing a map. The URL is localhost, showing that the project is running locally

Maps are a frequent resource in websites and applications. You may need to display a location on your site or allow people to interact with maps.

You need a service that provides the maps' metadata to integrate a map into your application, such as Google Maps or Felt. These services are typically offered through APIs that often have a free tier but will can also increase your costs drastically when the popularity of your application grows. Self-hosting is an alternative to using these third-party services.

In this article you will learn how to host your own maps service API at a fraction of the cost with Protomaps and Wasm Workers Server. We also showed this project in the Wasm I/O 2023 conference in Barcelona. In that talk we also introduced Wasm Workers Server main concepts. If you are interested, you can watch the recording on YouTube.

What is Protomaps?

From the Protomaps site:

Protomaps is a serverless system for planet-scale maps.

An alternative to map APIs at 1% the cost, via single static files on your own cloud storage.

The Protomaps project is composed of two parts:

  • The PMtiles open specification is an efficient format to store map metadata in a single file. You can store any map into a single .pmtiles file and query the information.
  • An open-source set of libraries to interact with this format: you can read, query, write and convert others formats to .pmtiles. These libraries are available in different languages like JavaScript and Python.

The combination of an efficient single-file format and the available libraries make this project suitable for hosting as a serverless app. With Wasm Workers Server, you can run it in 3 commands.

Running Protomaps with Wasm Workers Server

To run Protomaps with Wasm Workers Server, follow these steps:

  1. Download Wasm Workers Server:

    curl -fsSL https://workers.wasmlabs.dev/install | bash
  2. Clone the project repository and change your directory to examples/protomaps:

    git clone --depth=1 https://github.com/vmware-labs/wasm-workers-server && \
    cd wasm-workers-server/examples/protomaps
  3. Setup and run wws with Make (using a pre-downloaded map in ./_maps):

    make all
  4. Access your map at http://localhost:8080

This example shows a map of the beautiful Inverness, a city in the Scottish Highlands. We generated it using the Protomaps "Small map" tool.

You can create a different map or download the planet-scale example map (2.62Gb). Just make sure that the MAP_FILE variable in [z]/[x]/[y]/index.toml below points to the correct file name. You can use the make planet command to download that map and run wws directly.

The site you see comes from the public/index.html file. It uses the Leaflet and the Protomaps client libraries. We included it to showcase the final result, although you can remove the file and use only the API.

How does it work?

All the API requests from the map client access the /Z/X/Y URL, where X, Y, and Z represent the location. The ./[z]/[x]/[y]/index.py file is the worker that processes the request and returns the map metadata.

This worker uses the Reader and the Tile utilities from the PMtiles Python libraries. For every request, the worker loads the file in the _maps folder, fetches the metadata, and returns it.

To mount the folders, we are using the Mount folders feature from Wasm Workers Server v1.1.0. This feature allows you to mount folders in the workers' configuration.

This is the [z]/[x]/[y]/index.toml configuration file:

version = "1"

MAP_FILE = "map"

from = "../../../_libs"
to = "/src/libs"

from = "../../../_maps"
to = "/src/maps"

As you can see, the worker also mounts the _libs folder to access the shared libraries.

Read more information about all the Wasm Workers Server features in the documentation.

Hosting your maps server

You can host Wasm Workers Server in many different ways. You only need the wws server and the project files. You can reproduce the same installation steps in any remote server you manage. For example, on Digital Ocean, Amazon Web Services, or a traditional dedicated server.

For convenience, we also added a Dockerfile to the project. It's a minimal container that only includes wws and the project files. By default, the Dockerfile downloads the Protomaps planet-scale example map, so you may want to edit it if you need a different map.

You can host that container image in any Kubernetes deployment or platforms like Fly, Render, and Railway.

Maps for everyone

Thanks to Protomaps, now you can run your serverless maps service API. With Wasm Workers Server, you have the flexibility to run it anywhere. Just add the map you need and deploy it to your preferred platform.

What's your next project? Feel free to share your ideas with us on Twitter and GitHub. If you liked this project, come to our repo and give us a ⭐️

Do you want to stay up to date with WebAssembly and our projects?