Yahoo!スタティックマップAPIについて
住所一覧を取得・表示ができたら、次は一覧から住所を選んだ際に地図を表示する画面を作ります。
今回は1~4回目で使われてきたスクロール地図ではなく、静的な一枚の画像を取得できるYahoo!スタティックマップAPIを使うことにします。
Yahoo!スタティックマップAPIを使う上で必要な情報は以下のとおりです。
- 表示したい位置の緯度経度
- 表示したい地図のズームレベル
なお日本以外では、指定できるズームレベルなどに制約があります。詳しい情報については「掲載情報について」を参照してください。
以下、緯度経度とズームレベルを指定した一例です。
(latおよびlonは「東京都新宿区舟町5」の緯度経度)
http://map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?appid=<準備したアプリケーションID>&lat=35.68966308&lon=139.72146148&z=20
上記例でアクセスすると、縦横共に500(pixel)の画像が返ってきます。もちろん画像サイズも指定することができます。
(latおよびlonは「東京都新宿区舟町5」の緯度経度)
http://map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?appid=<準備したアプリケーションID>&lat=35.68966308&lon=139.72146148&z=20&width=320&height=320
地図表示画面の作成
キーワード入力画面、リストアップ画面に続いて、地図表示画面の作成に入ります。
ズームレベルを決めてしまえば、緯度経度だけでもその場所の地図は表示できますが、住所名も表示させた方がどこの地図なのかが分かりやすいので、住所名と緯度経度は一式として扱いましょう。
これら一式は、YOLP標準フォーマットであるYDFでは、Feature要素のことです。
大まかな流れは以下のとおりです。
- 初期化の際に緯度経度情報を取得する(どこの地図なのかが分かるように、住所名も含めてまとめて取得する)
- 基本的な画面生成を行う
- 画面生成後、緯度経度情報を元にYahoo!スタティックマップAPIにアクセスする
- Yahoo!スタティックマップAPIからレスポンスを取得したら、画像として画面に表示させる
レスポンスを取得した後の処理は、JSONか画像かの違いはありますが、先のYahoo!ジオコーダAPIにアクセスしたときと同じと言えます。
- UIViewControllerをサブクラスとし、緯度経度を受け取れるイニシャライズのメソッドを用意する
- UIViewControllerのviewDidLoadで、画像を表示するUIImageViewを準備する
- UIViewControllerのviewDidLoadの最後に、Yahoo!スタティックマップAPIへアクセスするためにNSURLConnectionを使う
- Yahoo!スタティックマップAPIから得られたデータを、viewDidLoadで用意したUIImageViewに反映させる
[File]-[New]-[New File](Xcode4.3では[File])を選んで、新しいファイルのテンプレート選択画面を出します。
テンプレートは「UIViewController subclass」(Xcode4.3では「Objective-C class」)を選んで、クラス名はMapImageViewController、サブクラスはUIViewControllerでファイルを作ります。
#import <UIKit/UIKit.h>
@interface MapImageViewController : UIViewController {
NSDictionary *_feature;
NSString *_lat;
NSString *_lon;
NSURLConnection *_connection;
NSMutableData *_data;
UIImageView *_imageView;
}
- (id)initWithFeature:(NSDictionary *)feature;
@end
#import "MapImageViewController.h"
#define APP_ID @"<準備したアプリケーションID>"
#define IMAGE_WIDTH 320.0f
#define IMAGE_HIGHT 320.0f
@implementation MapImageViewController
- (id)initWithFeature:(NSDictionary *)feature {
self = [super init];
if (self) {
_feature = [feature retain];
_connection = nil;
_data = nil;
_imageView = nil;
}
return self;
}
- (void)dealloc {
[_feature release];
if(_connection){
[_connection cancel];
[_connection release];
}
[_data release];
[_imageView release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = [_feature objectForKey:@"Name"];
if(_imageView == nil){
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, IMAGE_WIDTH, IMAGE_HIGHT)];
//feature要素から緯度経度を抜き出す
NSDictionary *targetGeometory = [_feature objectForKey:@"Geometry"];
NSString *coordinate = [targetGeometory objectForKey:@"Coordinates"];
NSArray *aryLonLat = [coordinate componentsSeparatedByString:@","];
NSString *lat = [aryLonLat objectAtIndex:1];
NSString *lon = [aryLonLat objectAtIndex:0];
//取得する画像サイズをあらかじめ定義しておく(Retina対応)
NSUInteger imageWidth = (NSUInteger)(IMAGE_WIDTH*[UIScreen mainScreen].scale);
NSUInteger imageHeight = (NSUInteger)(IMAGE_HIGHT*[UIScreen mainScreen].scale);
//ズームレベルは20で固定
NSMutableArray *paramList = [[NSMutableArray alloc] init];
[paramList addObject:[NSString stringWithFormat:@"appid=%@",APP_ID]];
[paramList addObject:[NSString stringWithFormat:@"lat=%@",lat]];
[paramList addObject:[NSString stringWithFormat:@"lon=%@",lon]];
[paramList addObject:@"z=20"];
[paramList addObject:[NSString stringWithFormat:@"width=%d",imageWidth]];
[paramList addObject:[NSString stringWithFormat:@"height=%d",imageHeight]];
NSString *urlString = [NSString stringWithFormat:@"http://map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?%@",[paramList componentsJoinedByString:@"&"]];
[paramList release];
NSLog(@"%@",urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//画面中央に置かれるように指定
_imageView.center = CGPointMake(self.view.bounds.size.width/2.0f, self.view.bounds.size.height/2.0f);
_imageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:_imageView];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - NSURLConnection delegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[_connection cancel];
[_connection autorelease],_connection = nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if(_data){
[_data release];
}
_data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
UIImage *tmpImage = [UIImage imageWithData:_data];
_imageView.image = [UIImage imageWithCGImage:tmpImage.CGImage scale:[UIScreen mainScreen].scale orientation:tmpImage.imageOrientation];
[_connection autorelease],_connection = nil;
[_data release],_data = nil;
}
@end
これで地図表示画面ができました。
この画面を住所候補リストアップ画面から呼び出すために、住所候補リストアップ画面のプログラムを少しだけ書き換えます。
#import "GeoCodingViewController.h"
//作成した地図表示画面を使えるようにimport文を追加
#import "MapImageViewController.h"
---- 中略 ----
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"AddressCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *target = [_resultList objectAtIndex:indexPath.row];
cell.textLabel.text = [target objectForKey:@"Name"];
cell.detailTextLabel.text = [[target objectForKey:@"Property"] objectForKey:@"Yomi"];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//ここから追加
NSDictionary *target = [_resultList objectAtIndex:indexPath.row];
MapImageViewController *next = [[[MapImageViewController alloc] initWithFeature:target] autorelease];
[self.navigationController pushViewController:next animated:YES];
//追加ここまで
}
---- 以下略 ----
これを実行してキーワード入力、住所一覧から選択することで以下のような画面で地図が表示されます。

