代码地址如下:
http://www.demodashi.com/demo/11030.html

一、准备工作

  • 需要集成百度地图SDK
  • 需要申请百度地图AppKey
  • 本例子实现了POI检索以及详情检索、路线规划

二、程序实现

首先贴一下项目截图:

(项目截图1)

(项目截图2)

POI详情:
第一步:在Appdelegate.m中设置AppKey


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];HouseMapTootsViewController *vc = [[HouseMapTootsViewController alloc] init];vc.latitude = 31.976;vc.longitude = 118.71;UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc];//配置百度地图[self configurationBMKMap];self.window.rootViewController = navi;[self.window makeKeyAndVisible];return YES;
}#pragma mark -- 百度地图- (void)configurationBMKMap {// 要使用百度地图,请先启动BaiduMapManager_mapManager = [[BMKMapManager alloc] init];BOOL ret = [_mapManager start:@"appkey" generalDelegate:self];if (!ret) {NSLog(@"manager start failed!");}
}

第二步:完成代理

#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);}
}

第三步:创建百度地图,开启用户定位(后面路线规划需要)。并且添加一个大头针,这个大头针就是你即将检索的中心点。

 self.mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 40+64, kScreenWidth, kScreenHeight - 40 - 64)];[self.view addSubview:self.mapView];[self.view addSubview:self.planView];self.locService = [[BMKLocationService alloc] init];self.mapView.delegate = self;self.locService.delegate = self;//定位方向模式  不能使用跟随,不然地图中心就不是大头针了[self.mapView setZoomLevel:16];self.mapView.showMapScaleBar = YES;self.mapView.userTrackingMode = BMKUserTrackingModeNone;self.mapView.showsUserLocation = YES;[self.locService startUserLocationService];CLLocationCoordinate2D coor;coor.latitude = self.latitude;coor.longitude = self.longitude;if (self.pointAnnotation == nil) {//自定义大头针self.pointAnnotation = [[YLAnnotationView alloc]init];self.pointAnnotation.coordinate = coor;self.pointAnnotation.title = @"房源位置";self.pointAnnotation.subtitle = @"点击到这里去";self.pointAnnotation.image = [UIImage imageNamed:@"homelocation"];}[self.mapView addAnnotation:self.pointAnnotation];//设置中心点[self.mapView setCenterCoordinate:coor];//检索周边设施self.poiSearch.delegate = self;//添加大头针后添加周边检索self.option.location = coor;self.option.pageIndex = 0;self.option.pageCapacity = 20;self.option.radius = 1500;

第四步:在点击事件中初始化检索对象,Demo中我自己定义了一个topView用来做不同点击区分。

#pragma mark -- YLSelectorItemViewDelegate- (void)didSelectedItems:(NSInteger)item {CLLocationCoordinate2D coor;coor.latitude = self.latitude;coor.longitude = self.longitude;self.seletItem = item;self.isFirst = YES;if (item == 1) {self.option.keyword = @"美食";BOOL flag = [self.poiSearch poiSearchNearBy:self.option];if(flag) {NSLog(@"周边检索发送成功");}else {NSLog(@"周边检索发送失败");}}else if (item == 2) {self.option.keyword = @"超市";BOOL flag1 = [self.poiSearch poiSearchNearBy:self.option];if(flag1) {NSLog(@"周边检索发送成功");}else {}}else if (item == 3) {self.option.keyword = @"ATM";BOOL flag2 = [self.poiSearch poiSearchNearBy:self.option];if(flag2) {NSLog(@"周边检索发送成功");}else {NSLog(@"周边检索发送失败");}}else if (item == 4) {self.option.keyword = @"购物";BOOL flag3 = [self.poiSearch poiSearchNearBy:self.option];if(flag3) {NSLog(@"周边检索发送成功");}else {NSLog(@"周边检索发送失败");}}}

第五步:点击后会进入下面这个代理,首先删除屏幕上的大头针,由于我这里还是需要显示这个房源大头针,这里我做了一个处理保存下来,在for循环中拿到了所有的list中的对象,这些对象就是我们要的周边信息,但是并不是详情,详情是需要拿到这个目标对象UID再次去检索(这里普通检索和详情检索被百度强行分开了,可能处于流量或者模块化的考虑吧)。那么就必须再次创建检索对象了,这次for循环每次都会出现一个详情检索,于是我们可以到详情代理中做事情了。

