標(biāo)簽 : 運(yùn)動(dòng)軌跡 百度地圖SDK
http://orchan.github.io/2016/02/22/基于百度地圖SDK記錄運(yùn)動(dòng)軌跡/
最終實(shí)現(xiàn)的效果如下圖所示###
- 注意1:模擬器上模擬要設(shè)置好
Location
(如果選擇None就無法定位了),同時(shí)第一次打開應(yīng)用會(huì)提示授權(quán)使用地理位置信息,點(diǎn)擊允許即可。
- 注意2:由上圖的經(jīng)緯度反查可知這是美國(guó)的一個(gè)州,所以百度地圖沒有可用信息顯示。
一、 前期準(zhǔn)備工作
1. 新建Xcode工程
2. 獲取Bundle Identifier
3. 申請(qǐng)key
4. 導(dǎo)入框架配置工程
5. 初始化 BMKMapManager
二、實(shí)戰(zhàn)記錄運(yùn)動(dòng)軌跡
1. 初始化工作
2. 開始定位
3. 存儲(chǔ)更新的用戶地理位置
4. 繪制軌跡線
一、 前期準(zhǔn)備工作
首先需要登錄[百度開放平臺(tái)][1]下載iOS地圖SDK(內(nèi)含開發(fā)者文檔、框架以及Demo示例),推薦下載全新Framework形式的靜態(tài)庫(kù),配置更加簡(jiǎn)單方便,具體看下圖:
1. 新建Xcode工程
File->New->Project->Single View Application,填寫好相關(guān)信息完成工程建立。
2. 獲取Bundle Identifier
通過project->target->general可以看到本應(yīng)用的Bundle Identifie,我們正是需要這串字符串去百度開發(fā)平臺(tái)申請(qǐng)一個(gè)Key用于百度地圖的調(diào)用。
3. 申請(qǐng)key
登錄[百度開放平臺(tái)][1]后,點(diǎn)擊右上角的API控制臺(tái)進(jìn)入申請(qǐng)key的界面,點(diǎn)擊創(chuàng)建應(yīng)用,在“安全碼”處填入你的應(yīng)用的Bundle Identifie,具體信息填寫請(qǐng)看下圖:
4. 導(dǎo)入框架配置工程
第一步 、引入
BaiduMapAPI.framework
百度地圖SDK提供了模擬器和真機(jī)兩種環(huán)境所使用的framework,分別存放在libs/Release-iphonesimulator和libs/Release-iphoneos文件夾下,開發(fā)者可根據(jù)需要使用真機(jī)或模擬器的包,如果需同時(shí)使用真機(jī)和模擬器的包,可以使用lipo命令將設(shè)備和模擬器framwork包中的BaiduMapAPI文件合并成一個(gè)通用的文件,命令如下:
lipo -create Release-iphoneos/BaiduMapAPI.framework/BaiduMapAPI Release-iphonesimulator/BaiduMapAPI.framework/BaiduMapAPI -output Release-iphoneos/BaiduMapAPI.framework/BaiduMapAPI
此時(shí)
Release-iphoneos
文件夾下的BaiduMapAPI.framework
即可同時(shí)用于真機(jī)和模擬器。將所需的BaiduMapAPI.framework
拷貝到工程所在文件夾下。在TARGETS->Build Phases-> Link Binary With Libaries
中點(diǎn)擊+
按鈕,在彈出的窗口中點(diǎn)擊“Add Other”按鈕,選擇BaiduMapAPI.framework
文件添加到工程中。
注:靜態(tài)庫(kù)中采用ObjectC++
實(shí)現(xiàn),因此需要您保證您工程中至少有一個(gè).mm后綴的源文件(您可以將任意一個(gè).m后綴的文件改名為.mm),或者在工程屬性中指定編譯方式,即將Xcode的Project -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As設(shè)置為Objective-C++
。
第二步、引入所需的系統(tǒng)庫(kù)
百度地圖SDK中提供了定位功能和動(dòng)畫效果,v2.0.0版本開始使用OpenGL渲染,因此您需要在您的Xcode工程中引入CoreLocation.framework
和QuartzCore.framework
、OpenGLES.framework
、
SystemConfiguration.framework
、CoreGraphics.framework
、
Security.framework
。添加方式:在Xcode的Project -> Active Target ->Build Phases ->Link Binary With Libraries,添加這幾個(gè)framework即可。
第三步、環(huán)境配置
在TARGETS->Build Settings->Other Linker Flags
中添加-ObjC
。
第四步、引入mapapi.bundle資源文件
如果使用了基礎(chǔ)地圖功能,需要添加該資源,否則地圖不能正常顯示
mapapi.bundle
中存儲(chǔ)了定位、默認(rèn)大頭針標(biāo)注View
及路線關(guān)鍵點(diǎn)的資源圖片,還存儲(chǔ)了矢量地圖繪制必需的資源文件。如果您不需要使用內(nèi)置的圖片顯示功能,則可以刪除bundle
文件中的image
文件夾。您也可以根據(jù)具體需求任意替換或刪除該bundle中image文件夾的圖片文件。
方法:選中工程名,在右鍵菜單中選擇Add Files to “工程名”…
,從BaiduMapAPI.framework||Resources
文件中選擇mapapi.bundle
文件,并勾選“Copy items if needed”
復(fù)選框,單擊Add
按鈕,將資源文件添加到工程中。
第五步、引入頭文件
在使用SDK的類引入頭文件:
#import <BaiduMapAPI/BMapKit.h>//引入所有的頭文件
#import <BaiduMapAPI/BMKMapView.h>//只引入所需的單個(gè)頭文件
--[引用自百度開放平臺(tái)iOS SDK環(huán)境配置][2]
5. 初始化 BMKMapManager
- 在
AppDelegate.m
中添加BMKMapManager
的定義:
@interface AppDelegate ()<BMKGeneralDelegate>
@property (nonatomic,strong) BMKMapManager *mapManager;
@end
- 遵守
BMKGeneralDelegate
實(shí)現(xiàn)其兩個(gè)代理方法,目的是為了得知本應(yīng)用是否聯(lián)網(wǎng)成功、授權(quán)成功:
- (void)onGetNetworkState:(int)iError
{
if (0 == iError) {
NSLog(@"聯(lián)網(wǎng)成功");
}
else{
NSLog(@"onGetNetworkState %d",iError);
}
}
- (void)onGetPermissionState:(int)iError
{
if (0 == iError) {
NSLog(@"授權(quán)成功");
}
else {
NSLog(@"onGetPermissionState %d",iError);
}
}
- 在AppDelegate.m文件中添加對(duì)BMKMapManager的初始化,并填入申請(qǐng)的授權(quán)Key,示例如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 要使用百度地圖先實(shí)例化 BMKMapManager
self.mapManager = [[BMKMapManager alloc]init];
// 如果要關(guān)注網(wǎng)絡(luò)及授權(quán)驗(yàn)證事件,請(qǐng)?jiān)O(shè)定 generalDelegate 參數(shù)
BOOL ret = [self.mapManager start:@"OjYbYha0YULmuLPaHT9wxxx" generalDelegate:self];
if (!ret) {
NSLog(@"manager start failed");
}
return YES;
}
二、實(shí)戰(zhàn)記錄運(yùn)動(dòng)軌跡
一條完整的運(yùn)動(dòng)軌跡是由一組地理位置坐標(biāo)數(shù)組描點(diǎn)連線構(gòu)成的,我們需要實(shí)時(shí)監(jiān)測(cè)用戶位置的變更,將最新的符合限定條件的地位位置數(shù)據(jù)存放到數(shù)據(jù)中,調(diào)用SDK中的畫折線方法繪制運(yùn)動(dòng)軌跡。
1. 初始化工作
@interface ViewController () <BMKMapViewDelegate, BMKLocationServiceDelegate>
/** 記錄上一次的位置 */
@property (nonatomic, strong) CLLocation *preLocation;
/** 位置數(shù)組 */
@property (nonatomic, strong) NSMutableArray *locationArrayM;
/** 軌跡線 */
@property (nonatomic, strong) BMKPolyline *polyLine;
/** 百度地圖View */
@property (nonatomic,strong) BMKMapView *mapView;
/** 百度定位地圖服務(wù) */
@property (nonatomic, strong) BMKLocationService *bmkLocationService;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化百度位置服務(wù)
[self initBMLocationService];
// 初始化地圖窗口
self.mapView = [[BMKMapView alloc]initWithFrame:self.view.bounds];
// 設(shè)置MapView的一些屬性
[self setMapViewProperty];
[self.view addSubview:self.mapView];
}
@end
- 初始化MapView后設(shè)置其一些屬性:
/**
* 設(shè)置 百度MapView的一些屬性
*/
- (void)setMapViewProperty
{
// 顯示定位圖層
self.mapView.showsUserLocation = YES;
// 設(shè)置定位模式
self.mapView.userTrackingMode = BMKUserTrackingModeNone;
// 允許旋轉(zhuǎn)地圖
self.mapView.rotateEnabled = YES;
// 顯示比例尺
self.bmkMapView.showMapScaleBar = YES;
self.bmkMapView.mapScaleBarPosition = CGPointMake(self.view.frame.size.width - 50, self.view.frame.size.height - 50);
// 定位圖層自定義樣式參數(shù)
BMKLocationViewDisplayParam *displayParam = [[BMKLocationViewDisplayParam alloc]init];
displayParam.isRotateAngleValid = NO;//跟隨態(tài)旋轉(zhuǎn)角度是否生效
displayParam.isAccuracyCircleShow = NO;//精度圈是否顯示
displayParam.locationViewOffsetX = 0;//定位偏移量(經(jīng)度)
displayParam.locationViewOffsetY = 0;//定位偏移量(緯度)
displayParam.locationViewImgName = @"walk";
[self.mapView updateLocationViewWithParam:displayParam];
}
- 百度定位服務(wù)的參數(shù)設(shè)置:
/**
* 初始化百度位置服務(wù)
*/
- (void)initBMLocationService
{
// 初始化位置百度位置服務(wù)
self.bmkLocationService = [[BMKLocationService alloc] init];
// 設(shè)置距離過濾,表示每移動(dòng)10更新一次位置
[BMKLocationService setLocationDistanceFilter:10];
// 設(shè)置定位精度
[BMKLocationService setLocationDesiredAccuracy:kCLLocationAccuracyBest];
}
2. 開始定位
// 打開定位服務(wù)
[self.bmkLocationService startUserLocationService];
// 設(shè)置當(dāng)前地圖的顯示范圍,直接顯示到用戶位置
BMKCoordinateRegion adjustRegion = [self.mapView regionThatFits:BMKCoordinateRegionMake(self.bmkLocationService.userLocation.location.coordinate, BMKCoordinateSpanMake(0.02f,0.02f))];
[self.mapView setRegion:adjustRegion animated:YES];
只要遵守了BMKLocationServiceDelegate
協(xié)議就可以獲知位置更新的情況,需要實(shí)現(xiàn)下面幾個(gè)代理方法:
/**
* 定位失敗會(huì)調(diào)用該方法
*
* @param error 錯(cuò)誤信息
*/
- (void)didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"did failed locate,error is %@",[error localizedDescription]);
}
/**
* 用戶位置更新后,會(huì)調(diào)用此函數(shù)
* @param userLocation 新的用戶位置
*/
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
// 如果此時(shí)位置更新的水平精準(zhǔn)度大于10米,直接返回該方法
// 可以用來簡(jiǎn)單判斷GPS的信號(hào)強(qiáng)度
if (userLocation.location.horizontalAccuracy > kCLLocationAccuracyNearestTenMeters) {
return;
}
}
/**
* 用戶方向更新后,會(huì)調(diào)用此函數(shù)
* @param userLocation 新的用戶位置
*/
- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation
{
// 動(dòng)態(tài)更新我的位置數(shù)據(jù)
[self.mapView updateLocationData:userLocation];
}
3. 存儲(chǔ)更新的用戶地理位置
/**
* 開始記錄軌跡
*
* @param userLocation 實(shí)時(shí)更新的位置信息
*/
- (void)recordTrackingWithUserLocation:(BMKUserLocation *)userLocation
{
if (self.preLocation) {
// 計(jì)算本次定位數(shù)據(jù)與上次定位數(shù)據(jù)之間的距離
CGFloat distance = [userLocation.location distanceFromLocation:self.preLocation];
self.statusView.distanceWithPreLoc.text = [NSString stringWithFormat:@"%.3f",distance];
NSLog(@"與上一位置點(diǎn)的距離為:%f",distance);
// (5米門限值,存儲(chǔ)數(shù)組畫線) 如果距離少于 5 米,則忽略本次數(shù)據(jù)直接返回方法
if (distance < 5) {
return;
}
}
// 2. 將符合的位置點(diǎn)存儲(chǔ)到數(shù)組中(第一直接來到這里)
[self.locationArrayM addObject:userLocation.location];
self.preLocation = userLocation.location;
// 3. 繪圖
[self drawWalkPolyline];
}
4. 繪制軌跡線
/**
* 繪制軌跡路線
*/
- (void)drawWalkPolyline
{
// 軌跡點(diǎn)數(shù)組個(gè)數(shù)
NSUInteger count = self.locationArrayM.count;
// 動(dòng)態(tài)分配存儲(chǔ)空間
// BMKMapPoint是個(gè)結(jié)構(gòu)體:地理坐標(biāo)點(diǎn),用直角地理坐標(biāo)表示 X:橫坐標(biāo) Y:縱坐標(biāo)
BMKMapPoint *tempPoints = new BMKMapPoint[count];
// 遍歷數(shù)組
[self.locationArrayM enumerateObjectsUsingBlock:^(CLLocation *location, NSUInteger idx, BOOL *stop) {
BMKMapPoint locationPoint = BMKMapPointForCoordinate(location.coordinate);
tempPoints[idx] = locationPoint;
}
}];
//移除原有的繪圖,避免在原來軌跡上重畫
if (self.polyLine) {
[self.mapView removeOverlay:self.polyLine];
}
// 通過points構(gòu)建BMKPolyline
self.polyLine = [BMKPolyline polylineWithPoints:tempPoints count:count];
//添加路線,繪圖
if (self.polyLine) {
[self.mapView addOverlay:self.polyLine];
}
// 清空 tempPoints 臨時(shí)數(shù)組
delete []tempPoints;
// 根據(jù)polyline設(shè)置地圖范圍
[self mapViewFitPolyLine:self.polyLine];
}
反饋與建議
感謝認(rèn)真閱讀這份幫助文檔,如果覺得有用可以分享到您的社交圈,也請(qǐng)注明出處,謝謝!
[1]:http://developer.baidu.com/map/index.php?title=首頁(yè)
[2]:http://developer.baidu.com/map/index.php?title=iossdk/guide/buildproject