Thursday, March 7, 2019

WhirlyGlobe-Maply 3.0 Status Report #2

I'm two months into the 3.0 effort.  It's going well!

I covered all of this last time, but here's the plan.  We have an Android version and an iOS version.  The iOS version is always better and it's been hard to update the Android version.  To fix this, I need a unified C++ core used on both platforms.

So the first step was a separate C++ core on iOS.  And it's done!

The Port No One Wants


The newly merged C++ core is the Port No One Wants on iOS.  It does nothing new and it's buggy. But it's an important step on the way to a unified toolkit.  And there are bug fixes from Android that can benefit iOS, even it mostly goes the other way.

The big news is it works!  WhirlyGlobe-Maply 3.0 for iOS is now 50% common C++ core.  I was hoping for more, but damn those Mapbox style parsers are wordy.  And I want to leave that in ObjC so users can modify it themselves.

It wasn't all C++ core, though.  I've moved the QuadPaging logic, what you use to load things other than images, over to the new Sampler/Loader architecture.  Man, that fixes a lot of problems.

To Android and Beyond!


Now I'm working on the Android version.  The common C++ core compiled easily and it's on to the JNI interface.  If you're not familiar, this is the C++ interface to Java and it is pretty "meh".

I'm slogging through that logic now and it's slow going.  Thankfully Android Studio has gotten better with native code.  But honestly, it was a pretty low bar.

The goal is feature parity between the platforms and I think we'll get pretty close.

Unwinding Technical Debt


You accrete a bunch of technical debt in 8 years (!) and now is the time to clean it up.  Here's a very boring list of some of it.

  • MaplyShader and the low level OpenGL ES programs now unified into one representation.
  • Texture loading for tiles now consolidated in one object which works in one place.
  • Elevation callbacks removed to be replaced with something more logical.
  • The entire RemoteSource infrastructure removed in favor of something simpler and more flexible.  Yeah, this will cause problems.  See the next section.
  • Cut the AutoTester app back to just the essentials.  Much easier for users to read.
  • Got rid of the DynamicDrawableAtlas.  Android never liked it.
  • Gestures now live at the Component level with no duplicates lower down.
  • ActiveModels only exist at one level in the toolkit.
  • Generators are now gone, replaced with ActiveModels where needed.
  • Component Objects are now a concept in the core toolkit, not just the high level.
  • Paging controllers handle arbitrary visual objects as well as images.  Really nice for vector maps.
  • Rather than passing around View objects, we use ViewState objects.  Fixes some threading problems.
  • Managers no longer being fetched by string.  Not sure why I never did that.
  • More logic moved into the BaseInfo descriptors.  Render target, that sort of thing.
  • Moved locking logic over to C++11 constructs.  Much cleaner.
  • Passing around references to CoordSystems, fixing a few recurrent shutdown problems.
  • Moved vector subdivision logic into a unified module.
You read this far?  Weirdo.

There was a lot of trivia to clean up in 8 years.  Now it all kind of makes sense.  Except OpenGL ES.  I'll be reorganizing that when I get to Metal.


(Not Going To) Sunset Version 2.6


I'm breaking things in Version 3.0.  The new version will work better, but it won't be 100% compatible with 2.6. 

The big issue is the move from the QuadImages and QuadPaging layers to the new Sampler/Loader approach.  I'll cover that more in its own blog post (with pictures!) but for now let's just say it's better and I'm not going to make it backward compatible.

In that spirit, I'm going to continue supporting 2.6 for both iOS and Android into the future.  This will include bug fixes and updates for new platform versions.

Android, Android, and more Android


The next few weeks is all about Android.  I'll continue hooking up C++ through JNI to the existing Java.  Then I'll start on the new interfaces and loading logic that Android never had.

Lastly, it's on to testing and feature parity.  I honestly forget what's in the Android version and I'm kind of excited to have a full feature spreadsheet comparing the two.

Monday, February 4, 2019

WhirlyGlobe-Maply 3.0 Status Report

The 3.0 effort's been going all month.  So how are things?

Things are boring.  Boring, but good.

Collateralized Technical Debt Obligations


The Android port of the toolkit was supposed to share C++ code with the iOS version.  It never really did.  This is the fundamental problem between iOS and Android.  It hurts the Android version and it's holding back other ports.

On Android we have a hard line between Java and C++ (JNI).  When I ported things the first time, I made a copy for Android and then hacked as needed.  Naturally, the versions diverged between platforms.

I've merged the C++ cores back together and introduced that hard line between Obj-C and C++ on iOS.  This should let me fix bugs for both platforms at the same time.  I'm excited.  In a boring way.

The Port No One Wants


All of this gives me an iOS version based on a solid C++ core.  No new functionality, not going to be faster or slower.  And it's going to have bugs for a while.

Which is to say, it's not a port anyone's excited about, but it's vital.  Once that's done, I get back to the good stuff.

Good Stuff Part I