//实现PoiSearchDeleage处理回调结果
- (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResultList errorCode:(BMKSearchErrorCode)error {// 清楚屏幕中除却房源外的所有的annotationNSMutableArray *array = [NSMutableArray arrayWithArray:self.mapView.annotations];//把房源的保存下载[array removeObjectAtIndex:0];[self.mapView removeAnnotations:array];array = [[NSArray arrayWithArray:self.mapView.overlays] mutableCopy];[self.mapView removeOverlays:array];if (error == BMK_SEARCH_NO_ERROR) {for (int i = 0; i < poiResultList.poiInfoList.count; i++) {BMKPoiInfo *poi = [poiResultList.poiInfoList objectAtIndex:i];//自定义大头针BMKPoiDetailSearchOption *option = [[BMKPoiDetailSearchOption alloc] init];option.poiUid = poi.uid;BMKPoiSearch *se = [[BMKPoiSearch alloc] init];se.delegate = self;//把所有的POI存入数组,用于最终的释放,避免循环引用;[self.poiDetails addObject:se];[se poiDetailSearch:option];}} else if (error == BMK_SEARCH_AMBIGUOUS_KEYWORD){NSLog(@"搜索词有歧义");} else {// 各种情况的判断。。。}
}

详情代理,这里我需要不同的大头针图片,做了一个处理

//周边搜索的详情代理
- (void)onGetPoiDetailResult:(BMKPoiSearch *)searcher result:(BMKPoiDetailResult *)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode {CLLocationCoordinate2D houseCoor;houseCoor.latitude = self.latitude;houseCoor.longitude = self.longitude;if (errorCode == BMK_SEARCH_NO_ERROR) {YLAnnotationView *item = [[YLAnnotationView alloc] init];item.coordinate = poiDetailResult.pt;switch (self.seletItem) {case 1:item.image = [UIImage imageNamed:@"food"];item.subtitle = [NSString stringWithFormat:@"均价:%.2f",poiDetailResult.price];break;case 2:item.image = [UIImage imageNamed:@"supermarket"];item.subtitle = poiDetailResult.address;break;case 3:item.image = [UIImage imageNamed:@"ATM"];item.subtitle = poiDetailResult.address;break;case 4:item.image = [UIImage imageNamed:@"shoping"];item.subtitle = poiDetailResult.address;break;default:break;}item.title = poiDetailResult.name;//加个判断,第一次进来的时候设置中心点,不能每次都移动中心,不然POI期间会拖不动地图。if (self.isFirst) {[self.mapView setCenterCoordinate:houseCoor animated:YES];}self.isFirst = NO;[self.mapView addAnnotation:item];}else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD) {NSLog(@"搜索词有歧义");}else {}
}

到这里主要代码就结束了。文末我会附上Demo
二:路径规划
点击搜索,传过来一种路线方式,并且传来开始地与目的地。我本想直接写出需要注意的地方,但是发现在代码中不少都已经注释了,请大家注意,例如 //每次必须是一个新的对象,不然ptname会混乱
下面代码有很多逻辑上的处理,为了一体性,我没有删去。

#pragma mark -- RoutePlanViewDelegate
//搜路线
- (void)didSelectorItems:(NSInteger)item withStartName:(NSString *)startName andEndName:(NSString *)endName {CLLocationCoordinate2D houseCoor;houseCoor.latitude = self.latitude;houseCoor.longitude = self.longitude;//每次必须是一个新的对象,不然pt和name会混乱self.startNode = [[BMKPlanNode alloc] init];self.endNode = [[BMKPlanNode alloc] init];self.startNode.cityName = @"南京";self.endNode.cityName = @"南京";//设置出发点与终点if ([startName isEqualToString:@""] || [endName isEqualToString:@""]) {NSLog(@"搜索字段有歧义");return;}if ([startName isEqualToString:@"当前位置"] && [endName isEqualToString:@"房源位置"]) {self.startNode.pt = self.userLocation.location.coordinate;self.endNode.pt = houseCoor;}else if ([endName isEqualToString:@"当前位置"] && [startName isEqualToString:@"房源位置"]) {self.startNode.pt = houseCoor;self.endNode.pt = self.userLocation.location.coordinate;}else if (![startName isEqualToString:@"当前位置"] && [endName isEqualToString:@"房源位置"]) {self.startNode.name = startName;self.endNode.pt = houseCoor;}else if([startName isEqualToString:@"当前位置"] && ![endName isEqualToString:@"房源位置"]) {self.startNode.pt = self.userLocation.location.coordinate;self.endNode.name = endName;}else if(![startName isEqualToString:@"当前位置"] && [endName isEqualToString:@"当前位置"]) {self.startNode.name = startName;self.endNode.pt = self.userLocation.location.coordinate;}else if([startName isEqualToString:@"房源位置"] && ![endName isEqualToString:@"当前位置"]) {self.startNode.pt = houseCoor;self.endNode.name = endName;}else {self.startNode.name = startName;self.endNode.name = endName;}NSLog(@"%@ ---- %@",self.startNode.name,self.endNode.name);if (item == 1) {//驾车BMKDrivingRoutePlanOption *driveRouteSearchOption =[[BMKDrivingRoutePlanOption alloc]init];driveRouteSearchOption.from = self.startNode;driveRouteSearchOption.to = self.endNode;BOOL flag = [self.routeSearch drivingSearch:driveRouteSearchOption];if (flag) {}else {}}else if (item == 2) {//公交BMKMassTransitRoutePlanOption *option = [[BMKMassTransitRoutePlanOption alloc]init];option.from = self.startNode;option.to = self.endNode;BOOL flag = [self.routeSearch massTransitSearch:option];if(flag) {NSLog(@"公交交通检索(支持垮城)发送成功");} else {NSLog(@"公交交通检索(支持垮城)发送失败");}} else if (item == 3) {//步行BMKWalkingRoutePlanOption *walkingRouteSearchOption = [[BMKWalkingRoutePlanOption alloc] init];walkingRouteSearchOption.from = self.startNode;walkingRouteSearchOption.to = self.endNode;BOOL flag = [self.routeSearch walkingSearch:walkingRouteSearchOption];if(flag) {NSLog(@"walk检索发送成功");}else {NSLog(@"walk检索发送失败");}}else {//骑车BMKRidingRoutePlanOption *option = [[BMKRidingRoutePlanOption alloc]init];option.from = self.startNode;option.to = self.endNode;BOOL flag = [self.routeSearch ridingSearch:option];if (flag) {NSLog(@"骑行规划检索发送成功");}else {NSLog(@"骑行规划检索发送失败");}}
}

点击后,会进入下面这个代理


#pragma mark -- BMKRouteSearchDelegate//驾车
- (void)onGetDrivingRouteResult:(BMKRouteSearch *)searcher result:(BMKDrivingRouteResult *)result errorCode:(BMKSearchErrorCode)error {NSMutableArray *array = [NSMutableArray arrayWithArray:self.mapView.annotations];[array removeObjectAtIndex:0];[self.mapView removeAnnotations:array];array = [[NSArray arrayWithArray:self.mapView.overlays] mutableCopy];[self.mapView removeOverlays:array];if (error == BMK_SEARCH_NO_ERROR) {//表示一条驾车路线BMKDrivingRouteLine *plan = (BMKDrivingRouteLine *)[result.routes objectAtIndex:0];// 计算路线方案中的路段数目int size = (int)[plan.steps count];int planPointCounts = 0;for (int i = 0; i < size; i++) {//表示驾车路线中的一个路段BMKDrivingStep *transitStep = [plan.steps objectAtIndex:i];if(i==0){RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = plan.starting.location;item.title = @"起点";item.type = 0;[self.mapView addAnnotation:item]; // 添加起点标注}else if(i==size-1){RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = plan.terminal.location;item.title = @"终点";item.type = 1;[self.mapView addAnnotation:item]; // 添加终点标注}//添加annotation节点RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = transitStep.entrace.location;item.title = transitStep.entraceInstruction;item.degree = transitStep.direction  *30;item.type = 4;[self.mapView addAnnotation:item];//轨迹点总数累计planPointCounts += transitStep.pointsCount;}// 添加途经点if (plan.wayPoints) {for (BMKPlanNode *tempNode in plan.wayPoints) {RouteAnnotation *item = [[RouteAnnotation alloc]init];item.coordinate = tempNode.pt;item.type = 5;item.title = tempNode.name;[self.mapView addAnnotation:item];}}//轨迹点BMKMapPoint *temppoints = new BMKMapPoint[planPointCounts];int i = 0;for (int j = 0; j < size; j++) {BMKDrivingStep *transitStep = [plan.steps objectAtIndex:j];int k=0;for(k=0;k<transitStep.pointsCount;k++) {temppoints[i].x = transitStep.points[k].x;temppoints[i].y = transitStep.points[k].y;i++;}}// 通过points构建BMKPolylineBMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];[self.mapView addOverlay:polyLine]; // 添加路线overlaydelete []temppoints;[self mapViewFitPolyLine:polyLine];}
}

上面我仅仅放了一个驾车的代理,还有步行等没有放上去,太长了,文末为了不想下载代码的同学观看,我会放上整页代码提供参考。
言归正传,你们发现我有自定义了一个RouteAnnotation类。这个路线需要字段比较多,我不想改动之前大头针类了,就直接重写了一个。如下

/*** 路线的标注  自定义一个大头针类   为了便捷,就直接放这里了*/
@interface RouteAnnotation : BMKPointAnnotation {int _type; ///<0:起点 1:终点 2:公交 3:地铁 4:驾乘 5:途经点int _degree;//旋转的角度
}@property (nonatomic) int type;
@property (nonatomic) int degree;
@end@implementation RouteAnnotation@synthesize type = _type;
@synthesize degree = _degree;
@end

如果你也这样做,那么就像我一样在大头针重用方法中做以下判断,并且实现这个方法,如下:

if ([annotation isKindOfClass:[RouteAnnotation class]]) {return [self getRouteAnnotationView:view viewForAnnotation:(RouteAnnotation *)annotation];}
#pragma mark -- 获取路线的标注,显示到地图(自定义的一个大头针类实例方法)我只贴到case 0;其他的在文末查找,需要注意的地方我已写注释
- (BMKAnnotationView *)getRouteAnnotationView:(BMKMapView *)mapview viewForAnnotation:(RouteAnnotation *)routeAnnotation {BMKAnnotationView *view = nil;//根据大头针类型判断是什么图标switch (routeAnnotation.type) {case 0:{   //开始点view = [mapview dequeueReusableAnnotationViewWithIdentifier:@"start_node"];if (view == nil) {view = [[BMKAnnotationView alloc] initWithAnnotation:routeAnnotation reuseIdentifier:@"start_node"];//从百度地图资源文件中拿到需要的图片view.image = [UIImage imageWithContentsOfFile:[self getMyBundlePath1:@"images/icon_nav_start"]];view.centerOffset = CGPointMake(0, -(view.frame.size.height * 0.5));view.canShowCallout = true;}view.annotation = routeAnnotation;}

在驾车路线的代理最后我们添加了一条线,就是如下代码

  // 通过points构建BMKPolylineBMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts];[self.mapView addOverlay:polyLine]; // 添加路线overlaydelete []temppoints;[self mapViewFitPolyLine:polyLine];

这样我们还需要实现一个划线的代理,这个是必须实现的。还有一个地图路线的范围计算,文末的所有代码中的最后一段,这些都是从百度地图官方代码拿来的。

#pragma mark -- 路线线条绘制代理- (BMKOverlayView *)mapView:(BMKMapView *)map viewForOverlay:(id<BMKOverlay>)overlay {if ([overlay isKindOfClass:[BMKPolyline class]]) {BMKPolylineView *polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];//设置线条颜色polylineView.fillColor = [[UIColor alloc] initWithRed:0 green:1 blue:1 alpha:1];polylineView.strokeColor = [[UIColor alloc] initWithRed:0 green:0 blue:0.8 alpha:0.7];polylineView.lineWidth = 3.0;return polylineView;}return nil;
}

虽然上面大多都是复制粘贴把,但是 Demo 代码都是我用心准备的,这里也主要是说个流程。

三、运行效果


四、其他补充

百度地图的集成很简单,按照开发文档几分钟就搞定了,我就不抄写了,但是记录几个可能会出问题的地方吧。

  • Privacy - Location Always Usage Description plist.info请求使用GPS
  • LSApplicationQueriesSchemes 如果你需要调起百度地图客户端
  • Bundle display name plist.info中需要加入,而且是必要的
  • 这个文件用到了c++代码,请务必把文件后缀名改为.mm

注:本文著作权归作者,由demo大师(http://www.demodashi.com)宣传,拒绝转载,转载需要作者授权

百度地图检索以及路径规划相关推荐

  1. 百度地图js简单路径规划

    lujing.html <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content= ...

  2. 安卓百度地图之步行路径规划

    使用的是百度地图的API,地址是:androidsdk | 百度地图API SDK 步骤一:配置build.gradle dependencies {implementation 'com.baidu ...

  3. Android安卓百度地图定位+导航+路径规划实现APP(源码+APK) 毕业设计

    百度地图实时定位+导航路径规划的实现APP 本科生毕业设计:<一种智能停车系统的设计>,成都信息工程大学,2018 使用到的技术 百度地图SDK LBS云数据管理 路径规划与导航 二维码扫 ...

  4. 结合奥维地图与百度地图api进行路径规划开发测试(python、HTML)

    第一步:奥维地图如何得到规划路径上轨迹点的经纬度(参见我之前的博客). 第二步:各种坐标系转换,选择对应转换坐标系以及输入输出文件路径后可以直接调用(python批量转换,每次运行前清空输出文件res ...

  5. 百度地图----检索功能的使用

    百度地图--检索功能的使用 ONE Goal ,ONE Passion ! 上面几篇写了如何集成以及使用百度地图和覆盖物.现在就说说百度地图的检索功能; 目前百度地图SDK所集成的检索服务包括:POI ...

  6. 常用的地图导航和路径规划算法

    作者:李传学 链接:https://www.zhihu.com/question/24870090/answer/73834896 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  7. Android 调用百度地图sdk 实现路线规划导航

    Android 调用百度地图sdk 实现路线规划导航 功能: 实现实时/需求定位 卫星地图查看 路况 周边poi检索 地点输入提示检索 驾驶 步行 公交 骑行路线规划 注:以上为实现的大概功能 ,接下 ...

  8. 百度无人驾驶apollo项目路径规划a*算法分析

    百度无人驾驶apollo项目路径规划a*算法分析 车辆路径规划寻路算法有很多,apollo路径规划模块使用的是启发式搜索算法A*寻路算法 a*算法是一种在路网上中求解最短路径的直接搜索寻路算法,原理是 ...

  9. 高德地图WebAPI : 驾车路径规划

    参考API 一个demo 获取路径规划返回结果中的两点间最短驾车距离 import java.io.BufferedReader; import java.io.BufferedReader; imp ...

最新文章

  1. Django源码分析5:session会话中间件分析
  2. poj 2010(优先队列)
  3. java知识博客网站(一些配置和学习的记录)
  4. geojson在线生成工具_logofree详解:LOGO设计在线生成
  5. linux怎么把磁盘的东西拷贝,[Linux]如何拷贝已有数据磁盘,并将新的磁盘挂接到其他虚机上...
  6. JQuery中text(),html(),val()的区别
  7. Oracle入门(十四.7)之良好的编程习惯
  8. hadoop fs 命令详解
  9. python实现猴子爬山算法
  10. 评价类模型:1.层次分析法
  11. Vue学习笔记之01-Vue的特点
  12. vgg19-dcbb9e9d.pth文件网盘下载
  13. 矩阵和向量的求导法则
  14. 粒子群算法-讲解+实例
  15. 按位与运算()和求余运算(%)的联系
  16. Day001-2021-07-29 变量定义/数据类型/基础运算 判断/循环/数组
  17. blob形式导出Excel
  18. ubuntu--ogv格式转mp4格式
  19. emlog mysql 设置_EMLOG模板自定义首页
  20. HDU 4125 Moles 笛卡尔树 + kmp

热门文章

  1. python编辑器中文字体倒立的_如何用Python+人工识别处理知乎的倒立汉字验证码...
  2. ideahtml标签不提示_「系统自带标签」如何帮门店区分价值顾客?| 早8点141期
  3. 链表在STM32中的应用
  4. Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
  5. Linux内外存访问
  6. linux初始:命令行解释器(shell)、权限
  7. ThinkPhp框架:父类及表单验证
  8. 关于跨域问题的解决办法
  9. SQL查询得到(按编号分组的日期最大的记录)
  10. asp.net 移除Server, X-Powered-By, 和X-AspNet-Version头