iOS百度地图SDK之实时绘制轨迹(后台仍执行)
来源:互联网 发布:网页游戏挂机软件 编辑:程序博客网 时间:2024/05/01 07:39
首先,对于百度地图SDK的配置和环境搭建就不做说明,需要的人可以博客中另一篇文章看 《iOS百度地图SDK基本使用》 ,本文的重点在于实现实时绘制轨迹的功能,并且对细节进行处理和优化
1、在AppDelegate.m文件中
#import "AppDelegate.h"// BMapKit.h代表导入了所有的头文件#import <BaiduMapAPI/BMapKit.h>@interface AppDelegate ()<BMKGeneralDelegate>{ BMKMapManager *mapManager;}@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 要使用地图,首先需要初始化和启动BMKMapManager mapManager = [[BMKMapManager alloc]init]; // 填入验证码, 如需要使用网络和授权验证服务,则需要设置代理信息 BOOL ret = [mapManager start:@"在这里填入的是密钥中的安全码" generalDelegate:nil]; if (!ret) { NSLog(@"地图管理器初始化失败"); } else{ NSLog(@"初始化成功"); } return YES;}
2、在ViewController.m文件中
#import "ViewController.h"#import <BaiduMapAPI/BMapKit.h>#define normalLocationTag 1#define compassLocationTag 2@interface ViewController () <BMKLocationServiceDelegate , BMKMapViewDelegate>{ BMKMapView *mapView; BMKLocationService *locationService; // 用于手动验证 CLLocationManager *locationManager; // 用于记录经过的点 NSMutableArray *locationPoint; // 在地图上绘制的折线 BMKPolyline *routeLine; // 中间变量->location类型(地理位置) CLLocation *currentLocation;}@end
在viewDidLoad中将两个初始化体现出来
- (void)viewDidLoad { [super viewDidLoad]; // 1、所有的初始化操作 [self initObjects]; // 2、所有的地图初始操作 [self operationForMap];}
初始化操作的封装后的方法
- (void)initObjects{ // 初始化mapView mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 120, self.view.bounds.size.width, self.view.bounds.size.height)]; // 初始化locationService locationService = [[BMKLocationService alloc]init];}
对地图的各个参数进行操作封装后的方法
- (void)operationForMap{ // 设置过滤距离,更新的最小间隔距离 [BMKLocationService setLocationDistanceFilter:6.0f]; // 设置定位精度模式 /* tips: 以前使用了kCLLocationAccuracyBest--> 表示在使用电池的最高精度 现在使用了kCLLocationAccuracyBestForNavigation--> 表示在外接电源的时候的最高精度(有些在AppStore上架的APP由于过度依赖于高精度的定位,所以采用了这种耗电的定位设置) */ [BMKLocationService setLocationDesiredAccuracy:kCLLocationAccuracyBestForNavigation]; // 设置地图类型 mapView.mapType = BMKMapTypeSatellite; // 设置是否需要热力图显示 [mapView setBaiduHeatMapEnabled:NO]; // 设置是否允许旋转地图 mapView.rotateEnabled = YES;<span style="white-space:pre"></span> // .....对于地图还有很多设置,这里不一一列举,需要的话可以在文档中查到<span style="white-space:pre"></span> [self.view addSubview:mapView];}
- (void)operationForLocation:(BMKUserLocation *)userLocation{ // 1、检查移动的距离,移除不合理的点 if (locationPoint.count > 0) { CLLocationDistance distance = [userLocation.location distanceFromLocation:currentLocation]; if (distance < 5) return; } // 2、初始化坐标点数组 if (nil == locationPoint) { locationPoint = [[NSMutableArray alloc] init]; } // 3、将合理的点添加到数组 [locationPoint addObject:userLocation.location]; // 4、作为前一个坐标位置辅助操作 currentLocation = userLocation.location; // 5、开始画线 [self configureRoutes]; // 6、实时更新用户位子 [mapView updateLocationData:userLocation];}
#pragma mark - 点击两个button触发的事件- (IBAction)startLocation:(UIButton *)button{ // 由于IOS8中定位的授权机制改变 需要进行手动授权(导致程序无法进行定位的主要原因) if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) { locationManager = [[CLLocationManager alloc] init]; [locationManager requestAlwaysAuthorization]; [locationManager requestWhenInUseAuthorization]; } // 开启用户定位 [locationService startUserLocationService]; // 开始先关闭地位图层(也就是定位的小圆点)-->用户体验问题 mapView.showsUserLocation = NO; // 根据所点击的button来开启不同的定位模式 if (button.tag == normalLocationTag) { mapView.userTrackingMode = BMKUserTrackingModeFollow; }else if(button.tag == compassLocationTag) { mapView.userTrackingMode = BMKUserTrackingModeFollowWithHeading; } mapView.showsUserLocation = YES; // 1、通过比例调试地图的显示#if 1 [mapView setZoomEnabled:YES]; mapView.zoomLevel = 19;// 级别是 3-19#endif #if 0 // 2、通过范围调试地图的显示 BMKCoordinateRegion adjustRegion = [mapView regionThatFits:BMKCoordinateRegionMake(locationService.userLocation.location.coordinate, BMKCoordinateSpanMake(0.03f,0.03f))]; [mapView setRegion:adjustRegion animated:YES];#endif}
#pragma mark - 视图的出现和消失(在其中设置代理和取消代理,优化内存管理)- (void)viewWillAppear:(BOOL)animated{ [mapView viewWillAppear]; mapView.delegate = self; locationService.delegate = self;}- (void)viewWillDisappear:(BOOL)animated{ [mapView viewWillDisappear]; // 一般情况下都需要在这里关闭掉代理,但是由于本程序需要在后台继续绘制轨迹,因为对应的代理方法是绘制轨迹,所以继续设置代理 mapView.delegate = self; locationService.delegate = self;}
#pragma mark - mapView的协议- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay{ if ([overlay isKindOfClass:[BMKPolyline class]]) { BMKPolylineView *polylineView = [[BMKPolylineView alloc]initWithPolyline:overlay]; // 设置划出的轨迹的基本属性-->也是使得定位看起来更加准确的主要原因 polylineView.strokeColor = [[UIColor blueColor]colorWithAlphaComponent:0.5]; polylineView.fillColor = [[UIColor blueColor]colorWithAlphaComponent:0.8]; polylineView.lineWidth = 6.0; return polylineView; } return nil;}
#pragma mark - 绘制轨迹-(void)configureRoutes{ // 1、分配内存空间给存储经过点的数组 BMKMapPoint* pointArray = (BMKMapPoint *)malloc(sizeof(CLLocationCoordinate2D) * locationPoint.count); // 2、创建坐标点并添加到数组中 for(int idx = 0; idx < locationPoint.count; idx++) { CLLocation *location = [locationPoint objectAtIndex:idx]; CLLocationDegrees latitude = location.coordinate.latitude; CLLocationDegrees longitude = location.coordinate.longitude; CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude); BMKMapPoint point = BMKMapPointForCoordinate(coordinate); pointArray[idx] = point; } // 3、防止重复绘制 if (routeLine) { //在地图上移除已有的坐标点 [mapView removeOverlay:routeLine]; } // 4、画线 routeLine = [BMKPolyline polylineWithPoints:pointArray count:locationPoint.count]; // 5、将折线(覆盖)添加到地图 if (nil != routeLine) { [mapView addOverlay:routeLine]; } // 6、清楚分配的内存 free(pointArray);}
#pragma mark - 更新用户位置时所调用的三种方法// 更新位置- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation{ // 说明:由于开启了“无限后台”的外挂模式(^-^)所以可以直接写操作代码,然后系统默认在任何情况执行,但是为了已读,规划代码如下 // 1、活跃状态 if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { [self operationForLocation:userLocation]; }else if([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) // 2、后台模式 { [self operationForLocation:userLocation]; } // 3、不活跃模式 else if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) { [self operationForLocation:userLocation]; }}// 更新方向- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation{ [mapView updateLocationData:userLocation];}// 定位失败了会调用- (void)didFailToLocateUserWithError:(NSError *)error{ NSLog(@"did failed locate,error is %@",[error localizedDescription]);}
到这里,代码就结束了,在viewWillDisappear中,依然没有关掉代理,是想让程序在锁屏后,或者是点击home键返回到桌面后仍然执行轨迹的绘制,但是仅仅设置代理是不够的,在没有进行配置的情况下,iOS系统最多可以让一个APP在有5秒钟的时间,用来进行保存和清理资源等任务。如果应用调用了UIApplication的beginBackgroundTaskWithExpirationHandler的方法,可以让APP在后台有10分组的运行时间,用来清理本地的缓存或者是进行数据的处理。超过了时间,APP便会被强制挂起
但是,就拿本例中所涉及的实时绘制轨迹来说,比如要开发一款跑步时绘制自己轨迹的应用,总不能跑步的时候都要将手机屏幕开着,并且还不能切换到其他地方,这样无疑增加了大量的电量消耗,所以,苹果也是为以下的几种提供了所谓的“无限后台”的外挂模式
1、Audio(音频播放)
2、Location/GPS(定位的实时更新)
3、Newsstand(杂志下载)
4、VoIP(网络电话)
所以,对于本例来说,苹果是允许启动外挂模式的,下面说明应该怎么配置这种模式
在info.plist文件中添加这样一项,Required background modes,然后这一项默认是数组类型,需要再在这项中添加一个item,默认生成了一项key为item0,接着将这个item0的value变为App registers for location updates
下面给出图例示范:
但是有人会想,那这样的话每个程序都可以开外挂了咯?话虽如此,但是在AppStore审核的时候,如果在plist文件中配置了这样的属性,那么AppStore会检测应用程序是否属于这种类型,如果不是的话,那么这样的APP就会被拒绝。
PS:demo的地址为 http://download.csdn.net/detail/nineteen_/9106725
0 0
- iOS百度地图SDK之实时绘制轨迹(后台仍执行)
- iOS百度地图SDK之实时绘制轨迹(后台仍执行)
- 百度地图轨迹绘制
- android 百度地图sdk v3.4 绘制历史轨迹
- iOS 之地图上绘制运动轨迹
- 百度地图--实时显示轨迹
- 百度地图绘制轨迹点
- iOS之地图的使用和实时描绘运动轨迹
- 安卓开发:怎样实时在百度地图上绘制运动轨迹?
- 百度鹰眼轨迹iOS SDK
- 百度地图3.5绘制轨迹线
- iOS 在地图上绘制运动轨迹
- ios百度导航SDK,iOS开发之百度地图导航
- iOS开发(第三方使用)——百度地图鹰眼轨迹SDK接入
- 百度地图之实时定位与画轨迹以及纠偏问题总结
- ios 百度地图轨迹回放一点心得
- iOS 百度地图 轨迹记录 道路贴合
- iOS 百度地图运动轨迹的角度
- Linux--安装nginx
- Java代理模式
- hdoj 1285 确定比赛名次 【拓朴排序】三种方法实现。
- java执行class文件简单示例
- BootStrap入门
- iOS百度地图SDK之实时绘制轨迹(后台仍执行)
- 3D模型的加载与使用
- Android 学习之逐帧动画(Frame)
- 总结导航设计模式的12种方法
- CZY的工程
- poj 2002 Squares
- 北国城,徒留旧梦
- 新浪微博SDK抛出异常-[__NSDictionaryM weibosdk_WBSDKJSONString]: unrecognized selector sent to instance 0x7fb
- 关于编码ansi、GB2312、unicode与utf-8的区别(带源码下载)