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

开篇

喵神镇楼.jpg

最近写简书不多,除了前段时间一篇匆匆的FFMPEG的理论学习基本没写多少,主要是最近比较忙,又是硬件设备的调试,又是新需求的加入,今天就来写一下项目中的一个知识,闲话少叙直入正题吧。

iPhone_6_-_iPhone_6___iOS_9_3__13E230_.png

百度地图的使用

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


奥联WIFI_xcodeproj.png

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


Pasted_Graphic_jpg.png

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

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

注意要点:
  • 这里我们采用的是地点到地点之间的路径规划,所以我们在查询的过程中一定要设置查询的城市,不然无法查找成功(当然也可以用经纬度的方式,那就另说了)。

  • 方式切换问题,如果我们想要像上图所示的不同路径规划间的切换,我们要注意的就是地图上已经存在的路线轨迹和标注的清除问题。

  • 我们在不同条件下规划路径要注意他们是不同的查询方法,以及他们不同的协议方法,这个我们可以具体点进百度地图静态库的方法去查看。

代码的实现

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


    [_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协议

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

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

 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];

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

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];
}

这样我们就实现了模糊搜索了,是不是还是比较简单的。有别的问题以后再接着补充吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容