這次給大家分享一個在地圖上畫出行程,軌跡的方法.
我使用的是高德地圖SDK.
首先得初始化高德地圖,在Appdelegate.m中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
初始化高德地圖. GDAPIKey就是你申請的key.
//高德地圖SDK
- (void)configureAPIKey {
[MAMapServices sharedServices].apiKey = (NSString *)GDAPIKey;
}
然后你需要在你使用地圖的那個類的.m文件的后綴改成.mm.
我們現(xiàn)在創(chuàng)建一個地圖.并且打開定位.
- (instancetype)init {
self = [super init];
if (self) {
self.pointArr = [NSMutableArray array];//存儲軌跡的數(shù)組.
[self setMapView];
}
return self;
}
- (void)setMapView {
//地圖初始化
self.mapView = [[MAMapView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_mapView.backgroundColor = [UIColor whiteColor];
self.mapView.delegate = self;
//設置定位精度
_mapView.desiredAccuracy = kCLLocationAccuracyBest;
//設置定位距離
_mapView.distanceFilter = 1.0f;
//普通樣式
_mapView.mapType = MAMapTypeStandard;
//地圖跟著位置移動
[_mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES];
//設置成NO表示關閉指南針;YES表示顯示指南針
_mapView.showsCompass= YES;
//設置指南針位置
_mapView.compassOrigin= CGPointMake(_mapView.compassOrigin.x, 22);
//設置成NO表示不顯示比例尺;YES表示顯示比例尺
_mapView.showsScale= YES;
//設置比例尺位置
_mapView.scaleOrigin= CGPointMake(_mapView.scaleOrigin.x, 22);
//開啟定位
_mapView.showsUserLocation = YES;
//縮放等級
[_mapView setZoomLevel:18 animated:YES];
//防止系統(tǒng)自動殺掉定位 -- 后臺定位
_mapView.pausesLocationUpdatesAutomatically = NO;
_mapView.allowsBackgroundLocationUpdates = YES;
[self.view addSubview:self.mapView];
}
實現(xiàn)相應的協(xié)議.
#pragma mark - MAMapViewDelegate
//當位置改變時候調用
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation {
//updatingLocation 標示是否是location數(shù)據(jù)更新, YES:location數(shù)據(jù)更新 NO:heading數(shù)據(jù)更新
if (updatingLocation == YES) {
self.currentUL = userLocation;//設置當前位置
//手機位置信息
[self setPointArrWithCurrentUserLocation];
}
}
//定位失敗
- (void)mapView:(MAMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
NSString *errorString = @"";
switch([error code]) {
case kCLErrorDenied:
//Access denied by user
errorString = @"Access to Location Services denied by user";
break;
case kCLErrorLocationUnknown:
//Probably temporary...
errorString = @"Location data unavailable";
//Do something else...
break;
default:
errorString = @"An unknown error has occurred";
break;
}
}
那么重點來了,既然要畫出軌跡,就要設置地圖覆蓋物.
//畫線方法
- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id <MAOverlay>)overlay {
//畫線
if ([overlay isKindOfClass:[MAPolyline class]]) {
MAPolylineView *polylineView = [[MAPolylineView alloc] initWithPolyline:overlay];
polylineView.lineWidth = 8.f;
polylineView.strokeColor = [UIColor colorWithRed:177 / 255.0 green:152 / 255.0 blue:198 / 255.0 alpha:0.6];
return polylineView;
}
return nil;
}
然后上方在在位置變更的時候調用了一個方法.我把每個變更的點統(tǒng)一轉成MAPointAnnotation對象,并且添加到數(shù)組.
[self setPointArrWithCurrentUserLocation];
//設置數(shù)組元素并且去執(zhí)行畫線操作
- (void)setPointArrWithCurrentUserLocation {
// NSLog(@"記錄一個點");
//檢查零點
if (_currentUL.location.coordinate.latitude == 0.0f ||
_currentUL.location.coordinate.longitude == 0.0f)
return;
MAPointAnnotation *point = [[MAPointAnnotation alloc] init];
point.coordinate = _currentUL.location.coordinate;
[_pointArr addObject:point];
//畫線
[self drawTrackingLine];
}
然后開始執(zhí)行畫線操作.
//繪制旅行路線
- (void)drawTrackingLine {
MAMapPoint *pointArray = new MAMapPoint[_pointArr.count];//創(chuàng)建結構體數(shù)組
for(int index = 0; index < _pointArr.count; index++) {
MAPointAnnotation *locationUser = [[MAPointAnnotation alloc] init];
locationUser = [_pointArr objectAtIndex:index];
MAMapPoint point = MAMapPointForCoordinate(locationUser.coordinate);
pointArray[index] = point;
}
//在每次畫出軌跡線的時候把之前的線刪除掉.不然會多次添加.
if (self.routeLine) {
[self.mapView removeOverlay:self.routeLine];
}
self.routeLine = [MAPolyline polylineWithPoints:pointArray count:_pointArr.count];
if (nil != self.routeLine) {
//將折線繪制在地圖底圖標注和興趣點圖標之下
[self.mapView addOverlay:self.routeLine];
}
delete []pointArray;
}
這樣子就可以運行了.整個軌跡記錄的過程分享完了.
當然在關閉地圖界面注意釋放內(nèi)存.
#pragma mark - clear mapview
- (void)clearMapView {
self.mapView.showsUserLocation = NO;
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeOverlays:self.mapView.overlays];
self.mapView.delegate = nil;
}
demo github地址:BYTrackDemo
demo中提供的方法,自己也可以將圓形覆蓋物和地理圍欄相結合,在記錄行程過程中,可以判斷有沒有經(jīng)過某個點的多少范圍(半徑)內(nèi).
demo編譯不通過,運行不了的話,可以將BYMapViewVC這個類,放到自己的已經(jīng)配置好高德地圖的項目進行測試.
使用百度地圖的話,有個更好的選擇百度鷹眼.如果想自己寫的話,就把高德的協(xié)議改成百度的,類也改成百度的就好了.
只不過記錄行程軌跡就得打開后臺持續(xù)定位,比較耗電,這點比較煩.
好了,以上就是分享的iOS記錄地圖軌跡.感覺不錯的可以點個喜歡,哈哈.
有什么不足的地方還請大家指出.謝謝~
更新:
在定位的方法中可以主動篩選一些距離相近的點.比如當前點和之前的點相差距離小于10米那么就不將這個點計入畫線數(shù)組.如下:
//當位置改變時候調用
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation {
//updatingLocation 標示是否是location數(shù)據(jù)更新, YES:location數(shù)據(jù)更新 NO:heading數(shù)據(jù)更新
if (updatingLocation == YES) {
// self.currentUL = userLocation;//設置當前位置
// //手機位置信息
// [self setPointArrWithCurrentUserLocation];
//增加距離判斷
if (self.currentUL) {
CLLocationDistance distance = [userLocation.location distanceFromLocation:self.currentUL.location];
//判斷當前點與之前點距離相差小于10米就不計入計算.
if (distance < 10) {
return;
} else {
self.currentUL = userLocation;//設置當前位置
}
} else {
self.currentUL = userLocation;//設置當前位置
}
//手機位置信息
[self setPointArrWithCurrentUserLocation];
}
}