高德地圖的使用心得
本人剛學習ios開發,有很多不懂的地方,期待和大家的交流;也是第一次寫部落格,寫得不好的地方請多多包涵。
最近一段時間在開發一個跑步軟體,要用到高德地圖來顯示使用者當前位置,記錄使用者跑步軌跡,下面就說說這個高德地圖的使用和一些需要注意的地方吧。
一.配置工程
高德地圖我是用cocoaPods來管理的,cocoaPods不知道怎麼使用的可以去百度一下,網上很多教程
(1)因為只是顯示使用者的位置,所以沒必要使用3D地圖,就使用的'AMap2DMap',先配置工程,既然是跑步,地圖肯定得後臺執行,在配置工程裡面點選TARCETS->Capabilities,選擇下圖所示的Background Modes,勾選Location updates
(2)在plist檔案中加入‘NSLocationWhenInUseUsageDescription’或‘NSLocationAlwaysUsageDescription’欄位,它是一個string型別的,值就是提示使用者開啟定位之內的內容(如下圖所示)
NSLocationWhenInUseUsageDescription 表示應用在前臺的時候可以搜到更新的位置資訊。 NSLocationAlwaysUsageDescription 表示應用在前臺和後臺(suspend或terminated)都可以獲取到更新的位置資料
iOS9為了增強資料訪問安全,將所有的http請求都改為了https,為了能夠在iOS9中正常使用地圖SDK,請在"Info.plist"中進行如下配置,否則影響SDK的使用:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
如下圖所示:在iOS9中為了能正常調起高德地圖App的功能,必須在"Info.plist"中將高德地圖App的URL scheme列為白名單,否則無法調起,配置如下:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>iosamap</string>
</array>
如下圖所示:到這裡工程基本配置完成。
二.接下來就是程式碼部分
(1)在AppDelegate.m中匯入如下標頭檔案
#import <MAMapKit/MAMapKit.h>
在地圖初始化之前- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法裡面新增如下程式碼,配置之前在官網上申請的Key(如果在高德地圖官網沒有申請應用獲取到key值,你還得去高德官網申請一個應用獲取key值)[MAMapServices sharedServices].apiKey = @"你申請的key";
如果出現如下情況,就是你申請的key值與你工程的Bundle Identifier不匹配,需要去高德官網重新配置一下(2)接下來就是初始化地圖,在需要初始化的ViewController裡匯入標頭檔案
#import <MAMapKit/MAMapKit.h>
再初始化地圖//初始化地圖
MAMapView *mapView = [[MAMapView alloc] initWithFrame:self.view.frame];
//是否顯示使用者位置
mapView.showsUserLocation = YES;
//設定代理
mapView.delegate = self;
//載入mapView
[self.view addSubview:mapView];
如果需要後臺定位,還得設定下面兩個屬性//設定允許後臺定位引數,保持不會被系統掛起
_mapView.pausesLocationUpdatesAutomatically = NO;
//是否允許後臺定位。iOS9(含)以上系統需設定
_mapView.allowsBackgroundLocationUpdates = YES
設定定位精度,預設為kCLLocationAccuracyBest_mapView.desiredAccuracy = kCLLocationAccuracyBest;
設定定位的最小更新距離,預設為kCLDistanceFilterNone
_mapView.distanceFilter = kCLDistanceFilterNone;
因為這裡設定的是kCLDistanceFilterNone,會根據任何移動而定位。客戶反應這樣定位很耗電,而android那邊的機制可以設定每隔多少秒定一次位,ios不支援這種機制,ios只要觸發兩個條件就會定位,一個是上面那個屬性,比如設定10米定一次位_mapView.distanceFilter = 10.0f,還有一個是裝置偏移了多少度//裝置轉動90°就會定一次位
_mapView.headingFilter = 90;
通過這兩個屬性可以設定何時定位,上面兩個屬性只要滿足一個就會定位,可以同時設定,也可以單獨設定,看你的需求這樣就簡單的初始化了一個地圖
它每定一次位就會走下面這個代理方法,我們一般在這個方法裡操作事件,比如獲取當前經緯度,速度等資訊
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation: (BOOL)updatingLocation{
//獲取速度(m/s)
CGFloat locationSpeed = userLocation.location.speed;
//當前座標經緯度
CLLocationCoordinate2D currentLocation = userLocation.location.coordinate;
//有時候我們需要在介面上顯示當前定位訊號的強弱,高德地圖沒有直接判斷訊號強弱的引數,但系統有一個當前水平位置的準確度的屬性,可以通過這個屬性來判斷訊號的強弱
CGFloat signal = userLocation.location.horizontalAccuracy;
if (signal < 20)
{
//強
}
elseif (signal < 70)
{
//中
}else
{
//差
}
}
(3)新增起點,終點這個方法是自定義的方法,傳入一個經緯度,一個標題
- (void)mapViewAddAnnotation:(CLLocationCoordinate2D)location title:(NSString *)title
{
MAPointAnnotation *pointAnnotation = [[MAPointAnnotationalloc] init];
pointAnnotation.coordinate = location;
pointAnnotation.title = title;
//把pointAnnotation物件裝入陣列
[_arrayaddObject:pointAnnotation];
}
向地圖視窗新增一組標註,需要實現MAMapViewDelegate的-mapView:viewForAnnotation:函式來生成標註對應的View[_mapViewaddAnnotations:_array];
根據anntation生成對應的View- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
if ([annotation isKindOfClass:[MAPointAnnotationclass]]) {
staticNSString *pointReuseIndentifier = @"pointReuseIndentifier";
MAPinAnnotationView *annotationView = (MAPinAnnotationView *)[mapViewdequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier];
if (annotationView == nil) {
annotationView = [[MAPinAnnotationViewalloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier];
}
//做到這裡時遇到一個問題,標註顯示的圖片是設定成自己想要的,地圖上有兩個標註,一個起點,一個終點,當地圖上面只顯示終點時,滑動到起點的時候起點圖片就換成終點的圖片了,這樣兩個標註都是終點的圖片了,這是重用導致的,所以就用了以下方法來判斷
if ([annotation.titleisEqualToString:@"起點"]) {
annotationView.image = [UIImageimageNamed:@"map_開始"];
}elseif ([annotation.titleisEqualToString:@"終點"]){
annotationView.image = [UIImageimageNamed:@"map_結束"];
}
//設定氣泡可以彈出,預設為NO
annotationView.canShowCallout = YES;
//設定標註動畫顯示,預設為NO
annotationView.animatesDrop = YES;
//設定標註可以拖動,預設為NO
annotationView.draggable = YES;
return annotationView;
}
returnnil;
}
(4)繪製跑步軌跡這個方法也是自定義的方法,傳入一個經緯度,多個經緯度只需要for迴圈這個方法,一個一個的傳入經緯度就可以構成跑步路徑
-(void)addLine:(CLLocationCoordinate2D)location
{
//構造折線資料物件,第一個經緯度和第二個經緯度
CLLocationCoordinate2D commonPolylineCoords[2];
//第一個經緯度 startLocation
commonPolylineCoords[0] = startLocation;
//第二個經緯度 location
commonPolylineCoords[1] = location;
//構造折線物件
MAPolyline *commonPolyLine = [MAPolylinepolylineWithCoordinates:commonPolylineCoords count:2];
//在地圖上新增折線物件
[_mapViewaddOverlay:commonPolyLine];
}
根據overlay生成對應的View- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id<MAOverlay>)overlay
{
if ([overlay isKindOfClass:[MAPolylineclass]]) {
MAPolylineView *polylineView = [[MAPolylineViewalloc] initWithPolyline:overlay];
//折線寬
polylineView.lineWidth = 8.f;
//折線顏色
polylineView.strokeColor = RGBA(180, 0, 0, 1);
//連線型別
polylineView.lineJoin = kCGLineJoinRound;
//端點型別
polylineView.lineCap = kCGLineCapRound;
return polylineView;
}
returnnil;
}
好了,以上便是我做地圖的心得,有什麼錯誤的地方請指點。