2013年4月29日 星期一

利用MKMapItem顯示地圖導航路線

彼得潘除了是個不折不扣的蘋果痴,同時也是個路痴。 利用iOS 6全新推出的MKMapItem,我們可以輕易實現導航的強大功能,終於可以不再因迷路而約會遲到了。只要指定起點和終點,設定行進的交通工具,即可啟動Apple Map App,讓它來指引我們約會的方向。接下來就讓我們來看看底下這段程式碼,看看MKMapItem如何幫助彼得潘從目前的所在地敦南誠品前往看得到卻走不到的台北101吧:

   NSDictionary *options = @{
                              MKLaunchOptionsDirectionsModeKey :      
                               MKLaunchOptionsDirectionsModeWalking
   };
    
    MKMapItem *startItem = [MKMapItem mapItemForCurrentLocation];
    
    NSDictionary *addressDict = @{ (NSString*)kABPersonAddressCountryKey : @"台灣", 
        (NSString*)kABPersonAddressCityKey : @"台北市", 
          (NSString*)kABPersonAddressStreetKey : @"信義區市府路45號"};
    
    CLLocationCoordinate2D coordiate = CLLocationCoordinate2DMake(25.033408,
                                                                  121.564099);
    MKPlacemark *endPlacemark = [[MKPlacemark alloc]
                                 initWithCoordinate:coordiate
                                 addressDictionary:addressDict];

    MKMapItem *endItem = [[MKMapItem alloc]
                          initWithPlacemark:endPlacemark];
    endItem.name = @"台北101";
    
    NSArray *directionsItems = @[startItem, endItem];
    [MKMapItem openMapsWithItems:directionsItems launchOptions:options];


說明:

 (1) NSDictionary *options = @{
                              MKLaunchOptionsDirectionsModeKey :      
                               MKLaunchOptionsDirectionsModeWalking
   };

設定交通工具。目前可以選擇的交通工具有開車和走路兩種。彼得潘目前還沒錢買車,只能辛苦地靠萬能的雙腳從敦南誠品走到台北101啦。

MKMapItem.h


NSString * const MKLaunchOptionsDirectionsModeDriving;
NSString * const MKLaunchOptionsDirectionsModeWalking;


為了使用MKMapItem,我們必須先import <MapKit/MapKit.h>和加入MapKit.framework。

(2)  MKMapItem *startItem = [MKMapItem mapItemForCurrentLocation];

建立代表起點的MKMapItem物件。利用mapItemForCurrentLocation method建立的MKMapItem物件,到時候將抓取彼得潘目前所在位置的經緯度,完全不用彼得潘操心。

(3) NSDictionary *addressDict = @{ (NSString*)kABPersonAddressCountryKey : @"台灣", 
        (NSString*)kABPersonAddressCityKey : @"台北市", 
          (NSString*)kABPersonAddressStreetKey : @"信義區市府路45號"};

設定台北101的地址資訊。為了使用kABPersonAddressCountryKey等相關字串,我們必須事先import <AddressBook/AddressBook.h>和加入AddressBook.framework。

(4) CLLocationCoordinate2D coordiate = CLLocationCoordinate2DMake(25.033408,
                                                                  121.564099);
  
利用CLLocationCoordinate2DMake建立儲存經緯度的CLLocationCoordinate2D型別變數coordinate。25.033408是101的緯度,121.564099則是經度。此method的宣告如下:

CLLocation.h

CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude, CLLocationDegrees longitude);

為了使用CLLocationCoordinate2DMake,我們必須加入CoreLocation.framework

(5)    MKPlacemark *endPlacemark = [[MKPlacemark alloc]
                                 initWithCoordinate:coordiate
                                 addressDictionary:addressDict];

建立MKPlacemark物件。利用它的初始化method initWithCoordinate:addressDictionary:,我們可以設定地點的經緯度和地址資訊。此method的宣告如下:


MKPlacemark.h



- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
       addressDictionary:(NSDictionary *)addressDictionary;


 (6) MKMapItem *endItem = [[MKMapItem alloc]
                          initWithPlacemark:endPlacemark];


