Monday, December 9, 2013

WhirlyGlobe-Maply For Android

For those of you with a short attention span.  The Android port is on.  Now for the details.

Yes, it will look exactly like this.

WhirlyGlobe-Maply is in great shape on iOS.  With the recent release of 2.2, I'm pretty happy with the architecture and functionality.

The toolkit has matured from a lightweight interactive globe to a serious geospatial display toolkit.  It's suitable for large globe based applications and interactive flat maps.  I have some pretty reliable clients in aviation, geography, and map display.

That's great and I can see this going on indefinitely, but there's one obvious thing that must happen fairly soon.  I need to port to Android

Why Android?

We can debate the pros and cons of Android vs. iOS endlessly.  It doesn't really matter and I don't really care.  I need to port to Android because big clients want me to port to Android.  No one wants to get stuck on iOS.

Most of my clients aren't selling their apps anyway, they're selling services.  To them, it's a matter of cost.  The iOS version is a given, but then how many customers are on Android and how much will it cost to get there?

There are other reasons.  Once the Android port works it opens the door for other ports.  What about the Mac?  PC?  Windows Phone?  How about some weird custom in-car navigation system?  I'm focused on mobile, but I'll take money for any of those ports.


Once I started asking around for Android money it became clear how this was going down.  I needed one big client to pay for the biggest chunk of it.  I'd toss in some of my own overhead money and then get the rest from a diverse set of clients.

Now I have that big client on board.  Negotiating deals for functionality that doesn't exist yet is always tricky, at least for a small project like mine.  But we did it, WhirlyGlobe-Maply is growing up!

I'm focusing on what that first customer needs so there will be plenty of gaps after the initial port.  Everything depends on the core rendering engine, naturally, so porting the rest of it will be much easier.

The initial version will be ready in late winter.  "So..." you may be thinking, "can I get it?"

Open Source + Private Beta

I'm very happy to announce that WhirlyGlobe-Maply 3.0 for iOS and Android will (still) be open source, distributed under the Apache 2.0 license.

That's nice, but I need money to finish porting everything else.  So here's how that's going down.  It's open source, but the toolkit will be in a private beta for a few months.  How long?  I'm not sure yet.  You want access to it right now?  Pay for some functionality.

Make no mistake, this thing is going to be usable in 2-3 months, depending on what you need.  Porting the rest of what you need will be easy.  So cough up some dough and off you go.

After I've reached a certain threshold of working functionality, I'll release the toolkit to everyone and we'll go back to normal.

Thursday, December 5, 2013

Maply 2.2

I'm pleased to announce the release of Maply 2.2.

Maply is a 2D and 3D map rendering toolkit for iPad and iPhone based on OpenGL ES 2.0.  It lets you put labels, markers, vectors, and shapes on top of an interactive map with one or more base layers of pageable image data.

Check out the video for a quick tour.

Maply is actually part of the WhirlyGlobe-Maply component.  The library handles both a 3D globe and a 2D/3D map with different entry points.

Go check out this page for details on how to get the library and use it.

WhirlyGlobe 2.2

I'm pleased to announce the release of WhirlyGlobe 2.2.

WhirlyGlobe is a 3D globe rendering toolkit for iPad and iPhone based on OpenGL ES 2.0.  It lets you put labels, markers, vectors, and shapes on top of a 3D interactive globe with one or more base layers of pageable image data.

Check out the video for a quick tour.

WhirlyGlobe presents a nice, simple Objective-C interface and uses standard MVC constructs such as view controllers and delegates.  It's very easy to integrate into your own app.

Where To Get It

The github repository is the best place.  The master branch is on 2.2.  You'll want to check out the readme, but basically it goes like this.

  • git clone WhirlyGlobe-Maply
  • cd WhirlyGlobe-Maply
  • git submodule init
  • git submodule update
  • Open the WhirlyGlobeComponentTester in Xcode
All the example data is in one of the submodules, so it takes a while.

There's also a binary distribution.  Download it and open the WhirlyGlobeComponentTester example.

Using The Framework - GitHub

It's pretty easy to use WhirlyGlobe in your own project.  If you're using WhirlyGlobe as a submodule, it's like so:

  • Set up a brand new project for your app with git enabled.
  • cd to the root directory of the project
  • mkdir libs
  • git submodule add libs/WhirlyGlobe-Maply
  • git submodule init
  • git submodule update
  • cd libs/WhirlyGlobe-Maply
  • git submodule init
  • git submodule update
One of WhirlyGlobe's submodules contains all the source data, so that'll take a while.  You only have to do it once.

Then in your Xcode project, do the following:
  • Go to Build Phases and open "Link Binary With Libraries".
  • Hit +
  • Select "Add Other"
  • Navigate to libs/WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/
  • Select WhirlyGlobe-MaplyComponent.xcodeproj
  • Hit + again
  • Select libWhirlyGlobe-MaplyComponent.a
  • Add a few other libraries you'll need
    • libc++
    • CoreLocation
    • libz
    • libxml2
    • libsqlite3
  • In Build Settings find "Header Search Paths"
  • Add the path "$(SRCROOT)/libs/WhirlyGlobe-Maply/WhirlyGlobeSrc/WhirlyGlobe-MaplyComponent/include/"
You should now be able to pull in WhirlyGlobeComponent.h and compile.

Using The Framework - Binary Distribution

