WIP: Initial implementation of Maplibre/vector tile rendering #332
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Addresses #272
I made an initial attempt to render vector tiles using the Open Street Map demos Shortbread and MapTiler MVT.
It is possible to do something with Mapnik. In particular, MVT or PBF files can be loaded, but the style files openstreetmap.org uses are in Maplibre JSON format. As far as i know, this can't be converted to Mapnik easily.
Instead i have drafted a version that uses Maplibre.
There's a bit of a snag that Maplibre seems to support Android and iOS more than desktop platforms. Prebuilt binaries of the core library are provided for e.g. Linux, but the documentation does not recommend directly coding with this API unless you are a Maplibre developer.
They do provide an example mbgl-render, but it needs headers that are not in the headers provided by the pre-built core.
My current solution is to add maplibre-native as a submodule.
Building
I am not good with Automake, so the current build process is not ideal and only works for Linux with OpenGL so far (there's a commented out version that will work with Vulkan in the Makefiles).
git submodule initthengit submodule update.maplibre-nativeand compile Maplibre Linux OpenGL core following the docs (you can buildmbgl-coreinstead ofmbgl-render).I have not put any flags in for controlling the build (e.g. selecting Windows or Linux or not using Maplibre at all). Instead i just bodged it in as best i could so that it compiles. This is something to work on if the general approach seems feasible.
Additions
I have added a new Maplibre Rendering layer based on the Mapnik layer. There are two main sets of files:
vikmaplibrelayerandmaplibre_interface. The interface follows the example Maplibre renderer.Adding a Layer in Viking
The arguments are:
The JSON file is the main thing that needs any effort. There are two examples being demoed on openstreetmap.org. I'm not sure what the legalities of using them are. Thunderforest also has one vector style file available.
https://vector.openstreetmap.orgbefore the URLs inglyphs,sprite, andtiles.https://api.maptiler.com/maps/openstreetmap/style.json?key=<my_api_key>into the JSON field when configuring the layer (but it will not save if it's a URL with a ?, see limitations). It's free to sign up, but the free API key will only get you OSM data from 2020. For up-to-date data, the subscription is $2,500 per year.https://api.thunderforest.com/styles/atlas/style.json?apikey=<my_api_key>directly into the JSON text field when configuring the layer (after substituting your API key).The JSON file requires sources of three types of data (these sources are defined inside the JSON itself):
.mbtilesfile with a URLmbtiles://<path to file>.glyphssection).spriteURL). It seems that things like@2x.pngare added to this URL to get the style sheets.To some extent you can try to mix and match different sources, but it doesn't always work out.
Limitations
The renderer cannot render multiple tiles on the same map at the same time. I have made a single-thread thread pool for it. Sometimes, with a badly configured JSON file, the renderer seems to hang, which stops all Maplibre Rendering layers from rendering.
Sometimes, i guess if text touches tile boundaries, it might get a bit clipped.
Only static libraries are compiled/provided by Maplibre. It adds about 140mb to the size of the Viking executable. An alternative approach might be to call out to
mbgl-render, but this means an external process loading the cache (and possibly large.mbtilesfile) for each tile.The rendered tiles are not cached on disk. Perhaps we don't want to.
The style file URLs can be entered directly when configuring the layer, but they have ?s in before the API key argument. Viking does not seem to like saving/reloading URLs with ?s in them, so erases the value during save/load. Is there a fix for this?
TODO
Lots, it's very rough. But off the top of my head.
Video
maplibre.mp4