iOS调用百度地图 V2.3.0

第一次使用百度地图,在iOS上。上一次使用百度地图是在一个多月前,因为那时刚好百度地图更新了SDK,之前也没有这么研究过百度地图,所以这个项目的Android版本使用的百度地图SDK不是最新的。

先上效果图:


但这次,iOS版本开发使用的是v2.3.0 版本,目前最新的百度地图SDK,当然,也遇到了不少问题。知道现在,才勉强解决好了自己需要的那些功能。

这次,就记录下来,作为分享,当然,也是为了方便自己以后的开发使用。

1.首先,进百度地图<iOS SDK>界面:http://developer.baidu.com/map/sdk-ios.htm,页面上有获取密钥这栏(如果,还没有百度账号的,要先注册账号),申请一个密钥,需要自己项目的Bundle Identifier(开发过Android的读者应该知道,这个类似于Manifest中的包签名)。这一步也不是很重要,从百度地图官网都可以得到:http://developer.baidu.com/map/sdkiosdev-1.htm#.E7.AE.80.E4.BB.8B3。所以不做过多接受了。

2.下载SDK  v2.3.0,这个进入第一个链接的相关下载即可下载得到。得到的文件中包含了百度地图demo/sdk/doc等,即

这三个文件分别是参考文档/库函数/官方例子。当然,我们工程中需要的是Lib.zip,当然,不论是谁,都应该去看看百度提供的Sample以及他的参考文档,这样,才能拥有不同的收获。


3.将类库以及静态库拉入项目中,我的项目是这样:,其中BaiduMapSDK是自己建立的一个分组,mapapi.bundle是存放地图的一些资源,libbaidumapapi.a是静态库,inc是一些类库头文件。这三者都是必须的。当然,这里关于静态库需要说一下。因为下载的SDK中有两个静态库,不同的区别。一个试用与真机,一个试用于虚拟机。这些在官网中说的也非常详细了,所以,处理静态文件可以按照官网提供的方式:http://developer.baidu.com/map/wiki/index.php?title=iossdk/guide/hellobaidumap 参考 引入静态库文件,(个人建议使用第三种方式,静态库的合成:http://www.myexception.cn/mobile/1683246.html<如果百度官网中还没有研究透彻,那么就看这个简单的合成>)  然后就是各种引入系统Framework,这个导入同样参考这个网址中的数据。

4.特别注明,这期间不用修改任何系统文件/属性。只需要按照步骤一步一步来就可。小编就是听从朋友的建议,改了又改,造成了很多的误解。切记呀。


5.开始研发:小编采用的是StoryBoard布局,布局如下:

当然,这里的父视图是一个View,然后添加了一个View子视图,用来替换导航栏。当然了,这是用来显示地图的,所以,全屏设置了一个BMKMapView,由于这里是空白,显示出来就看不见了。这样设置了,添加一个全屏UIView,修改他的父类为BMKMapView,当然,也可以在代码中实现这些。不过,这些都不是重点。绑定对应的控件就不作出阐述了。

6.布局完成了,就该来实现代码了。找到AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    UIWindow *windows;
    UINavigationController *navigationController;
    BMKMapManager* _mapManager;
}
 6.1 继续完成在AppDelegate.m的配置

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
    // 要使用百度地图,请先启动BaiduMapManager
    _mapManager = [[BMKMapManager alloc]init];
    // 如果要关注网络及授权验证事件,请设定     generalDelegate参数
    BOOL ret = [_mapManager start:@"ugr9Z0DoKlalwgjRDmHGi4MY"  generalDelegate:nil];
    if (!ret) {
        NSLog(@"manager start failed!");
    }
    // Add the navigation controller's view to the window and display.
    [windows addSubview:navigationController.view];
    [windows makeKeyAndVisible];
    return YES;
}

不过记得在.h 文件中导入  

#import "BMKMapManager.h"


7.回到定义的显示地图的ViewController中,将其.m文件修改为.mm文件,这个在百度官网中解释为:注:静态库中采用ObjectC++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm)   

7.1 开始初始化地图控件,设置相关属性

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initMapView];
}

//初始化MapView
-(void)initMapView{
    //地图类型为普通类型
    _mapView.mapType=BMKMapTypeStandard;
    //地图缩放级别
    _mapView.zoomLevel=16;
}

关于显示地图,还需要设置

#pragma mark 地图将要出现
-(void)viewWillAppear:(BOOL)animated
{
    [_mapView viewWillAppear];
    self.navigationController.navigationBarHidden = YES;
    _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
    _locationService.delegate = self;//这是定位服务
}
#pragma mark 地图将要消失
-(void)viewWillDisappear:(BOOL)animated {
    [_mapView viewWillDisappear];
    _mapView.delegate = nil; // 不用时,置nil
    _locationService.delegate = nil;
    _searcher.delegate=nil;//这是进行关键词搜索
}
这里一起将之后需要用到的定位服务,关键词搜索等委托一起复制了出来,无怪,这里给出MapView的一些协议方法,如果需要做出什么操作,根据自己需要处理。

