iPhoneSDKで現在位置取得&地図表示

TamaCです。
iPhoneアプリをいじってみたのでメモ代わりにのこしておきます。

Objective-Cを1週間ほどやってみたのですが、
なかなか難しいですね。

初めてObjective-Cを触る方は、どこがObjective-Cのコードで、どこがiPhoneSDKのライブラリなのかをはっきりわけるとこから入るといいと思います。

ところで、現在位置を取得して位置表示など簡単なアプリを設計しましたので
復習がてら書きます
開発ツールバージョンは
xcode4.0.2
iOS SDK4.3
です。

現在位置表示アプリ


こんな感じのをつくります。
いまいる現在地から地図を表示するものです。
※この緯度、経度、マップはでたらめです




作る!

早速つくります
まずはプロジェクトの生成。特に遷移とかもないのでView-based Applicationで。
名前は「CurrentMap」などにしました。




xibの設定

xibは最初にできあがりイメージをつかむのにも、私は最初に基盤だけ設定します。
画面の大半をMKMapViewにして
下の方にLabelを配置しました。ドラッグアンドドロップでできるわかりやすいインターフェースです。




フレームワークの追加

今回の現在位置のマップを表示するにあたって



・現在位置の取得
・マップの表示

が必要です。デフォルトではこのような機能を実装するには大変なので、簡単に使えるようにライブラリ追加して使えるようにします。
ちょっとわかりにくいですが
左上の「CurrentMap」からTARGETSの「CurrentMap」、右側の「Build Phases」からその下の「Link Binary With Libraries」の▶をクリックします。
するといま入っているフレームワークが出てくるので、その下の「+」記号をクリックします。

クリックすると既存ライブラリが出てくるので、
位置情報関連ライブラリの「CoreLocation.framework」と
マップ関連ライブラリの「MapKit.framework」と追加します。

↓追加前

↓追加後




CurrentMapViewController.hの設定

だいぶ準備が整ってきたのでコード編集にいきます。
CurrentMapViewController.hを編集します。

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h> // 位置情報関連のライブラリ読み込み
#import <MapKit/MKmapView.h> // 地図情報関連のライブラリ読み込み

@interface CurrentMapViewController : UIViewController<CLLocationManagerDelegate> {
    MKMapView    *mapview;        // 地図表示用
    UILabel      *locationlabel;  // 下部の表示用
    
    CLLocationCoordinate2D coordinate; // 現在の緯度経度
}

@property (nonatomic, retain) IBOutlet MKMapView *mapview;
@property (nonatomic, retain) IBOutlet UILabel   *locationlabel;

@property (nonatomic) CLLocationCoordinate2D coordinate;

@end

こんな感じです。nonatomic とかはまだ勉強中です。よく使うので今のところおまじないの感覚です。




xibの編集

ここでCurrentMapViewController.hでIBOutletを定義したので、xibファイルで場所を結びつけてあげます。
IBOutletで定義した変数はxibのどこかの部分と結びついている = 画面からタッチした後の動きなどを定義するためのパイプ役
と考えてもらっていい思います。

CurrentMapViewController.xibで
「File's Owner」を選択し、
右側の→記号をクリックします。

すると下のような画像が出るので、○部分をドラッグアンドドロップして、MKMapViewとLabel部分に結びつけます。



CurrentMapViewController.mの編集

まずはCurrentMapViewController.hで定義した変数をsynthesizeします。

#import "CurrentMapViewController.h"

@implementation CurrentMapViewController
@synthesize mapview;
@synthesize locationlabel;

@synthesize coordinate;




viewDidLoadの編集

同じファイルのCurrentMapViewController.mのviewDidLoadの編集。
アプリが起動したタイミングで呼ばれるメソッドです。

- (void)viewDidLoad
{
    [super viewDidLoad];
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    if ([CLLocationManager locationServicesEnabled]){ // 位置情報が取得可能か
        locationManager.delegate = self;
        [locationManager startUpdatingLocation]; // 位置取得開始
    } else {
        NSLog(@"ロケーションサービスを利用できません");
    }
}


現在地が取得できた場合のメソッドのオーバーライド

こちらも同じくCurrentMapViewController.m内で次のメソッドを定義します。
これは追加したライブラリのCoreLocation内のメソッドのオーバーライドです。
ファイルないであれば基本的に場所はどこでも良いので追加します。

// 位置情報が取得できた場合の処理
- (void)locationManager:(CLLocationManager *)manager
 didUpdateToLocation:(CLLocation *)newLocation
 fromLocation:(CLLocation *)oldLocation
{
    // 緯度経度取得の確認のため。
    NSLog(@"緯度:%fと経度%f", [newLocation coordinate].latitude,
 [newLocation coordinate].longitude);
    
    coordinate = newLocation.coordinate;
    
    [self displayLocation];
    // 取得した座標を中心に地図を表示
    MKCoordinateRegion zoom = mapview.region;
    // どのくらいの範囲までズームするか。※値が小さいほどズームします
    zoom.span.latitudeDelta = 0.001;
    zoom.span.longitudeDelta = 0.001;
    // ズームする
    [mapview setRegion:zoom animated: YES];
    // 動きをつけながら表示
    [mapview setCenterCoordinate:newLocation.coordinate animated:YES];
    // ラベルに書き出す
    [locationlabel setText:[NSString stringWithFormat:
                            @"緯度:%.2f 経度:%.2f 方位:%.0f",
                            coordinate.latitude,
                            coordinate.longitude,
                            0]]; // 方位はシュミレータだと取得できなかったので、また今度。
}




表示

ここまで来るとシュミレータでこんな感じの表示になります。

勉強あるのみ。

日々勉強ですね。C言語も知らない私にとっては最初つらいものがありましたが
ちょっとやるとおもしろさ感じました。

開発はやっぱ楽しいですね。

べた書きだらけで良いコードではないと思いますが

誰かの参考になればと思います。