1. 程式人生 > >高德地圖的使用心得

高德地圖的使用心得

本人剛學習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 = [[MAPointAnnotationallocinit];

    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 = [[MAPinAnnotationViewallocinitWithAnnotation: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;

}

好了,以上便是我做地圖的心得,有什麼錯誤的地方請指點。