iOS学习笔记橙红科技有限公司技术教程

IOS之百度地图-集成+定位+模糊查询(实现钉钉签到功能)

2017-08-13  本文已影响477人  辛小二

目录:

     1、集成
       (1)百度地图私钥申请
        (2) pod最新版本百度SDK
     2、定位功能实现
        (1)头文件导入
        (2)声明代理
        (3)创建对象
        (4)讲创建好的对象视图放置在制定位置
        (5)实现代理方法
        (6)生命周期对代理的释放
     3、模糊搜索
       (1)声明代理
        (2)创建对象
        (3)设置对象参数
       (4)获取对象当中的属性并赋值到cell上(此代理方法自动检索你想搜索(keyWord)内容下的地标)
       (5)将检索到的name传递给签到页面,并且更改签到页面的地址和地图位置
      4、附带钉钉签到旋转Demo

下面例子API使用百度API,APP程序仿照钉钉制作

百度地图开放平台传送门

集成

(1)百度地图私钥申请流程如下:

IOS百度地图开发->百度地图开放平台开发者注册->绑定邮箱注册->创建应用(填写白名单)->提交成功

(2)pod最新版本百度SDK

这个在这不做过多解释,直接Podfile中添加 pod 'BaiduMapKit',然后终端pod install即可.

定位功能实现

(1)头文件导入

#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
#import <BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件
#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的头文件
#import <MapKit/MapKit.h>
#import <BaiduMapAPI_Search/BMKSearchComponent.h>/*正/反向地理编码*/

(2)声明代理

<BMKMapViewDelegate,BMKLocationServiceDelegate, BMKGeoCodeSearchDelegate>

(3)创建对象

    BMKMapView * mapView;
#pragma mark - 地图定位
    BMKLocationService *_locService;
    
    BMKGeoCodeSearch *_searcher;/*正/反向地理编码*/

(4)讲创建好的对象视图放置在制定位置

-(void)mapUI{
    /*将地图放到头部视图上*/
    mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 0, kSCREEN_WIDTH, 400)];
    [self.mapView addSubview:mapView];
    //普通态121.185506 31.12268
    NSLog(@"%f",[self.latStr floatValue]);
    NSLog(@"%f",[self.lngStr floatValue]);
    //以下_mapView为BMKMapView对象
    mapView.centerCoordinate = CLLocationCoordinate2DMake([self.latStr floatValue], [self.lngStr floatValue]);
    
    //设置默认显示地图比例
    [mapView setZoomLevel:18];
    //初始化检索对象
    _searcher =[[BMKGeoCodeSearch alloc]init];
    _searcher.delegate = self;
    //发起反向地理编码检索
    CLLocationCoordinate2D pt = (CLLocationCoordinate2D){[self.latStr floatValue], [self.lngStr floatValue]};
    BMKReverseGeoCodeOption *reverseGeoCodeSearchOption = [[
                                                            BMKReverseGeoCodeOption alloc]init];
    reverseGeoCodeSearchOption.reverseGeoPoint = pt;
    BOOL flag = [_searcher reverseGeoCode:reverseGeoCodeSearchOption];
    if(flag)
    {
        NSLog(@"反geo检索发送成功");
    }
    else
    {
        NSLog(@"反geo检索发送失败");
    }
      }
}

(5)实现代理方法

#pragma mark 接收正向编码结果
- (void)onGetGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error{
    if (error == BMK_SEARCH_NO_ERROR) {
        //在此处理正常结果
        NSLog(@"result----%f----%f", result.location.latitude, result.location.longitude);
    }
    else {
        NSLog(@"抱歉,未找到结果");
    }
}
//接收反向地理编码结果
-(void) onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:
(BMKReverseGeoCodeResult *)result
                        errorCode:(BMKSearchErrorCode)error{
    if (error == BMK_SEARCH_NO_ERROR) {
        NSLog(@"result----%@", result.address);
    }
    else {
        NSLog(@"抱歉,未找到结果");
    }
}
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView{
    NSLog(@"地图展示完毕");
}

(6)生命周期对代理的释放

-(void)viewWillAppear:(BOOL)animated
{

    [mapView viewWillAppear];
    
    mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
    
}
-(void)viewWillDisappear:(BOOL)animated
{
    [mapView viewWillDisappear];
    
    mapView.delegate = nil; // 不用时,置nil
    
}

小结:如上代码能够实现当前位置的获取,利用接收反向地理编码结果来获取当前地址(当然对象中所具有的属性不仅仅只有这些,还有内容如下** )

///层次化地址信息
@property (nonatomic, strong) BMKAddressComponent* addressDetail;
///地址名称
@property (nonatomic, strong) NSString* address;
///商圈名称
@property (nonatomic, strong) NSString* businessCircle;
///结合当前位置POI的语义化结果描述
@property (nonatomic, strong) NSString* sematicDescription;
///城市编码
@property (nonatomic, strong) NSString* cityCode;
///地址坐标
@property (nonatomic) CLLocationCoordinate2D location;
///地址周边POI信息,成员类型为BMKPoiInfo
@property (nonatomic, strong) NSArray* poiList;

