iPhone 位置情報を取得するには

今日は、iPhoneアプリケーションで場所を取得する方法を学んだので記載したいと思います。CLLocationManagerクラスを利用しますが、そのクラスへの設定情報の種類も記載しました。
こんな画面です。

「Start」ボタンを押す事で位置情報取得を開始し、「Stop」ボタンを押す事で位置情報取得を終了します。位置情報を取得したら随時、ラベルに表示します。


事前準備

位置情報取得のサービスを利用するには、CoreLocationFrameworkが必要です。XCODEプロジェクトに「CoreLocation.framework」を追加します。また利用するクラスのヘッダファイル(例:LocationViewController.h)で、「#import 」を記述し、CoreLocationFrameworkをインポートします。
また、位置情報取得したときに動作を行いたいため、「CLLocationManagerDelegate」をデリゲードに指定しています。
ヘッダファイル例:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface LocationViewController : UIViewController <CLLocationManagerDelegate> {

UILabel *locationLabel;
CLLocationManager *manager;
}

@property (nonatomic, retain) IBOutlet UILabel *locationLabel;

- (IBAction) start : (id) sender;
- (IBAction) stop : (id) sender;

@end

位置情報取得を開始する

位置情報取得を開始するために、以下のようなコードを記述します。

- (IBAction) start : (id) sender {
// if CLLocationManager Instance already exists, no need this process;
if (manager)
  return;


manager = [[CLLocationManager alloc] init];
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyBest;
manager.distanceFilter = kCLDistanceFilterNone;

if ([CLLocationManager locationServicesEnabled] == YES || locationManager.locationServicesEnabled == YES) {
 [manager startUpdatingLocation];
}
}

今回はstart:というメソッドに、位置情報取得の開始を記述しています。「CLLocationManager」インスタンスを作成後、デリゲート(delegate)、取得精度(desiredAccuracy)、更新頻度(distanceFilter)を指定し、その後、位置取得を開始しています。

「CLLocationManager」の「desiredAcuracy」に設定できる情報

■ kCLLocationAccuracyBestForNavigation(iOS4.0以降)。最高精度の設定。ナビアプリなど常に位置情報を更新する必要がある時に利用する。また電池消費量がとても多いので、デバイスがプラグに接続されているときに利用する方が良い。
■ kCLLocationAccuracyBest(iOS2.0以降)。iOS2やiOS3では最高精度設定。
■ kCLLocationAccuracyNearestTenMeters(iOS2.0以降)。誤差が10メートル以内の精度設定。
■ kCLLocationAccuracyHundredMeters(iOS2.0以降)。誤差が100メートル以内の精度設定。
■ kCLLocationAccuracyKilometer(iOS2.0以降)。誤差が約1キロメートル以内の精度設定。
■ kCLLocationAccuracyThreeKilometers(iOS2.0以降)。精度が約3キロメートルいないの精度設定。

「CLLocationManager」の「desiredAcuracy」に設定する情報

ユーザーが何メートル動いたら位置更新イベントを生成するかを設定する。単位はメートル。デフォルト値は「kCLDistanceFilterNone」でユーザーの全ての動きに合わせて位置情報イベントを生成する。

その他「CLLocationManager」に関する詳細情報は、CLLocationManager Class Referenceを参考にしてみてください。


位置情報サービスが利用できるかを確認する

バイスによっては位置情報取得サービスを利用できない、またはユーザーによって無効かされている事があるので、位置情報サービスを利用できるかは確認する必要があります。確認方法はiOSのバージョンにより異なります。
iOS4.0 or later : CLLocationMangerのプロパティlocationServicesEnabledを利用します。
■IOS3.x or before : CLLocationMangerのlocationServicesEnabledクラスメソッドを利用します。
上記のどちらかがYESを返す場合は、位置情報サービスを利用できます。


位置情報を取得したときに動作させる

位置情報取得時の動作は以下のようなコードを記載します。

- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// locationManager sometimes return cache object, so i shold check newLocation is row or cache.
NSTimeInterval howRecent = [newLocation.timestamp timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
 NSMutableString *str = [[NSMutableStringalloc] init];
 [str appendFormat:@"旧経緯度:%+.6f, %+.6f \n", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude];
 [str appendFormat:@"新経緯度:%+.6f, %+.6f \n", newLocation.coordinate.latitude, newLocation.coordinate.longitude];
 [str appendFormat:@"高度:%+.6f \n", newLocation.altitude];
 [str appendFormat:@"詳細:%@ \n", [newLocation description]];
 [str appendFormat:@"経過時間:%.4f \n", [newLocation.timestamp timeIntervalSinceNow]];

 self.locationLabel.text = str;
}
// else skip the event.
}

「CLLocationManagerDelegate」の「locationManager:didUpdateToLocation:fromLocation:」メソッドをオーバーライドする事で、位置情報取得時に任意の動作を規定できます。ここでは、経度、緯度、高度、詳細説明、位置情報取得時からの経過時間をラベルに表示しています。
また、メソッドの最初でイベント生成時間をチェックしています。CLLocationManagerは時々キャッシュしたイベントを通知する場合があるため、本メソッドでは取得したイベントは直近のものかキャッシュのものかを確認する必要があります。


位置情報取得を終了させるには

位置情報取得を終了させるには以下のようなコードを記載します。

- (IBAction) stop : (id) sender {
[manager stopUpdatingLocation];
[manager release];
manager = nil;
}

「CLLocationManager」の「stopUpdatingLocation」メソッドを呼び出し、位置情報取得を終了させます。その後、インスタンスをリリースしています。


最後に

今回の方法は、細かい間隔で位置情報を取得できるところはいいんですが、電池をたくさん消耗するようです。代わりに「CLLocationManager」クラスの「startSignificantLocationChanges」を利用して、電池消耗を抑えて位置情報を取得する方法もあるようです(色々と制約がありますが)。詳細はLocation Awareness Programming Guideを参考にしてみてください。
位置情報取得できたので、お散歩コース記憶アプリでも作ってみよー。iPhoneアプリはたくさん学ぶ事があって楽しいですね(⌒▽⌒)
またもし良ければTwitter@yoheiMuneもよろしくお願いします。フォローお返しします。
またまた関係ないですが、豊洲ららぽーとで食事をしたときにテーブル上にあったろうそくの写真。おしゃれ。