iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
地図アプリケーションといえば住所から地図を検索する機能を期待すると思うが、住所から位置情報を取得する機能はBing Maps iOS SDKに含まれていない。特に、Bingにこだわる必要はないが、せっかくなので、Bing Maps REST Servciesを使うことにした。
以下が検索要求を出すコードだ。
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
if ((searchBar.text == nil) || (searchBar.text.length <= 0)) return;
self.data = [[NSMutableData alloc] init];
NSString *bingMapsKey = [[NSBundle mainBundle] objectForInfoDictionaryKey: @"BingMapsKey"];
NSString *query = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)searchBar.text,
NULL,
(CFStringRef)@"!*%'();:@&=+-$,/?%#[]~",
kCFStringEncodingUTF8);
NSString *url = [[NSString alloc] initWithFormat:@"http://dev.virtualearth.net/REST/v1/Locations?query=%@&key=%@&c=%@-%@",
query,
bingMapsKey,
[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode],
[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]];
NSLog(@"url: %@", url);
NSURLRequest *urlRequest = nil;
urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
cパラメータにja-jpを指定しないと、日本語の住所が上手く検索できない。当初、入力されたテキストの言語に対応したcパラメータの指定を考えてみたが、よい考えが思い浮かばなかったので、止めた。
応答結果から緯度経度を取り出して、その位置を表示するコードだ。
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSError *error = nil;
NSDictionary *content = [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingAllowFragments error:&error];
NSLog(@"content:%@", content);
if (content) {
NSArray *resourceSets = [content objectForKey:@"resourceSets"];
NSLog(@"resourceSets:%@", resourceSets);
if (resourceSets) {
NSDictionary *resource = [resourceSets objectAtIndex:0];
NSLog(@"resource:%@", resource);
if (resource) {
NSArray *resources = [resource objectForKey:@"resources"];
NSLog(@"resources:%@", resources);
if ((resources) && (0 < [resources count])) {
resource = [resources objectAtIndex:0];
NSLog(@"resource:%@", resource);
if (resource) {
NSDictionary *point = [resource objectForKey:@"point"];
NSLog(@"point:%@", point);
if (point) {
NSArray *coordinates = [point objectForKey:@"coordinates"];
NSLog(@"coordinates:%@", coordinates);
if ((coordinates) && (0 < [coordinates count])) {
NSString *latitude = [coordinates objectAtIndex:0];
NSString *longitude = [coordinates objectAtIndex:1];
NSLog(@"latitude:%@", latitude);
NSLog(@"longitude:%@", longitude);
if ((latitude) && (longitude)) {
BMCoordinateRegion newRegion;
newRegion.center.latitude = [latitude floatValue];
newRegion.center.longitude = [longitude floatValue];
newRegion.span.latitudeDelta = 0.005;
newRegion.span.longitudeDelta = 0.005;
[self.mapView setRegion:newRegion animated:YES];
}
}
}
}
}
}
}
}
if ([self.searchBar canResignFirstResponder])
[self.searchBar resignFirstResponder];
}
条件分が深くなっているのは格好が悪いが、サンプルなので勘弁して欲しい。
探偵物語の工藤探偵事務所の住所を表示してみた。