再轉一篇mapkit的文章



1、概述


OS開發之MapKit學習筆記





插入MapView,設置Delegate(一般爲Controller),Annotations記錄興趣位置點(AnnotationView用來顯示興趣位置點),annotation是可選的,選中的annotation會顯示callout,用來顯示信息。

 

2、設置地圖顯示類型:
mapView.mapType = MKMapTypeStandard;
mapView.mapType = MKMapTypeSatellite;
mapView.mapType = MKMapTypeHybrid;

 

3、顯示用戶位置
設置爲可以顯示用戶位置:
mapView.showsUserLocation = YES;
判斷用戶當前位置是否可見(只讀屬性):
userLocationVisible
得到用戶位置座標:當userLocationVisible爲YES時
CLLocationCoordinate2D coords = mapView.userLocation.location.coordinate;

 

4、座標範圍
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];
以上代碼爲:最終顯示該區域

 

5、Delegate
使用MapView須符合MKMapViewDelegate協議

5.1、地圖加載Delegate
當需要從Google服務器取得新地圖時
mapViewWillStartLoadingMap:
當成功地取得地圖後
mapViewDidFinishLoadingMap:
當取得地圖失敗後(建議至少要實現此方法)
mapViewDidFailLoadingMap:withError:

5.2、範圍變化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) {
// 座標在範圍內
}6、Annotation

Annotation包含兩部分:Annotation Object和Annotation View

Annotation Object必須符合協議MKAnnotation,包括兩個方法:title和subtitle,分別用於顯示註釋的標題和子標題。還有 coordinate屬性,返回CLLocationCoordinate2D,表示Annotation的位置
然後,需使用mapView:viewForAnnotation: 方法來返回MKAnnotationView或者MKAnnotationView的子類用來顯示Annotation(注意:這裏顯示的不是選中Annotation後的彈出框)

你可以子類化MKAnnotationView,然後再drawRect:方法裏面進行自己的繪製動作(這個方法很蠢)

你完全可以實例化一個MKAnnotationView,然後更改它的image屬性,這樣很簡單。

7、添加移除Annotation
添加一個Annotation
[mapView addAnnotation:annotation];
添加一個Annotation數組
[mapView addAnnotations:[NSArray arrayWithObjects:annotation1, annotation2, nil]];
移除一個Annotation
removeAnnotation:
移除一個Annotation數組
removeAnnotations:
移除所有Annotation
[mapView removeAnnotations:mapView.annotations];

8、選中Annotation
一次只能有一個Annotation被選中,選中後會出現CallOut(浮動框)
簡單的CallOut顯示Title和SubTitle,但你也可以自定義一個UIView作爲CallOut(與自定義的TableViewCell一樣)
可通過代碼選中Annotation:
selectAnnotation:animated:
或者取消選擇:
deselectAnnotation:animated:

9、顯示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;
}

 

10、取得真實地址
示例:
初始化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];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章