If you're using the binary distribution instead of github, there are even fewer steps.
  • Set up a brand new project for your app.
  • Go to Build Phases and open "Link Binary With Libraries".
  • Hit +
  • Select Add Other
  • Navigate to WhirlyGlobeMaplyComponent.framework in the binary distribution and select it.
  • Hit + again
  • Select libWhirlyGlobe-MaplyComponent.a
  • Add a few other libraries you'll need
    • libc++
    • CoreLocation
    • libz
    • libxml2
    • libsqlite3
  • In Build Settings find "Header Search Paths"
  • Add the path to "$(binary dist path)/WhirlyGlobeMaplyComponent.framework/Headers".  You fill in the binary dist path.
You should now be able to pull in WhirlyGlobeComponent.h and compile.


The full set of reference documentation is now available.  That's documentation for each of the Objective-C classes.  The crazy C++ internals are not documented there, so think twice before using them.

To see what's possible, consult the WhirlyGlobeComponentTester app which is included both in git and the binary distribution.  TestViewController.m is the best place to start.  Getting a simple globe up and running is surprisingly easy.

Wednesday, November 13, 2013

WhirlyGlobe-Maply 2.2 Beta4

Busy, busy, busy.  So here's the next WhirlyGlobe-Maply 2.2 beta.

That's animating, trust me.

I probably should have shipped the last one and moved on to version 2.3.  But I didn't.  I was busy integrating with a few client projects and that shook out a lot of bugs.  The user community was pretty active as well, finding bugs and minor gaps in functionality.  The result is beta4, which I quite like.

Updates to Beta4

There were many, many bug fixes.  We shook out a lot of problems and I added a whole bunch of new functionality.

  • 2D Maps
    • These work more smoothly in general.
    • When displaying a tile source that's in the same coordinate system as the viewer, we skip all the complicated screen space calculation logic.  This makes the loading look better.
    • For that case (simple flat map, basically) you can now ask "what zoom level are we at?"  That question only makes sense for a flat map.
    • The display supports coordinate systems other than spherical mercator.  Only one other is available, but in the future... more.
    • Rotation is now working thanks to a pull request.
  • Quad Image Paging Layer
    • Image paging now lives in its own thread and synchronizes with the frame draw boundaries.  This is very fast.
    • More knobs for controlling animation.
    • Many bug fixes to animation.  This deserves its own blog post.
    • Handles empty tiles better.  Now you can have a tile source that only provides levels 10-12, say, and it'll work.
    • Better error reporting including feedback at the tile source for failed loads.
    • Support for asynchronous loading if that's how you swing.
  • WhirlyGlobeViewController / MaplyViewController
    • You can now ask the control how high you should be to see a given bounding box.  This is nice for centering on data.
    • There are delegate methods for didStartMoving and didStopMoving.  These are useful for reacting to where the user is looking.  Be careful, they're on the main thread.
    • I support images on various high level objects, like stickers or markers.  The toolkit reference counted those when converting to OpenGL ES textures.  Now you can nail those down in the format you want with the settings you want and avoid creation/deletion thrashing.
    • Stickers support multiple images which they will happily pass to custom shaders.
    • Filled vectors now support textures.  [You should be saying "Oooooo" right now.]
    • Shader support has been there for a while, but now it tracks updates and forces redraws more consistently.
    • You can pass an image to a shader where it'll use it to do... whatever you write your shader to do.
    • Billboards are... hard to explain.  Useful if you know what they're for.


You've got a couple different options for getting WhirlyGlobe-Maply 2.2 (beta4):
Don't forget about the documentation.  It took long enough to write, so read it.

The Future

This is more or less it for 2.2, I think.  Maybe a few bug fixes if anything heinous turns up.

I've absorbed 2.3 into the last beta, so next up is probably 3.0.  That'll be a while.

Friday, October 4, 2013

WhirlyGlobe-Maply 2.2 Beta3

The WhirlyGlobe-Maply 2.2 beta #3 is live on the master branch on github.  You can work with the precompiled distribution as well.

Yeah, I'm repeating myself.

What's New

Mostly bug fixes, but there is some new functionality of note.

  • Elevation Support - It's in there, hooked up at the Component level so go wild.  The test app also has a nice data set.  Look in the Washington state area.  Upper left in the U! S! A! for those of you overseas.
  • Basemap animation - I'm still messing with it.  Be warned.  Sure looks cool.
  • Multi-texture support - In at a low level.  Not much to see here yet, but hints of things to come.
  • Image paging layers changed quite a lot.
    • Each one gets its own thread.  This lets them be incredibly anti-social.
    • They work in a metered mode where they're tracking frame boundaries.  This reduces latency to the renderer.  Think: render, switch, render, switch, and so on.
    • Reload will now appear to switch instantly if all the tiles are local and it doesn't take too long.  This is nice for things like weather layers.
    • There's a mode to wait for all outstanding loads before switching to new geometry.  This looks great for local tile sets when loading is fast.  I'm ambivalent about how it looks for remote tile sets.  You've go the knobs, go twiddle.
  • QuadImageTilesLayer - I've consolidated all the image paging functionality at the top level in a single layer.  You can now mess with fairly advanced settings to your hearts' content.  The defaults are fine for most uses.
  • Xcode5 / iOS7 Support - It was mostly there before.  Now it's all pretty much there.  If it doesn't work then maybe it's you.  Ever consider that?
  • The death of -all_load - The Objective-C categories used to cause no end of trouble linking.  Now they don't.
  • Maply Fixes - Flat map 2D mode is working better and a user was kind enough to add rotation.
  • Documentation.  Lots and lots and lots of documentation.  Boy am I ever sick of writing documentation.
The image paging caused a bit of heartburn and I considered holding off to 2.3.  But damn, it's sweet, so I went ahead anyway.  The elevation support seems solid, but there are some obvious things it could do.  Animation is still a bit wonky.

The Future

This is it for big changes in the beta.  I've got a few more bugs I'm eyeballing.  I'm sure others will turn up, but I think beta3 is pretty stable.

