Tuesday, 5 May 2015

Client side rendering of our map using MapCSS!

We want to support an offline mode in GNOME Maps. A mode where you could download an area and have the map data available even if you do not have an Internet connection. The problem is that we are currently using pre-rendered bitmaps. We download them and we show them. This makes supporting an offline mode a bit tough since the amount of data we would have to save would be large.

We have talked off and on about how neat it would be if we could download some kind of vector data and render the map ourselves. But never really made any progress. Until now, kind of.

I have been working on a library that I call Vector-tile-glib. This library will parse and render the Mapbox Vector tile format, and style it using MapCSS. I have hacked a bit on evenings and other spare times when my son has been asleep. It has been fun. It is not done, nor stable. But it has reached a point where I want to tell more people about it and maybe even get some help. There is much left to do, and many many rough edges.

So what I have now is pretty much something that parses the vector tile and can output something to a Cairo context using MapCSS. Or in pictures:



In order to try it out I have also written a subclass of a Champlain renderer in Maps so we can try this library out in real time. The work is on a branch on the GNOME Maps git repository  called wip/jonasdn/vector-tiles, try it out!
Andreas Nilsson and Marcus Lundblad have been helping me out with an initial style. Join them!

For you to try this, build Maps from the wip branch, then choose the aerial view to get the client side rendered map. Like in the video below:

You can also try out live editing the MapCSS, like in this video:

There are also tools to use in the vector-tile-glib repo, for rendering to PNG, dumping tags from a vector tile and downloading tiles from Mapzen tile service. See the Github README.md for more details on them.

I think this could be something cool to have. Partly for providing a path towards offline Maps and partly to have a map style of our GNOME. Help is appreciated! I am not a parser person or a render person, so I am sure I have made a bunch of really silly mistakes. Pointing them out would be helpful!


  1. That is awesome progress jonas! Looking forward to try this out (:

    I'd be super excited If you make it possible to save as PNG, My phone has no internet connection so I usually just load pictures of maps on it with directions when before I go on a trip and such. d:

    1. Thanks!

      I think your use case would be better solved with being able to print a route? So you could print it to PDF maybe?


      Hopefully we can get that in during the 3.18 cycle.

  2. This is very cool. I am looking for a tool to export maps in a higher resolution then the displayed one for integrating them to photo books. Afaik at the moment no such tool exists.
    I would really like to have a Button in GNOME Maps to Export the map as PNG with entering the DPI, and perhaps a save as SVG, if it is possible.

    1. Thanks!

      This would be possible, but you could also do it sort of yourself using the tools in vector-tile-glib, or writing a small tool that would do it, if you specify more what it is you want on Github or in a mail to me, we could see what we can do!

    2. The vector-tiles comes with a "resolution" of 4096x4096 pixels per tile, in the videos and pictures in this post they are scaled down to 256x256.

  3. This comment has been removed by the author.

  4. Incredibly awesome to see this!

    Some questions:
    Did you use mapbox-gl? Or was it not possible because of license issues?

    I am wondering if progressive rendering would enhance the user experience (ie. first render streets, than buildings). I noticed that streetnames are rendered first.

    Also I am thinking it might be beneficial to add an abstraction to GTK, something like a InteractiveCanvas implementation which implements all the pan and zoom stuff and just calls a render function.

    It could also be used by programs such as evince or gnome photos.

    The main functions would be caching and prerendering of tiles. I think it would be cool to have a zoom function that scales the previous tile(s) first and then waits for the rerender instead of showing a blank tile and wait.

    - Wolf

    1. Hi,

      No I do not use mapbox-gl. Maybe I should've. But I couldn't really get it to build. And it was all C++ and I couldn't really grok it easily. I do not have any time in my life to sit and stare att stuff for a long time.

      I couldn't really see how to package/wrap/fit the mapbox-gl code into a GNOME:y infrastructure. So it is pretty much written from scratch... sorry.

      There is a Map widget, libchamplain, that we use in GNOME Maps. It is also used in GNOME Contacts to show a map for contacts with an address. And I have written a champlain renderer (see the Maps wip-branch) that "just calls a render function" pretty much. Champlain also does caching. No pre-rendering tho.

      Progressive rendering... maybe.

      The text is pretty much a hack. They are not rendered as part of the rest. Since the renderer right now only operates on one tile. And text does not respect tile-boundries :) So the texts are added after by the Champlain-renderer. The fact that they appear before is because I havent't made that layer obey Champlains trix of fading the tiles in, I think.

      Thanks for your comments!

    2. I don't know if it would've been a good idea to use mapbox ... I think it's incredible what you've been able to achieve in what little code, proves the power of the toolkit I guess.

      I like the fact that libchamplain exists and I knew it (despite never having used it). But it feels slower and less responsive than even rendering the map on osm.org with leaflet.js... Are tiles not downloaded in parallel?

      Maybe it would be a good idea to isolate the parts that do the 2D canvas rendering from libchamplain and try to improve the user experience there. I for one am a guy who is all for aggressive caching and prefetching :) I would love to have your thoughts on that and if it would be useful or duplication?

      I am sorry if my comments come out as negative but I actually love gnome maps! :)



    3. I agree about libchamplain, it will need some love and attention in order to bring it up to what we would want for a smooth and fast Maps app. It is an awesome library, and I love it. But I agree with you. And I think Jiri, the maintainer does as well.

      I think the tiles are not loaded in parallel.

      The problem, as always, is developer bandwidth. But maybe when GSK arrives we can take a stab at writing something that fills the need for Maps, and maybe, yes, isolate a 2D canvas thingie.