iOSPOI检索详细总结

iOS百度地图路径规划和POI检索详细总结c++


路径规划.png

百度地图的使用

百度地图API的导入网上说了许多坑,不过我遇到的比较少,这里就放两个比较常见的吧。
坑一:sql


奥联WIFI_xcodeproj.png


如上图所示,在infoplist里加入这个字段,并且这里还能够设置提示的内容。不加的话,嘿嘿嘿,期待你的尝试。
坑二:以下图api


Pasted_Graphic_jpg.png


导入百度地图API运行以后报上图错误大约18到20个左右,解决方法添加libstdc++.6.0.9 的库。
填完坑以后看一下咱们今天要演示的效果吧。数组


路线规划图.gif


这里实现的内容就是在定位到的当前城市内的路径规划,实现驾车,公交,步行三种规划方式。xcode

注意要点:
  • 这里咱们采用的是地点到地点之间的路径规划,因此咱们在查询的过程当中必定要设置查询的城市,否则没法查找成功(固然也能够用经纬度的方式,那就另说了)。
  • 方式切换问题,若是咱们想要像上图所示的不一样路径规划间的切换,咱们要注意的就是地图上已经存在的路线轨迹和标注的清除问题。
  • 咱们在不一样条件下规划路径要注意他们是不一样的查询方法,以及他们不一样的协议方法,这个咱们能够具体点进百度地图静态库的方法去查看。

代码的实现

因为在项目中,并无整理出来,这里咱们就贴一些主要的代码。
由于三种路径规划其实原理一致这里咱们以驾车的路径规划作一个例子。
由于要顾及到在此以前是否有轨迹和标注所以咱们要先作清除处理,代码以下post

[_mapView removeOverlays:_mapView.overlays]; NSArray *annArray = [[NSArray alloc]initWithArray:_mapView.annotations]; [_mapView removeAnnotations: annArray];

以后咱们建立路径规划的方法动画

_searcher = [[BMKRouteSearch alloc]init];
  _searcher.delegate = self;

 //发起检索
    BMKPlanNode* start = [[BMKPlanNode alloc]init] ; start.name = _startFiled.text; BMKPlanNode* end = [[BMKPlanNode alloc]init]; end.name = _endFiled.text; start.cityName = self.city; end.cityName = self.city; BMKDrivingRoutePlanOption *driveRouteSearchOption =[[BMKDrivingRoutePlanOption alloc]init]; driveRouteSearchOption.from = start; driveRouteSearchOption.to = end;

这里要注意的就是由于咱们是驾车路径规划,因此建立的是BMKDrivingRoutePlanOption,咱们进入到内部方法能够看到,入过咱们是公交和步行对应的则是他们各自的Option,发起检索成功后会调取他的协议方法,这里的前提是要遵循BMKRouteSearchDelegate协议ui

- (void)onGetDrivingRouteResult:(BMKRouteSearch*)searcher result:(BMKDrivingRouteResult*)result errorCode:(BMKSearchErrorCode)error

在上述的协议方法中,咱们设置起点,终点,以及路段入口信息和各轨迹点的总数atom

for (int i = 0; i < size; i++) { BMKDrivingStep *tansitStep = [plan.steps objectAtIndex:i]; if (i == 0 ) { BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = plan.terminal.location; annotation.title = @"起点"; [_mapView addAnnotation:annotation]; } else if (i == size - 1) { BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = plan.terminal.location; annotation.title = @"终点"; [_mapView addAnnotation:annotation]; } BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init]; annotation.coordinate = tansitStep.entrace.location; //路段入口信息 annotation.title = tansitStep.instruction; //路程换成说明 [_mapView addAnnotation:annotation]; //轨迹点总数累计 planPointCounts += tansitStep.pointsCount; } //轨迹点 BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts]; //文件后缀名改成mm int i = 0; for (int j = 0; j < size; j++) { BMKTransitStep *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构建BMKPolyline BMKPolyline *polyLine = [BMKPolyline polylineWithPoints:temppoints count:planPointCounts]; [_mapView addOverlay:polyLine]; //添加路线overlay delete []temppoints; [self mapViewFitPolyLine:polyLine];

这样咱们就完成了路径规划的主要设置。spa

POI检索

百度地图提供了详细的POI检索,以下图咱们设置一个界面选择咱们想要检索的内容,而后根据咱们选择的内容去在地图上标记处各个对应的点,并显示出他的详细信息。而后咱们点击具体的cell,而后咱们根据模型中的数据地点或者经纬度,能够规划处咱们所在地到目的地的线路规划,同样有驾车,公交,步行,三种。这里不得不吐槽一下为啥那么多电话都没有嘞。


IMG_0003.PNG

IMG_0004.PNG


咱们要进行POI检索,首先要遵循BMKPoiSearchDelegate协议,而后进行检索

