IOS之百度地图-集成+定位+模糊查询(实现钉钉签到功能)
目录:
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
实现效果图实现效果图 实现效果图
希望帮助到你,我是辛小二 记得点赞哦😘
本人个人微信公众号地址(喜欢记得关注😯)
辛小二个人微信公众号地址