@end

///地址编码结果
@interface BMKGeoCodeResult : NSObject
{
    CLLocationCoordinate2D _location;
    NSString* _address;
}
///地理编码位置
@property (nonatomic) CLLocationCoordinate2D location;
///地理编码地址
@property (nonatomic,strong) NSString* address;

不过当你打印过这些地址之后,你会发现这些有可能都不是你想要的,那么我猜你想要的一定是地标建筑的名称,而不是街道的名称,那么我们接下来看下面的功能---->模糊搜索的功能.

模糊搜索

(1)声明代理

在实现搜索功能时候我们还需要添加一项代理<BMKPoiSearchDelegate>

(2)创建对象

CLLocationCoordinate2D _leftBottom;/*用来记载更改之后的经纬度位置*/
 CLLocationCoordinate2D _rightTop;/*用来记载更改之后的经纬度位置*/
  BMKPoiSearch * _poisearch;
    
 CLLocationCoordinate2D leftBottomPoint;/*用来记载更改之后的经纬度位置*/
 CLLocationCoordinate2D rightBottomPoint;/*用来记载更改之后的经纬度位置*/
BMKBoundSearchOption*boundSearchOption;/*矩形云检索参数信息类*/
BMKNearbySearchOption *searchOption;/*周边云检索参数信息类*/
- (void)initMapView{
    _poisearch = [[BMKPoiSearch alloc]init];
    _poisearch.delegate = self;
    
    BMKBoundSearchOption*boundSearchOption = [[BMKBoundSearchOption alloc]init];
    boundSearchOption.pageIndex = 0;
    //    boundSearchOption.radius = 1000;
    boundSearchOption.pageCapacity = 50;
    NSLog(@"%@",self.searchTF.text);
    /*如果什么也不填写默认选择公司*/
    if ([self.searchTF.text isEqualToString:@""]) {
        boundSearchOption.keyword = @"公司";
    }else{
        boundSearchOption.keyword = self.searchTF.text;
    }
    
    boundSearchOption.leftBottom =leftBottomPoint;
    boundSearchOption.rightTop =rightBottomPoint;
    
    
    
    
    BMKNearbySearchOption *searchOption = [[BMKNearbySearchOption alloc]init];
    //    [searchOption setLocation:coord]; //设置搜索中心点
    searchOption.pageIndex = 0;
    searchOption.pageCapacity = 50;
    searchOption.keyword = self.searchTF.text;
    searchOption.radius = 100000000; //搜索范围
    
    BOOL flag1 = [_poisearch poiSearchNearBy:searchOption];
    
    if (flag1) {
        NSLog(@"搜索成功");
        //        [self.tableView.mj_footer endRefreshing];
    }else{
        
        NSLog(@"搜索失败");
        //        [self.tableView.mj_footer endRefreshing];
    }
    BOOL flag = [_poisearch poiSearchInbounds:boundSearchOption];
    if(flag)
    {
        NSLog(@"范围内检索发送成功");
    }
    else
    {
        NSLog(@"范围内检索发送失败");
    }
}

上方创建的两种搜索类BMKBoundSearchOption 和 BMKNearbySearchOption 都是可以获取到周边信息的,两者任选其一都可以.

(3)设置对象参数

上面说到的BMKBoundSearchOption & BMKNearbySearchOption 这两个类里面都具有keyword(搜索关键字)&pageIndex(分页)&pageCapacity(页面展示数量)&city(区域名称)&_radius(设置搜索周边半径大小)&location(中心点的设置)等属性

(4)获取对象当中的属性并赋值到cell上(此代理方法自动检索你想搜索(keyWord)内容下的地标)

