iOS实现百度地图定位签到功能
写在前面:
项目需求用到这个功能,主要目的是实现老师设置位置签到范围,学生在一定范围内进行签到的功能。
功能如下方截图:
屏幕快照 2019-01-28 上午10.29.26.png
简要介绍:
下面记录一下主要的实现流程,功能的实现主要是根据百度地图开发者官网提供的api文档,各项功能之间组合。百度地图的sdk现在分成了地图功能和定位功能两块不同的sdk,baidumapapi这个是基础的地图功能,bmklocationkit这个是定位功能。项目里实现定位签到功能用的的sdk包括上面说的这两个模块,所以在用cocopods引入framework的时候,需要引入: #百度地图 pod 'bmklocationkit' pod 'baidumapkit'
功能实现
一、在appdelegate.m文件中引入:
#import <baidumapapi_base/bmkbasecomponent.h> #import <bmklocationkit/bmklocationcomponent.h>
加入功能代码:
#pragma mark 百度地图设置 - (void)configbaidumap { nsstring *ak = @"xxxx"; bmkmapmanager *mapmanager = [[bmkmapmanager alloc] init]; self.mapmanager = mapmanager; bool ret = [mapmanager start:ak generaldelegate:nil]; [[bmklocationauth sharedinstance] checkpermisionwithkey:ak authdelegate:self]; if (!ret) { nslog(@"manager start failed!"); } }
二、在用到地图定位功能的viewcontroller中
#import <bmklocationkit/bmklocationcomponent.h> #import <baidumapapi_base/bmkbasecomponent.h>//引入base相关所有的头文件 #import <baidumapapi_map/bmkmapcomponent.h>//引入地图功能所有的头文件
遵循协议<bmkmapviewdelegate,bmklocationmanagerdelegate>
声明全局变量
@property (nonatomic, strong) bmkuserlocation *userlocation; //当前位置对象 @property (nonatomic, strong) bmklocationmanager *locationmanager;/** locationmanager*/ @property (nonatomic, strong) bmkmapview *mapview;/** 百度地图*/ //@property (nonatomic, strong) bmkpointannotation* annotation ;/** 标记*/ @property (nonatomic, strong) nsmutablearray *annotationarr;/** 标记数组*/ @property (nonatomic, strong) nsmutablearray *circlearr;/** 圆形数组*/
地图sdk文档中建议在以下代码中如此设置, 目的是控制内存
- (void)viewwillappear:(bool)animated { [super viewwillappear:animated]; [_mapview viewwillappear]; _mapview.delegate = self; } - (void)viewwilldisappear:(bool)animated { [super viewwilldisappear:animated]; [_mapview viewwilldisappear]; _mapview.delegate = nil; } - (void)dealloc { if (_mapview) { _mapview = nil; } }
初始化数组,这两个数组在接下来会用到
- (nsmutablearray *)annotationarr { if (!_annotationarr) { _annotationarr = [nsmutablearray array]; } return _annotationarr; } - (nsmutablearray *)circlearr { if (!_circlearr) { _circlearr = [nsmutablearray array]; } return _circlearr; }
添加地图view
#pragma mark 添加地图 - (void)addsignmapbgview { if (!self.mapbgview) { uiview *mapbgview = [uiview new]; self.mapbgview = mapbgview; mapbgview.backgroundcolor = [commutls colorwithhexstring:app_bgcolor]; [self addsubview:mapbgview]; [mapbgview makeconstraints:^(masconstraintmaker *make) { make.top.equalto(self.tipview.bottom); make.left.right.bottom.equalto(0); }]; _mapview = [[bmkmapview alloc] initwithframe:cgrectzero]; // _mapview.delegate = self; [_mapview setzoomlevel:21];//精确到5米 _mapview.showsuserlocation = yes;//显示定位图层 [mapbgview addsubview:_mapview]; [_mapview makeconstraints:^(masconstraintmaker *make) { make.edges.equalto(0); }]; _mapview.usertrackingmode = bmkusertrackingmodenone; } }
初始化地图定位:这里我用的是一次定位而没有选择持续定位。
#pragma mark 初始化locationmanager - (void)inituserlocationmanager { //因为mapview是在一个分离出来的view中创建的,所以在这里将signsettypeview中的mapview赋给当前viewcontroller的mapview; self.mapview = self.mainview.signsettypeview.mapview; self.mapview.delegate = self; // self.annotation = [[bmkpointannotation alloc] init]; // self.mapview是bmkmapview对象 //精度圈设置 bmklocationviewdisplayparam *param = [[bmklocationviewdisplayparam alloc] init]; //设置显示精度圈,默认yes param.isaccuracycircleshow = yes; //精度圈 边框颜色 param.accuracycirclestrokecolor = [uicolor colorwithred:242/255.0 green:129/255.0 blue:126/255.0 alpha:1]; //精度圈 填充颜色 param.accuracycirclefillcolor = [uicolor colorwithred:242/255.0 green:129/255.0 blue:126/255.0 alpha:0.3]; [self.mapview updatelocationviewwithparam:param]; self.userlocation = [[bmkuserlocation alloc] init]; //初始化实例 _locationmanager = [[bmklocationmanager alloc] init]; //设置delegate _locationmanager.delegate = self; //设置返回位置的坐标系类型 _locationmanager.coordinatetype = bmklocationcoordinatetypebmk09ll; //设置距离过滤参数 _locationmanager.distancefilter = kcldistancefilternone; //设置预期精度参数 _locationmanager.desiredaccuracy = kcllocationaccuracybest; //设置应用位置类型 _locationmanager.activitytype = clactivitytypeautomotivenavigation; //设置是否自动停止位置更新 _locationmanager.pauseslocationupdatesautomatically = no; //设置是否允许后台定位 //_locationmanager.allowsbackgroundlocationupdates = yes; //设置位置获取超时时间 _locationmanager.locationtimeout = 15; //设置获取地址信息超时时间 _locationmanager.regeocodetimeout = 15; //请求一次定位 [self requestlocation]; }
请求定位,获取经纬度
#pragma mark 请求定位 - (void)requestlocation { [_locationmanager requestlocationwithregeocode:yes withnetworkstate:yes completionblock:^(bmklocation * _nullable location, bmklocationnetworkstate state, nserror * _nullable error) { if (error) { nslog(@"locerror:{%ld - %@};", (long)error.code, error.localizeddescription); } if (location) {//得到定位信息,添加annotation if (location.location) { nslog(@"loc = %@",location.location); } if (location.rgcdata) { nslog(@"rgc = %@",[location.rgcdata description]); } if (!location) { return; } if (!self.userlocation) { self.userlocation = [[bmkuserlocation alloc] init]; } self.userlocation.location = location.location; [self.mapview updatelocationdata:self.userlocation]; cllocationcoordinate2d mycoordinate = location.location.coordinate; self.mapview.centercoordinate = mycoordinate; //赋予初始值 self.viewmodel.lat = [nsstring stringwithformat:@"%f", location.location.coordinate.latitude]; self.viewmodel.lng = [nsstring stringwithformat:@"%f",location.location.coordinate.longitude]; self.viewmodel.radius = @"50"; //打印经纬度 nslog(@"didupdateuserlocation lat %f,long %f",location.location.coordinate.latitude,location.location.coordinate.longitude); } nslog(@"netstate = %d",state); }]; }
地图长按选点功能实现:
//长按地图选点 - (void)mapview:(bmkmapview *)mapview onlongclick:(cllocationcoordinate2d)coordinate { if (self.annotationarr.count > 0) { [mapview removeannotations:self.annotationarr]; [self.annotationarr removeallobjects]; bmkpointannotation *annotation = [[bmkpointannotation alloc]init]; annotation.coordinate = coordinate; [self.annotationarr addobject:annotation]; [mapview addannotations:self.annotationarr]; } else { bmkpointannotation *annotation = [[bmkpointannotation alloc]init]; annotation.coordinate = coordinate; [self.annotationarr addobject:annotation]; [mapview addannotations:self.annotationarr]; } //弹出半径选择框 [self showlocationselectradiusviewwithcoordinate:coordinate]; }
选点后弹出选择定位范围弹框
#pragma mark 弹出位置弹框 - (void)showlocationselectradiusviewwithcoordinate:(cllocationcoordinate2d)coordinate { extraactlocationsignpopview *popview = [extraactlocationsignpopview new]; [popview show]; @weakify(self); [popview.locatioonsuresignal subscribenext:^(nsstring *x) { @strongify(self); self.viewmodel.radius = x; cgfloat radius = [x floatvalue]; [self circlewithcenterwithcoordinate2d:coordinate radius:radius]; }]; }
设置好定位点以及半径范围后绘制范围圈,开始的时候声明的circlearr在这里用来盛放添加的区域圆形,在添加新的圆圈的时候,将之前旧的移除,保证每次绘制的范围都是最新的,同理annotationarr也是这个功能,因为api有提供的- (void)addoverlays:(nsarray *)overlays;这个方法:/** *向地图窗口添加一组overlay,需要实现bmkmapviewdelegate的-mapview:viewforoverlay:函数来生成标注对应的view overlays 要添加的overlay数组 */
#pragma mark 添加区域圆形覆盖 - (void)circlewithcenterwithcoordinate2d:(cllocationcoordinate2d )coor radius:(cgfloat)radius { nslog(@"coordinate lat %f,long %f",coor.latitude,coor.longitude); //赋予点击选点值 self.viewmodel.lat = [nsstring stringwithformat:@"%f", coor.latitude]; self.viewmodel.lng = [nsstring stringwithformat:@"%f",coor.longitude]; if (self.circlearr.count > 0) { [_mapview removeoverlays:self.circlearr]; [self.circlearr removeallobjects]; bmkcircle *circle = [bmkcircle circlewithcentercoordinate:coor radius:radius]; [self.circlearr addobject:circle]; [_mapview addoverlays:self.circlearr]; } else { bmkcircle *circle = [bmkcircle circlewithcentercoordinate:coor radius:radius]; [self.circlearr addobject:circle]; [_mapview addoverlays:self.circlearr]; } } #pragma mark 重绘overlay - (bmkoverlayview *)mapview:(bmkmapview *)mapview viewforoverlay:(id <bmkoverlay>)overlay{ if ([overlay iskindofclass:[bmkcircle class]]){ bmkcircleview* circleview = [[bmkcircleview alloc] initwithoverlay:overlay]; circleview.fillcolor = [uicolor colorwithred:33/255.0 green:196/255.0 blue:206/255.0 alpha:0.3]; circleview.strokecolor = [uicolor colorwithred:33/255.0 green:196/255.0 blue:206/255.0 alpha:1]; circleview.linewidth = 1.0; return circleview; } return nil; }
至此,在地图上选点进行签到功能基本实现,另外,关于 自定义的范围圆圈的颜色,边框大小都是可以自定义的,选点的标记也是可以自定义的,官方文档有说明
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
上一篇: 详解使用HTML5 Canvas创建动态粒子网格动画
下一篇: 喝茶好处有哪些