Writing a tile server in Python
grulic.org.ar
grulic.org.ar
Raster tiles get huge at level 12 onwards. For generic usage it is hard to take the entire planet and make it available in a way where any user can use the same file at any zoom level in any location. For me, vector would solve this in a much better way, as we have a lot more control over which features to include and what level of detail to have in specific areas to reduce the overall size of the data.
It's cross platform (Linux, OS X, Windows, and BSD) [1] and written in C++. There are bindings for Python/Node/C++.
There is also maplibre-native [2] (which suports Android and iOS as well as Linux/Windows/macOS).
Mapnik is usually used to pre-render raster tiles on a workstation or server. MapLibre Native is a native alternative to the MapLibre GL JS library (both forks of the no-longer open-source MapBox equivalents) for rendering vector tiles in the browser.
[0]: https://mapnik.org/
[1]: https://github.com/mapnik/mapnik/blob/master/INSTALL.md
We basically need a "tilesource" for XYZ PNG based tiles that is fed on the fly from vector tiles and is cross platform enough that it relies only on something like Skia.
The nuts and bolts of it boil down to writing a short program in C++ that accepts a few arguments and makes the relevant library calls, and is then called as an external program from my sorbet code. I guess you could PInvoke it but I’ve never got my head around that part of .Net :)
It’s cross-platformish _enough_ for me, as I dev on macos and host on Linux. Can’t think of any reason it wouldn’t compile on windows though.
The flexibility is rather good, and I created a DSL without realising that I was doing so by supplying one program variation with a list of map types, dimensions, starting coordinates + zoom levels etc, which it can iterate over to produce a bunch of static map images.
Highly recommend it, the initial learning curve was steep - for me, at least - but is all one-time learning stuff that you don’t to relearn later on.
Its worked out very well so far, but I'm working with time series that adds a new set of data every 5 minutes so I need the "on the fly" approach. After some heavy optimization it's become quite fast and often the generated tiles are returned before the base map layer is.
The upside is that it works with any map system that supports raster tiles, so any platform really.
It is so annoying that they don't give you a way to do this. I built an LLM inference API but am still working on how to cancel an inference job if a client cancels. I really don't want to rewrite my entire server in Twisted so I'll probably end up just building the HTTP responses like you did.
In any case, it was fun to think about this problem and learn things about the limitations of some of the async frameworks.