一、概述 插入MapView,設置Delegate(通常爲Controller),Annotations記錄興趣位置點(AnnotationView用來顯示興趣位置點),annotation是可選的,選中的annotation會顯示callout,用來顯示信息。 二、設置地圖顯示類型: mapView.mapType = MKMapTypeStandard; mapView.mapType = MKMapTypeSatellite; mapView.mapType = MKMapTypeHybrid; 三、顯示用戶位置 設置爲能夠顯示用戶位置: mapView.showsUserLocation = YES; 判斷用戶當前位置是否可見(只讀屬性): userLocationVisible 獲得用戶位置座標:當userLocationVisible爲YES時 CLLocationCoordinate2D coords = mapView.userLocation.location.coordinate; 四、座標範圍 MKCoordinateRegion用來設置座標顯示範圍。 包括兩部分:Center(CLLocationCoordinate2D struct,包括latitude和longitude),座標中心 和Span(MKCoordinateSpan struct,包括latitudeDelta和longitudeDelta),縮放級別 MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000, 2000); 以上代碼建立一個以center爲中心,上下各1000米,左右各1000米得區域,但其是一個矩形,不符合MapView的橫縱比例 MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion]; 以上代碼建立出來一個符合MapView橫縱比例的區域 [mapView setRegion:adjustedRegion animated:YES]; 以上代碼爲:最終顯示該區域 五、Delegate 使用MapView須符合MKMapViewDelegate協議 5.一、地圖加載Delegate 當須要從Google服務器取得新地圖時 mapViewWillStartLoadingMap: 當成功地取得地圖後 mapViewDidFinishLoadingMap: 當取得地圖失敗後(建議至少要實現此方法) mapViewDidFailLoadingMap:withError: 5.二、範圍變化Delegate 當手勢開始(拖拽,放大,縮小,雙擊) mapView:regionWillChangeAnimated: 當手勢結束(拖拽,放大,縮小,雙擊) mapView:regionDidChangeAnimated: 判斷座標是否在MapView顯示範圍內:
CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0);
CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0); CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0); CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0); if (leftDegrees > rightDegrees) { // Int’l Date Line in View leftDegrees = -180.0 – leftDegrees; if (coords.longitude > 0) // coords to West of Date Line coords.longitude = -180.0 – coords.longitude; } If (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) { // 座標在範圍內 }六、Annotation Annotation包含兩部分:Annotation Object和Annotation View Annotation Object必須符合協議MKAnnotation,包括兩個方法:title和subtitle,分別用於顯示註釋的標題和子標題。還有 coordinate屬性,返回CLLocationCoordinate2D,表示Annotation的位置 而後,需使用mapView:viewForAnnotation: 方法來返回MKAnnotationView或者MKAnnotationView的子類用來顯示Annotation(注意:這裏顯示的不是選中Annotation後的彈出框) 你能夠子類化MKAnnotationView,而後再drawRect:方法裏面進行本身的繪製動做(這個方法很蠢) 你徹底能夠實例化一個MKAnnotationView,而後更改它的image屬性,這樣很簡單。 七、添加移除Annotation 添加一個Annotation [mapView addAnnotation:annotation]; 添加一個Annotation數組 [mapView addAnnotations:[NSArray arrayWithObjects:annotation1, annotation2, nil]]; 移除一個Annotation removeAnnotation: 移除一個Annotation數組 removeAnnotations: 移除全部Annotation [mapView removeAnnotations:mapView.annotations]; 八、選中Annotation 一次只能有一個Annotation被選中,選中後會出現CallOut(浮動框) 簡單的CallOut顯示Title和SubTitle,但你也能夠自定義一個UIView做爲CallOut(與自定義的TableViewCell同樣) 可經過代碼選中Annotation: selectAnnotation:animated: 或者取消選擇: deselectAnnotation:animated: 九、顯示Annotation 經過mapView:viewForAnnotation: 方法顯示Annotation,每在MapView中加入一個Annotation,就會調用此方法 示例(與tableView:cellForRowAtIndexPath: 很類似) - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation { static NSString *placemarkIdentifier = @」my annotation identifier」; if ([annotation isKindOfClass:[MyAnnotation class]]) { MKAnnotationView *annotationView = [theMapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier]; annotationView.image = [UIImage imageNamed:@"blood_orange.png"]; } else annotationView.annotation = annotation; return annotationView; } return nil; } 十、取得真實地址 示例: 初始化MKReverseGeocoder MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinates]; geocoder.delegate = self; [geocoder start]; 若是沒法處理座標,則調用reverseGeocoder:didFailWithError: 方法 - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error { NSLog(@」Error resolving coordinates: %@」, [error localizedDescription]); geocoder.delegate = nil; [geocoder autorelease]; } 若是成功,則調用reverseGeocoder:didFindPlacemark: 並把信息存儲在MKPlacemark 中 didFindPlacemark:(MKPlacemark *)placemark { NSString *streetAddress = placemark.thoroughfare; NSString *city = placemark.locality; NSString *state = placemark.administrativeArea; NSString *zip = placemark.postalCode; // Do something with information geocoder.delegate = nil; [geocoder autorelease]; } ******************************************************* User Location: MapViews 用Core Location 來保存用戶的路徑並在地圖上用一個藍色的點表示出來。 你能夠打開:mapView.showUserLocation = YES; 若是地圖跟蹤的是用戶的未知,你能夠經過只讀的屬性userLcoationVisible 來檢測用戶當前的位置是否是可見的。若是是YES,就是可見的。 你能夠首先設定 showsUserLocation 爲 YES來獲得用戶當前指定的座標。而後訪問userLocation 屬性。這個屬性返回一個MKUserLocation的實例變量。 MKUserLocation 是一個對象,有一個屬性叫作location(CLLocation 類型)。 一個CLLocation 包含一個coordinate屬性指向一個座標的集合,全部的這些意味着你能夠獲得實際的座標從MKUserLocation對象裏:下屬那個: CLLocationCoordinae2D coords = mapView.userLocation.location.coordinate; Coordinate Regions 若是你不告訴要顯示什麼或者找出世界上的當前某個具體的位置,那麼map view 就不那麼smart了。 經過map view, 作到這些工做的關鍵是 MKCoordinateRegion, 一個結構包含兩部分數據,同時也定義了在map view種要顯示的位置。 第一個成員是 center 。 這是另一個結構類型是:CLLocationCoordinate2D, 一個CLLocationCoordinate2D包含兩個浮點數值,經度和緯度。 這個點表明着map view的中間。 第二個叫作span。 是MKCoordinateSpan類型的結構。 它有兩個程序叫作 latitudeDelta and longitudeDelta。 這兩個程序被用來設定地圖的縮放級別——在center周圍應該顯示多大的區域。 這些值表明經度和緯度的距離。若是latitudeDelta and longitudeDelta是很小的,地圖將會被縮放的十分密集,若是大的話,地圖將會被放大並顯示一個較大的區域。 Convert degree to distance 每個緯度表明69英里,或者是111km,不論你在那裏。這樣就使做爲MKCoordinateSpan的參數的 latitudeDelta被傳遞的時候更容易計算。 經度所表明的距離就不是那麼容易去計算了。爲了作一樣的計算,你必須使用緯度,由於它表明的距離取決與你在的地方相對與赤道的距離。 爲了計算經度所表明的距離,你必須執行一些數學計算。 實際上apple已經提供了一些方法作這樣的計算: MKCoordinateRegionmakeWithDistance() 建立一個region。 你提供座標做爲center , 距離(m)爲經度和緯度的span。 例如建立一個region 來顯示指定區域位置 1km。 經過調用 CLLocationCoordinate2D MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center, 2000, 2000); 爲了顯示每一個邊周圍的1km, 咱們必須指定2000m 爲每一個span:1000m向左,1000m向右,1000m向上,1000m向下。 調用以後,viewRegion 將會包含一個格式化的MKCoordinateRegion,固然你可使用了。剩下的就是比率轉換問題了。 橫總比: MKMapView 類優一個實例方法將會適應一個座標區域來匹配map view的橫縱比例。 regionThatFits: 使用的時候你只需在你建立的座標區域裏面傳遞,同時它會返回一個新的座標區域來適應map view的比例。 MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion[; 設定區域顯示: 一旦建立好座標區域,你能夠告訴map view 來顯示經過setRegion:animated:方法建立的區域。若是你傳遞YES給第二個參數,mapView將會縮放移動等。 MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000,2000); MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion]; [mapView setRegion:adjustedRegion animated:YES]; 原文連接: http://palmsky.net/?p=3162 | 掌中天際
[_mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES]語句設置用戶跟蹤模式,用戶跟蹤模式有3種: MKUserTrackingModeNone 。沒有用戶跟蹤模式; MKUserTrackingModeFollow 。能夠跟蹤用戶的位置變化; MKUserTrackingModeFollowWithHeading 。能夠跟蹤用戶的位置和方向變化;- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{ MKPinAnnotationView *annView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"snda.pin"]; if (annView == NULL) { annView = [[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"snda.pin"] autorelease]; } //annotation的相關設置(不是自定義的) annView.annotation = annotation; annView.canShowCallout = YES; annView.calloutOffset = CGPointMake(0, 0); annView.image = [UIImage imageNamed:@"capture-exposure-plus.png"]; annView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; return annView; }
- if ([annotation isKindOfClass:[MyMapAnnotation class]]) {
- static NSString* travellerAnnotationIdentifier = @"TravellerAnnotationIdentifier";
- MKPinAnnotationView* pinView = (MKPinAnnotationView *)
- [mapView dequeueReusableAnnotationViewWithIdentifier:travellerAnnotationIdentifier];
- if (!pinView)
- {
- // if an existing pin view was not available, create one
- MKAnnotationView* customPinView = [[[MKAnnotationView alloc]
- initWithAnnotation:annotation reuseIdentifier:travellerAnnotationIdentifier] autorelease];
- customPinView.pinColor = MKPinAnnotationColorPurple;
- customPinView.animatesDrop = YES; //若是不須要這個從天而降的效果,設置爲NO便可。
- customPinView.canShowCallout = NO;
- return customPinView;
- }
- else
- {
- pinView.annotation = annotation;
- }
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) return nil; if ([annotation isKindOfClass:[TravellerMapAnnotation class]]) { // try to dequeue an existing pin view first static NSString* travellerAnnotationIdentifier = @"TravellerAnnotationIdentifier"; MKPinAnnotationView* pinView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:travellerAnnotationIdentifier]; if (!pinView) { // if an existing pin view was not available, create one MKAnnotationView* customPinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:travellerAnnotationIdentifier] autorelease]; customPinView.canShowCallout = YES; //很重要,運行點擊彈出標籤 UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [rightButton addTarget:self action:@selector(showDetails:) //點擊右邊的按鈕以後,顯示另一個頁面 forControlEvents:UIControlEventTouchUpInside]; customPinView.rightCalloutAccessoryView = rightButton; MyMapAnnotation *travellerAnnotation = (TravellerMapAnnotation *)annotation; UIImageView *headImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:travellerAnnotation.headImage]]; customPinView.leftCalloutAccessoryView = headImage; //設置最左邊的頭像 [headImage release]; UIImage *image = [UIImage imageNamed:@"smileFace.png"]; customPinView.image = image; customPinView.opaque = YES; [travellerImage release]; return customPinView; } else { pinView.annotation = annotation; } return pinView; } return nil; }- return pinView;
- }
蘋果地圖資源連接:http://blog.csdn.net/wu11wuwu/article/details/7070034