iOS实现百度地图定位签到功能

2025-05-29 0 89

写在前面:

项目需求用到这个功能,主要目的是实现老师设置位置签到范围,学生在一定范围内进行签到的功能。

功能如下方截图:

iOS实现百度地图定位签到功能
屏幕快照 2019-01-28 上午10.29.26.png

简要介绍:

下面记录一下主要的实现流程,功能的实现主要是根据百度地图开发者官网提供的api文档,各项功能之间组合。百度地图的sdk现在分成了地图功能和定位功能两块不同的sdk,baidumapapi这个是基础的地图功能,bmklocationkit这个是定位功能。项目里实现定位签到功能用的的sdk包括上面说的这两个模块,所以在用cocopods引入framework的时候,需要引入: #百度地图 pod 'bmklocationkit' pod 'baidumapkit'

功能实现

一、在appdelegate.m文件中引入:

?

1

2
#import <baidumapapi_base/bmkbasecomponent.h>

#import <bmklocationkit/bmklocationcomponent.h>

加入功能代码:

?

1

2

3

4

5

6

7

8

9

10

11
#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中

?

1

2

3
#import <bmklocationkit/bmklocationcomponent.h>

#import <baidumapapi_base/bmkbasecomponent.h>//引入base相关所有的头文件

#import <baidumapapi_map/bmkmapcomponent.h>//引入地图功能所有的头文件

遵循协议<bmkmapviewdelegate,bmklocationmanagerdelegate>

声明全局变量

?

1

2

3

4

5

6
@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文档中建议在以下代码中如此设置, 目的是控制内存

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17
- (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;

}

}

初始化数组,这两个数组在接下来会用到

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
- (nsmutablearray *)annotationarr {

if (!_annotationarr) {

_annotationarr = [nsmutablearray array];

}

return _annotationarr;

}

- (nsmutablearray *)circlearr {

if (!_circlearr) {

_circlearr = [nsmutablearray array];

}

return _circlearr;

}

添加地图view

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24
#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;

}

}

初始化地图定位:这里我用的是一次定位而没有选择持续定位

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42
#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];

}

请求定位,获取经纬度

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39
#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);

}];

}

地图长按选点功能实现:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20
//长按地图选点

- (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];

}

选点后弹出选择定位范围弹框

?

1

2

3

4

5

6

7

8

9

10

11

12
#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数组 */

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
#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;

}

至此,在地图上选点进行签到功能基本实现,另外,关于 自定义的范围圆圈的颜色,边框大小都是可以自定义的,选点的标记也是可以自定义的,官方文档有说明

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS实现百度地图定位签到功能 https://www.kuaiidc.com/89184.html

相关文章

发表评论
暂无评论