_searcher2 =[[BMKPoiSearch alloc]init]; _searcher2.delegate = self; //发起检索 BMKNearbySearchOption *option = [[BMKNearbySearchOption alloc]init]; option.pageIndex = 1; //当前索引页 option.pageCapacity = 10; //分页量 option.location = CLLocationCoordinate2DMake(self.lat2, self.lon2); option.keyword = self.str; option.radius = 3000; BOOL flag = [_searcher2 poiSearchNearBy:option]; if(flag) { NSLog(@"周边检索发送成功"); } else { NSLog(@"周边检索发送失败"); }

检索成功后会走到协议方法

- (void)onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPoiResult*)poiResultList errorCode:(BMKSearchErrorCode)error

在这里咱们获得了包含详细信息的一个数组,而后咱们取出BMKPoiInfo对象中的uid,去进行详细检索,同时并把它转换为一个model,去建立咱们的tableview,而后把获得的对应数据展现到下半部的列表中,在点击tableview的详细事件中进行传值,实现路线的规划。model中的部分属性以下:

@interface GSMapModel : NSObject ///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;

详情检索对应的协议方法

//搜索的详细结果 - (void)onGetPoiDetailResult:(BMKPoiSearch*)searcher result:(BMKPoiDetailResult*)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode{ if (errorCode == BMK_SEARCH_NO_ERROR) { //在此处理正常结果 } else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD){ //当在设置城市未找到结果,但在其余城市找到结果时,回调建议检索城市列表 // result.cityList; NSLog(@"起始点有歧义"); } else { NSLog(@"抱歉,未找到结果"); }

大头针的自定义

咱们想要本身定义咱们想要看到的大头针模样,就要对他进行自定义。下面介绍一种简单的处理大头针样式的方法,若是想要具体的根据不一样的情形来进行自定义,就要进行判断,根据他们不一样的状况去给定相应的标注图片

- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation{ BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"]; newAnnotationView.pinColor = BMKPinAnnotationColorPurple; newAnnotationView.animatesDrop = NO;// 设置该标注点动画显示 newAnnotationView.annotation=annotation; newAnnotationView.image = [UIImage imageNamed:@"mapicon"]; //把大头针换成别的图片 newAnnotationView.size = CGSizeMake(20, 33); return newAnnotationView; }

后记

地图中咱们用的比较多的就是定位,POI检索和路径规划了,定位的话,相信不论是官方SDK仍是网上各类资料都够详细的了,我就再也不重复了,这里主要对路径规划和POI检索作出说明,但愿对你们有所帮助。

补充内容

今天有小伙伴问看了文章想知道百度地图的模糊搜索是怎么作的,输入地名就能自动联想好厉害的样子,这里就补充一下吧,其实也是POI搜索的一部分,是城市内搜索根据输入的地名发起搜索,而后把搜索内容展现到tableview上罢了。以下图:


模糊搜索.gif


当咱们改变输入框的内容时其实内部的操做是什么呢,下面咱们一点点介绍一下他。
这里咱们要作的是POI检索,所以首先要遵循BMKPoiSearchDelegate协议,建立搜索的代码以下:

_poisearcher = [[BMKPoiSearch alloc]init]; _poisearcher.delegate = self; BMKCitySearchOption *citySearchOption = [[BMKCitySearchOption alloc]init]; citySearchOption.pageIndex = 0; citySearchOption.pageCapacity = 20; citySearchOption.city= self.city; citySearchOption.keyword = _inputFiled.text;

成功以后会走下面这个协议方法

-(void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode

这里咱们就获得了返回的内容,而后把它里面的数据取到转换为模型展现到tableview上就行了,可是,为何是可是呢,由于你这样作并不能获得想要的结果,由于你这里作的检索只是一次的,并不能实现每改变一个字就从新检索展现出地点,咱们要对输入框作处理

[_inputFiled addTarget:self action:@selector(inputaction:) forControlEvents:UIControlEventEditingChanged];

添加事件,实现对输入框变化的监听,而后实现方法。

#pragma mark - 输入框的实时监听 -(void)inputaction:(UITextField *)textField{ [self performSelector:@selector(delay) withObject:self afterDelay:0.5]; }

这里咱们监听输入框的变化,而后把相应的检索写到delay方法中就能够了。这样就实现了数据的展现,而后点击对应的cell的时候,把数据传给上个界面接Ok了啊,这里为了用户体验咱们能够监听tableview的滚动,当滚动的时候让输入框的键盘消失,代码以下:

#pragma mark -滚动隐藏键盘 -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ [self.view endEditing:YES]; }

这样咱们就实现了模糊搜索了,是否是仍是比较简单的。有别的问题之后再接着补充吧。

相关文章
相关标签/搜索