iOS系统内部的地图在国内使用的是高德地图,由于官方文档的限制百度地图其实也是对系统地图API的二次封装而已。由于公司的项目是一款与物流相关的APP,主界面是以地图为蓝本,所以就必须对百度地图十分熟悉(项目的老版本使用的百度地图)。
第一步、 在appDelegate的didFinishLaunchingWithOptions:方法中进行百度地图的初始化操作:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { mapManager = [[BMKMapManager alloc]init]; BOOL ret = [mapManager start:BAIDU_MAP_KEY generalDelegate:self];//BAIDU_MAP_KEY为百度注册获取的Key if(!ret) { NSLog(@"manager start failed!"); } }
第二步、在展示地图view的controller中实例化BMKMapView对象并添加相关UI控件
BDMapView=[[BMKMapView alloc] initWithFrame:CGRectMake(0,0,self.frame.size.width ,self.frame.size.height)]; BDMapView.zoomEnabled=true; BDMapView.showMapScaleBar =true; BDMapView.mapScaleBarPosition = CGPointMake(10,BDMapView.frame.size.height - 45); BDMapView.zoomLevel=15; //自定义精度圈 BMKLocationViewDisplayParam * param = [[BMKLocationViewDisplayParam alloc]init]; param.isAccuracyCircleShow = NO;//去掉大圆圈 param.locationViewImgName=@"icon_center_point"; [BDMapView updateLocationViewWithParam:param]; //定位按钮UI UIButton *btnLocation = [UIButton buttonWithType:UIButtonTypeCustom]; btnLocation.frame=CGRectMake(self.frame.size.width-50,BDMapView.mapScaleBarPosition.y-40,35,35); btnLocation.backgroundColor = WhiteColor; [btnLocation.layer setMasksToBounds:YES]; [btnLocation.layer setCornerRadius:AppCornerRadius]; [btnLocation setBackgroundImage:[ColorUtils createImageWithColor:WhiteColor rect:btnLocation.frame]forState:UIControlStateNormal]; [btnLocation addTarget:self action:@selector(locationOnDown:)forControlEvents:UIControlEventTouchDown]; //添加控件在View上面 [self addSubview:BDMapView]; [self addSubview:btnLocation];
#pragma mark - 定位按钮按下 -(void)locationOnDown:(UIButton*)button { [button setBackgroundColor:CheckColor]; [self onStart]; }
至此,调用定位方法。在项目中为方便使用结合API对其进行了二次封装。如果我们只是定位的话比较简单只需要是使用初始化BMKLocationService类并调用其对象方法即可如下:
-(id)init { locService = [[BMKLocationService alloc]init]; return self; } #pragma mark 开始定位 -(void)onStartLocation { [locService startUserLocationService]; } #pragma mark 结束定位 -(void)onStopLocation { [locService stopUserLocationService]; }
如果我们还需要获取详细的省市县三级地址或者经纬度的话稍微麻烦一点。需要遵守两个代理:
代理一:BMKLocationServiceDelegate
代理二:BMKGeoCodeSearchDelegate
遵守代理一 是因为需要用到其内部方法
/** *用户位置更新后,会调用此函数 *@param userLocation 新的用户位置 */ - (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation;
遵守代理二 是因为需要用到其内部方法
/** *返回反地理编码搜索结果 *@param searcher 搜索对象 *@param result 搜索结果 *@param error 错误号,@see BMKSearchErrorCode */ - (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error;
是不是到此就算结束了?错!
还有一些小问题需要解决:
问题1:
//在定位的方法里将定位获取的位置传给百度geo的位置这样才能定位成功并显示!!! #pragma mark 定位成功返回(调用位置更新的方法) - (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation { if(userLocation.location!=nil) { BMKUserLocation *bmkUserLocation = userLocation; CLLocationCoordinate2D position = userLocation.location.coordinate; BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init]; reverseGeocodeSearchOption.reverseGeoPoint = position; geocodesearch.delegate=self; [geocodesearch reverseGeoCode:reverseGeocodeSearchOption]; } else { [delegate onLocationError:@"定位异常..." addressFlag:false]; } }
为题2:
#pragma mark 反向地理编码,经纬度转地址 -(void) onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error { //检索结果正常返回 if (error == 0) { BMKAddressComponent *address = result.addressDetail; [delegate onLocationAddress:address.province city:address.city town:address.district street:[address.streetName stringByAppendingString:address.streetNumber]]; //显示经纬度 [delegate onLocationAngle:bmkUserLocation]; } else { [delegate onLocationError:@"经纬度转地址-地址编码未实现..." addressFlag:true]; } }
备注:代码中所涉及到的delegate为二次封装的代理。针对百度地图二次封装的源码待我百度网盘弄好之后会以超链接的形式共享出来。