2009年1月3日土曜日

iPhoneでMapView route-meを使ってみよう! RMMarkerManager編

  • マーカーを配置するには、まずRMMarkerクラスのインスタンスを適当に生成する
  • 生成には[RMMarker markerWithNamedStyle:]を使うと便利。styleNameはRMMarker.hで2種類ほど定数として定義されている
  • マーカーを生成したら、[RMMarkerManager addMarker: AtLatLong:]で地図上に配置する
  • RMMarkerのlocation初期値はおそらくnilなので、生成したマーカーを何も考えずに[RMMarkerManager addMarker]とするとエラーになるはず(未確認)
  • マーカーにラベルをつけるときには[RMMarker setLabel:]または[RMMarker setTextLabel:]でよい。setTextLabelは正直いまいち

地図のズーム設定に初期位置設定もできるようになり、さらには地図の提供元の設定もできるようになりました。
しかしこれだけではただの地図が存在するだけです。実用的なアプリケーションにするためには、地図上に情報を配置して、アプリケーションからユーザーに何かを提示してあげなければなりません。
ということでお次は地図上にマーカーを配置してみようと思います。

route-meには標準でマーカーを管理するための機能があります。
マーカーそのものを表すRMMarkerクラスと、マーカーを管理するRMMarkerManagerクラスです。
まずはRMMarkerManagerクラスからみていきましょう。RMMarkerManager.hから、重要そうなプロパティおよびメソッドだけを切り出してみました。
//マーカーの追加・削除・表示非表示
- (void) addMarker: (RMMarker*)marker;
- (void) addMarker: (RMMarker*)marker AtLatLong:(CLLocationCoordinate2D)point;
- (void) addDefaultMarkerAt: (CLLocationCoordinate2D)point;
- (void) removeMarkers;
- (void) hideAllMarkers;
- (void) unhideAllMarkers;

//マーカーの取得
- (NSArray *)getMarkers;
- (void) removeMarker:(RMMarker *)marker;
- (CGPoint) getMarkerScreenCoordinate: (RMMarker *)marker;
- (CLLocationCoordinate2D) getMarkerCoordinate2D: (RMMarker *) marker;
- (NSArray *) getMarkersForScreenBounds;

//状態を取得
- (BOOL) isMarkerWithinScreenBounds:(RMMarker*)marker;
- (BOOL) isMarker:(RMMarker*)marker withinBounds:(CGRect)rect;
- (BOOL) managingMarker:(RMMarker*)marker;

//マーカーの移動
- (void) moveMarker:(RMMarker *)marker AtLatLon:(RMLatLong)point;
- (void) moveMarker:(RMMarker *)marker AtXY:(CGPoint)point;

一通り必要そうなメソッドはそろっており、「使い方等はもう宣言をみればわかるだろ!」といわんばかりの丁寧な作りになっています。
マーカーを配置したければ、- (void) addMarker: (RMMarker*)markerあたりを呼び出せばよさそうですね。

次にRMMarker.hをみてみます。重要な物だけ抜粋してみました。
//マーカーインスタンスの生成
+ (RMMarker*) markerWithNamedStyle: (NSString*) styleName;
- (id) initWithCGImage: (CGImageRef) image anchorPoint: (CGPoint) anchorPoint;
- (id) initWithCGImage: (CGImageRef) image;
- (id) initWithKey: (NSString*) key;
- (id) initWithUIImage: (UIImage*) image;
- (id) initWithStyle: (RMMarkerStyle*) style;
- (id) initWithNamedStyle: (NSString*) styleName;

//ラベルの設定および表示&非表示
- (void) setLabel: (UIView*)aView;
- (void) setTextLabel: (NSString*)text;
- (void) setTextLabel: (NSString*)text toPosition:(CGPoint)position;
- (void) toggleLabel;
- (void) showLabel;
- (void) hideLabel;
- (void) removeLabel;

//マーカーの画像変更および表示&非表示
- (void) replaceImage:(CGImageRef)image anchorPoint:(CGPoint)_anchorPoint;
- (void) hide;
- (void) unhide;

//各種プロパティ(おそらくここから直接操作することはない)
@property (assign, nonatomic) RMXYPoint location;
@property (retain) NSObject* data;
@property (nonatomic, retain) UIView* labelView;

デフォルトで用意されているマーカーを利用する場合は、+ (RMMarker*) markerWithNamedStyle: (NSString*) styleNameを使えばよさそうです。
自分でマーカーの画像を指定する場合は- (id) initWithUIImage: (UIImage*) image;などを用いればうまくいきそうです。

では実際に地図上にマーカーを配置してみます。
例によってRMMapViewの初期表示時に、以下のようなソースを追加します。
    CLLocation *markerLocation = [[[CLLocation alloc]
initWithLatitude:35.689613731585375 longitude:139.7616720199585]
autorelease];
RMMarker *marker = [RMMarker markerWithNamedStyle:RMMarkerRedKey];
[mapView.markerManager addMarker:marker AtLatLong:markerLocation.coordinate];

ソースの先頭で"RMMarker.h"と"RMMarkerManager.h"を#importするのをお忘れなく!
では実行してみましょう。


ばっちりです!マーカーが表示されました。

今度はマーカーにラベルをつけてみます。
ラベルとはマーカーの上に表示される説明書き領域です。RMMarkerには標準でラベルを扱う機能があります。
ラベルとしてシンプルに文字列を指定する方法と、凝ったUIViewを指定する方法が用意されていますが、まずはシンプルに文字列を出してみようと思います。
    [marker setTextLabel:@"Japan Meteorological Agency"];

これを実行すると・・・


出ましたね。
しかし正直言ってこれではわかりづらすぎです。とても実用に耐えません。
ラベルを使いたい場合には、setTextLabel:を用いず、きちんとしたUIViewを設計してから、setLabel:を利用して指定する方がよいと思います。