2011/12/16更新

[XCODE] iPhone 方角を取得するには!?

このエントリーをはてなブックマークに追加      

本日は、iPhoneアプリケーションで方角を取得する方法を学んだので、ブログに残したいと思います。ナビアプリとかとかで方角取得処理は必要になりそうです。

f:id:yoheiM:20110318193236j:image



2つの方角

iPhoneで方角を取得する場合には注意が必要です。方角には2つあります。1つは地図上の北を表す方角(true north)、もう1つは磁石が北を示す方角(magnetic north)です。地図上の方角を取得するにはGPS機能が必要です。磁石が示す方角を取得するにはMagnetMeterが必要です(iPhone4に装備)。




方角取得のための前準備

方角取得のためには、CoreLocation.FrameworkのCLLocationManagerクラスとCLLocationManagerDelegateプロトコルを利用します。そのため以下の準備が必要です。

1、CoreLocation.Frameworkをアプリケーションに追加する。

2、CoreLocation.Frameworkをヘッダファイルで読み込む。

3、方角取得したいクラスのデリゲートにCLLocationMangerDelegateプロトコルを設定する。

ヘッダファイルの例は以下です。

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface DirectionViewController : UIViewController 
  <CLLocationManagerDelegate> {
  CLLocationManager *locationManager;
  UILabel *directionLabel;
}
@property(nonatomic, retain) IBOutlet UILabel *directionLabel;
- (IBAction) start : (id) sender;
@end



方角取得処理を開始する

方角取得処理を開始するためには、以下のような実装をします。

- (IBAction) start : (id)sender {

  if (!locationManager) {
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
  }

  // start location services to get the true heading.
  locationManager.distanceFilter = 100;
  locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
  [locationManager startUpdatingLocation];

  // start heading update
  //if (locationManager.headingAvailable == YES) {
  if ([CLLocationManagerheadingAvailable] == YES) {
  [locationManager startUpdatingHeading];
  }
}

まずは、CLLocationMangerクラスのインスタンスを作成し、デリゲートを設定します。今回はGPSも利用して方角を特定するので、位置情報が必要となります。そのため、CLLocationManagerインスタンスのstartUpdatingLocationメソッドを呼び位置情報処理を開始します。詳細な使い方は位置情報を取得するにはを参考にしてみてください。

その後、GPS機能が利用可能かを確認した後、startUpdatingHeadingメソッドで方角取得処理を開始しています。

本処理はiOS4.0以降で動作します。iOS3.xかそれ以前で動作させる場合には、GPS機能利用可能チェック処理で、locationManager.headingAvailableを利用すると動作します。




方角情報を取得する

とうとうメイン。方角を取得する方法です。CLLocationManagerDelegateの以下のメソッドをオーバーライドします。

■- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading

実装サンプルは以下です。

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
  if (newHeading.headingAccuracy < 0)
  return;

  // use true heading if it is valid.
  CLLocationDirection theHeading 
    = ((newHeading.trueHeading > 0) ? newHeading.trueHeading : newHeading.magneticHeading);

  directionLabel.text = [NSStringstringWithFormat:@"Direction : %f", theHeading];
}

まず情報の正確性について検証しています。newHeading.headingAccuracy < 0 の場合は、周り(例:PC)の磁気に影響され、正しい値が取得できていないという場合です。

続いて方角を取得しようとします。newHeading.trueHeadingが0,90,180,270など値の場合は、地図上の方角が取得できます。new.Heading.trueHeadingが負数の場合は、方角が特定できていない状態を表します。そのため負数の場合には、磁石が表す方角をここでは利用しています。CLHeadingの詳細は、CLHeading Class Referenceを参考にしてみてください。




最後に

今日は方角をiPhoneで取得してみました。この方法を学習する迄は、方角が2種類あるなんて考えて無かったですね。学習して、中学生に学んだ内容を思い出しましたw。位置情報に関するiPhoneのAPIは簡単めで使いやすい印象です。さて次はMapか。

最後にTwitter(@yoheiMune)も宜しくお願いします。







こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。