One of the great things about the APRS system is that it can function in areas where the Internet doesn’t reach. But, with many APRS clients, even though you can receive the coordinates of various stations and objects, it can be difficult to visualize these items without the benefit of a map underneath. And so, the quest to use maps without Internet is born.
The most popular mapping systems today are those provided by Google, Apple, and OpenStreetMap. The way that most of these systems work is that there is are clusters of servers on the Internet that have large amounts of storage. The mapping data is pre-rendered into a series of tiled images at different zoom levels. As you pan and zoom around the map, your mapping application will fetch the appropriate tiles from the tileserver.
Of course, without an Internet connection, your mapping application cannot contact the tileservers in order fetch the tiles. This results in blank areas of the map. So how do we get these tiles when we’re offline?
Enter OpenStreetMap.
OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world.
The challenge is that the OSM project maintains its maps as a database of map elements; it’s not a set of images that can be displayed on screen. In fact, the OSM source data does not even specify what these mapping features, roads, waterways, etc, should look like; the OSM maps that we see on the web are the result of applying particular styling information.
What we need is a way to render the source OSM data into a set of tiles, but in a local manner, not relying on the online tiles. I had considered building this rendering functionality directly into QTH.app, but ultimately decided to keep it external to QTH.ap. This has a least a couple advantages: 1) The functionality can be changed without having to update QTH.app and 2) multiple QTH.app installations can potentially share a tileserver. More on that later.
The team over at Switch2OSM have developed a way to run the same tileserver technology found on the Internet on your local machine.
To do this, we’ll be using Docker Desktop. Docker is a technology that allows a packaged set of programs to run inside a “container”. This makes it easier to start, stop, and move around this container and keeps it separate from the rest of your machine.
I am going to assume that you are installing the tileserver on the same machine that your are running QTH.app, so the instructions are for macOS. Also, you will see several commands to run; these should be run in the Terminal.app
Setting up the Docker tileserver
-
- The first step is to install Docker Desktop for macOS.
- While Docker is running, there should be an icon that appears on your menu bar that allows you to view the dashboard and start and stop the Docker engine.
- Next, we will create a volume in Docker that will provide storage space for the database
-
docker volume create openstreetmap-data
-
- Make a directory to download the OSM data to. I chose to create a folder called “osm” in my home directory
-
mkdir ~/osm
-
- Download a subset of the OSM dataset in the “Protocolbuffer Binary Format” (PBF).
- You don’t have to download a subset, but be aware that the entire OSM dataset weighs in at over 50GB compressed. It will expand in size when loaded.
- Go to https://download.geofabrik.de and navigate to the area of the world that you would like maps for and download the corresponding “.osm.pbf”
- I live in Michigan, so I downloaded https://download.geofabrik.de/north-america/us/michigan-latest.osm.pbf
- Import the dataset into the Docker container’s database
-
docker run \ -v /Users/weston/osm/michigan-latest.osm.pbf:/data.osm.pbf \ -v openstreetmap-data:/var/lib/postgresql/12/main \ overv/openstreetmap-tile-server \ import
- Let’s break this command down:
- The
-v
parameters tells Docker to mount a volume, where the format is[location_on_the_host]:[location_inside_the_container]
- The first
-v
in the example mounts the .pbf file into the container. You will need to change the path to the .pbf file to reflect wherever you downloaded it. - The second
-v
in the example mounts theopenstreetmap-data
volume that was created earlier to the correct path for the PostgreSQL database inside the container. - The
overv/openstreetmap-tile-server
is the name of the Docker container to run. Docker will automatically download the container. If you would like more details on this container, go to https://github.com/Overv/openstreetmap-tile-server - The last part, specifies what command to run inside the container. In this case, we want to
import
the data. - This command will take several minutes to run, depending on the size of the dataset to import. When the import is complete, the container will terminate.
-
- Run the tileserver
-
-
docker run \ -p 8080:80 \ -v openstreetmap-data:/var/lib/postgresql/12/main \ -d overv/openstreetmap-tile-server \ run
-
- Again, breaking the command down:
- The
-p
parameter sets up a port mapping, where the format is[port_on_the_host]:[port_inside_the_container]
- The web server inside the Docker container will be running on port 80. On your machine, though, you will want to choose a different port, like 8080. Whatever port you choose, you will need to remember it for later.
- Again, the
-v
parameter mounts theopenstreetmap-data
volume for the database. - The
-d
parameter causes the container to detach from the terminal session and run in the background. - Same docker container as before
- The
run
command starts the programs necessary for running the tile server.
-
- Test it!
- Once the tileserver is up and running, go to http://localhost:8080/tile/0/0/0.png in your web browser and you should see a map image.
- The first step is to install Docker Desktop for macOS.
Connect QTH.app
- In QTH.app, go to
View
→New Layer
→Local Tile Server
- The URL Template should be
http://localhost:8080/tile/{z}/{x}/{y}.png
You should adjust the port number if you chose a different one above. - Click
Ok
- That’s it! You should now see the tiles start to appear in QTH.app
Advanced Configurations
In the above example, the tileserver is running on the same machine that is running QTH.app. However, this is not required; the tileserver can run on any other machine that is capable of running Docker and that your Mac can access.
- You could run the tileserver on a Raspberry Pi running Linux
- You could share the tileserver among several client machines
Of course, any time you separate QTH.app and the tileserver, there will need to at least be a TCP/IP connection between the two. An example scenario of where this might be desirable is you had a field operations center where you were running a search and rescue operation or a race and you wanted several workstations monitoring the situation with QTH.app. You could either have one of the Macs set up an ad-hoc WiFi network or use a wireless router. Keep in mind that if the tileserver is running somewhere else, you will need to change the ‘localhost’ in the URL Template to the appropriate hostname or IP address of the tileserver.
Good luck and happy mapping!
I’ve been using QTH for a few weeks now, having set it up with my Kenwood TH-D75 and a KISS over TCP/IP TNC on my home network. Really like the app and will be recommending it to my fellow MacOS hams.
I have a feature request. Can you add the ability to mass-delete messages or have them auto-delete after a set time period (say 24 hours)? I’ve been playing around with ANSRVR and seeing lots of messages come in (APRS Thursday net being the biggest source), and having them self-remove after being read or a manual deletion method similar to how iOS messages works would be a great addition.
Thanks for your hard work!