Generate XYZ Tiles in QGIS and Serve on the Internet

Tommy
4 min readMay 4, 2022

Previously I mentioned the performance bottleneck in leaflet.js imageOverlay. So I had georeferenced the images and, in this article I will show how to generate map tiles from QGIS and serve the files on internet.

What is XYZ Tiles?

According to Wikipedia — Tiled web map, tile map is a map displayed in a web browser by seamlessly joining dozens of individually requested image or vector data files.

For my loose description… just imagine you are infeasible to download the whole world map into your browser when you are using the map, the size is large, and a lot burden to the internet traffic. XYZ tile map is to divide the map into pieces (x,y for 2D coordinates, z for zoom level). When you are zooming and panning the map, the map library will calculate which tiles you actually need, so that no unnecessary map images requests to the map server.

HK Government XYZ Tile API

HK LandsD Topographic Map API website

In HK Geodata Store, there are plenty of free open data and APIs. LandsD provides map API for FREE! (In UK, many data is not free) The above screen capture shows how the image files of XYZ tile organized in URL. (intuitively it is in directory structure right?)

Export XYZ Tiles in QGIS

Basically you can follow the above video to complete the export. Make sure you have unchecked (i.e. hide) basemap and other unintended files in QGIS before export.

In my case, I choose zoom level 12–20 and manual select minimum extent that includes my images, customize output directory, while other parameters remain default. When you are tuning the parameters, make sure you know how these parameters affect the processing time / file size / image quality.

After I select the parameters and click “Run”, a Python error prompted. (I don’t know why.) Then I choose batch processing with the same parameters, it works!

Batch Processing for generate XYZ Tiles in directory

Testing map tiles before upload to server

Apart from writing JS code for leaflet.js, you may use QGIS to view the map tiles generated. You may follow the below video to add your XYZ tiles.

My XYZ Tiles Connection Configuration in QGIS (for testing)

If you are not familiar with local server settings, you may use Python. Two lines of code can start the server conveniently.

cd /your/tile/directory
python -m http.server
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
Testing server for images map tile success!

Deploy the map tiles on internet

If you want to deploy the map tiles on internet, you may set-up server yourself like nginx / apache. Cloud service like AWS / GCP / Azure is also worth for consideration, but you must clearly understand how the pricing is. Map tiles requests produce massive and frequent network requests. It may charges you a lot if you configure wrongly.

Most of the cloud platforms provide AWS-S3 like storage services, while your map tile files are “static” (read is more frequent than write/change), using CDN (content delivery network) to serve the files in storage bucket would be a good choice, it’s faster and cheaper.

I would use DigitalOcean (DO) to serve my files because I’m using it already (no need to pay more as it is paid lol), it is much cheaper than other providers, USD $5 for 250GB storage per month, and CDN service is free. AWS pay-as-you-go model may be somehow cheaper / more expensive, while DO $5 per month is a safe deal for me, no need to worry for potential terrible bills.

(The data centre region of the bucket storage does matter, it will affect the traveling time of the files (and user-experience). I am using Singapore data centre because my target users are mainly from Hong Kong.)

Interface of DO Spaces is user-friendly, simply drag-and-drop the files to the browser can upload the files, but for massive map tiles files, I failed to do so. So I use command line (s3cmd, the user guide is well-written) to complete the upload.

s3cmd put * s3://your-bucket/directory/ --recursive --acl-public# Remember set the files to be public

(After upload, remember to use CDN url instead of bucket url.)

My files are 141.3 MB / 37344 items, takes more than an hour for the upload, so make sure the images files are correct before upload~

Handling 404 Error

If you move the map outside the bounds of the map tiles, the map will still request the corresponding map tiles to the map server, and of course the server will return “404 not found”. One of the solutions is restriction to the bounds (in leaflet if you use leaflet) in map, that means user cannot move outside the bounds.

Another possible solution is return default file (blank png) if 404, so the map can still get a blank image back. When I was using GCP storage, it provides similar function, but DO seems not available for this feature.

--

--