#pragma mark implement BMKSearchDelegate
- (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult*)result errorCode:(BMKSearchErrorCode)error
{
    if (error == BMK_SEARCH_NO_ERROR) {
        NSArray* array = [NSArray arrayWithArray:_adressMapView.annotations];
        [_adressMapView removeAnnotations:array];
        NSLog(@"%@",self.searchTF.text);
        array = [NSArray arrayWithArray:_adressMapView.overlays];
        [_adressMapView removeOverlays:array];
        
        self.annotationsArray = [NSMutableArray array];
        self.annotationsArrayModel = [NSMutableArray array];
        
        //在此处理正常结果
        for (int i = 0; i < result.poiInfoList.count; i++)
        {
            BMKPoiInfo* poi = [result.poiInfoList objectAtIndex:i];
            NSLog(@"%@",poi.name);
            [self addAnimatedAnnotationWithName:poi.name withAddress:poi.pt];
            
            //逆地理编码
            BMKGeoCodeSearch *_geoCodeSearch = [[BMKGeoCodeSearch alloc]init];
            _geoCodeSearch.delegate = self;
            //初始化逆地理编码类
            BMKReverseGeoCodeOption *reverseGeoCodeOption= [[BMKReverseGeoCodeOption alloc] init];
            //需要逆地理编码的坐标位置
            reverseGeoCodeOption.reverseGeoPoint = poi.pt;
            [_geoCodeSearch reverseGeoCode:reverseGeoCodeOption];
            
            NSLog(@"%f",poi.pt.latitude);/*纬度*/
            NSLog(@"%f",poi.pt.longitude);/*经度*/
            NSString * latitudeStr = CZString(@"%f",poi.pt.latitude);
            NSString * longitudeStr = CZString(@"%f",poi.pt.longitude);
            NSDictionary *parma = @{
                                    @"name":poi.name,
                                    @"adress":poi.address,
                                    @"jing":longitudeStr,
                                    @"wei":latitudeStr,
                                    };
            NSLog(@"%@",parma);
            [self.annotationsArray addObject:parma];
            /*对象转model*/
            for (int i =0; i<_annotationsArray.count; i++) {
                baiduModel * model = [[baiduModel alloc]initWithInfoDic:_annotationsArray[i]];
                [self.annotationsArrayModel addObject:model];
            }
        }
        NSLog(@"%@",self.searchTF.text);
        NSLog(@"%@",self.annotationsArray);
        [self.mainTableView reloadData];
    } else if (error == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR){
        NSLog(@"起始点有歧义");
    } else {
        // 各种情况的判断。。。
    }
}
// 添加动画Annotation(检索中实现动画效果)
- (void)addAnimatedAnnotationWithName:(NSString *)name withAddress:(CLLocationCoordinate2D)coor {
    
    BMKPointAnnotation*animatedAnnotation = [[BMKPointAnnotation alloc]init];
    animatedAnnotation.coordinate = coor;
    animatedAnnotation.title = name;
    [_adressMapView addAnnotation:animatedAnnotation];
    
}

上方BMKPoiInfo* poi创建的poi类中就可以精准的获取到如下属性(其中name就是我们上文中检索不到地标名称属性)

///POI信息类
@interface BMKPoiInfo : NSObject
{
    NSString* _name;            ///<POI名称
    NSString* _uid;
    NSString* _address;     ///<POI地址
    NSString* _city;            ///<POI所在城市
    NSString* _phone;       ///<POI电话号码
    NSString* _postcode;        ///<POI邮编
    int       _epoitype;        ///<POI类型,0:普通点 1:公交站 2:公交线路 3:地铁站 4:地铁线路
    CLLocationCoordinate2D _pt; ///<POI坐标
}
///POI名称
@property (nonatomic, strong) NSString* name;
///POIuid
@property (nonatomic, strong) NSString* uid;
///POI地址
@property (nonatomic, strong) NSString* address;
///POI所在城市
@property (nonatomic, strong) NSString* city;
///POI电话号码
@property (nonatomic, strong) NSString* phone;
///POI邮编
@property (nonatomic, strong) NSString* postcode;
///POI类型,0:普通点 1:公交站 2:公交线路 3:地铁站 4:地铁线路
@property (nonatomic) int epoitype;
///POI坐标
@property (nonatomic) CLLocationCoordinate2D pt;
///是否有全景
@property (nonatomic, assign) BOOL panoFlag;

(5)将检索到的name传递给签到页面,并且更改签到页面的地址和地图位置

思路 : 当我们点击cell选中搜索的cell时我们需要点击按钮然后将选中位置传递给签到,那么我们就需要获取到你存在数据源数组当中的name&CLLocationCoordinate2D pt属性,然后通过代理&block&通知&反向传值的方式传递给上级页面实现位置更改.

我们分别创建两个NSString来接受model当中的经度和纬度两个属性(因为在对象转model赋值给cell的时候我们已经将CLLocationCoordinate2D pt转化为了两个属性),然后添加下面这句话,你所创建的BMKMapView对象的视图就自动更改了位置

这是上面检索代理中的两个字符串属性,都是POI信息类当中能获取到的资源,分别存储到了数据源数组当中.
NSLog(@"%f",poi.pt.latitude);/纬度/
NSLog(@"%f",poi.pt.longitude);/经度/

/直接一句话刷新中心经纬度
其中weiStr代表poi中获取到的poi.pt.latitude而 jingStr代表poi.pt.longitude/
_adressMapView.centerCoordinate = CLLocationCoordinate2DMake([weiStr floatValue], [jingStr floatValue]);

小结:上方检索周边商户和实现定位功能唯一的区别就在于,检索周边商户多了一个代理方法和创建了如下三个对象(BMKPoiSearch& BMKBoundSearchOption& BMKNearbySearchOption).同时通过代理检索到了BMKPoiInfo信息类中的多种属性,存到数据源当中通过赋值的方式赋值到cell上,又通过传值的方式传递给了上级页面实现签到功能.

附带钉钉签到旋转Demo

------>钉钉签到旋转Demo

实现效果图
实现效果图 实现效果图

希望帮助到你,我是辛小二 记得点赞哦😘

本人个人微信公众号地址(喜欢记得关注😯)


辛小二个人微信公众号地址
上一篇下一篇

猜你喜欢

热点阅读