Next up is 2.3, which should be fairly minor.  I'm thinking vector map updates, more on the animation, and whatever else I get paid for.  The big architectural changes are on hold until 3.0.

Wednesday, September 18, 2013

Contributions and Copyright

I've had clients for WhirlyGlobe-Maply for a couple years now.  Recently I've been getting contributors.  As an open source project, that's very exciting and I'm happy to see them!

They do add a bit of complexity, though, because of the way my project works.

Who Owns The Code?

That's easy, I own the code.  Every line of WhirlyGlobe-Maply is MINE!  But don't worry, you can use it for free.

Copyright is separate from license (I can hear my lawyer frowning).  I hold the copyright on the code, but I release it under an Apache 2.0 license so you can use it.  That license is incredibly friendly to commercial interests so you can make apps, modify the source, and generally go wild while abiding by its pleasant terms.

Sometimes I put WhirlyGlobe-Maply under another license for a client.  Why?  Money, that's why.  This doesn't effect the Apache 2.0 version and you needn't worry about it.  But it does mean I must own every line of WhirlyGlobe-Maply.

This is Open Source?

It is, yes, one of the variants.  It's not GPL, it's not even one of those big techno-hippie projects we all love.  But it is a well known, well tested, well understood variety of open source.

Okay, so if I own it, can I take it away?  I cannot.  Even if I decide to start charging for WhirlyGlobe-Maply 3.0 you still have the 2.2 version released under the Apache 2.0 license.  That can never go away.  [I have no plans to do this, by the way.]

Git Pull and Contributed Source

Now we get to the point of this post.  When contributors send me a pull request, what's the copyright on it?  Legally, it's "All Rights Reserved".

This won't do for either the open source version or for my own.  It could potentially taint the apps of anyone who uses the toolkit.  I can't have that.

If you're sending me a pull request, I need you to resolve the copyright and ownership.

Copyright Options

