Az

Static File Webmap

Listen, one of the roadblocks to protecting your users' privacy is basemaps. You want a nice imagery layer, your users want a nice imagery layer, and you both want to protect each other’s privacy. The problem is you forgot to ask Old Father Google (or another provider with the same creepy attitude to your data) for some privacy and so he gets to sit in the corner, watching and breathing heavily while you both awkwardly do GIS while trying to ignore him. But thanks to the power of Open Data and Open Source you can make your own and stop giving away your users' data.

But in true open data and open source fashion:

  • It’s not really easy or accessible to the average user,
  • Can quickly get expensive,
  • And anything that goes wrong is your responsibility.

But that’s some of the common trade-offs when you’re dealing with open source software and hand-rolled solutions - the advantage to commercial stuff is that plug’n’play with some great tooling that only occasionally1 tends towards vendor lock-in. But if you’ve got some tech chops and want a satellite basemap you can keep reading because I’ll walk through creating a tiled, static file imagery basemap suitable to use with your choice of you GIS software.

Why Static File?

I run a lot of my own servers and services so I will always recommend the two reigning queens of open source spatial data servers (MapServer and GeoServer) but they do have the same fallibility as most GIS software: stonkingly high hardware requirements.

GIS operations can be computationally expensive if you’re trying to pull together a smaller zoomed-out tile from a massive GeoTIFF. And scanning through a large file - or multiple with a VRT - will smash your disk I/O. Of course, that can be ameliorated by using a GeoTIFF with internal tiling and pyramiding but at that point we’re just doing a tiled basemap with extra processing unless we also add a caching layer and then… Oh we’ve just recreated the static file system.2

The main reason I prefer this option is I can take advantage of cheap cloud static hosting (like I use for this blog[1][2]) so I’m also not having to smash my home internet upload bandwidth just so people can look at pretty satellite imagery on AzMaps (a division of ScorpInc).

Where Do I Get Data?

There’s a bunch of cool satellites in orbit that are capturing high resolution scans of the world on a regular basis. A few of the good’uns are below with resolution (how big a pixel is) and revisit time (frequency of new image, same spot):

These are pretty solid options for creating a high resolution static basemap - one that you don’t plan on changing very often.

If you want higher frequency images and aren’t too worried about clouds and can also build yourself a good update pipeline I’d look at older satellites rocking the MODIS or VIIRS sensors which have a coarser resolution (500m+) but can get you multiple images a day with a good source.

There’s a lot of places you can get data from - if you search for the satellite/sensor name and some form of “cloudless mosaic”/“download”/“data cube” you’ll find a bunch of options. I grabbed the ESA 2021 WorldCover Sentinel-1 and Sentinel-2 10m composite hosted on the AWS open data marketplace.

Now, you probably don’t want to download An Entire Mosaicâ„¢ if you value your hard drive space (for local processing) and the credit card attached to your cloud provider ($0.039 per gigabyte is cheap until it’s not). I drew a polygon in WGS84 over an area of the greatest state/province in the world and then grabbed the bounding box coordinates of it. Accessing the data cube with the AWS CLI you can find the folder structure starting here:

aws s3 ls s3://esa-worldcover-s2/rgbnir/2021/

You’ll find folders for each latitude, prefixed with N/S. In each folder you’ll find a GeoTIFF for each latitude/longitude like:

ESA_WorldCover_10m_2021_v200_S31E115_S2RGBNIR.tif

Using aws s3 sync and some smart file globbing you should be able to grab all the files you want for a particular area.

Each pixel is 10m!?

Yeah.

This means you won’t be able to pick out cars or people3 but this is one of the limitations of open source satellite imagery. Companies like Google and Esri can afford to pay for higher resolution satellite or aerial imagery. If you’ve got the dosh there’s a number of satellites that do 30cm to 1m resolution including tasks and regular interval but you’ll probably be on the hook for dealing with clouds, lighting, etc so plan in advance and maybe spare me a few bob if you’re throwing around that cash?

Measure once, cut once.

The next steps involve using our favourite open source spatial desktop suite, QGIS. Pull in all the rasters you downloaded and you might notice how some of the tiles have slightly different colouring to the rest and that’s because the default for QGIS is showing each raster in isolation rather than averaged against each other. To fix this we’ll build a VRT by going to Raster -> Miscellaneous - Build Virtual Raster. Here, make sure you select all the layers for input and export it to a VRT.

Open a new QGIS project with just the VRT layer and open the processing toolbox (Processing -> Toolbox) and type XYZ into the search box. Under “Raster tools” we’ll want Generate XYZ Tiles (Directory). Double click on that, set the extent to the VRT layer and then change all the options appropriate to you. You might need to play a bit with the minimum and maximum zoom levels depending on how big the extent of your area is as well as how detailed. Smaller numbers are a coarser view up until you’re zoomed out looking at the whole world, higher numbers are finer detail and maybe looking at individual hairs on an ants leg so you need to take into account your base image resolution4 and how long it will to take to process and how much space the result takes up. The example I’ll use below has zoom levels 9 to 16.

Depending on what framework you’ll be using to display the data I’d usually recommend PNG, allow transparency (so leave the optional background colour). Make sure you create an output directory for it and for sanity checking create the output HTML file before running the process.

Then grab a coffee or appropriate energy drink and wait.

Completed!

Cool. Now you can serve those files on a webserver or upload them to some form of static hosting and Bob’s your uncle.

You’ve now got a satellite imagery basemap without clouds and adjusted for daytime and colour and most of all it’s privacy preserving because you’re not required to load any JS bundles or tiles from a 3rd party who cares more about your users as a product than real people.5

Want to know what it looks like? Check out this demo below:


  1. Always. ↩︎

  2. Even if QGIS or ArcGIS Pro can can render a view in a couple of seconds when you’re looking at a massive GeoTIFF, the end result will suck if twenty (20) people are visiting your site at the same time and all trying to grab a bunch of tiles. ↩︎

  3. ‘cept ya mum. ↩︎

  4. No, if you get 10m imagery and then choose a really fine resolution it won’t make it more detailed. Like any “AI upscaling” it’s not revealing anything new it’s just making shit up. ↩︎

  5. I don’t view you as users or products tbh. More of like a delectable snack? By the way I love what you’re doing with your hair, you should come spend a weekend at my remote mountain castle. You’re welcome to bring any friends who are O+ and have low bio-accumulation of heavy metals in their blood. ↩︎