Friday, September 13, 2013

Vectors, OpenStreetMap, and Maply

A few months ago I gave a talk at the OpenStreetMap conference in San Francisco.  It was all about using vector tiles for map display on iOS.

Not San Francisco
This was based on new functionality in Maply, the 2D part of WhirlyGlobe-Maply.  Since then I've improved things.

Vector Support in Maply

I've had support for vector data in WhirlyGlobe since 1.0.  With version 2.2 it's gotten much better, specifically for map display.  The important bit was the MaplyQuadPagingLayer and the MaplyPagingDelegate protocol.

It works like this.  You provide an object that supports the MaplyPagingDelegate protocol, start up a MaplyQuadPagingLayer and wait for the callbacks.  When it's time to load a tile, you load your data, convert it to a displayable form and then hand it over.  The system cleans it up for you when it's no longer needed.

Now we can treat vector data like we do image tiles.  If only we had a good data source...

OSM Vectors

A few months ago OpenStreetMap began providing vector data tiles experimentally.  Mike Migurski was the driving force behind it, and he explains it better than I.

Tasteful buildings
The short of it is, we've got vector data chopped up into individual tiles, with some basic cartographic choices made at the various levels.  The server responds much like an image tile server, but it returns GeoJSON.

That's great, but how well does it all work?

Base Map + Vector Overlay

There are two sorts of vector maps we might want to display with Maply.  The first is comprised of vector data overlaid on an image base map.

That's the easier case.  It's a subset of the full vector features, including roads, labels, and buildings.  More importantly, the polygons are fairly simple.  Which leads to the next question:  How about everything?

Pure Vector Map

An entirely vector based map is the goal, at least from a technical standpoint.  With pure vector on one end and pure image on the other, we'd like to dial in the appropriate mix for a given app.  The OSM data is there, so how well does it work?

It works well.  Quite well indeed.  That's the big innovation from a few months ago:  WhirlyGlobe-Maply 2.2 can handle the weird polygons it gets from the server.  The tessellation is working well even for complex polygons with holes.

Room For Improvement

Nothing's perfect, of course; that would be creepy.  There are a few areas that could be better, in no particular order, they are:

  • Parsing GeoJSON is just slow.  It needs to be faster.
  • A binary vector data cache would make things appear much faster.  For some cases it would be a big improvement.
  • The vector data is coming in tiny little chunks.  This is messing with the drawing optimization.  There are ways to fix this.
  • Place names are dominating the display in cities.  For a real app, I'd suggest making some cartographic choices.
  • It needs more styles.  I've broken out a few of the feature types, but more is better.

Even so, this is usable as is.  Go check out the code, all open source, and give it a try.

What's Next

I build out serious toolkit functionality with serious apps.  On the WhirlyGlobe side I've had some great clients who did some really ambitious things.  There's been some interest on the Maply side, but so far nothing really big.  The toolkit is ready (more than ready) so as soon as I reel those clients in, we should have some interesting results.

In the mean time Maply vectors are pretty stable.  Go give the OSM example a look and feel free to use it in your own apps.


  1. Hi, I tried to build the OSM example, but it uses some classes whose definitions I can't find. For example, I searched for MaplyRemoteTileSource in the WhirlyGlobe repo and found no results. In the osmmobilevectors repo, I only found two results where an object of that class is constructed.

  2. Whoops. The library was out of sync. It's updated to use the right version of WhirlyGlobe-Maply.

    You may need to do another submodule init and update.

  3. Hi, sorry for off topic but dont found info about my question:
    I want add local 2d map for some part of city how I understood for that I need set coordinates (top left and bot right) but I dont found how I can do it

    1. If you're using the MaplyViewController you can call:

      There's a similar routine for the WhirlyGlobeViewController.

    2. Thanks, How I can set pvrt files to flat Map? If I can use only mbtiles can you provide some little instruction for it. (I try use map box but there all world but i need some part of city)

    3. Well the first question is what format your base tiles are in. You have to generate a map that covers a given set of extents and chop it up into little images.

    4. I have pvrt tilec (I was use image chopper) but I cannot found method for 2d map like addSphericalEarthLayerWithImageSet

    5. This comment has been removed by the author.

  4. Hm I found interesting bug when I export mbtiles from TilleMill with zoom 1-18 all good, but if I export 16-18 zoom then map doesnt appear and after some time I get crash
    WhirlyGlobeComponentTester(371,0xb0219000) malloc: *** mach_vm_map(size=1048576) failed (error code=3)
    *** error: can't allocate region

    1. I'll be happy to track that down. Can you move this over to github:

      And get me access to the mbtiles archive?