Psst! Hey you! Yes, you! The mousebird consulting blog moved. And there's a new version of the toolkit.
We're the makers of Maply and WhirlyGlobe, 3D toolkits for flat map and globe display on iPad, iPhone, and Android devices.
Thursday, April 1, 2021
Wednesday, February 24, 2021
New Blog: Location Tracking For Android
We've moved the mousebird consulting blog. Check out this post on Location Tracking for Android.
Thursday, December 10, 2020
An Offer to the Mobile Mapping Community
The short version: We're offering to fix a key problem with the open source version of the Mapbox mobile display toolkit. But it'll cost money.
To emphasize, I'm talking about the native mobile display SDK here, not the web.
The Situation
A lot of discussion is happening around Mapbox closing their Javascript API. For good reason. It's the most flexible geospatial display API on the web that focuses on performance.
Less noise has been made about Mapbox doing something similar to their mobile APIs back in July. Same problem, different platform.
Mapbox Did What Now?
It's a little convoluted, but it goes like this. They changed the license on the mobile APIs to make it more restrictive, sure, but they also did something more worrying. They scooped out the rendering engine for Android and iOS and placed it in a binary blob. So it's no longer open source, or even visible.
Obviously that makes the SDK no longer open. In a big, big way. So you can just use the old version, right? Well, there's a wrinkle.
Apple, OpenGL ES and Metal
So Why Not Switch to WhirlyGlobe-Maply
Who Do We Know With a Metal Renderer?
So You Just Drop It In Then?
Lawyers, Drugs & Money
So Maybe Someone Will Just Do This For Free?
Summary
Tuesday, December 8, 2020
Closing of the Mapbox APIs
The web? Sure, we'd love to make a Javascript/WebGL version. Pay us!
And while you're here, do you have any ideas for free marketing?
![]() |
| MapTiler Streets in WhirlyGlobe-Maply |
Mapbox & Competition Lost
Let's be honest, Mapbox makes the biggest and best maps SDKs for developers. Google's map is better, but their SDK is meh. Apple Maps is pretty good in both ways. Bing is... also around. As are lots of others. But MapboxGL was always our competition.
My vector toolkit predated theirs. Really! And I had a few map app developers because of that. But when they turned on the Softbank money hose, my little toolkit never had a chance. I lost most of those customers in the ensuing years. That wasn't fun.
Lucky me, I could see it coming. I steered the company into weather and aviation. Unlike a lot of competitors, we survived.
Closed vs. Open Source
Mapbox has changed the license on its mobile and now Javascript APIs to something that is not open source. Is it free? I can't really tell. But it's certainly not open.
I've been expecting this for years. It's the standard Silicon Valley Venture Capital play. Make a thing cheap, destroy the competition, enjoy your market. They executed it well.
So now we're going to get all those customers back, right? Ha!
Lock In / New Users
The truth is those developers won't ever come back. The cost of switching is too high and they're off doing other things. Anyway, if you're using Mapbox services, it's fine. That strategy totally works.
We have picked up a few open source map extremists in recent years. They've contributed money to our Vector Tiles and Style Sheet support. It's getting really good.
So what's next?
We Are Open Source
Let me reiterate that the WhirlyGlobe-Maply toolkit is licensed under Apache 2.0, a very friendly license for doing all sorts of commercial work.
Open source powers our small business and we're committed to it. It's a contract between us and our community. One we've honored through several major upgrades.
Javascript / WebGL
And hey, we're open to making a Javascript version of the toolkit. And not just a cross-compiled version, a real SDK for JS developers.
I've actually proposed this to weather users a few times. Just the parts they need, overlaid on a web map. Not the whole thing, but the core rendering is the same.
We'd open source it, because that's who we are. If you're interested, reach out. Preferably with money.
Marketing on the Cheap
With less competition, you'd think we'd be set, right? Not so much. Mapbox remade the market in its image and we have to live in that world.
But there are opportunities. Projects that have to switch, projects that are just starting out, competitors who don't want to write their own. That sort of thing.
So if you have ideas for marketing to those people, I'd love to hear them. Free ideas, preferably. Because open source.
Tuesday, November 10, 2020
WhirlyGlobe-Maply 3.0 Integration & Housekeeping
WhirlyGlobe-Maply Versions
Tutorials
Monday, November 2, 2020
We Can Display Your Mapbox Style Map
When people think of us, most think of WhirlyGlobe. It's the iconic interface in weather apps like DarkSky and tons of aviation apps you'd only know if you're a pilot.
![]() |
| Saildrone Forecast |
But did you know we also make a good 2D slippy map? That's Maply and it's completely open source.
Our support for Mapbox style maps has gotten really good this year, but we'd like to make it better!
Mapbox Kinda Maps
Vector Tiles and Mapbox Style Sheets are a potent combo and they've won the geospatial format wars. If you want to make your own vector slippy map, that's likely how you're doing it.
Maply has supported Vector Tiles for years, but the Mapbox Style Sheet support lagged.... until this year.
With the recent move to a unified code base we've got one single Mapbox Style Sheet implementation for iOS and Android.... and wherever else we port to. On iOS we upgraded our shaders to react to zoom level changes and it looks fantastic.
But there's a lot more to do. The spec if vast, and the fiddly bits are so very fiddly. We need money for more.
Who Are You Again?
mousebird consulting is a little company that makes WhirlyGlobe-Maply. We specialize in weather, aviation, and GIS mobile app development based on the toolkit.
We've been around with this thing for nearly a decade. It actually predates most of the competition... and it really is open source.
How Much Money We Talking?
I Dunno, We're Kind of Invested In...
Wednesday, May 20, 2020
Elevation / Synthetic Vision
But before I dive in, a bit about terminology. Aviation developers tend to refer to a simulated display of where a pilot is and where they're going as Synthetic Vision. The rest of you might just think of it as elevation support in the toolkit. It's the same thing.
![]() | |
| Mt. Rainier from Mapbox Satellite with elevation |
I’m going to try to put together a small group of WhirlyGlobe-Maply users to sponsor a new development effort. Let’s look at what that would be.
How Loading Used to Work
![]() |
| Level 0 loaded |
The biggest problem was loading time. The visuals would get super chunky as users waited for things to load. And it was all serial. Wait for imagery, then wait for elevation. Not great.Can we see enough of this tile to load it?Request the imagery & wait for it to returnRequest the elevation & wait for it to returnBuild the geometrySlap them all together
How Loading Works Now
With the move to the Sampler/Loader architecture in 3.0 things got a lot better. The tile loading process now looks like this.
Can we see enough of this tile to load it?
Rebuild the geometry immediately.
Slap whatever we currently have on the tile
Request the image
![]() |
| Saildrone Forecast uses a hybrid vector map on a globe |
How Elevation Should Work
![]() |
| Super complex diagram of the render pipeline |
![]() |
| Geometry Tile Points to Elevation and Imagery Pools |
Elevation Overlays
![]() |
| Elevation + Runway = Flattened Elevation |
Point Model Placement
![]() |
| Objects sitting on top of terrain |
3D Loading Details
![]() |
| Tiles with St. Helens take up more screen space |
Airport/Runway Generator
Elevation Database
Conclusion
Vector Features / Mapbox Style Sheet Roadmap
Vector Maps
Who This is For
Zoom Level
Wide Vectors
![]() |
| https://www.w3.org/TR/SVG/painting.html#StrokeLinejoinProperty |
We have some facility for dots and dashes, but those need to be updated and tested properly. Much of this logic just needs to go into a more intelligent shader.
Polygons
Text
Layout
But general Mapbox Style Sheet users would like this too.
Screen Objects
Mapbox Specific Features
Sprite Sheets
Mapbox Font Madness
Layout Specifics
Hillshades, Heatmaps, Fake 3D & Rasters
Conclusion
Odds are you're reading this because I sent you here with the request "I'd like some money to add several of these features I know you want". So, you know, let's do that. There's efficiency in scale and the more time I spend on vector maps, the better they will get.
For everyone else, this is where I'd like to take the vector map support in WG-Maply. Your feedback is welcome too.
Monday, December 2, 2019
Mapbox Style Support
![]() |
| MapTiler Basic |
I did some work for a client on MapTiler and Mapbox map sources. You get to benefit. Open source!
MapTiler & Mapbox
We were focused on Map Tiler primarily, so those work best. You can find examples for their Basic, Hybrid Satellite, and Streets styles in the AutoTester app.
![]() |
| MapTiler Streets |
As for Mapbox, we were trying out their Satellite offerings so you'll see examples for Satellite and Hybrid Satellite. Streets will probably kind of work, but it wasn't my priority.
![]() |
| Mapbox Satellite Streets |
You'll need to add in your own Map Tiler or Mapbox tokens. I'm not that much of a sucker.
Mapbox Kinda Map
Mapbox-style maps lean more toward the web side of things: Load a lot of random junk before you're ready. That's always been hard on my users.
Look for a new Swift object called MapboxKindaMap in the AutoTester app. Just copy it into your app. For various reasons it's hard to add an actual Swift module to the old version (2.6) of the toolkit.
At its simplest, give the thing a URL for the style and it'll figure out the rest. Consult the MapTiler and Mapbox Test Cases for details.
Caveats
It's working fine for my client, but their needs were pretty simple. If you want highway shields and fades per zoom level and that good stuff, it's not there. I'll be bugging my users for money to add all that and make it work on Android.... soonish.
MapTiler has pretty flexible usage, but Mapbox does not. So work it out with them before you ship anything.
Monday, July 1, 2019
WhirlyGlobe-Maply 3.0 Is Feature Complete
If you're a sponsor, you can have it whenever you like. That's why you're a sponsor.
I just fixed the last missing piece which was.... the Layout Manager. It's always the Layout Manager.
What 3.0 Means To You
Performance & Optimization
The Island of Lost Features
What's Next
Friday, May 17, 2019
WhirlyGlobe-Maply 3.0 Status Report #4
As a reminder, this is about the WhirlyGlobe-Maply 3.0 effort: A better version of Android and a port to the Metal rendering toolkit on iOS.
Quarantining OpenGL ES
WhirlyGlobe-Maply was designed around OpenGL ES. Version 1 if you can believe it! It's been upgraded since then, but OpenGL permeates its design. Like fish in a microwave.
Multithreading and state management are particularly bad in OpenGL ES and my toolkit works around this in a variety of bad ways.
I've just finished shoving all of this logic into its own separate modules. Twenty-something of them. The top level interface doesn't change. This was my own private pain I'm sharing with you!
Very little of the system now knows about the low level rendering which leads us to the...
Journey Into Metal
Sure, it sounds like a Heavy Metal Parking Lot sequel, but way less cool. Behold the first of the new Metal code for setting up a texture.

