百度地图 API 使用过程记录(OC&SWIFT)

首先感谢群里的某位网友热心帮助,虽然时间太长,找不到当初的聊天记录了..大笑


一.创建账号,进入 API 控制台,创建一个应用,填写程序的 Bundle ID ,获得访问应用 AK(秘钥)

百度地图iOS SDK开发密钥的申请地址为:http://lbsyun.baidu.com/apiconsole/key

需要注意

(1).选择安全码的时候,一定要选择跟你应用相符合的,我这里选择的是 iOS.

(2).Bundle ID 一定要填写正确,一般程序后面名称都是自动填出,直接全选复制是不能选取的,需要注意.


二.创建完成后可以开始程序内部的更改了.首先是配置开发环境,这里直接套用百度给出的解释.

百度地图官网: http://developer.baidu.com/map/index.php?title=iossdk

第一步、根据需要导入 .framework包

百度地图 iOS SDK 采用分包的形式提供 .framework包,请广大开发者使用时确保各分包的版本保持一致。其中BaiduMapAPI_Base.framework为基础包,使用SDK任何功能都需导入,其他分包可按需导入。

将所需的BaiduMapAPI_**.framework拷贝到工程所在文件夹下。

在 TARGETS->Build Phases-> Link Binary With Libaries中点击“+”按钮,在弹出的窗口中点击“Add Other”按钮,选择BaiduMapAPI_**.framework添加到工程中。

注: 静态库中采用Objective-C++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm),或者在工程属性中指定编译方式,即将Xcode的Project -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As设置为"Objective-C++"


第二步、引入所需的系统库

百度地图SDK中提供了定位功能和动画效果,v2.0.0版本开始使用OpenGL渲染,因此您需要在您的Xcode工程中引入CoreLocation.framework和QuartzCore.framework、OpenGLES.framework、SystemConfiguration.framework、CoreGraphics.framework、Security.framework、libsqlite3.0.tbd(xcode7以前为 libsqlite3.0.dylib)、CoreTelephony.framework 、libstdc++.6.0.9.tbd(xcode7以前为libstdc++.6.0.9.dylib)

(注:红色标识的系统库为v2.9.0新增的系统库,使用v2.9.0及以上版本的地图SDK,务必增加导入这3个系统库)

添加方式:在Xcode的Project -> Active Target ->Build Phases ->Link Binary With Libraries,添加这几个系统库即可。


第三步、环境配置

在TARGETS->Build Settings->Other Linker Flags 中添加-ObjC。


第四步、引入mapapi.bundle资源文件

如果使用了基础地图功能,需要添加该资源,否则地图不能正常显示mapapi.bundle中存储了定位、默认大头针标注View及路线关键点的资源图片,还存储了矢量地图绘制必需的资源文件。如果您不需要使用内置的图片显示功能,则可以删除bundle文件中的image文件夹。您也可以根据具体需求任意替换或删除该bundle中image文件夹的图片文件。

方法:选中工程名,在右键菜单中选择Add Files to “工程名”…,从BaiduMapAPI_Map.framework||Resources文件中选择mapapi.bundle文件,并勾选“Copy items if needed”复选框,单击“Add”按钮,将资源文件添加到工程中。


第五步、引入头文件

在使用SDK的类 按需 引入下边的头文件:

#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
 
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
 
#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
 
#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入云检索功能所有的头文件
 
#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的头文件
 
#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
 
#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周边雷达功能所有的头文件
 
#import < BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件
其中第五步需要注意一下,如果你使用的是 V2.9.0,之前的版本的话,是没有进行具体的划分的,也就是说,我们只需要导入原本的头文件即可.

#import <BaiduMapAPI/BMapKit.h>


三.导入库文件完成后,还需要对程序中内容进行修改.

1.将任意一个.m后缀的文件改名为.mm

2.如果您只在Xib文件中使用了BMKMapView,没有在代码中使用BMKMapView,编译器在链接时不会链接对应符号,需要在工程属性中显式设定:在Xcode的Project -> Edit Active Target -> Build -> Linking -> Other Linker Flags中添加-ObjC.

3.如果你使用的是 Xcode 7 以及上版本,需要额外添加内容

(1).由于iOS9改用更安全的https,为了能够在iOS9中正常使用地图SDK,请在"Info.plist"中进行如下配置,否则影响SDK的使用。

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

