以下に、このユースケースの実装における私の経験を紹介します。
2つのビジョン
iOS SDKについての私の知識は、2つの実装の可能性につながりました。
- 複雑な MKOverlayViewを使用します。
- よりシンプル。 デフォルトでインストールされるマップアプリケーションを使用します。
最初の方法は、ルートの制御点のソースが必要であるという点で複雑であり、その後、これらの点のうちどれだけが道路のすべての曲がり角にあるために必要であるかまだ不明です。 したがって、2番目の方法はその機能の大部分を満たすと思います。
実装
特定の例の実装を検討してください。 仕事にはMapKit.frameworkが必要です。
UINavigationControllerのスタックに配置され、MKMapViewを表示するUIViewControllerのインスタンスがあると仮定します。 マップ上に、UserLocationと取得する必要があるポイントを表示します。 私の練習では、目的地がすでに住所で記述されており、ユーザーの現在位置の住所しか取得できないことがよくあります。
順番に試してみましょう。
デザイナを通じて、目的地を説明するデータ(場所の座標、名前、住所)を転送します。 コンストラクターで、この場所の注釈と「ルート」ボタンを作成します。これはUINavigationBarに表示され、プログラムが現在の場所の住所を見つけた後にユーザーが使用できるようになります。
@interface RouteController : UIViewController <MKMapViewDelegate, MKReverseGeocoderDelegate> {
MKPointAnnotation * _pointAnnotaion;
NSString * _selfAddress;
}
- ( id ) initWithPlaceCoordinate : ( CLLocationCoordinate2D ) coorinate
placeName : ( NSString * ) name
placeAddress : ( NSString * ) address;
@end
@implementation RouteController
- ( id ) initWithPlaceCoordinate : ( CLLocationCoordinate2D ) coorinate placeName : ( NSString * ) name placeAddress : ( NSString * ) address {
self = [ super init ] ;
if ( self ) {
self.navigationItem.rightBarButtonItem = [ [ [ UIBarButtonItem alloc ] initWithTitle : @ ""
style : UIBarButtonItemStyleBordered
target : self
action : @selector ( routeAction ) ]
autorelease ] ;
self.navigationItem.rightBarButtonItem.enabled = NO ;
_pointAnnotaion = [ MKPointAnnotation new ] ;
_pointAnnotaion.title = name;
_pointAnnotaion.subtitle = address;
_pointAnnotaion.coordinate = coorinate;
}
return self;
}
- ( void ) dealloc {
[ _pointAnnotaion release ] ;
[ _selfAddress release ] ;
[ super dealloc ] ;
}
コントローラーがxibファイルなしで開始され、self.viewがMKMapViewインスタンスを指すとします。
- ( void ) loadView {
MKMapView * mapView = [ [ [ MKMapView alloc ] initWithFrame : [ UIScreen mainScreen ] .bounds ] autorelease ] ;
mapView.showsUserLocation = YES ;
mapView.delegate = self;
[ mapView addAnnotation : _pointAnnotaion ] ;
self.view = mapView;
}
マップがユーザーの座標を決定したら、MKReverseGeocoderを使用してこれらの座標から住所を取得します(MKReverseGeocoderは特定のルールに従って使用する必要がありますが、ここでは詳しく説明しません)。
#pragma mark - Map view delegate
- ( void ) mapView : ( MKMapView * ) mapView didUpdateUserLocation : ( MKUserLocation * ) userLocation {
MKReverseGeocoder * geocoder = [ [ MKReverseGeocoder alloc ] initWithCoordinate : userLocation.coordinate ] ;
geocoder.delegate = self;
[ geocoder start ] ;
}
#pragma mark - Reverse geocoder delegate
- ( void ) reverseGeocoder : ( MKReverseGeocoder * ) geocoder didFindPlacemark : ( MKPlacemark * ) placemark {
[ geocoder autorelease ] ;
NSArray * formattedAddress = [ placemark.addressDictionary objectForKey : @ "FormattedAddressLines" ] ;
[ _selfAddress release ] ;
_selfAddress = [ [ formattedAddress componentsJoinedByString : @ "," ] retain ] ;
MKMapView * mapView = ( MKMapView * ) self.view;
for ( id<MKAnnotation> annotation in [ mapView annotations ] ) {
if ( [ annotation isKindOfClass : [ MKUserLocation class ] ] ) {
( ( MKUserLocation * ) annotation ) .subtitle = _selfAddress;
}
}
self.navigationItem.rightBarButtonItem.enabled = YES ;
}
- ( void ) reverseGeocoder : ( MKReverseGeocoder * ) geocoder didFailWithError : ( NSError * ) error {
[ geocoder autorelease ] ;
}
アドレスを受け取ったら、_selfAddress変数に保存し、ユーザーが[ルート]ボタンを使用できるようにします。 [3月]ボタンをクリックすると、 maps.google.com / mapsでリクエストを行うことができますか? daddr =&saddr =。ここで、daddrとsaddrは、それぞれ終了アドレスとルート開始アドレスです。
#pragma mark - Private methods
- ( NSString * ) escapedStringFromString : ( NSString * ) string {
NSString * result = ( NSString * ) CFURLCreateStringByAddingPercentEscapes (
NULL , /* allocator */
( CFStringRef ) string ,
NULL , /* charactersToLeaveUnescaped */
( CFStringRef ) @ "!*'();:@&=+$,/?%#[]" ,
kCFStringEncodingUTF8 ) ;
return [ result autorelease ] ;
}
#pragma mark - Public methods
- ( void ) routeAction {
NSString * daddr = [ self escapedStringFromString : [ _pointAnnotaion subtitle ] ] ;
NSString * saddr = [ self escapedStringFromString : _selfAddress ] ;
NSString * routeURL = [ NSString stringWithFormat : @ "maps.google.com/maps?daddr=%@&saddr=%@" , daddr, saddr ] ;
[ [ UIApplication sharedApplication ] openURL : [ NSURL URLWithString : routeURL ] ] ;
}
@end
URLが正しく構成されていれば、「マップ」アプリケーションが開き、そこにルートが構築されます。
関連資料
Apple Urlスキーム
______________________