BBC Bangladesh River Journey

Been lending a hand to Brighton local web developers Dharmafly with a project for the BBC World Service, Bangladesh River Journey, Charting the course of climate change. World Service reporters from 17 different language services are joining the journey, tracking the effects of climate change in Bangladesh — historically flooding year after year, and extremely vulnerable to raising sea levels and extreme weather. It was fun to work these guys, their focus is on Ethical Web Development, and Dharmafly pulled together a nice package of services, including a few cool hacks, to pull this off.

There’s very live coverage of the journey. The reporters are taking photos on flickr and posting updates on twitter. Of course, it’s all on a Google Map. One really nice geekity are locations reported from the field via location nanoformats, ala twittervision. There’s GeoRSS, microformats, and an API (dharmafly has more on this on their blog).

It’s interesting to ponder that with the relaunch of FireEagle, and perhaps some extensions to Pipes, the majority of the backend which brings together twitter, flickr, and their blog, with geographical ordering, could be developed without a server, on web native platforms.

Notice anything unusual in this screenshot? This is what I spent a good chunk of my time on…


That GMaps InfoWindow has escaped the bounds of the Google Map. The map area we had within the template is on the small side, so to take full advantage of the space we developed a CustomBalloon class, which steals the InfoWindow from Google Maps, and places it in the main DOM and takes over all the positioning. So it’s a freed infowindow, in the familiar Google Maps style.

It’s a nice little, useful hack. And it gave me a new appreciation for the humble GInfoWindow. Google is doing some very clever things there, just take a look at the single image used to construct all elements of an GInfoWindow. CSS based masking and positioning are employed so that only a single image download is required.

OpenStreetMap on the iPhone!

The iPhone is amazing. And the Maps application is pretty special. Only problem with it is that Google Maps is the only available data source. Well I’ve just been working on that. Now, there’s OpenStreetMap on the iPhone

OSM Central London on the iPhone
OSM Isle of Wight on the IPhone

These are screenshots of OpenStreetMap tiles, viewed in the native iPhone Maps application. Wooooooo

How you can do it

So it’s pretty easy to try it out. You’ll need to have jailbreak’d your phone (I used iBrickr, there’s plenty of other methods out there, even for 1.1.1). Download the maps tile cache db, and copy it over to your phone, using scp or whatever. The tile cache db is about 30 MB, so please only download if you’re going to try it. Also, I’ve had the Maps App crash occasionally when browsing the Maps, though nothing fatal .. so use at your own risk.

cp to /var/root/Library/Caches/MapTiles/MapTiles.sqlitedb on your phone
restart your phone

How its done

My first idea was to modify the configuration or constant that the Maps App used for constructing Google Maps tile requests. Andrew helped with decompiling and pointers to other files, but we had no luck as yet. But looking at the app or at the GMM module in a hex editor, there appeared to be SQL inserts of tile pointers .. perhaps Maps was using a database to cache requested tiles. Searching through the filesystem found MapTiles.sqlitedb. That db has just two tables..

sqlite> .schema
CREATE TABLE images(zoom int, x int, y int, flags int, length int, data blob);
CREATE TABLE version(version int);
CREATE INDEX index1 on images (zoom,x,y,flags);

images was simply storing the zoom, x, and y of each tile. flags was set to ‘2’ for street maps, ‘3’ for aerial imagery. length appeared to be the size of the data blob. And data was the png. So simply adding new rows to this table, with OpenStreetMap tiles rather than Google, would have the Map app using OSM.

I needed to grab a bunch of OSM tiles. Asked on #osm, and Almien helpfully contributed a script to download all tiles on a zoom level within a bbox.

And I needed to easily insert BLOBs of the tile pngs into the sqlite db. This sqlite tutorial had just the right code, eatblob.c. I wrote a script which walked through the directory of downloaded tiles, and insert each one into a copy of MapTiles.sqlitedb. All of central London at zoom 18 took a while to download and insert, and came out at 60 MB.

Actually, there’s nothing particularly OSM about this method. Could download Yahoo or Multimap or yea Google tiles, and stuff them into the cache db.


There are the crashes I mentioned. Haven’t debugged this yet, but I figure this is surmountable. Perhaps the file size of the tiles are too large.

The Maps App zoom levels are off by one. What it calls zoom level 13, are actually being tiled as if it was zoom level 14.
(zoom off by 1). Perhaps the tiles on the iPhone are half the width and height of normal tiles? I haven’t looked into this and its late, so I don’t even know if that’s a plausible explanation.

There’s still a little Google logo in the lower left corner, need to replace that too!

Last thing, don’t know how the cache is refreshed. It’s not going to grow without bound — when and why are things expired from the cache?

Other Methods

There are probably better ways to do this. One would be to modify the binary, or whatever module or library or configuration file that stores the url or ip address used when constructing requests for Google Maps tiles, and modifying that to request directly from OSM. Or write a provider independent version of the Map App — tiling seems to be part of a core library in the phone, it looks like Safari uses the same stuff to zoom in and out on web pages. If anyone starts looking into this, drop me a line.