CoreLocationで現在位置を取得する


CoreLocationフレームワークを使うと現在の位置情報を取得することができる。

iPhoneにはGPSセンサーが搭載されているが、GPS衛生からの電波だけでなくWi-Fiホットスポットや携帯の基地局から信号を使って位置特定の精度をあげているようだ。この部分についてはプログラムの実装上意識する必要はなく、単純にCoreLocationフレームワーク側でその時使える情報を元に位置特定をしてくれる。

CoreLocationフレームワークの追加

CoreLocation.frameworkをプロジェクトに追加しておく。

位置情報取得の流れ

位置情報の取得もUIAccelerometerによる加速度情報の取得のようにデリゲートを使った、Cocoaらしい実装方法になっている。

  1. CLLocationManagerのインスタンスを生成する
  2. 位置情報の取得を開始させる
  3. 位置情報が更新されると、デリゲート先として指定したオブジェクト上でメソッドが呼ばれる

startUpdatingLocationとstopUpdatingLocationメソッドで計測を開始/停止できる。なお、startUpdatingHeading/stopUpdatingHeadingメソッドを使うと方位情報の取得もできるようだが、残念ながら3GSが手元にないため実験できない。

位置情報が更新されると、locationManager:didUpdateToLocation:fromLocation:というメソッドが呼ばれる。引数には移動前と現在の地点の緯度と経度情報が入っているので、ここから現在の位置情報を取得することができる。

実際に実装してみると下記のような形になる。

LocationTracker.h

//
//  LocationTracker.h
//  gps_tracking
//

#import 
#import 

@interface LocationTracker : NSObject  {
	id _delegate;

	CLLocationManager *locationManager;
	BOOL isTracking;

	float currentLatitude, currentLongitude;
}
@property (readonly) BOOL isTracking;
@property (readonly) float currentLatitude, currentLongitude;
- (id)initWithDelegate:(id)delegate;
- (void)startTracking;
- (void)stopTracking;
- (void)toggleTracking;
@end

LocationTracker.mm

//
//  LocationTracker.mm
//  gps_tracking
//

#import "LocationTracker.h"

@implementation LocationTracker
@synthesize isTracking, currentLatitude, currentLongitude;

- (id)initWithDelegate:(id)delegate{
	if (self = [super init]){
		_delegate = delegate;

		locationManager = [[CLLocationManager alloc] init];
		locationManager.delegate = self;

		isTracking = NO;
		currentLatitude = 0.0f;
		currentLongitude = 0.0f;
	}
	return self;
}
- (void)startTracking{
	isTracking = YES;
	[locationManager startUpdatingLocation];
}
- (void)stopTracking{
	isTracking = NO;
	[locationManager stopUpdatingLocation];
}

- (void)toggleTracking{
	if (isTracking) {
		[self stopTracking];
	}else{
		[self startTracking];
	}
}

//位置情報が更新されたときに呼ばれるメソッドです
- (void)locationManager:(CLLocationManager*)manager
	didUpdateToLocation:(CLLocation*)newLocation
		   fromLocation:(CLLocation*)oldLocation
{
    CLLocationCoordinate2D coordinate = newLocation.coordinate;
	currentLatitude = coordinate.latitude;
	currentLongitude = coordinate.longitude;

	//デリゲート先に情報が更新されたことを通知しておきます
	[_delegate performSelector:@selector(locationUpdated:) withObject:self];
}

- (void)dealloc{
	[locationManager stopUpdatingLocation];
	locationManager.delegate = nil;
	[locationManager release];

	[super dealloc];
}

@end

コントローラ ヘッダファイル

//
//  gps_trackingViewController.h
//  gps_tracking
//

#import 
#import "LocationTracker.h"

@interface gps_trackingViewController : UIViewController {
	LocationTracker *tracker;
	IBOutlet UILabel *currentLocationLabel;
}
- (IBAction)toggleTracking:(id)sender;
- (void)locationUpdated:(id)sender;
@end

コントローラ モジュールファイル(重要部分のみ)

- (IBAction)toggleTracking:(id)sender{
	[tracker toggleTracking];
}

//LocationTracker側で位置情報が更新された時に呼ばれます
- (void)locationUpdated:(id)sender{
	LocationTracker* _tracker = (LocationTracker*)sender;
	[currentLocationLabel setText:[NSString stringWithFormat:@"%f, %f",
								   _tracker.currentLatitude, _tracker.currentLongitude]];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

	tracker = [[LocationTracker alloc] initWithDelegate:self];
}

実際に上のコードを使って位置情報の取得を行おうとすると、確認ダイアログが表示される。
img_0222

セキュリティの都合上、これを表示させないようにすることはプログラム側ではできないようだ。
img_0223

OKを押すと計測が始まり、現在位置を取得することができた。なお、iPod touchでもWi-Fiの信号を元に位置特定ができるのだが、試しに実験してみたところアメリカのとある地点の位置情報が表示された(ここは日本)ので、どうやらあまり期待はできない模様。iPod touchでどうしても位置情報の取得が必要になる場合はPlace Engineのサービス開放に期待するしかなさそうだ。

参考資料:

  1. アップル – iPhone – GPS搭載マップと新しいコンパスで経路を確認。
  2. iPhone Dev Center: CLLocationManager Class Reference
  3. iPhoneアプリ入門(GPS) (iPhone App Docs)
  4. 【コラム】実践! iPhoneアプリ開発15 ロギングアプリの作り方 (1) – Core Locationで現在地を取得する | エンタープライズ | マイコミジャーナル

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です