Android's behind on new functionality.  The whole Sample/Loader approach, which is working so well in 2.6, is only on iOS.  Before I port it, I need to clean up some old things (QuadPagingLayer), remove stuff I've replaced (QuadImagesLayer) and make sure those deprecations can be supported.

That's more fun than it sounds, I swear.  The QuadPagingLayer is used for loading all sorts of data objects and its replacement, based on the new Sampler/Loader, will fix a host of problems.

On the more exciting front, there's elevation support.  It's always been a mess on iOS and never worked on Android.  It'll be fun to fix that definitively.

Other good stuff will follow, including but not limited to, Metal for iOS.

Friday, January 11, 2019

Saildrone Forecast

Is there anything cooler than shipping an app you've spent a year and a half working on?
It was a rhetorical question.  There is not.


Saildrone Forecast

Hint: It's a weather app.

Saildrone Forecast


Yup, Saildrone Forecast is a weather app.  Just watch the video.


Go download it.  I'll wait.

Technical Bits


There's a ton of stuff in Saildrone Forecast that's unique.  But there are a couple bits of interest in WhirlyGlobe-Maply itself, like the new sampler/loader architecture and offscreen render targets.  Go watch the video.



Could you make your own weather app out of the box now?  Ha ha.  Oh god no.  There's so much other stuff to do.  Not to mention the data.  But there are cool things to do with the vector maps and render targets.

Acknowledgements


I didn't do this all alone.  Heck, I didn't even write the whole app. 

Credit goes to Logical Animal for the rest of the UI.  Big thanks to the meteorology/modeling team at Saildrone for the data and putting up with stupid questions.  Thanks to the platform developers and ops for processing data and keeping it running.  And, of course, management and finance upon whom I can bestow the greatest contracting honor:  They always pay early.

Wednesday, December 19, 2018

Technical Advisory Committee

I'm forming a technical advisory committee.  We'll meet a few times and discuss the iOS Metal port and rendering architecture in the toolkit.

This post is for developers I'm trying to recruit to the committee.  Let's start with the basics.

What is WhirlyGlobe-Maply?

National Geographic World Atlas (RIP)
WhirlyGlobe-Maply is a real time geospatial display toolkit for iOS and Android.  It's used in a whole bunch of apps, like FlyQ EFB and a few big weather apps like Dark Sky.

Dark Sky
The toolkit's been around since 2011 and it's carved out a crazy little niche in aviation and weather.  It's not a wildly profitable business, but it doesn't lose money either.  How many can say that?

Morecast

Oh, and it's open source.  So that's fun.

WhirlyGlobe-Maply 3.0


The last version I shipped was 2.6 a few weeks.  A huge improvement for data loading on iOS and a nice upgrade to the Android build system.  I.... need to do a post on that.  But no time.

3.0 is the big upgrade.  I'm going to add iOS Metal support, redo the rendering internals and upgrade the Android port with a better shared C++ core and newer versions of OpenGL ES.

Technical Advisory Committee


So here's the deal.  I'm adding a new renderer for Metal and replumbing the internals to match.  I'd really love to discuss it with a few experts along the way.

This is an open source project so, you know, not a ton of resources.  Here's what I'm offering:

  • Free lunch in a pleasant conference room at my coworking space in San Francisco
  • An invitation to pontificate on real time rendering without having to do any work
  • A cool entry on your resume

You do not need to know anything about geospatial or weather or aviation.  I got that covered.  Here's what I need from you:

  • Work in San Francisco or nearby.  No budget for travel, sorry.
  • Know something about real time rendering, iOS Metal or Android OpenGL 3.x
  • Willingness to chat about real time rendering

It's your real time rendering chops I'm interested in.  So game developers most welcome!

Contact me at sjg@mousebirdconsulting.com and we'll see if you're a good fit.

Tuesday, April 25, 2017

Data Paging Layers

We load a lot of data sources in WhirlyGlobe-Maply, usually over the network.  Images are relatively easy, but how do you deal with things like vector tiles?

Ye olde vector tile example

That would be the job of the Paging Layer.

Quadtree Structured Data Paging


It all starts with a quadtree, a simple enough data structure.  It's here that we decide what's visible and what needs to be loaded.

Quadtree courtesy wikipedia
The quadtree for a data source can be in any proj.4 supported coordinate system, but most people use Spherical Mercator which is... what they use.  No judgement.

In deciding what to load, we start at the top node (0: 0,0), projecting a box into the view and then recursing if the box is visible.  It's not all that expensive, because quadtree.  But does get a bit tricky when using the globe or multiple coordinate systems.



For image layers, the toolkit has its own complex logic for loading image tiles and frames and handling failure and so on.  We provide similar logic for vector tiles, but for anything else, the logic is you.

Quad Paging Layer


You've got a data source, sqlite file full of points, let's say.  You want to turn them into markers, but there's too many to load at once.



Here's where the QuadPagingLayer (Android) or MaplyQuadPagingLayer (iOS) comes in.  Set up one of these babies with the coordinate system and extents of your data source and it'll figure out what to load.

