iOSでGoogleMaps及び地図アプリを利用した経路検索
アプリからGoogle MapsやApple標準の地図アプリを起動し、経路を表示させる方法。
GoogleMapの起動方法
以下のサイトに記載されているURLとパラメータでGoogle Mapsが起動できる。Google Mapsがインストールされていない場合は、後述の方法で、SafariでGoogleMapsを開くことができる。
Google Maps URL Scheme - Google Maps SDK for iOS — Google Developers
//GoogleMapsがインストールされている場合 if ([[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"comgooglemaps://"]]) { //Google Mapsの起動 [[UIApplication sharedApplication] openURL: [NSURL URLWithString:@"comgooglemaps://?saddr=40.765819,-73.975866&daddr=14&directionsmode=transit"]]; //インストールされていない場合 } else { NSLog(@"Can't use comgooglemaps://"); }
saddr
は出発地のパラメータで、緯度(latitude),経度(longitude)
での指定と東京都新宿区西新宿二丁目8番1号
のような住所指定が可能である。但し、住所で指定する場合は、URLEncodeが必要である。何も指定しない場合は、現在地が使われるとあるが、上手く動作しない場合もある?
daddr
は目的地のパラメータで、saddr
と同じ指定が可能。
directionsmode
は、経路の手段で、公共交通機関を使う場合はtransit
を指定する。他に、車、自転車、徒歩の指定が、それぞれdriving
, bicycling
, walking
で指定可能である。
Safariで起動する場合は、URLを変更してopenURL
をするだけで良い。以下はGoogleMapsがインストールされていない場合に、SafariでGoogle Mapsを開くように、上記のプログラムを改良したものである。
//GoogleMapsがインストールされている場合 if ([[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"comgooglemaps://"]]) { //Google Mapsの起動 [[UIApplication sharedApplication] openURL: [NSURL URLWithString:@"comgooglemaps://?saddr=40.765819,-73.975866&daddr=14&directionsmode=transit"]]; //インストールされていない場合 } else { //Safariで起動 [[UIApplication sharedApplication] openURL: [NSURL URLWithString:@"https://maps.google.com/maps?saddr=40.765819,-73.975866&daddr=14&directionsmode=transit"]]; }
最後にまとめとして、目的地と出発地を指定して地図アプリを起動するメソッドを載せておく。
/* source:出発地。@"住所" or @"緯度(latitude),経度(longitude)"を指定。 destination:目的地。@"住所" or @"緯度(latitude),経度(longitude)"を指定。 @""やnilの場合は、現在地が指定されるが上手く動作しない場合もある。 directionsMode:@"transit" or @"driving" or @"bicycling" or @"walking"を指定。 */ - (void)launchMapApplicatoinToGetDirections:(NSString *)source destination:(NSString *)destination directionsMode:(NSString *)directionsMode { NSString *encodedSource = @""; NSString *encodedDestination = @""; if ([destination length] > 0) { encodedDestination = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)destination, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); } if ([source length] >0 ) { encodedSource = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)source, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); } NSString *url = [NSString stringWithFormat:@"comgooglemaps://?saddr=%@&daddr=%@&directionsmode=%@", encodedSource, encodedDestination, directionsMode]; NSURL *URL = [NSURL URLWithString:url]; if ([[UIApplication sharedApplication] canOpenURL:URL]) { [[UIApplication sharedApplication] openURL:URL]; } else { NSString *httpUrl = [NSString stringWithFormat:@"https://maps.google.com/maps?saddr=%@&daddr=%@&directionsmode=%@", encodedSource, encodedDestination, directionsMode]; NSURL *httpURL = [NSURL URLWithString:httpUrl]; [[UIApplication sharedApplication] openURL:httpURL]; } }
Appleの地図アプリの起動
Appleの地図アプリでは、(少なくともiOS7までは)経路は車ないし徒歩での経路しか表示できないが、一応起動方法をかく。
iOS5以前の場合はこの方法では起動しないので注意。
sourceCoordinate
及びdestinationCoordinate
を指定すれば動作する。sourcePlace
及びdestinationPlace
は出発地と目的地の名称で、ピンに付与される。
//出発地の緯度、経度 CLLocationCoordinate2D sourceCoordinate = CLLocationCoordinate2DMake(35.69384, 139.703549); //目的地の緯度、経度 CLLocationCoordinate2D destinationCoordinate = CLLocationCoordinate2DMake(35.689185, 139.691648); //出発地の名称 NSString *sourcePlace = @"新宿"; //目的地の名称 NSString *destinationPlace = @"東京都新宿区西新宿二丁目8番1号"; Class itemClass = [MKMapItem class]; //iOS5以前は実行されない if (itemClass) { //出発地の作成 MKPlacemark *sourcePlacemark = [[MKPlacemark alloc] initWithCoordinate:sourceCoordinate addressDictionary:nil]; MKMapItem *source = [[MKMapItem alloc] initWithPlacemark:sourcePlacemark]; source.name = sourcePlace; //目的地の作成 MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoordinate addressDictionary:nil]; MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark]; destination.name = destinationPlace; /// option NSDictionary *options = @{ //車の場合はMKLaunchOptionsDirectionsModeDriving MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking }; NSArray *array = [NSArray arrayWithObjects:source, destination, nil]; //開く BOOL result = [MKMapItem openMapsWithItems:array launchOptions:options]; if (result == NO) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Apple Map.app を開けませんでした" delegate:nil cancelButtonTitle:@"閉じる" otherButtonTitles:nil]; [alert show]; } }
現在位置の取得
現在地の取得は、CLLocationManager
クラスを使う。startUpdatingLocation
で位置情報の取得を開始する。
位置情報は、delegateで指定した- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
がcallbackとして呼ばれるので、位置情報取得後の処理はそちらに書く。このメソッドは、位置情報が更新される度に呼ばれるので、一度で良い場合は、stopUpdatingLocation
で更新を停止させる。
locations
には、- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
が呼ばれるまでに取得された位置情報がCLLocation
クラスで記録される。最後に取得された位置情報は、[locations lastObject]
で取得される。
- (void)someMethod{ if (self.locationManager == nil) { self.locationManager = [[CLLocationManager alloc] init]; } self.locationManager.distanceFilter = kCLDistanceFilterNone; //精度 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; //CLLocationManagerDelegate self.locationManager = self; [self.locationManager startUpdatingLocation]; } /* callbackとして呼ばれる。 manager:startUpdatingLocationを実行したCLLocationManager locations:以前の更新から現在までに新しく取得された位置情報。1個から複数個 */ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { //位置情報の更新をやめる [self.locationManager stopUpdatingLocation]; //現在位置 CLLocation *location = [locations lastObject]; /* locationを使った処理 */ }
CLLocationsManagerは、クラスのインスタンス変数として保持した方が良い。startUpdatingLocation
メソッドは、GPSに位置情報の取得を依頼するだけですぐ処理が終了するので、someMethod
内で宣言している変数は破棄される。