#pragma mark 地图zoomlevel++
-(void)zoomMap:(id)sender
{
    _mapView.zoomLevel = _mapView.zoomLevel++;
}
#pragma mark 地图ZoomLevel--
-(void)subMap:(id)sender
{
    _mapView.zoomLevel = _mapView.zoomLevel--;
}
//上边是放大缩小

#pragma mark 地图长按事件
-(void)mapview:(BMKMapView *)mapView onLongClick:(CLLocationCoordinate2D)coordinate
{
}
#pragma mark 地图双击手势
- (void)mapview:(BMKMapView *)mapView onDoubleClick:(CLLocationCoordinate2D)coordinate
{
}


到这里,地图就能够显示了,关于地图类型,缩放级别,库函数中已经说得很明白了,这里就不做过多阐述,好吧,还是介绍一个:比如地图类型

// 当前地图类型,可设定为标准地图、实时路况、卫星地图、同时打开实时路况和卫星地图模式
@property (nonatomic) BMKMapType mapType;

enum {
    BMKMapTypeStandard   = 1,               ///< 标准地图
    BMKMapTypeTrafficOn  = 2,               ///< 实时路况 
    BMKMapTypeSatellite  = 4,               ///< 卫星地图
    BMKMapTypeTrafficAndSatellite  = 8,     ///< 同时打开实时路况和卫星地图
};
typedef NSUInteger BMKMapType;
源码中给出了这几个类型,敢兴趣的可以尝试一下。


7.2 关于使用百度地图进行定位

//初始化定位设置
- (void)initLocation{
    //定位服务
    _locationService = [[BMKLocationService alloc]init];
    [_locationService startUserLocationService];//开始定位
    _mapView.showsUserLocation = NO;//不显示定位图层
    _mapView.userTrackingMode = BMKUserTrackingModeFollow;//设置定位模式为定位跟随,这里提供了三者模式,小编就不一一介绍了
    _mapView.showsUserLocation = YES;//设置为显示
}
定位之后,相关的处理方法都需要在其协议方法中实现,故此推出以下方法:


#pragma mark 在开时定位时调用
- (void)willStartLocatingUser
{
}
#pragma mark 在停止定位后,会调用此函数
- (void)didStopLocatingUser
{
}

#pragma mark 在地图View将要启动定位时,会调用此函数
- (void)mapViewWillStartLocatingUser:(BMKMapView *)mapView
{
}

#pragma mark 用户位置更新后,会调用此函数
- (void)didUpdateUserLocation:(BMKUserLocation *)userLocation
{
    [_mapView updateLocationData:userLocation];
    //物理地址
    BMKGeoCodeSearch *search = [[BMKGeoCodeSearch alloc]init];
    search.delegate=self;
    //进行反地理位置编码
    BMKReverseGeoCodeOption *rever = [[BMKReverseGeoCodeOption alloc]init];
    rever.reverseGeoPoint = userLocation.location.coordinate;
    [search reverseGeoCode:rever];
    //停止定位
    [_locationService stopUserLocationService];
}

#pragma mark 在地图View停止定位后,会调用此函数
- (void)mapViewDidStopLocatingUser:(BMKMapView *)mapView
{
}
#pragma mark 定位失败后,会调用此函数
- (void)mapView:(BMKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
}

这里提到了反地理编码,原因是定位的时候只得到了经纬度,本次通过经纬度来进行反地理编码,得到详细地址,这里的反地理编码实现了代理,所以结果在代码方法中处理:

#pragma mark 获取到物理地址信息
-(void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error
{
    //得到当前详细地址和城市
    _address=result.address;
    _city=result.addressDetail.city;
    //设置显示的值
    [_addressTextField setText:_address];
}

上面是两个属性和一个控件,主要是得到城市和地址以及显示地址信息,

BMKReverseGeoCodeResult 这个类是得到的地址信息,其属性四个,可以点击进库函数查看,这里就不做详细介绍了。


8.关于重新定位:就是自己手动再调用一次定位函数

- (IBAction)setLocationButton:(id)sender {
    [self initLocation];
}<span style="color:#ffffff;">
</span>


9.关于关键词搜索,这个,我也想了好久,是进行热点搜索好,还是进行在线建议查询好。最后采用了后面这种,因为进行POI搜索需要经纬度,而我是没有经纬度的。所以,推荐后面一种

//这里进行地址搜索
- (void)sureButton{
    NSLog(@"确定");
    //初始化检索对象
    _searcher =[[BMKSuggestionSearch alloc]init];
    _searcher.delegate = self;
    BMKSuggestionSearchOption* option = [[BMKSuggestionSearchOption alloc] init];//初始化搜索设置参数对象
    option.cityname = cityText.text;//设置搜索城市
    option.keyword  = addressText.text;//设置关键词
    BOOL flag = [_searcher suggestionSearch:option];
    if(flag)
    {
        NSLog(@"建议检索发送成功");
    }
    else
    {
        NSLog(@"建议检索发送失败");
    }
}

关于cityText/addressText是小编定义的两个UITextField,而SureButton是按钮的点击事件。效果图如下:

这是小编自定义的UIAlertDialog,没有什么技术含量,就不解释了。继续地图

点击按钮后,就进行了关键词搜索,搜索出来的,全是地理位置信息,这个就有点不好弄了,因为小编要把搜索出来的地址显示到界面,所以就采用了地理编码。详情如下

//实现Delegate处理回调结果
- (void)onGetSuggestionResult:(BMKSuggestionSearch*)searcher result:(BMKSuggestionResult*)result errorCode:(BMKSearchErrorCode)error{
    if (error == BMK_SEARCH_NO_ERROR) {
        //在此处理正常结果
        NSLog(@"找到%@--%@---%@",result.districtList,result.cityList,result.keyList);
        [addressText setText:[result.districtList objectAtIndex:2]];
        NSString *citys=@"";
        NSString *addresses=@"";
        
        for (int i=1; i<[result.districtList count]; i++) {
            //初始化检索对象
            _geoCodeSearch =[[BMKGeoCodeSearch alloc]init];//必须将BMKGeoCodeSearch的创建放在这里面,因为不用他的时候,他自动销毁了。内容也会覆盖。如果放在外面创建,那么地理编码永远都只会得到最后一个
            //实现委托
            _geoCodeSearch.delegate = self;
            //设置城市
            citys=[result.cityList objectAtIndex:i];
            //设置详细地址信息
            addresses=[NSString stringWithFormat:@"%@%@",[result.districtList objectAtIndex:i],[result.keyList objectAtIndex:i]];
            //创建地理编码的Option对象
            BMKGeoCodeSearchOption *geoCodeSearchOption = [[BMKGeoCodeSearchOption alloc]init];
            //设置地理编码参数
            geoCodeSearchOption.city= citys;
            geoCodeSearchOption.address = addresses;
            //获取是否成功
            BOOL flag = [_geoCodeSearch geoCode:geoCodeSearchOption];
            if(flag)
            {
                NSLog(@"geo检索发送成功");
            }
            else
            {
                NSLog(@"geo检索发送失败");
            }
        }
    }
    else {
        NSLog(@"抱歉,未找到结果");
    }
}

当然了,还有一些属性,小编采用系统默认的,也就不设置了,如果读者有需要,可以自行设置。这里进行了正向地理编码,也设置了委托。同上反向地理编码,实现委托协议

//接收正向编码结果
- (void)onGetGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error{
    if (error == BMK_SEARCH_NO_ERROR) {
        //在此处理正常结果
        /*if (annotations != nil) {
            [_mapView removeAnnotation:annotations];
        }*/
        // 添加一个PointAnnotation
        annotations = [[BMKPointAnnotation alloc]init];
        //设置当前地理编码位置:CLLocationCoordinate2D ===result.location
        annotations.coordinate = result.location;
        //设置点击弹出POP的显示title
        annotations.title = result.address;
        //添加图标
        [_mapView addAnnotation:annotations];
        
        //通过ragion设置图标显示居中
        BMKCoordinateRegion region;
        region.center.latitude=result.location.latitude;
        region.center.longitude=result.location.longitude;
        _mapView.region=region;
    }
    else {
        NSLog(@"抱歉,未找到结果");
    }
}
小编这里将产生出来的位置进行了地图绘制《大头针》,当然也设置了大头针所在位置为居中,这个想必大家都明白,也实现了大头针点击的弹出pop,上面注释的代码 是移除大头针的。因为这里是多个图标,所以就没有移除,不过,根据读者需要自行设置。


然后就是弹出的POP了和绘制大头针,继续实现协议方法


//这是绘制大头针
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
        BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
        [newAnnotationView setImage:[UIImage imageNamed:@"btn_back_action_bar"]];
        newAnnotationView.pinColor = BMKPinAnnotationColorRed;//设置大头针颜色
        newAnnotationView.animatesDrop = NO;// 取消该标记点动画显示
        return newAnnotationView;
    }
    return nil;
}

到这里,基本上就结束了,当然,提供上.h 文件中的代码

#import <UIKit/UIKit.h>
#import "BMapKit.h"

@interface MapLocationViewController : UIViewController<BMKMapViewDelegate,BMKLocationServiceDelegate,BMKSuggestionSearchDelegate,BMKGeoCodeSearchDelegate,UITextFieldDelegate>{
    BMKSuggestionSearch *_searcher;
    BMKGeoCodeSearch *_geoCodeSearch;
}
@property(nonatomic,strong)BMKLocationService *locationService;
- (IBAction)saveButton:(id)sender;
- (IBAction)backButton:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet BMKMapView *mapView;
- (IBAction)setLocationButton:(id)sender;
- (IBAction)searcheButton:(id)sender;
@property(nonatomic,strong)NSString *city;
@property(nonatomic,strong)NSString *address;

@end

没有注释,见谅,嘻嘻,主要是实现了各种协议,这个在实现协议的时候,可以点击进去看看,到底是什么协议。小编这里就不解释了。不好意思,因为百度地图的库函数写的都特别详细,注释都特别到位。


当然了,小编乃小白一枚,走过路过的大牛们,有指导的希望能够指导指导,想喷的尽全力喷。小编将不胜感激。在磨砺中,咱们共同成长!谢谢!



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值