(2).如果在iOS9中使用了调起百度地图客户端功能,必须在"Info.plist"中进行如下配置,否则不能调起百度地图客户端。

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>baidumap</string>
    </array>


(3).自iOS SDK v2.5.0起,为了对iOS8的定位能力做兼容,做了相应的修改,开发者在使用过程中注意事项如下: 需要在info.plist里添加

(以下二选一,两个都添加默认使用NSLocationWhenInUseUsageDescription):

NSLocationWhenInUseUsageDescription ,允许在前台使用时获取GPS的描述

NSLocationAlwaysUsageDescription ,允许永久使用GPS的描述


(4).在使用Xcode6进行SDK开发过程中,需要在info.plist中添加:Bundle display name ,且其值不能为空.Xcode6新建的项目没有此配置,若没有会造成manager start failed


四.添加完成后,就正式进入代码部分

首先在您的AppDelegate.h文件中添加BMKMapManager的定义

AppDelegate.h

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate> {
     BMKMapManager* _mapManager;  
}

@property (strong, nonatomic) UIWindow *window;


@end


之后需要在. m 文件中填写之前在官网获取的 AK(秘钥).

AppDelegate.m

#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()<BMKGeneralDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    _window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    _window.backgroundColor = [UIColor whiteColor];
    _mapManager = [[BMKMapManager alloc]init];
    // 如果要关注网络及授权验证事件,请设定     generalDelegate参数
    BOOL ret = [_mapManager start:@"Y1TKLraxiftqGsewOzLeRVFb"  generalDelegate:self];
    if (!ret) {
        NSLog(@"manager start failed!");
    }
    ViewController *vc = [[ViewController alloc]init];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
    _window.rootViewController = nav;
    [_window makeKeyAndVisible];
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

#pragma mark - BMKGeneralDelegate

- (void)onGetNetworkState:(int)iError
{
    if (0 == iError) {
        NSLog(@"联网成功");
    }
    else{
        NSLog(@"onGetNetworkState %d",iError);
    }
    
}

- (void)onGetPermissionState:(int)iError
{
    if (0 == iError) {
        NSLog(@"授权成功");
    }
    else {
        NSLog(@"onGetPermissionState %d",iError);
    }
}
@end


之后在创建的根视图中添加方法

ViewController.m

//使用百度地图定位,poi搜索,地理编码功能
#import "ViewController.h"
#import "WJBaiduMapTools.h"
@interface ViewController ()<BMKPoiSearchDelegate,BMKMapViewDelegate,BMKGeoCodeSearchDelegate>{
    BMKMapView *_mapView;                //地图
    BMKPoiSearch *_poisearch;            //poi搜索
    BMKGeoCodeSearch  *_geocodesearch;   //geo搜索服务
}
@end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}
-(void)viewWillDisappear:(BOOL)animated
{
    [_mapView viewWillDisappear];
    _mapView.delegate = nil; // 不用时,置nil
    _poisearch.delegate = nil; // 不用时,置nil
}

