zoukankan      html  css  js  c++  java
  • iOS百度地图开发之路径规则

    最近要做个类似这样的地图效果。在这里不得不吐槽下iOS百度地图开发文档,内容远没有安卓版的详细。。。。

    要实现这种效果,这就得用到百度地图的路径规划了。开发文档上是这样写的

    路径规划

    百度地图iOS SDK为开发者提供了公交换乘、驾车和步行三种类型的线路规划方案,同时根据不同的方案还可以选择“时间最短”、“距离最短”等策略来完成最终的线路规划。开发者可根据自己实际的业务需求来自由使用。
    公交换乘的线路规范实现方式如下:

    -(void)viewDidLoad                   
    {                                    
        //初始化检索对象                        
        _searcher = [[BMKRouteSearch alloc]init];
        _searcher.delegate = self;
        //发起检索
        BMKPlanNode* start = [[[BMKPlanNode alloc]init] autorelease];
        start.name = @"龙泽";
        BMKPlanNode* end = [[[BMKPlanNode alloc]init] autorelease];
        end.name = "西单";
        BMKTransitRoutePlanOption *transitRouteSearchOption =         [[BMKTransitRoutePlanOption alloc]init];
        transitRouteSearchOption.city= @"北京市";
        transitRouteSearchOption.startNode = start;
        transitRouteSearchOption.endNode = end;
        BOOL flag = [_searcher transitSearch:transitRouteSearchOption];
        [transitRouteSearchOption release];
     
            if(flag)                     
            {                            
                NSLog(@"bus检索发送成功");     
            }                            
            else                         
            {                            
                NSLog(@"bus检索发送失败");     
            }                            
        }                                
        //实现Deleage处理回调结果
        -(void)onGetTransitRouteResult:(BMKRouteSearch*)searcher result:    (BMKTransitRouteResult*)result
        errorCode:(BMKSearchErrorCode)error
        {
            if (error == BMK_SEARCH_NO_ERROR) {
                //在此处理正常结果
            }
            else if (error == BMK_SEARCH_AMBIGUOUS_ROURE_ADDR){
                //当路线起终点有歧义时通,获取建议检索起终点
                //result.routeAddrResult
            }
        else {
            NSLog(@"抱歉,未找到结果");
        }
    }
        //不使用时将delegate设置为 nil
        -(void)viewWillDisappear:(BOOL)animated
        {
            _searcher.delegate = nil; 
        }

    但是,我们从字面上理解根本不知道返回的字段是什么,文档上也没说。。。。。

    此时,我们就该利用到百度地图开发demo了,在demo上它是这样写的

    - (void)onGetTransitRouteResult:(BMKRouteSearch*)searcher result:(BMKTransitRouteResult*)result errorCode:(BMKSearchErrorCode)error
    {
        NSArray* array = [NSArray arrayWithArray:_mapView.annotations];
        [_mapView removeAnnotations:array];
        array = [NSArray arrayWithArray:_mapView.overlays];
        [_mapView removeOverlays:array];
        if (error == BMK_SEARCH_NO_ERROR) {
            BMKTransitRouteLine* plan = (BMKTransitRouteLine*)[result.routes objectAtIndex:0];
            // 计算路线方案中的路段数目
            int size = [plan.steps count];
            int planPointCounts = 0;
            for (int i = 0; i < size; i++) {
                BMKTransitStep* transitStep = [plan.steps objectAtIndex:i];
                if(i==0){
                    RouteAnnotation* item = [[RouteAnnotation alloc]init];
                    item.coordinate = plan.starting.location;
                    item.title = @"起点";
                    item.type = 0;
                    [_mapView addAnnotation:item]; // 添加起点标注
                    
                }else if(i==size-1){
                    RouteAnnotation* item = [[RouteAnnotation alloc]init];
                    item.coordinate = plan.terminal.location;
                    item.title = @"终点";
                    item.type = 1;
                    [_mapView addAnnotation:item]; // 添加起点标注
                }
                RouteAnnotation* item = [[RouteAnnotation alloc]init];
                item.coordinate = transitStep.entrace.location;
                item.title = transitStep.instruction;
                item.type = 3;
                [_mapView addAnnotation:item];
                
                //轨迹点总数累计
                planPointCounts += transitStep.pointsCount;
            }
            
            //轨迹点
            BMKMapPoint * temppoints = new BMKMapPoint[planPointCounts];
            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;
        }
        
    }

    按照它的逻辑,似乎好像这个BMKTransitRouteLine对象就是我们想要的结果呢。

    为什么这么说呢,因为这句话。

    BMKTransitRouteLine* plan = (BMKTransitRouteLine*)[result.routes objectAtIndex:0];

    它是取数组中的第一个元素,然后在这个对象中取得路径点,最后开始绘图。为证明没有猜错,我们在去百度地图头文件中看看这个对象到底是什么。

    在文件BMKRouteSearchType.h中,我们可以看到

    ///此类表示一个换乘路线,换乘路线将根据既定策略调配多种交通工具
    @interface BMKTransitRouteLine : BMKRouteLine
    @end

    在往下看,我们还可以看到

    @interface BMKTransitRouteResult : NSObject{
        BMKTaxiInfo*        _taxiInfo;
        BMKSuggestAddrInfo* _suggestAddrResult;
        NSArray*            _routes;
    }
    ///该路线打车信息
    @property (nonatomic, strong) BMKTaxiInfo* taxiInfo;
    ///返回起点或终点的地址信息结果
    @property (nonatomic, strong) BMKSuggestAddrInfo* suggestAddrResult;
    ///方案数组,成员类型为BMKTransitRouteLine
    @property (nonatomic, strong) NSArray* routes;
    
    @end

    这就证明我们的想法是没错。

    找到了我们所需要的对象,那怎么具体把它解析出来了?不急,再慢慢往下看

    BMKTransitRouteLine对象继承BMKRouteLine对象,那我们就得看BMKRouteLine对象了,

    ///此类表示路线数据结构的基类,表示一条路线,路线可能包括:路线规划中的换乘/驾车/步行路线
    ///此类为路线数据结构的基类,一般关注其子类对象即可,无需直接生成该类对象
    @interface BMKRouteLine : NSObject{
        int                  _distance;
        BMKTime*             _duration;
        BMKRouteNode*        _starting;
        BMKRouteNode*        _terminal;
        NSString*            _title;
        NSArray*             _steps;
    }
    ///路线长度 单位: 米
    @property (nonatomic) int distance;
    ///路线耗时 单位: 秒
    @property (nonatomic, strong) BMKTime* duration;
    ///路线起点信息
    @property (nonatomic, strong) BMKRouteNode* starting;
    ///路线终点信息
    @property (nonatomic, strong) BMKRouteNode* terminal;
    ///路线名称(预留字段,现为空)
    @property (nonatomic, strong) NSString* title;
    ///路线中的所有路段,成员类型为BMKWalkingStep,BMKDrivingStep,BMKTransitStep
    @property (nonatomic, strong) NSArray* steps;
    @end

    在这,我们可以很肯定的知道我们所需的信息一定在数组steps中(不要问为什么,如果这都看不出的话,那你面壁去)。

    在例子中,我们要检索公交,那么应该是steps由BMKTransitStep对象组成的数组,

    查看BMKTransitStep对象

    ///此类表示公交换乘路线中的一个路段
    @interface BMKTransitStep : BMKRouteStep{
        BMKRouteNode*        _entrace;
        BMKRouteNode*        _exit;
        NSString*            _instruction;
        BMKTransitStepType   _stepType;
        BMKVehicleInfo*      _vehicleInfo;
    }
    ///路段入口信息
    @property (nonatomic, retain) BMKRouteNode* entrace;
    ///路段出口信息
    @property (nonatomic, retain) BMKRouteNode* exit;
    ///路段换乘说明
    @property (nonatomic, retain) NSString* instruction;
    ///路段类型
    @property (nonatomic) BMKTransitStepType stepType;
    ///当路段为公交路段或地铁路段时,可以获取交通工具信息
    @property (nonatomic, retain) BMKVehicleInfo* vehicleInfo;
    @end

    可以确定,我们最终所需要的信息就在对象BMKVehicleInfo中了,为保险点,我们在看下对象BMKVehicleInfo

    ///路线换乘方案里的交通工具信息类
    @interface BMKVehicleInfo : NSObject{
        NSString* _uid;
        NSString* _title;
        int       _passStationNum;
        int       _totalPrice;
        int       _zonePrice;
    }
    ///该交通路线的标识
    @property (nonatomic, retain) NSString* uid;
    ///该交通路线的名称
    @property (nonatomic, retain) NSString* title;
    ///该交通路线的所乘站数
    @property (nonatomic) int passStationNum;
    ///该交通路线的全程价格
    @property (nonatomic) int totalPrice;
    ///该交通路线的所乘区间的区间价格
    @property (nonatomic) int zonePrice;
    @end

     在这已经很明显了,title就是我们所需的信息了。

  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/kw-ios/p/4211489.html
Copyright © 2011-2022 走看看