MapKit の代わりに使える route-me でマップのデータソースを切り替える

前回の、[地図SDKは MapKit だけじゃない！OSMやBingが使える iOS用 Map SDK、route-me のセットアップ方法 ](http://qiita.com/items/8f0d1e5b6d90bb93d883) の記事の続きです。
**++++10/10 15:20 追記++++**
記事中、Google Maps タイルの呼び出し方を書いていますが、既に書いている通りやはりGoogle のタイルを直接呼び出すことはライセンス的にNGなようです。
route-me を使っていたアプリではありませんが、MapKit 経由でGoogle Mapsのタイルを直接呼び出しているアプリケーションが本日マーケットから削除されたことからも、直接呼び出しができないことが伺えます。（リンク先では「スクレイピング」と表現されていますが）
参考：http://link-man.net/apps/16686/
**++++10/6 14:30 追記++++**
この記事では技術的なタイルの呼び出し方について書いていますが、実際に利用する際には各データプロバイダーの利用規約やライセンスを確認してください。
OpenStreetMap については、コメント欄で指摘されている通りライセンスはODbL に切り替わっていますので、route-me のデフォルトである CC ライセンスから変更しましょう。

```objective-c:RMOpenStreetMapSource.m
-(NSString *)shortAttribution
{
	return @"© OpenStreetMap contributors";
}
```

と書くといいでしょう。
**++++追記ここまで++++**

![前回の結果](https://dl.dropbox.com/u/442212/qiita/style-997.png "前回の結果")

MapKit の代わりに route-me を使って、上記のように無事地図が表示されるようになりましたが、どうせなら MapQuest 以外の地図も表示してみたくありませんか？ route-me を使えば、地図データのプロバイダを簡単に変更することができます。標準でサポートしているデータプロバイダーは、XCode プロジェクトの MapView.xcodeproj/Map/Tile Source/ 以下にあります。9月30日現在で、RMYahooMapSource、RMOpenCycleMapSource、RMTileMapServiceSource、RMOpenStreetMapSource、RMVirtualEarthSource、RMDBMapSource、RMAbstractMercatorWebSource、RMOpenAerialMapSource、RMSpatialCloudMapSource、RMMBTilesTileSource、RMWMSSource、RMMapQuestOSMSource、RMTileStreamSource というデータソースが存在しています。

# デフォルトロケーションの変更
データソースを変える前に、デフォルトロケーションを変更しておきましょう。デフォルトだと、RMMapContents.h で定義されているシドニー(-33.858771,151.201596)になっているので、東京駅あたりにしてみます。Map の緯度経度を設定するには、[mapView moveToLatLong:(CLLocationCoordinate2D)] が利用できます。
MainViewController:viewDidLoad を以下のように変更します。

```objective-c:MainViewController.m
/*省略*/
#define DEFAULT_LATITUDE 35.68044f
#define DEFAULT_LONGITUDE 139.76756f
/*省略*/
- (void)viewDidLoad {
    [super viewDidLoad];
    [mapView setDelegate:self];
    // use CloudMade
    id myTilesource = [[[RMCloudMadeMapSource alloc] initWithAccessKey:@"MY_MAP_KEY" styleNumber:997] autorelease];

	// have to initialize the RMMapContents object explicitly if we want it to use a particular tilesource
	[[[RMMapContents alloc] initWithView:mapView 
							  tilesource:myTilesource] autorelease];
    
    /* -- Uncomment to constrain view
    [mapView setConstraintsSW:((CLLocationCoordinate2D){-33.942221,150.996094}) 
                           NE:((CLLocationCoordinate2D){-33.771157,151.32019})]; */
	// デフォルトロケーションへ移動
    [mapView moveToLatLong:CLLocationCoordinate2DMake(DEFAULT_LATITUDE, DEFAULT_LONGITUDE)];
    
    [self updateInfo];
}
/*省略*/
```
無事東京が表示されるようになりました。
![東京](https://dl.dropbox.com/u/442212/qiita/cloudmade_tokyo.png "東京")


# Bing Maps を表示する
それでは、まずは Bing Maps を表示してみましょう。
事前に https://www.bingmapsportal.com/ でAPIキーを取得しておいてください。（アカウント作成後、Create or view keys というメニューから作成できます。）
タイルサーバの切り替えは、MapViewController.m の中の tilesource を変更することで行います。前回

```objective-c:MapViewController.m
id myTilesource = [[[RMCloudMadeMapSource alloc]
                     initWithAccessKey:@"YOUR_API_KEY" styleNumber:997] autorelease];
```

と書いていた部分ですね。ここで呼び出しているクラスを変更することで、データプロバイダを切り替えることができます。Bing Map は、RMVirtualEarthSource という名前になっています（昔 Microsoft Virtual Earth という名前だったので）。したがって、以下のように変更しましょう。（#import "RMVirtualEarthSource.h" も宣言部に追加してください。）

```objective-c:MapViewController.m
id myTilesource = [[[RMVirtualEarthSource alloc] 
                     initWithRoadThemeUsingAccessKey:@"YOUR_BING_KEY"] autorelease];
```
たったこれだけで、Bing Map に切り替えることができました。
![Bing Map](https://dl.dropbox.com/u/442212/qiita/bing_map.png "Bing Map")
initWithAerialThemeUsingAccessKey や initWithHybridThemeUsingAccessKey を使うと、航空写真やハイブリッドなども選択可能です。

# OpenStreetMap を表示する
では、次に OpenStreetMap を直接表示してみます。

```objective-c:MapViewController.m
#import "RMOpenStreetMapSource.h"
/*省略*/
id myTilesource = [[[RMOpenStreetMapSource alloc] init] autorelease];
```
簡単ですね。
![OpenStreetMap](https://dl.dropbox.com/u/442212/qiita/osm_map.png "OpenStreetMap")

# Google Map を表示する

route-me では、タイル形式で配信を行っているウェブサービスであれば、プロバイダとして利用できます。ということは、実は Google Maps もデータソースとして利用できるということになります。Google Maps のタイルサーバへ直接アクセスすることはライセンス的に許可されていない（はず）ですので、実際には使えない可能性が高いですが、一応紹介しておきます。Google のタイルサーバーに直接アクセスしているプロジェクトは他にもある（OpenLayersなど）ので、何かOKな方法があるのかも？とか思ってますが、よくわかりません。詳しい人がいたら是非教えて下さい。
**++++10/6 15:00 追記++++**
コメントにある通り、openLayers も直接タイルは呼んでないそうです。というわけで、ライセンス的にOKな方法は今のところ無いってことですかね。残念・・・
**++++追記終わり++++**

まず、RMAbstractMercatorWebSource を拡張する RegionGmapTile.h を作ります。

```objective-c:RegionGmapTile.h
//
//  RegionGmapTile.h
//  SampleMap
//
//  Created by Haruyuki Seki on 9/30/12.
//
//

#import "RMAbstractMercatorWebSource.h"

@interface RegionGmapTile : RMAbstractMercatorWebSource

@end

```

RegionGmapTile.m にタイルのエントリポイントその他を記述します。

```objective-c:RegionGmapTile.m
//
//  RegionGmapTile.m
//  SampleMap
//
//  Created by Haruyuki Seki on 9/30/12.
//
//

#import "RegionGmapTile.h"

@implementation RegionGmapTile

-(NSString*) tileURL: (RMTile) tile
{    
    NSString* url = [NSString stringWithFormat:@"http://mt0.google.com/vt/lyrs=m@127&x=%d&y=%d&z=%d",tile.x, tile.y,tile.zoom];
    return url;
}
-(NSString*) uniqueTilecacheKey
{
    return @"My Awesome Map App";
}
-(NSString *)shortName
{
    return @"My Awesome Map App";
}
-(NSString *)longDescription
{
    return @"My Awesome Map App Test";
}
-(NSString *)shortAttribution
{
    return @"Google maps";
}
-(NSString *)longAttribution
{
    return @"Google maps";
} 

@end
```

で、このクラスを呼んで見ると・・・

```objective-c:MainViewController.m
#import "RegionGmapTile.h"
/*省略*/

id myTilesource = [[[RegionGmapTile alloc] init] autorelease];
```

iOS6 に Google Map が戻ってきた！
![Google Map](https://dl.dropbox.com/u/442212/qiita/google_map.png "Google Map")

いかがでしたでしょうか。時間ができたら独自タイルサーバの呼び出しや、アノテーションなんかについても書いてみたいと思います。