- (void)viewDidLoad {
    [super viewDidLoad];
    _mapView = [[BMKMapView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    _mapView.delegate = self;
    [self.view addSubview:_mapView];
    [_mapView setZoomLevel:13];
    _mapView.isSelectedAnnotationViewFront = YES;
    //延迟搜索
    [self performSelector:@selector(delay) withObject:self afterDelay:2];
}
//根据方法调用需要使用的搜索方法,这里给出三种方法
- (void)delay {
    [self reverseGeoPointSearch];
}
#pragma mark - 根据经纬度搜索
- (void)reverseGeoPointSearch {
    _geocodesearch = [[BMKGeoCodeSearch alloc]init];
    _geocodesearch.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
    CLLocationCoordinate2D pt = (CLLocationCoordinate2D){0, 0};
    
    NSString *longitude = @"116.404";
    NSString *latitude = @"39.915";
    if (latitude != nil && longitude != nil) {
        pt = (CLLocationCoordinate2D){[latitude floatValue], [longitude floatValue]};
    }
    BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
    reverseGeocodeSearchOption.reverseGeoPoint = pt;
    BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption];
    if(flag)
    {
        NSLog(@"反geo检索发送成功");
    }
    else
    {
        NSLog(@"反geo检索发送失败");
    }
}
#pragma mark - poi搜索
- (void)citySearch {
    _poisearch = [[BMKPoiSearch alloc]init];
    _poisearch.delegate = self;
    BMKCitySearchOption *citySearchOption = [[BMKCitySearchOption alloc]init];
    citySearchOption.pageIndex = 0;
    citySearchOption.pageCapacity = 20;
    citySearchOption.city= @"成都";
    citySearchOption.keyword = @"餐厅";
    BOOL flag = [_poisearch poiSearchInCity:citySearchOption];
    if(flag)
    {
        NSLog(@"城市内检索发送成功");
    }
    else
    {
        NSLog(@"城市内检索发送失败");
    }
}
#pragma mark - 根据名称搜索
- (void)nameSearch {
    _geocodesearch = [[BMKGeoCodeSearch alloc]init];
    _geocodesearch.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
    BMKGeoCodeSearchOption *geocodeSearchOption = [[BMKGeoCodeSearchOption alloc]init];
    geocodeSearchOption.city= @"成都";
    geocodeSearchOption.address = @"武侯祠";
    BOOL flag = [_geocodesearch geoCode:geocodeSearchOption];
    if(flag)
    {
        NSLog(@"geo检索发送成功");
    }
    else
    {
        NSLog(@"geo检索发送失败");
    }
}
#pragma mark - BMKGeoCodeSearchDelegate
// *返回地址信息搜索结果
- (void)onGetGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error {
    NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
    [_mapView removeAnnotations:array];
    array = [NSArray arrayWithArray:_mapView.overlays];
    [_mapView removeOverlays:array];
    if (error == 0) {
        BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init];
        item.coordinate = result.location;
        item.title = result.address;
        [_mapView addAnnotation:item];
        _mapView.centerCoordinate = result.location;
        NSString* titleStr;
        NSString* showmeg;
        
        titleStr = @"正向地理编码";
        showmeg = [NSString stringWithFormat:@"经度:%f,纬度:%f",item.coordinate.latitude,item.coordinate.longitude];
        UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:titleStr message:showmeg delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定",nil];
        [myAlertView show];
        
        //应该在这里得到经纬度然后进行处理
    }
}
// *返回反地理编码搜索结果
- (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error {
    NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
    [_mapView removeAnnotations:array];
    array = [NSArray arrayWithArray:_mapView.overlays];
    [_mapView removeOverlays:array];
    if (error == 0) {
        BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init];
        item.coordinate = result.location;
        item.title = result.address;
        [_mapView addAnnotation:item];
        _mapView.centerCoordinate = result.location;
        NSString* titleStr;
        NSString* showmeg;
        titleStr = @"反向地理编码";
        showmeg = [NSString stringWithFormat:@"%@",item.title];
        UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:titleStr message:showmeg delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定",nil];
        [myAlertView show];
    }
}
#pragma mark - BMKPoiSearchDelegate

- (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode {
    // 清楚屏幕中所有的annotation
    NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
    [_mapView removeAnnotations:array];
    if (errorCode == BMK_SEARCH_NO_ERROR) {
        NSLog(@"正常返回");
        NSMutableArray *annotations = [NSMutableArray array];
        for (int i = 0; i < poiResult.poiInfoList.count; i++) {
            BMKPoiInfo* poi = [poiResult.poiInfoList objectAtIndex:i];
            BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init];
            item.coordinate = poi.pt;
            item.title = poi.name;
            NSLog(@"%@",poi.name);
            [annotations addObject:item];
        }
        [_mapView addAnnotations:annotations];
        [_mapView showAnnotations:annotations animated:YES];
    } else if (errorCode == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR){
        NSLog(@"起始点有歧义");
    } else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_NOT_SUPPORT_BUS){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_NOT_SUPPORT_BUS_2CITY){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_RESULT_NOT_FOUND){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_ST_EN_TOO_NEAR){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_KEY_ERROR){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_NETWOKR_ERROR){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_NETWOKR_TIMEOUT){
        // 各种情况的判断。。。
        NSLog(@"其他情况");
    } else if (errorCode == BMK_SEARCH_PERMISSION_UNFINISHED){
        // 各种情况的判断。。。
        NSLog(@"还未完成鉴权,请在鉴权通过后重试");
      
    }else {
        NSLog(@"不知道了");
    }
}

