? ? ? ?在圖2所示的界面中輸入查詢地點關鍵字,然后進行地理信息編碼查詢,結果會調入自帶的蘋果地圖,如圖3所示,界面中的標注點是我們傳遞給它的。我們可以像使用自帶地圖應用一樣進行查詢線路、設置地圖類型等操作。
? ? ? ?南昌APP開發公司要告訴大家的是,在iOS中想要實現這個功能,需要使用Map Kit中的MKPlacemark和MKMapItem這兩個類。因此,還需要在工程中添加MapKit.framework,主要代碼如下:
? ? ? ?@IBAction func geocodeQuery(sender: AnyObject) {
? ? ? ? if (self.txtQueryKey.text == nil) {
? ? ? ? return
? ? ? ? }
? ? ? ? var geocoder = CLGeocoder()
? ? ? ? geocoder.geocodeAddressString(self.txtQueryKey.text,
? ? ? ? completionHandler: { (placemarks, error) -> Void in
? ? ? ?if placemarks.count > 0 {
? ? ? ?NSLog("查詢記錄數:%i", placemarks.count)
? ? ? ?let placemark = placemarks[0] as CLPlacemark
? ? ? ?let coord = placemark.location.coordinate ①
? ? ? ?let address = placemark.addressDictionary ②
? ? ? ?var place = MKPlacemark(coordinate:coord, addressDictionary:address) ③
? ? ? ?let mapItem = MKMapItem(placemark: place) ④
? ? ? ?mapItem.openInMapsWithLaunchOptions(nil) ⑤
? ? ? ?}
? ? ? ?//關閉鍵盤
? ? ? ?self.txtQueryKey.resignFirstResponder()
? ? ? ?})
? ? ? ?}?
? ? ? ?- (IBAction)geocodeQuery:(id)sender {
? ? ? ?if (self.txtQueryKey.text == nil || [self.txtQueryKey.text length] == 0) {
? ? ? ?return;
? ? ? ?}
? ? ? ?CLGeocoder *geocoder = [[CLGeocoder alloc] init];
? ? ? ?[geocoder geocodeAddressString:self.txtQueryKey.text
? ? ? ?completionHandler:^(NSArray *placemarks, NSError *error) {
? ? ? ?NSLog(@"查詢記錄數:%lu",[placemarks count]);
? ? ?? if ([placemarks count] > 0) {
? ? ? ?CLPlacemark* placemark = placemarks[0];
? ? ? ?CLLocationCoordinate2D coordinate = placemark.location.coordinate; ①
? ? ? ?NSDictionary* address = placemark.addressDictionary; ②
? ? ? ?MKPlacemark *place = [[MKPlacemark alloc]
? ? ? ?initWithCoordinate:coordinate addressDictionary:address]; ③
? ? ? ?MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place]; ④
? ? ? ?[mapItem openInMapsWithLaunchOptions:nil]; ⑤
? ? ? ?//關閉鍵盤
? ? ? ?[_txtQueryKey resignFirstResponder];
? ? ? ?}
? ? ? ?}];
? ? ? ?}
? ? ? ?在上述代碼中,第③行代碼用于實例化MKPlacemark對象。注意,MKPlacemark與CLPlacemark不同,前者是地圖上的地標類,后者是定位使用的地標類。其中coordinate參數是地理坐標點,該地理坐標點通過第①行中的placemark.location.coordinate語句取得;addressDictionary參數是該地點信息,它的參數可以通過第②行語句中的placemark.addressDictionary獲得。
? ? ? ?第④行代碼用于實例化MKMapItem對象。MKMapItem類封裝了地圖上一個點的信息類。我們把需要在地圖上顯示的點封裝到MKMapItem對象中。構造器參數placemark是MKPlacemark類型。
? ? ? ?第⑤行代碼調用iOS自帶的蘋果地圖應用。openInMapsWithLaunchOptions:方法是MKMapItem類的實例方法,其參數是NSDictionary類型,這個參數可以控制顯示地圖的初始化信息,它包含一些鍵,具體如下。??
? ? ? ?1、MKLaunchOptionsDirectionsModeKey。設定路線模式,它有兩個值MKLaunchOptionsDirectionsModeDriving(駕車路線)和MKLaunchOptionsDirectionsModeWalking(步行路線)。
? ? ? ?2、MKLaunchOptionsMapTypeKey:設定地圖類型。
? ? ? ?3、MKLaunchOptionsMapCenterKey:設定地圖中心點。
? ? ? ?4、MKLaunchOptionsMapSpanKey:設置地圖跨度。
? ? ? ?5、MKLaunchOptionsShowsTrafficKey:設置顯示交通狀況。
? ? ? ?例如,我們可以使用下面的代碼在地圖上設置行車路線:
? ? ? ?let options = NSDictionary(object: MKLaunchOptionsDirectionsModeDriving,
? ? ? ?forKey: MKLaunchOptionsDirectionsModeKey)
? ? ? ?let mapItem = MKMapItem(placemark: place)
? ? ? ?mapItem.openInMapsWithLaunchOptions(options)?
? ? ? ?NSDictionary* options =[[NSDictionary alloc]initWithObjectsAndKeys:
? ? ? ?MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsDirectionsModeKey, nil];
? ? ? ?MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place];
? ? ? ?[mapItem openInMapsWithLaunchOptions:options];?
? ? ? ?設置行車路線后,會在地圖上標注出路線,如圖4所示。默認情況下,起點是當前位置,這個位置通過定位服務獲得。終點是我們查詢的地點,即place變量所包含的信息。
? ? ? ?如果有多個點需要標注,可以使用MKMapItem的類方法:
? ? ? ?class func openMapsWithItems(_ mapItems: [AnyObject]!,
? ? ? ?launchOptions launchOptions: [NSObject : AnyObject]!) -> Bool
? ? ? ?+ (BOOL)openMapsWithItems:(NSArray *)mapItems
? ? ? ?launchOptions:(NSDictionary *)launchOptions?
? ? ? ?其中參數mapItems是標注點的集合,launchOptions是啟動參數。如果想使用這個方法,則上面的例子可以修改如下:
? ? ? ?var geocoder = CLGeocoder()
? ? ? ?geocoder.geocodeAddressString(self.txtQueryKey.text,
? ? ? ?completionHandler: { (placemarks, error) -> Void in
? ? ? ?if placemarks == nil {
? ? ? ?return
? ? ?? }
? ? ? ?var array = NSMutableArray()
? ? ? ?for item in placemarks {
? ? ? ?let placemark = item as CLPlacemark?
? ? ? ?let coord = placemark.location.coordinate
? ? ? ?let address = placemark.addressDictionary
? ? ? ?var place = MKPlacemark(coordinate:coord, addressDictionary:address)
? ? ? ?let mapItem = MKMapItem(placemark: place)
? ? ? ?mapItem.openInMapsWithLaunchOptions(nil)
? ? ? ?array.addObject(mapItem) ①
? ? ? ?}
? ? ? ? //關閉鍵盤
? ? ? ?self.txtQueryKey.resignFirstResponder()
? ? ? ?if (array.count > 0) {
? ? ? ?MKMapItem.openMapsWithItems(array, launchOptions: nil) ②
? ? ? ?}
? ? ? ?})?
? ? ? ?CLGeocoder *geocoder = [[CLGeocoder alloc] init];
? ? ? ?[geocoder geocodeAddressString:_txtQueryKey.text completionHandler:^(NSArray
? ? ? ?*placemarks, NSError *error) {
? ? ? ?NSLog(@”查詢記錄數:%u”,(unsigned int)[placemarks count]);
? ? ? ?NSMutableArray* array = [NSMutableArray new];
? ? ? ?for (int i = 0; i < [placemarks count]; i++) {
? ? ? ?CLPlacemark* placemark = placemarks[i];
? ? ? ?CLLocationCoordinate2D coordinate = placemark.location.coordinate;
? ? ? ?NSDictionary* address = placemark.addressDictionary;?
? ? ? ?MKPlacemark *place = [[MKPlacemark alloc]
? ? ? ?initWithCoordinate:coordinate addressDictionary:address];
? ? ? ?MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:place];
? ? ? ?[array addObject:mapItem]; ①
? ? ? ?}
? ? ? ?//關閉鍵盤
? ? ? ?[_txtQueryKey resignFirstResponder];
? ? ? ?if ([array count] > 0) {
? ? ? ?[MKMapItem openMapsWithItems:array launchOptions:nil]; ②
? ? ? ?}
? ? ? ?}];?
? ? ? ?與傳遞單個標注點不同的是,我們需要進行循環遍歷,然后把地圖地標對象MKMapItem放到集合中,如第①行代碼所示。第②行代碼用于在循環完成后啟動自帶蘋果地圖。運行結果如圖5所示,可以發現,傳遞的兩個地標點都標注處理了。