Monday, October 20, 2014

Dark Sky & Progressive Loading

There's a new Dark Sky for iOS out.  If you're interested in weather apps, I suggest checking it out.

Terrible weather is pretty!

Forecast.io is one of my favorite clients (translation: They pay on time), but whenever they ask for something it's going to be hard.  This was no exception.

Tile Loading


Dark Sky has a ton of custom logic in it, not to mention all the custom data they feed it.  But large parts are using standard WhirlyGlobe-Maply.  The tile loading logic, for instance, is all in there.

Let's review.  For the globe, we start loading at level 0 and work our way down.

I will reuse this at least 5 more times.

The app does something funkier when you're zoomed in, but let's ignore that.  This approach works well for the globe, but for one problem:  Animation means frames.

So let's say you're loading 20 frames of animation to show the weather changing over the course of a day.  That means you have to load each tile 20 times.  Sure, you can do it in parallel... but still.  It takes a while.

Progressive Tile Loading


Adam at Forecast.io wanted something better.  "Couldn't we load individual frames" he said?  "Sure", I said.  "Just let me renew my Xanax prescription and we'll give it a try."

And now WG-Maply can load frames progressively.  That means it'll start at your most important frame and work its way outward.  It'll load depth first, so that first frame looks good everywhere and then work outward to the less important frames.

You can set the frame priorities yourself, change them on the fly, and get feedback on what is properly loaded.  When the user moves, we start loading at the most important frame again, then work on the others.

That Sounds... Complicated


Why yes, voice in my head that may never, ever go away, it is complicated!  It's not all that hard to use, though.  You provide your tile sources as normal and let the loader do its thing.  If you want to tell the user what's going on, there's a callback for that.

Weather apps are the most obvious users here, but anything with animation is fair game.  I'd love to see some data visualization apps using this feature.

5 comments:

  1. This is fantastic! But it's not clear to me how I can take advantage of this progressive loading feature.

    I have a MaplyQuadImageTilesLayer initialized with an instance of MaplyMultiplexTileSource, Every tile source in the MaplyMultiplexTileSource instance is a MaplyRemoteTileInfo. I have a vector of potentially more than 100 tile sources to multiplex and show in an animation and this progressive loading strategy is exactly what I need. Would you be so kind to explain how to activate this?

    Thank you very much for your work on this fantastic toolkit.

    ReplyDelete
    Replies
    1. First off, 100 is probably going to be too many unless you have very few levels. You'll also want to cut them down to their very simplest by using a 16 bit or, better yet, 8 bit layer with lookup. Granted, that can be complicated.

      But first, to just get it working, take a look at TestViewController.m in the WhirlyGlobeComponentTester around line 1315 (develop branch).

      There's the external source setup, which you've done. But then there's the precipLayer setup itself. At the very least you'll need to set imageDepth and animationPeriod.

      Delete
    2. Thank you very much for your reply.

      I looked at the code in TestViewController.m and it really looks like
      mine: an NSArray of MaplyRemoteTileInfo objects feeded as a tileSource
      to a MaplyMultiplexTileSource object, then a MaplyQuadImageTilesLayer
      initialized with the MaplyMultiplexTileSource and configured with the
      appropriate imageDepth and animationPeriod values.

      What I'm not able to do is to activate the progressive frame loading
      functionality, set the most important frame, change priorities and get
      feedback on frame loading.

      It seems to me that loading multiple layers the way they are loaded for
      the percipLayer in TestViewcontroller.m, does not activate this
      progressive loading feature. My first frame is still displayed only
      after all the tiles for each frame are loaded.

      Maybe I'm missing something big here.

      Any help would be greatly appreciated.

      Thank you again,
      Andrea.

      Delete
    3. Ah, the progressive loading! I was worried about your frames loading at all. Sounds like they are.

      In MaplyQuadImageTilesLayer look for setFrameLoadingPriority:
      That takes an NSArray of NSNumbers. To simulate the current order, but with frame loading enabled, just fill it with 0,1,2,....

      For further questions, we might want to move to a Github Issue. Other users who have messed with this might have some feedback.

      Delete
    4. Many thanks for your reply.
      I'll play with setFramLoadingPriority and see what I can do.

      See you on github :-)

      Thank you again!

      Delete