#pragma mark - BMKMapViewDelegate
//长按获取经纬度,并添加标注
- (void)mapview:(BMKMapView *)mapView onLongClick:(CLLocationCoordinate2D)coordinate {
    //这里是直接进行标注,显示直接为 title 内容
    BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init];
    item.coordinate = coordinate;
    //主标题内容
    item.title = @"您已成功标记此处";
    //副标题内容
    item.subtitle = [NSString stringWithFormat:@"您当前经纬度:%f,%f",coordinate.longitude,coordinate.latitude];
    [_mapView addAnnotation:item];
    
//    //通过反地理编码,获取到标记地点的名称,并添加为 title
//    BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
//    reverseGeocodeSearchOption.reverseGeoPoint = coordinate;
//    BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption];
//    if(flag)
//    {
//        NSLog(@"反geo检索发送成功");
//    }
//    else
//    {
//        NSLog(@"反geo检索发送失败");
//    }
}
//标签视图的代理方法
- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation
{
    // 生成重用标示identifier
    NSString *AnnotationViewID = @"LP";
    
    // 检查是否有重用的缓存
    BMKAnnotationView* annotationView = [view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
    
    // 缓存没有命中,自己构造一个,一般首次添加annotation代码会运行到此处
    if (annotationView == nil) {
        annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
        ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed;
        // 设置重天上掉下的效果(annotation)
        ((BMKPinAnnotationView*)annotationView).animatesDrop = YES;
    }
    
    // 设置位置
    annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));
    annotationView.annotation = annotation;
    // 单击弹出泡泡,弹出泡泡前提annotation必须实现title属性
    annotationView.canShowCallout = YES;
    // 设置是否可以拖拽
    annotationView.draggable = NO;
    
    return annotationView;
}
//选中特定大头针时调用
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view
{
    [mapView bringSubviewToFront:view];
    [mapView setNeedsDisplay];
}
//标记大头针成功时调用
- (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    NSLog(@"已经成功标记");
}

实现效果如下:



五.定位效果

在刚才 ViewDidLoad 中,注释掉的方法内,是调用定位页面的方法

具体页面方法如下:

WJBaiduMapTools.h

#import <Foundation/Foundation.h>

@interface WJBaiduMapTools : NSObject
/**单例*/
+(WJBaiduMapTools *)instance;

/**定位,能得到省市街道*/
- (void)startlocation:(BOOL)needaddress
      locationSuccess:(void(^)(double longitude,double latitude)) locationSuccess
       addressSuccess:(void(^)(double longitude,double latitude,BMKAddressComponent *address))addressSuccess;

/**停止定位*/
- (void)stoplocation;
@end


WJBaiduMapTools.m

#import "WJBaiduMapTools.h"
//注:需要导入百度地图api

@interface WJBaiduMapTools ()<BMKLocationServiceDelegate,BMKGeoCodeSearchDelegate> {
    BMKLocationService *_locService; //定位
    BMKGeoCodeSearch *_searcher;     //geo搜索服务
    BOOL _needaddress;               //是否定位
    //得到经纬度
    void (^ _locationSuccess)(double longitude,double latitude);
    //得到经纬度和地理位置信息
    void (^ _addressSuccess)(double longitude,double latitude,BMKAddressComponent *address);
}

@end

@implementation WJBaiduMapTools

+(WJBaiduMapTools *)instance {
    static WJBaiduMapTools *location;
    @synchronized(self) {
        if(!location) {
            location = [[WJBaiduMapTools alloc] init];
            
        }
    }
    return location;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _needaddress=NO;
        [BMKLocationService setLocationDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
        [BMKLocationService setLocationDistanceFilter:100.f];
        _locService = [[BMKLocationService alloc]init];
        _locService.delegate = self;
        _searcher =[[BMKGeoCodeSearch alloc]init];
        _searcher.delegate = self;
    }
    return self;
}

//开始定位
-(void)startlocation:(BOOL)needaddress locationSuccess:(void (^)(double, double))locationSuccess addressSuccess:(void (^)(double, double, BMKAddressComponent *))addressSuccess{
    _needaddress=needaddress;
    _locationSuccess=locationSuccess;
    _addressSuccess=addressSuccess;
    if (_locService!=nil) {
        [_locService startUserLocationService];
    }
}

