登录 立即注册
金钱:

Code4App-188bet注册-iOS 开源代码库-188bet官网实例搜索-iOS特效示例-188bet官网例子下载-Code4App.com

m88 188bet uedbet 威廉希尔 明升 bwin 明升88 bodog bwin 明升m88.com 18luck 188bet unibet unibet Ladbrokes Ladbrokes casino m88明升 明升 明升 m88.com 188bet m88 明陞 uedbet赫塔菲官网 365bet官网 m88 help

iOS 百度地图定位签到实现 [复制链接]

2019-2-13 10:32
ceshishangchuan 阅读:2105 评论:1 赞:2
Tag:  

写在前面:

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

image.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=""></bmklocationkit></baidumapapi_base>

加入功能代码:

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="">//引入地图功能所有的头文件</baidumapapi_map></baidumapapi_base></bmklocationkit>
1
遵循协议<bmkmapviewdelegate,bmklocationmanagerdelegate></bmkmapviewdelegate,bmklocationmanagerdelegate>
1
2
3
4
5
6
7
声明全局变量
@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
25
#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 *@param 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
#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;
}</bmkoverlay>

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

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(1)
18603696628 2019-3-15 14:22
敢问老兄有 demo 么? 是否在同性交友网站上? 你们的 APP 上架了么?叫什么名字? 谢咯~
回复
关闭

每日头条

通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
[email protected]
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

返回顶部