You have to create the visible objects and that's where the PagingInterface (Android) and MaplyPagingDelegate (iOS) come in.  The paging layer calls you back when it's time to load a tile's worth of data.

Mt. St. Helens LIDAR
We love our threading in WhirlyGlobe-Maply and it was ever so hard to implement.  So use it.  Try a dispatch queue on iOS or use a worker thread on Android.  But don't hold up the paging layer.  It has other things to do.

When you make a visible object (marker, label, etc) tell the paging layer what you created with the addData (iOS, Android) method and call tileDidLoad (Android, iOS) when you're finished.

That's enough information for the paging layer to do the rest, which includes...

Cleanup on Node (12: 129,1304)


One of the trickier bits here is deciding when to delete something.  Luckily, you don't have to.

You told the paging layer what you created and it'll delete it for you.  There's even a callback if you really, really want to know it did that.

Paging Layers are Awesome


There it is, one of the key pieces of WhirlyGlobe-Maply: the paging layer.  We use it all over the place and if we don't support your data type, you'll use it too.

Tuesday, February 21, 2017

Styled Layer Descriptor and Metro Extracts

In WhirlyGlobe-Maply 2.5 we added support for the Styled Layer Descriptor format.  We also added an example in the AutoTester and a tutorial.

Belfast, it seems.

Let's start with the data.

Metro Extracts


Mapzen provides regular extracts of OpenStreetMap data.  These are available in a variety of formats; useful if you just want a little OSM data.

Courtesy Mapzen

We chose Belfast in GeoJSON for our own example.  This is just data, though, so how do we make it visual?

Styled Layer Descriptor


The Styled Layer Descriptor format is an OGC standard used to style data into map images.  It's a bit crusty but, you know, standard.  We edit it in QGIS and export it for use in our toolkit.



WhirlyGlobe-Maply reads SLD and uses it to style Shapefiles, GeoJSON, or Mapbox Vector Tiles.  Any vector data, basically.  So let's put it all together.

Example & Tutorial


Rather than blather about it here, we put a nice example in the AutoTester app for iOS.  In Swift!

Ranen put together a tutorial that walks you through the process.  You can start with a Metro Extract and modify the SLD styles to your heart's content.

Up Next


We're picking up SLD users for the toolkit at a steady clip.  There's a lot more to SLD we could support, so let us know how you like it.

We'd also like to circle back and improve the Mapbox GL Style Sheet support and implement Mapzen's Tangram format.  But we need customers for those.  Speak up if you're interested.

Thursday, February 2, 2017

WhirlyGlobe-Maply 2.5 Release

Version 2.5 is out for both iOS and Android.

Location Tracking

You can get v2.5 off of the build page or from the master branch.  We'll update the master Podspec for Cocoapods soonish.

As usual, getting this version out the door took way too long.  But here it is and it's really good.

Big Changes in Version 2.5


Android.  Without a doubt.  We now have a good Android version with a bunch of deployed Android apps.  Millions of people are using WhirlyGlobe-Maply on Android.  Crazy, right?

We started doing automated builds.  I can't over stress how useful those have been.

Both iOS and Android have AutoTester apps; individual test cases presented in a list format.  Useful both for testing and user examples.

We upgraded to Swift 3.0 and kept pace with all the new Xcode versions and UIKit deprecations.

Ripped out AFNetworking and Boost.  Respect to both packages, but AFNetworking was interfering with users' own version and we eliminated Boost with C++11.

Vector (tiled and not) support got fancier with Styled Layer Descriptor format and the Simple Styles approach for building your own.

True 3D interaction got fancier in support of LIDAR.  There's an example in the AutoTester so check it out.

We added user location tracking and display.  A relatively simple change, but a popular one for map users.

Important but Boring Stuff


We made an enormous number of small fixes, efficiency improvements and minor functionality tweaks.  Also a lot of new tests for things that are (no longer) broken.  Here's a partial list in a boring format no one is going to look at.

Maps now have ViewState animations like the globe.  Feature selection is smarter with individual and group features.  Widened vectors is faster, smaller, and better.  We've got a 3D model builder for things like airstrips.  Elevation support is better and more flexible.  Stars and atmosphere work better.  Vector tiles kept up with new versions and added more style options.  Particle systems work better.  Internal coordinates are now double everywhere for getting really close to things.  3D support includes the ability to "grab" objects via the IntersectionManager.  Removed Mapbox GL Style Sheet support and then put it back.  Single level loading works on the globe now for both vector and image layers.  Screen Label layout works correctly for all modes.  Great circles work in 2D across the date line.  And much, much more.

What's Next


We're going to make some internal changes to the source tree, like unify the Android and iOS branches.  Then we'll move to git-flow methodology to hopefully speed up minor releases.

In terms of functionality, I've been rolling out statements of intent for things like Windows, True 3D support, MapKit, and Mapbox support.  We've also got the Imagery Pro toolkit for weather apps and another one in the pipeline.  Much of this requires money, so let me know if you have some.