Sunday, March 18, 2012

Exploiting Cloudmade Map features in iPhone

Apple provide APIs for using google maps by adding MapKit.framework
in iOS SDK. Google map is pretty and provide a lot of features like adding pins to map, creating overlay views, making annotations, traversing the map with animation, setting region in the map.... the list leads. But it does not provide caching functionality. You can't pin on the map in off line mode. You need a active Internet connection all time when you are using the map. You cant even see your current location on map, as the current location can be fetched using GPS. These are some functionalities they excluded, till the date of writing this post.

Here comes CloudMade maps. It features all that listed above and it support custom map styles also. The disadvantage is compared to apple its not well documented. It has an active wiki, but some of the functionalities are not directly supported, which we can develope ourself !!! I am sharing some of them I have developed while using CloudMade.

1)  Caching

I have steeled this from their wiki. But this is  my suggestion and I have successfully implemented it with less pain. Others I tried (like downloading tiles using downloadosmtiles.pl and inset each tile to  map2sqlite) and not succeeded ( Actually I didn't get much time :) ). The map2sqlite is not present at their link but can be downloaded from here   (see this post)  And my suggestion is to add the plist file as described here . I edited the 'capacity' key in 'db-cache' to '0' means I configured the default database they are using with unlimited capacity. 


2) To know tiles were downloaded.


a) Import 'RMTileImageSet' by adding 

#import "RMTileImageSet.h"

b) You have to set up a Timer to achieve this like

timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self  
selector:@selector(startDowloadingTiles) userInfo:nil repeats:YES];


c) Then set delegates as


sampleMapView.delegate = self;
 
 sampleMapView.contents.tilesUpdateDelegate=self;
d) In   startDowloadingTiles method do,  

RMTileImageSet *set=[sampleMapView.contents imagesOnScreen]; 

if (set.fullyLoaded) { 

//Tiles are loaded on screen 

} 

[sampleMapView.contents imagesOnScreen] returns all the tiles on the screen. The
 
'fullyLoaded' property returns YES if all tiles on screen are loaded.