If you've modified the source, those modifications are yours (or your employer's).  If you write something new, that source is yours (or your employer's).  It's up to you (or your employer) to assign the copyright.  I'll explain some options.

All Rights Reserved

If you reserve copyright I can't touch it.  You can do what you like with it, including putting it up on github, but I'd ask you to put an explicit copyright on it so no one gets confused.

If you modified my source code in the process, you can't change my Apache 2.0 license and the copyright is now ambiguous, in my mind at least.  It would be great if you put a notice to that effect at the top of the files you've changed.  That way no one will accidentally get into trouble.

In any case, I won't be putting any of this code in my github repo.

Retain Ownership & Assign an Open Source License

If you write brand new code, you could retain ownership for yourself, of course.  If you then put an open source license on it, I will be delighted to put it in the Contributed directory.  Please pick a really, really permissive license, if you would.

I don't own source code in the Contributed area of WhirlyGlobe-Maply.  I may maintain it, from time to time, but I make no guarantees.

If you want to modify code in Contributed, feel free.  Just respect the license that's on it.

Transfer Ownership

The last option is transferring ownership to mousebird consulting inc (e.g. me).  In this case I'll pull it back into the toolkit, slap the Apache 2.0 license on it and treat it as my own, because it now is my own.

I'm only going to ask this for small amounts of code and bug fixes.  I know, it seems stupid to ask for bug fixes, but I legally have to.

Let me emphasize: YOU DO NOT HAVE TO DO THIS.  Sending me a pull request does not imply anything.  When I ask you, you can then make your choice and I will respect it.

Working For The Man

If you're an employee or doing work for hire, you must get your employer's permission to assign ownership.  I cannot accept the assignment if I think you can't give it, so I may ask some probing questions.

I know no one does this and I'm sorry to be difficult.  Look, I've been in silicon valley a long time now and I've seen a lot of stupid go by.  Much as I love github, and I really do, there is a lot of stupid around it and copyright.  I won't have it on my project.

"But hey", you may be thinking, "don't you work for The Man as well!"  I do, random interlocutor, but I have a Lawyer and a Contract.  It's a big nasty contract that spells out what I own and what The Man owns.  I trust it works because it's killed a few potential deals.

Standard work for hire contracts or employment agreements do not look like mine.  I very much doubt you have the same rights I do unless you specifically negotiated for them.


If I've sent you here for a pull request, let me just say:  Thank You!  Even if I can't accept it, it's helpful for a few reasons:

  • I can see what developers are interested in
  • If it's a bug fix, I can see what the problem is
  • It gets my stats up on github (don't laugh)
  • It was probably useful in your own app

So again, thank you!

Please take a look at your copyright options and pick the one most appropriate.  Picking nothing defaults to "All Rights Reserved".  That's fine too.

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.

Thursday, September 12, 2013

WhirlyGlobe-Maply Feature: Elevation

Terrain support has been a very popular request in WhirlyGlobe-Maply.  Here you go.

Works pretty well, actually.  The data set I'm using there is in Spherical Mercator to match the map tiles coming from MapBox.  There's one 32x32 sample tile for each image and the data is stored locally in an sqlite database.  More about the tools later.

Component Support

If the elevation data is stored in a sqlite database, we obviously have to get it out.  We use a MaplyElevationDatabase to do that.  That object implements the MaplyElevationSourceDelegate protocol, which you can use to query individual tiles.

You can also implement your own elevation database, perhaps one which fetches data remotely.  Just implement the MaplyElevationSourceDelegate protocol.  Don't worry, you're called in another thread so go ahead and block on the network calls.

We hand the elevation database over to a MaplyBaseViewController, which is the parent of both globe and map view controllers.  Though that object doesn't use it, it does pass it on to layers that care about elevation.  At present, that's just the MaplyQuadImageTilesLayer, which now handles all of the local and remote image tile paging.

Here's what that all looks like, from the WhirlyGlobeComponentTester app.

And all that will get you this.

How active could that volcano be?

Elevation Pyramid Generator

Getting terrain support in the toolkit wasn't actually all that difficult.  I know kind of a lot about this stuff.  No, the real problem is how to generate the data.

From past experience I knew I couldn't just throw this functionality out there and expect users to pick it up.  I needed to provide a tool.

This one's just gratuitious
That tool is elev_tile_pyramid and you can find it on github in the develop branch.  It deserves its own blog post, but for now you can look in the README file.  That explains how to compile it and how to run off the Pacific Northwest example.  You can also just download that database.

The Fine Print

It's cool and it works!  But there are some caveats.

Elevation data adds complexity.  We can no longer predict where the surface of the earth is at any given point and, even worse, it moves between levels of detail.  That means features are hard to place.

The settings panel.  Titillating!
That's the settings panel from the WhirlyGlobeComponentTester app.  The base layers are all there, but you might notice all the overlays are missing, as are the vectors.

You can do vectors, labels, markers, and all that good stuff in this mode, but they won't work well.  Markers and labels might, actually, but vectors certainly won't.  Why not?  Because topology.

We've got a different version of the surface for each level of detail, and there are 14 levels in the example.  That means whatever you stick on top of the earth needs to move around as those levels of detail swap in and out.  It's not impossible, but it does require some work.  Work that, frankly, a client can pay for.

The Conclusion

It works pretty well and it's in the develop branch on github.   Go have fun.  I'm sure more features will be forthcoming, but I'm going to see what clients want to do.

Wednesday, September 4, 2013

WhirlyGlobe-Maply 2.2 Beta

As promised, the WhirlyGlobe-Maply beta is up for version 2.2.  You can get it on github from the master branch.  That's the preferred location.

Gratuitous Image
If you want a binary distribution, I've got one of those up now too.  This includes the framework, now stripped of its debug info, as well as a the sample app and all dependent libraries.

Tuesday, August 27, 2013

Geospatial Data Display using OpenGL ES (for iOS)

A few weeks ago I gave this talk at the local NSMeetup.  That's a nice venue, primarily for iOS development, with a very strict technical bent.  Most iOS related meetups around here (San Francisco) devolve into meet markets for "technical cofounders".

Anyway, I asked to give a talk and after a bit of back and forth I made it more general than my usual WhirlyGlobe-Maply pitch.  Here it is in its full glory.


I had about an hour so I couldn't do a full OpenGL ES tutorial.  I tried to distill a few lessons from geodata display, things that you run into when you have more data than you can easily draw.  And of course, how to draw it fast.

There was code!  I honed a few examples related to my favorite problems.  Hit the links below to jump to the code examples in the video.

I tend to think of these as really big problems I throw a lot of code at to fix.  It was interesting to boil them down to their essence in a little code and show the solutions.

The Code

You can get the NSMeetup app source on github.  It has the code examples, as well as links to the code in github gists.

Cubes are like spheres, only less so.
The github gists were an experiment.  I've watched any number of talks with the speaker struggling to use Xcode in less pixels than Xcode would prefer.  And anyway, I do my talks on an iPad because my demos are on an iPad.  So why not show the code on the iPad?

Using gists and a UIWebView let me keep the flow going.  I went back and forth between code and the working example without leaving the app.  I'd definitely do that again.

More Tutorials?

I may do a few more, but just related to WhirlyGlobe-Maply.  This was very interesting, but time consuming and I'm not in the OpenGL ES training business.  If you are in that business, feel free to link to the video if you find it useful.

Tuesday, August 20, 2013

WhirlyGlobe-Maply 2.2

I've been working on 2.2 for a few months now, ever since 2.1 was released.  There's a lot of new stuff in this version.  So much that I've been actively delaying writing it up.

Let's get on with it!  Here's what's in WhirlyGlobe-Maply 2.2.

Base Map Display

The quad paging layers changed radically in this version.  I talk a bit about the underlying technology elsewhere, suffice it to say that they draw fast.  Real fast.

In addition to that (which is big), I've also exposed a lot more functionality at the Component level.  Now you can do tricky stuff like this.

That's three base maps stacked on top of each other:

  • My variant of Geography Class, paged locally.
  • USGS Ortho photos coming from their WMS server
  • Transparent weather data from the OpenWeatherMap server

Each of those layers is independent, with its own coordinate system, level range and protocol.  You can now stack these things up to your heart's content and control their order.  And it's fast.

In addition to my own low level layers, you can also make your own.   Just create a MaplyQuadEarthTilesLayer and hand it an object implementing the MaplyTileSource protocol.  Have that object return an image for a given tile and off you go.  It even uses dispatch queues.

Vector Paging Layer

Though vector display hasn't changed all that much in 2.2, I have added high level support for paging your own data sets.  We organize base image maps as tiles and we can do the same with vector tiles.

OpenStreetMap vector data

In this example we're paging vector data from the US OpenStreetMap server.  That's an experimental setup where they're serving up GeoJSON tiles, sort of like what we used for images.

You don't have to have GeoJSON or anything specific.  Just create a MaplyQuadPagingLayer and fill in the MaplyPagingDelegate protocol.  You create the visible objects associated with your tile and the Component handles everything else, including cleanup.  It's also multi-threaded.

ZBuffer Control / Draw Priority

This one's a bit low level, but really useful.  You can now control which features respect the zBuffer (or ignore it) and which write to it.  That's incredibly useful for features you want to stick right to the globe.


From the picture, here's how the standard defaults play out.

  • Geography class is the base layer at priority 100.  It writes to the zbuffer, but doesn't read.
  • The USGS Ortho layer is next around priority 101.  Also writes to the zbuffer, but doesn't read.
  • Next, we draw the stickers (priority 30,000) which neither read from nor write to the zbuffer.
  • Grid lines (in blue) are drawn next (priority 50,000).  They ignore the zbuffer entirely and have a tricky little shader program to deal with the lines behind the globe.
  • Lastly, we throw on the shapes, including those spheres and the great circles (with altitude) at about priority 80,000.  They read from the z buffer, but don't write to it.
There's also a little book keeping for skirts.  What are skirts?  Do you see any obvious lines between levels in the base map?  That's what skirts do.

That's all without the dreaded drawOffset; drawPriority now rules the day.

Anyway, that's all with the defaults.  Odds are you'll never need to set any of this yourself, but it's there if you do.

Text Fonts & Layout

We've now got a font glyph manager.  It's not too tricky, but it speeds things up and (potentially) saves a lot of memory.

We used to render each label in Quartz, which worked great, but was kind of slow and a memory hog.  Now when you ask for a label, it renders the appropriate glyphs, saves them to a giant texture atlas and makes up the polygons for your string.

When you delete the string, it may delete the glyphs as well.  So feel free to use weird fonts with impunity.

Labels now support a wider range of features, including an outline color and size.  That's nice for maps with cluttered backgrounds.

The layout engine is a bit more sophisticated as well.  It can handle rotation and does a better job with justification.

Vectors & Lofted Polygons

The toolkit can now tesselate large, weird polygons.  Why?  Because sometimes you get large, weird polygons.

Oh goodie, lakes.

This is useful in a couple of places.  First, the kMaplyFilled attribute works a hole (pun intended) lot better on vectors.  Second, the lofted poly layer is a lot faster.  Tapping Russia is now interactive.

Ha ha.  Red.  I get it.

Thread Control & Active Objects

Now for the obscure stuff.  You can add things on the main thread!  Gasp!  Wait.  What?

That little sphere is moving.  Just keep staring.
WhirlyGlobe-Maply likes its threads, it uses a bunch of them.  We try to do everything on either the layer thread or in custom dispatch queues.

Well great, but what if you want to change something RIGHT NOW.  You know, if you're editing it.  Or maybe animating it.  Now you can.

All the usual add calls (i.e. addScreenLabels:) take a mode: parameter.  Right now the mode is either MaplyThreadAny (the old way) or MaplyThreadCurrent.  For the latter we do the deed right now on the thread we're currently in.

There's also a new MaplyActiveObject, which is wrapper around a callback you get right before the next frame draws.  This is how you animate if you're so inclined.  Use it wisely.

Screen Space Calculation & Tilt

The toolkit spends a lot of its time trying to figure out what to load and when to load it.  It does this by deciding how big things are on the screen.  That works fine if you're staring straight down, it gets trickier if you're not.

Crazy!  Who knew?  Well I knew, I was just avoiding it.

And now I'm not avoiding it.  We can display the sampled curved surface of a globe when looking outward.  That was fun.

You can mess with the tilt in a WhirlyGlobeViewController.  This can get tricky, so check out the setTiltMinHeight:maxHeight:minTilt:maxTilt: method.  That'll muck with the tilt as you get close to the ground in a somewhat intuitive fashion.

Maply (2D) Changes

Support for the 2D/3D map mode is fleshed out a bit more.  I think you can actually use it for apps now, because... well... I have.

Like a Globe, only Flat.

There's a true 2D map mode now, where you can turn off lighting and even tie the map to a UIScrollView.  It's a bit... tricky yet.

The gestures could use a bit of work and I'm getting a better idea of what users might want (hint: looks like MapKit).  There will probably more of this in 2.3.

Component vs. WhirlyGlobe-Maply API

I used to stress the difference between the low level WhirlyGlobe-Maply API and the high level Component.  The API uses a combination of C++, STL, Boost, and apparently MADNESS.  I'm just pushing the WhirlyGlobe-Maply Component these days.

In fact, most of my clients are using the Component, so all the good stuff gets exposed there.  Point being, just use the Component.

Other Stuff

There's a lot of new functionality in WhirlyGlobe-Maply 2.2.  Did I mention custom shaders?  I did not.  The low level rework that'll make Android porting easier?  Didn't really go into that.  How about elevation data?  Yeah, it's there, but you need your own data.  Don't have that... let's wait until 2.3.

And, oh yeah, the WhirlyGlobe-Maply Component Tester app has been heavily reworked to show all this off.  Check that out for examples.

The Future

I'm putting 2.2 into Beta shortly.  It'll go active on the main branch on github, then we'll update the pod specs, the documentation, and the binary distribution.

After 2.2 I'm looking more toward map related features.  The globe is fun, but maps (vector and image) are a bigger user base.  Rather than crazy high end stuff (which my clients like), I need to put some time into making things easier to use.  Annotations are an obvious problem, as is area based update.

Of course, clients pay the bills, so expect more high end craziness as well.

Tuesday, August 6, 2013

Geospatial data display using OpenGL ES

I'm doing a talk tomorrow night on geospatial display and OpenGL ES for iOS.  Down in SOMA in good old San Francisco.

There's a few examples, a bit of code, and a whole lot of slides.  Should be fun.

Along with the talk is a tutorial illustrating some of the problems you run into doing geospatial data display.  You can find the code on github.

Thursday, July 25, 2013

Web Map Service (WMS) Support

The Web Map Service protocol has been around a while.  A long while.  I just got around to implementing it in WhirlyGlobe-Maply.

Add witty caption
Of course the toolkit has been able to do this sort of thing since 1.0, but with a variant of TMS.  I think.  You know, what OpenStreetMap and Google publish.  Bing does something weirder.

Anyway, you can do WMS now in your WhirlyGlobe or Maply app.

The Code

All this is in WhirlyGlobe-Maply 2.2, a rather massive update to the toolkit I'll be publishing shortly.  It's in the develop branch if you're feeling frisky.

Here's how you'd add the NAIP ortho quads to your globe (or map).

Pretty simple, actually.  Here's all we're doing.

  • Create a coordinate system that describes good old WGS84 lat/lon.
  • Setting up a tile source to point to the WMS end point.
  • Starting a new layer which uses that tile source.

Incidentally, you can write your own tile sources now.  The code for MaplyWMSTileSource is pretty simple and it lives at the Component level.  That means it's entirely Objective-C.

Oh, and I don't think you should do this for WMS sources you don't own.  WMS is much more general and I'm using it for tiles, which is... yeah.  Anyway, be sure you know what services you're hitting and how they feel about it.

Thursday, July 18, 2013

COM.Geo Talk - Monday July 22

I'm giving a short talk on WhirlyGlobe-Maply at the COM.Geo conference in San Jose on Monday.

It's a 10 minute overview of the toolkit, who uses it, what it's for and such.

Here are the slides.

Sunday, July 7, 2013

StrataLogica 2.0

This is a beast of an app based on WhirlyGlobe.

Woo!  Topical!
They've got a free mode, so I suggest checking it out.

The 2.0 version just came out and it's a lot of new functionality and a whole new interface.  You can draw on the globe.  I kid you not.

They're going for schools here.  Teachers, students, geography, history, that sort of thing.


Of course it's all about me, so yes it's using WhirlyGlobe-Maply.  More WhirlyGlobe than Maply, for sure.  StrataLogic 1.0 was using WhirlyGlobe, but I never got around to posting about it.  Er, duh.

Anyway, without going into too much (any) detail on the inner workings, there are a lot of moving parts here.  The interface is entirely the product of a talented team at RoundArch Isobar.  The data sets are shared with the desktop version, which is based on Google Earth and owned by HerffJones-Nystrom.

I did the globe portion, as you might guess.  That may look like the big piece, but trust me, it ain't.  That interface is pretty deep.


These guys have been a client for the better part of a year and it's nice working with a team.  They've been willing to experiment and bring the necessary resources to bear.  I think the result speaks for itself.

Friday, June 21, 2013

Android Port: Begging for Money

I'm getting a lot of queries about an Android port.  Just to recap, I make the WhirlyGlobe-Maply toolkit, an open source 3D interactive globe and map display toolkit for iPad and iPhone.

Globe                            3D Map                         2D Map
Most of the development I do is incremental.  If I add, say, font based text rendering it doesn't cost all that much and one client can pay for it.  Everyone else gets the benefit and that's how open source works.

The Money

Some things are just too big for that model.  An Android port isn't like a feature request, it's big.  How big?  About $50k (USD).

Normally I'd approach this one of two ways:

  1. Do it myself.  I absorb the cost of lots of features no one really wants to pay for.
  2. Wait until a big client needs it.  Pretty likely, but could take a while.
This is just too big for the former.  Remember, I give this stuff away.  The latter will probably happen... eventually.

What if I could speed that up?

The Engineering

I've bid an Android port on several projects now and worked out the details.  Here's how it would go.

The core rendering modules of WhirlyGlobe-Maply are largely C++. We would be making heavy use of the NDK on Android to port the rendering engine.  

The first step would be to move more of the rendering modules into pure C++ on iOS. This has the virtue of being easily testable with the current toolkit.

The next step would be a direct port of the rendering engine modules to the Android NDK.  After that we would rewrite the threading and messaging logic in Java for Android as well as the various interface logic to go between Java and the rendering engine.

Lastly, we would rewrite the high level interface in Java. This would correspond to the Component level on iOS. These objects need to be native Java and function in ways Android developers expect, just as the Component on iOS is native Objective-C. 

The Appeal

A lot of companies are interested in an Android port of WhirlyGlobe-Maply.  Some are using the globe, but most want to do custom map display on both platforms.  Mine is probably the best open source toolkit for that and superior to a lot of the commercial solutions.

So, I'm talking to you guys here:
How much would you kick in for an Android port?

Drop me an email and let me know.  If I hit a certain threshold, I'll come back to you for details.

Monday, June 17, 2013

CartoDB Example

I whipped up a guest blog post over at the CartoDB blog.

That's a simple app that queries country outlines from their spatial database service.  Lot of interesting possibilities there, go check it out.

Saturday, June 8, 2013

State Of The Map - San Francisco 2013

I'm giving a talk this year's at State Of The Map (US) in San Francisco.  This is unrelated to the fact that I live in San Francisco, but convenient nonetheless.

The Talk

It's all about vector display on iOS devices using OpenStreetMap data.  Scintillating.

The green is marijuana cultivation.
You can go grab the slides there.

The talk is based on my toolkit, WhirlyGlobe-Maply, unsurprisingly, and an app I built for fetching vector tiles from the US OpenStreetMap server and displaying them.

The App

The app, called osmmobilevectors, is on github and you can clone the repository, build it and put it on your own device.  I mean, you're set up to do that, right?  Of course you are.

Lots of interesting little bits and pieces went into the WhirlyGlobe-Maply toolkit to make this happen.  I'll break it down for all three of my loyal readers next week.

Friday, June 7, 2013

OpenStreetMap Vectors

I've got a talk tomorrow at the State Of the Map US conference in San Francisco.  It's about paging tiled vectors straight form the US OpenStreetMap server.

Naturally, there's new functionality in WhirlyGlobe-Maply to support this stuff.  Here's a teaser.

There are no clouds in California.  Be serious.

That's a base map overlaid with vector roads, which is one of the options I'll be talking about.

I'll put the talk up next week along with a deeper technical explanation.

Friday, May 17, 2013

GeoData Display for Mobile Devices with OpenGL ES

I gave a talk last night at the San Francisco Bay Area GeoMeetup.  This one was timed to coincide with Google I/O.

The talks were the 5 minute Ignite format and, just to be different, I went deep technical.  I pulled a couple algorithms out of WhirlyGlobe-Maply and explained them.  I like how it turned out.

The video has audio and, hey, it's short.

The slides, sans video, can be found here.

Wednesday, May 15, 2013

MapBox Earth

It's been a busy month for MapBox.  Their new OpenStreetMap editor launched, for one thing, and now they've published a pretty little app to show off their satellite data sets.

In English, yes.
Actual picture of the earth.  NASA photoshops out the labels.

It's WhirlyGlobe-Maply powering that app and, indeed, the whole thing is open source.

How It Happened

I approached MapBox about doing this one a few weeks ago.  It's basically advertising for me and it was really simple to write.  Take a look at the source code, it's just not that big.

Once I put the first version together, Justin@MapBox cleaned it up and generally made the UI elements work better.  That stuff takes more time than you realize.

Then we shipped it and now you can play with.

Future of MapBox Earth

The app's goals were to show off MapBox's lovely satellite data sets and advertise WhirlyGlobe-Maply.  I'd say we're good on both of those.  What's next depends on what people want to do with it.

Since the app itself is open source and the toolkit is open source... you can do whatever you like (within the constraints of an Apache 2.0 license).  Or you can pay me to do whatever you like, which is kind of how I make my living.

We'll see how that goes.  In the mean time there are other interesting things afoot with MapBox and mousebird consulting.

Thursday, May 2, 2013

route-me and Maply

I like route-me.  It's open source, it's been around a while, lots of people use it, and it works.  Heck, I used it on a project once.

For those in the dark, route-me is a free toolkit for displaying custom slippy maps with overlaid shape, marker and other features on iOS.

Anyway, I like route-me, which puts me in an awkward position.  I want to replace it.


I make an open source toolkit called WhirlyGlobe-Maply.  There are three ways you can use it.

3D Interactive Globe   -   Interactive 3D map with tilt   -   Interactive flat (2D) map

The WhirlyGlobe part is the globe, the Maply part is the other two.  I've done a bit with the interactive 3D map and it's a blast, but it's not what most people want to do.  They want a true flat map.

Okay, so great, I can do a flat map.  But why bother?  If you want Apple's data, you use MapKit, if you want Google's data you use their iOS API.  If you want your own data, you buy a commercial toolkit or you use route-me.  Do I really have anything to offer over route-me?

I do.  WhirlyGlobe-Maply is based on OpenGL ES.  My toolkit is in the same class of "stupid fast" as Apple's, Google's, and the commercial alternatives.  I can't beat them feature for feature, but then I don't have to.  Mine is open source.

That's a fun bit of self aggrandizement, but it really needs to lead somewhere.  I think it's only worth matching route-me's features if someone's paying.  There's money out there for this kind of thing and it's welcome to look me up.  And it did.


The MapBox guys, Justin particularly, have their own route-me variant they call the MapBox iOS SDK.  It's really nice, with a lot of functionality filled in and tons of documentation and examples, things that open source projects often lack (cough).

Very cool, but route-me uses Quartz, the technology behind UIKit (kind of).  That's what you're supposed to do, but it's not as fast as the new Apple Maps.  They're obviously not using Quartz, they're using OpenGL ES.  Maply uses OpenGL ES so...

MapBox is paying me to jack up their version of route-me and stick Maply underneath.

route-me + Maply = What?

The idea is pretty simple.  Accelerate route-me's tile display with Maply, then see if we can do anything with annotations.  In theory it looks pretty good.  The initial experiment looks good too, but we've got a ways to go.

If everything goes well, the standard route-me app might be able to switch over seamlessly.  Your custom Quartz rendering will still be Quartz, but anything you represented in route-me tile sources and annotations could be handled by Maply.  Or not.  It's an experiment, we'll see.

Two Apps: Global Schooner and Pray 2x714

Here are a couple of apps that developers have put together recently I'd like to highlight.  I had nothing to do with these other than answering a question or two along the way.

Global Schooner
Pray 2x714

Global Schooner is an app for Prairie Schooner Magazine showing where their authors are located around the world.  I like the subdued icons and the corner based navigation.

Pray 2x7:14 is an app by Rueben Thiessen and seems to be a bit of a social network for prayer.  I like his use of great circles, very nice visual.

Both of these are great examples of what you can do with the WhirlyGlobe-Maply Component without too much trouble.  These are far removed from the iPad melting insanity I make my living at and are just the sort of specialty apps I love to see using the toolkit.

I'm way behind on apps, so feel free to bug me if I haven't posted yours yet.

Wednesday, April 17, 2013

Symantec Protection Center Mobile

Sometimes big companies pick up on WhirlyGlobe-Maply.  And sometimes I can actually talk about it.  This is one of those times.

Things are calm now, but an eruption of orange pins can happen at ANY TIME.

What It Is

I'll just borrow their text to describe it.

Symantec Protection Center Mobile 1.0 provides you a view of live security threats across the globe as well as executive summary of your organization’s security posture.

Only, ya know, with a spinny globe!  It's quite fun to play with.  I sometimes use it at trade shows because it has a self actuating mode.  It will spin from threat to threat on its own if you let it.

How It Uses the Globe

In many ways, this is the quintessential WhirlyGlobe app.  It makes good use of pre-2.0 features like the static blue marble texture set and lots of vectors.  They use markers for points and labels too.  And hey, they made a video.

The absolute best part of the app is that I didn't write a single line of it.  They did ask a few questions and did some careful due diligence on the open source libraries I use, but otherwise it was a delightful surprise when it came out.  In November.... yeah, I don't know why I'm just getting around to writing about it.

More Apps Like This

I don't know why there aren't more apps like this one.  This is pretty much what I designed WhirlyGlobe version 1 to do.  What WhirlyGlobe 1.x really did was attract the high performance iPad melting map display crowd.... which resulted in WhirlyGlobe-Maply 2.x, so no complaints, but I was expecting to see more of this sort of app.

If you're looking to make a fairly straightforward spinny globe app that integrates well with your own business logic, I'd check this one out.  They did a very nice job.

Monday, April 15, 2013

Android Port

I'm exploring an Android port of WhirlyGlobe-Maply.  With the recent release of Maply, I'm getting a lot of inquiries about Android support.

Like this, but more Android-y
These are fairly serious companies asking about it.  If I had some way of simply dividing the cost among them, I suspect we'd already be there.  But that's not how consulting works or how corporations think, so we get to do this the hard way.

How Would it Work?

The low level rendering engine in WhirlyGlobe-Maply is C++.  I didn't plan it that way, I just like C++ for tossing data around and it meshes nicely with OpenGL.  All the higher level interaction code is Objective-C as you'd hope.

On Android, they provide the NDK, an interface for writing native C/C++ and running it on Android devices.  It looks pretty good and the OpenGL ES support looks solid.  The Java Native Interface is an exercise in pain, but it seems dependable.

The plan would be to port the low level rendering engine after a little restructuring on the iOS side.  Then we'd rewrite the Component level for Android, basically all the UI and object manipulation.

Android users would only see the nice, friendly thread-safe higher level interface and we'd hide all the crazy stuff only I understand.  Just like on iOS.

About the Money

I'm a consultant and I give WhirlyGlobe-Maply away for free, so I'm not going to do this for the heck of it.  It needs to be paid for.

A local mapping company, Gaia GPS, is interested.  They only need Maply, logically enough, so we'd just port the pieces to support that.  Full WhirlyGlobe-Maply support would have to follow based on other clients.

Their support, assuming the numbers work, would get the core toolkit ported, but it wouldn't be enough for a full Android release.  I need other clients to step up.

Update (5/14/2013)

The first try fell through, as deals do.  Now I'm shopping it around.  If you've got a lot of money burning a whole in your pocket, let me know.

Saturday, April 6, 2013

TransitVis - Urban Data Challenge

TransitVis is live on the Apple app store for iPad.  It's a free download.  Watch the video to learn how to use it.

Don't forget to go get some data.  That's sold separately (also free).

The Urban Data Challenge awards were today and we took 3rd.  Thanks to everyone involved in that.  Lots of great projects.

What's next for TransitVis, you might ask?  All the interesting technology is in WhirlyGlobe-Maply so that'll be popping up in client projects.  For the app itself... we'll wait to see if anyone uses TransitVis for anything and go from there.

Thursday, April 4, 2013

WhirlyGlobe-Maply 2.1 Announcement

The 2.1 release is now official.  Come, let us celebrate with an overly cluttered screen shot.

Now with 0.1 more functionality

What's In 2.1

Some of the less exciting changes are covered in various blog posts.  The good stuff is as follows.

  • Lofted Polygons.  They're pretty.
  • Auto-layout for makers and labels.  Now you can display lots of labels.
  • More shapes, like great circles and such.  
  • Now based on OpenGL ES 2.0 which allows for stuff like shaders.
  • Continuous zoom mode for getting really, really close to the ground.
  • The git project uses submodules for dependencies and data.  Easier to build.
  • Many bug fixes and performance improvements.

The high level Component is now functional enough to do just about anything you can do with the low level API.  The WhirlyGlobe-Maply Component interface is pure Objective-C, making it easier on developers.

As always, the WhirlyGlobe-Maply page is your main source of download instructions.

What's Next

Shockingly, WhirlyGlobe-Maply 2.2 is next.  It's already underway in the develop branch.  At this point it's looking like a performance release.  Crazy good performance.

TransitVis - How to Load Data

This post is about loading data into TransitVis.  I cover this in the announcement post for TransitVis, but it can't hurt to be even more explicit.  Plus I need something to link to from the app.

What does it mean?  Dunno.  Pretty!

How to Get Some Data

Once you've got the app, you'll need to load some data.  We processed all three of the data sets for use.  A data set consists of two geojson files and a sqlite database for each data set.  Be sure to download all three files and then upload them to the app via iTunes.

Getting Data Into TransitVis

Getting data into an app once you've installed is actually pretty easy.  Install the app first and then follow Apple's instructions for file sharing via iTunes.  Look for the app "TransitVis" in that window.

Here's what that looks like on my MacBook Pro.  Bring up iTunes.

Next page is all Hello Kitty apps

Select your iPad, like mine in the upper right there.  That should look like so.

That's right, rename your iPad 'mousebird'. [Don't do that]

Select the Apps tab up there along the top.  Then you should see something like this.

Only you're not trying to hide the name of client apps.

Select TransitVis and upload those files.

If you already ran the app, you'll need to kill it and rerun it as TransitVis looks for its data files on startup.  It should load the first data set it finds and make the others available for selection.