建立代表終點的MKMapItem物件,透過剛剛建立的MKPlacemark物件初始化,設定此終點的資訊。

(7)  endItem.name = @"台北101";

設定當我們點選地圖上的終點標記時,顯示的標題。

(8)   NSArray *directionsItems = @[startItem, endItem];

將起點和終點組合成array。

(9)   [MKMapItem openMapsWithItems:directionsItems launchOptions:options];

打開Apple Map,告訴它我們的起點,終點,以及交通工具。此method的宣告如下:


MKMapItem.h



+ (BOOL)openMapsWithItems:(NSArray *)mapItems launchOptions:(NSDictionary *)launchOptions;

參數mapItems: 傳入起點,終點MKMapItem物件組合而成的array。

參數launchOptions: 傳入額外的補充資訊。在這裡我們傳入交通工具資訊。

執行App:

神奇的導航路線出現了! 綠色的大頭針代表起點的敦南誠品,紅色的大頭針代表終點的101。原來從敦南誠品走到101只要22分鐘呀。看來健步如飛的彼得潘應該只要一半的時間,十分鐘就可以走到了。

點選紅色的大頭針,可顯示我們剛剛於程式裡設定的標題"台北101"



點選紅色大頭針上的藍白箭頭,可顯示我們剛剛於程式裡設定的完整101地址。



然而路痴如彼得潘,看到了路線其實還是不知道怎麼走。別擔心,只要點選左下角的三條線按鈕,馬上可以看到更詳細的導航路線列表,保證忘了迷路怎麼寫 ! 








9 則留言:

  1. 請問有目的地的"經緯度"為啥還需要設定"地址"??

    回覆刪除
    回覆
    1. 到時候點選紅色大頭針上的藍白箭頭時,顯示的地址將是我們設定的字串

      刪除
  2. 你好,因為我已經有自己規劃了地圖頁面的呈現,所以不想要跳到AppleMap來執行導航這部分,請問是否有辦法在我自己的頁面呈現出AppleMap替我規劃的路線圖還有取得路徑表資料自己使用TableView呈現,我有試過MKpolyLine但是效果很差,很容易造成穿河穿山的情況,期待您的解惑彼得大大

    回覆刪除
    回覆
    1. 您好,在App裡導航的部分在iOS 7 SDK已經可以做到了。不過目前iOS 7還未公開,需要付費的開發會員才能看到。而且由於Apple要求不能公開,所以目前我還不能夠介紹這個部分。等未來Apple正式推出iOS 7,我會再發表相關的SDK教學。

      刪除
  3. Dear Peter:

    所以在ios6的環境下無法做到要到ios7才有辦法的意思嗎?我也是付費開發者,不過身上有案子也不敢更新ios7跟xcode5,那就有勞您以後的教學喔!!再請教您一件事情,因為目前公司鎖版本在4.3那這樣ios7的新功能能夠用嗎?對了我也有買您出的出噢,寫得很不錯!!加油

    Adam

    回覆刪除
    回覆
    1. 現在Xcode 5已經推出了,未來開發跟上架App都需要搭配Xcode 5。至於規劃路線,其實iOS 6也可以做到,只是iOS 6的方式是啟動Map App,從Map App裡顯示路線

      刪除
  4. 感謝彼得潘精彩的分享~
    話說我今年中也是從您的“App程式設計入門”進入這塊領域的!

    另外對於上面所提到的iOS 7相關的SDK教學,不知道能在哪裡看到?(我已經是付費會員)
    我對於iOS還不是很熟悉,沒有在官網上看到相關的說明,可能是哪裡漏看到了 :(
    再次感謝

    回覆刪除
    回覆
    1. 哦,相關的教學從Apple的官方文件就可以找到了。你可以在https://developer.apple.com/devcenter/ios/index.action上方的search框裡輸入欲查詢的主題,比方跟地圖相關的MKMapItem。不過有時候官方文件可能不是那麼好懂,如果想看一些比較容易了解的教學,建議查詢App開發的相關書籍或是網路上的教學文章

      刪除
    2. 謝謝 :)
      聖誕節剛過,先預祝彼得潘新年快樂!

      刪除