//停止定位
- (void)stoplocation {
    if (_locService!=nil) {
        [_locService stopUserLocationService];
    }
}

// 定位成功
-(void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation{
    [_locService stopUserLocationService];
    double longitude=userLocation.location.coordinate.longitude;
    double latitude=userLocation.location.coordinate.latitude;
    if (_locationSuccess) {
        _locationSuccess(longitude,latitude);
    }
    if (_needaddress) {
        //发起反向地理编码检索
        BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
        reverseGeocodeSearchOption.reverseGeoPoint = (CLLocationCoordinate2D){latitude,longitude};
        BOOL flag = [_searcher reverseGeoCode:reverseGeocodeSearchOption];
        if(flag)
        {
            NSLog(@"反geo检索发送成功");
        }
        else
        {
            NSLog(@"反geo检索发送失败");   
        }
    }else{
        
    }
}

-(void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error{
    if (error == BMK_SEARCH_NO_ERROR) {
        if (_addressSuccess) {
            _addressSuccess(result.location.longitude,result.location.latitude,result.addressDetail);
        }
    }
}
@end


六.其他效果补充

(1).计算两点之间距离

//计算特定坐标之间距离
    BMKMapPoint point1 = BMKMapPointForCoordinate(CLLocationCoordinate2DMake(39.918,116.408));
    BMKMapPoint point2 = BMKMapPointForCoordinate(CLLocationCoordinate2DMake(39.915,116.404));
    CLLocationDistance distance = BMKMetersBetweenMapPoints(point1,point2);
    NSLog(@"distance:%f",distance);


(2).判断两点之间距离是否超出界限

<span style="font-size:14px;">//判断两个点是否在对应距离内
    BOOL ptInCircle = BMKCircleContainsCoordinate(CLLocationCoordinate2DMake(39.918,116.408), CLLocationCoordinate2DMake(39.915,116.404), 1000);
    NSLog(@"%d",ptInCircle);</span>


(3).绘制圆形范围(可以结合上方两种方法,制成电子围栏功能,超出距离报警)

<span style="font-size:14px;">- (void)viewDidLoad {
  CLLocationCoordinate2D coor;
    coor.latitude = 39.915;
    coor.longitude = 116.404;
    
    BMKCircle* circle = [BMKCircle circleWithCenterCoordinate:coor radius:5000];
    
    [_mapView addOverlay:circle];
}
//绘制图形代理方法
- (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay{
    if ([overlay isKindOfClass:[BMKCircle class]]){
        BMKCircleView* circleView = [[BMKCircleView alloc] initWithOverlay:overlay];
        circleView.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
        circleView.strokeColor = [[UIColor yellowColor] colorWithAlphaComponent:0.5];
        circleView.lineWidth = 5.0f;
        
        return circleView;
    }
    return nil;
}</span>


(4).绘制折线功能

<span style="font-size:14px;">iOS地图SDK自v2.8.0版本起,新增了折线多段颜色绘制能力,实现的核心代码如下:
第一步,BMKMapView对象,添加分段纹理绘制折线覆盖物,核心代码如下:</span>
<span style="font-size:14px;">
//构建顶点数组
CLLocationCoordinate2Dcoords[5] = {0};
coords[0].latitude = 39.965;
coords[0].longitude = 116.404;
coords[1].latitude = 39.925;
coords[1].longitude = 116.454;
coords[2].latitude = 39.955;
coords[2].longitude = 116.494;
coords[3].latitude = 39.905;
coords[3].longitude = 116.654;
coords[4].latitude = 39.965;
coords[4].longitude = 116.704;
//构建分段纹理索引数组
NSArray *textureIndex = [NSArrayarrayWithObjects:
                              [NSNumbernumberWithInt:0],
                              [NSNumbernumberWithInt:1],
                              [NSNumbernumberWithInt:2],
                              [NSNumbernumberWithInt:1], nil];
 
//构建BMKPolyline,使用分段纹理
BMKPolyline* polyLine = [BMKPolylinepolylineWithCoordinates:coordscount:5textureIndex:textureIndex];
//添加分段纹理绘制折线覆盖物
    [_mapViewaddOverlay:polyLine];
第二步,实现BMKMapViewDelegate的mapView:viewForOverlay:回调,核心代码如下:
- (BMKOverlayView*)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay
{
if ([overlay isKindOfClass:[BMKPolylineclass]]) {
BMKPolylineView* polylineView = [[BMKPolylineViewalloc] initWithOverlay:overlay];
polylineView.lineWidth = 5;
polylineView.isFocus = YES;// 是否分段纹理绘制(突出显示),默认YES
//加载分段纹理图片,必须否则不能进行分段纹理绘制
        [polylineView loadStrokeTextureImages:
         [NSArrayarrayWithObjects:[UIImageimageNamed:@"road_blue_arrow.png"],
          [UIImageimageNamed:@"road_green_arrow.png"],
          [UIImageimageNamed:@"road_red_arrow.png"],nil]];
returnpolylineView;
    }
returnnil;
}</span>


七.日常错误记录汇总

1.程序运行,只出现网格

你的程序的bundle id和百度官网上注册生成的key不同


你没有导入地图资源文件


你没有启动百度地图引擎


2.程序运行,一片空白

请打印你当前显示的坐标是否有误(可以在长按添加大头针方法内添加)

经纬度(0,0)的地方是一片大海,如果没有设置经纬度,默认显示此处,从而导致一片空白,请仔细检查程序.

3.程序进入后台,在从新进入,地图界面整体消失,但是图层存在

请查看是否调用了重绘方法

app在前后台切换时,需要使用下面的代码停止地图的渲染和openGL的绘制:

- (void)applicationWillResignActive:(UIApplication *)application {
    [BMKMapView willBackGround];//当应用即将后台时调用,停止一切调用opengl相关的操作
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
    [BMKMapView didForeGround];//当应用恢复前台状态时调用,回复地图的渲染和opengl相关的操作
}
4.地图声明周期的管理

管理地图的生命周期:自2.0.0起,BMKMapView新增viewWillAppear、viewWillDisappear方法来控制BMKMapView的生命周期,并且在一个时刻只能有一个BMKMapView接受回调消息,因此在使用BMKMapView的viewController中需要在viewWillAppear、viewWillDisappear方法中调用BMKMapView的对应的方法,并处理delegate,代码如下:

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

配置开发环境

第一步、导入地图SDK,参考配置开发环境

第二步、Swift编译配置

首先,新建桥接头文件(放在工程目录下),这里命名为 BMKSwiftDemo-Bridging-Header.h,在该头文件中import需要的库文件,代码如下:

#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入云检索功能所有的头文件
#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的头文件
#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周边雷达功能所有的头文件
#import < BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件

然后,在 TARGETS->Build Phases-> Swift Compiler - Code Generation -> Objective-C Briding Header 中输入桥接文件的路径(该路径要和桥接头文件所在的目录一致),如下图所示: 

Hello Swift BaiduMap

一、初始化BMKMapManager 在您的AppDelegate.swift文件中添加对BMKMapManager的声明和初始化,并填入您申请的授权Key,示例如下

var _mapManager: BMKMapManager?
 
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        _mapManager = BMKMapManager()
        // 如果要关注网络及授权验证事件,请设定generalDelegate参数
        let ret = _mapManager?.start("在此处输入您的授权Key", generalDelegate: self)
        if ret == false {
            NSLog("manager start failed!")
        }
        return true
}


二、创建BMKMapView 在您的ViewController.swift文件中添加BMKMapView的创建代码,示例如下

var _mapView: BMKMapView?
 
    override func viewDidLoad() {
        super.viewDidLoad()
        _mapView = BMKMapView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        self.view.addSubview(_mapView!)
    }


自2.0.0起,BMKMapView新增viewWillAppear、viewWillDisappear方法来控制BMKMapView的生命周期,并且在一个时刻只能有一个BMKMapView接受回调消息,因此在使用BMKMapView的viewController中需要在viewWillAppear、viewWillDisappear方法中调用BMKMapView的对应的方法,并处理delegate,代码如下:

override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        _mapView?.viewWillAppear()
        _mapView?.delegate = self // 此处记得不用的时候需要置nil,否则影响内存的释放
    }
 
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        _mapView?.viewWillDisappear()
        _mapView?.delegate = nil // 不用时,置nil
    }


三、编译,运行,效果如下图所示:




更多精彩文章,尽在我的公众号.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值