And let's not forget the shaders. Shaders that Xcode can syntax check! And compile at compile time! [Okay, fine there's probably a way to do that with an OpenGL extension, but it's guaranteed annoying.]

It's glorious! In a boring way! But there's a ways to go and nothing interesting to show yet.
Summary
If OpenGL development is Napoleon's Russia Campaign, Metal is like taking light rail to the mall. Which is to say it's going well and there's no reason to suspect it won't continue doing so.
Ideally, I should designate 3.0 finished sometime in June. If you're a sponsor, you get it then (or now, if you're bold). For the rest of you, that means next January.
Friday, April 12, 2019
WhirlyGlobe-Maply 3.0 Status Report #3
So where are we now?
The Android Port
Android Internals & Development Flow
Wither Kotlin
What's Next & Thanks
Thursday, March 7, 2019
WhirlyGlobe-Maply 3.0 Status Report #2
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.
(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
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
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
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) |
![]() |
| Dark Sky |
![]() |
| 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
- 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
Tuesday, April 25, 2017
Data Paging Layers
![]() |
| 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 |
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 |
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
![]() |
| Belfast, it seems. |
Let's start with the data.
Metro Extracts
![]() |
| Courtesy Mapzen |
Styled Layer Descriptor
Example & Tutorial
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
![]() |
| 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.





































