腾讯位置服务地图SDK公交路线规划应用示例

逻辑探幽人
• 阅读 2227

前言

今天分享腾讯位置服务地图SDK检索功能的应用,使用公交路线规划功能实现Demo,暂时还没有做同一路线不同公交线路切换功能(后续完善此Demo)。

使用场景

公交路线规划

准备

腾讯位置服务iOS地图SDK

公交路线规划检索结果的数据说明

1、检索结果:QMSBusingRouteSearchResult中的NSArray *routes属性包含了检索到的结果,每个结果都是一个独立的公交出行方案QMSBusingRoutePlan。

2、公交出行方案:QMSBusingRoutePlan,表示从起点到终点的完整出行规划

属性说明
CGFloat distance方案的总距离
CGFloat duration方案的预估时间
NSString *bounds方案的东北、西南坐标,用于调整地图视角显示路线
NSArray <QMSBusingSegmentRoutePlan *> *steps总路线的分段信息(包含步行、公交,其中公交可能包含多个方案)

3、出行方案的分段路线规划

属性说明
NSString *mode"WALKING":步行
"TRANSIT":公交
标记该分段的出行方式
CGFloat distance分段的距离
CGFloat duration分段的预估时间
CGFloat price如果是公交或者地铁,需要花费的金额,元
CNSString *direction方向描述,如果为步行,表达为向哪个方向走
NSArray *polyline分段途径坐标点(这里必须说一下,腾讯地图SDK使用的是CLLocationCoordinate2D的encode类型,因此还需要decode才能使用)
NSArray *lines如果是公交,并且有多个线路可以乘坐的话,该数组就会包含多个路线:QMSBusingRouteTransitLine

4、公交线路规划:QMSBusingRouteTransitLine,到这里才是最麻烦的地方,因为是一个线路的不同方案

属性说明
NSString *vehicle交通工具:公交、地铁
NSString *id_应该是个标记,没发现作用
CGFloat distance距离
NSTimeInterval duration预计乘坐时间
NSString *title车名:如333路、软件园通勤车等
NSArray *polyline途径坐标点
NSInteger station_count途径站的数目
NSArray<QMSBusStation *> *stations途径站的站名
QMSStationEntrance *destination目的地的地址,也就是属于哪个街道
QMSBusStation *geton上车车站
QMSBusStation *getoff下车车站

公交路线规划的详细说明

1、公交路线规划的起点和终点坐标的检索(不支持地名检索)

1)SDK检索参数并不支持地名检索,只有坐标检索,因此要使用检索功能就必须先通过POI检索功能来获取起点和终点的坐标位置:

- (IBAction)searchButtonClicked:(UIButton *)sender {
    _startPoiData = nil;
    _endPoiData = nil;
    
    // 起点:腾讯北京总部
    _startPoiOption = [[QMSPoiSearchOption alloc] init];
    _startPoiOption.keyword = _startPointTextField.text;
    [_startPoiOption setBoundaryByRegionWithCityName:@"北京" autoExtend:NO];
    [self.mapSearcher searchWithPoiSearchOption:_startPoiOption];
    
    // 终点:西二旗地忒站
    _endPoiOption = [[QMSPoiSearchOption alloc] init];
    _endPoiOption.keyword = _endPointTextField.text;
    [_endPoiOption setBoundaryByRegionWithCityName:@"北京" autoExtend:NO];
    [self.mapSearcher searchWithPoiSearchOption:_endPoiOption];
}

- (void)searchWithPoiSearchOption:(QMSPoiSearchOption *)poiSearchOption didReceiveResult:(QMSPoiSearchResult *)poiSearchResult {
    if (poiSearchOption == _startPoiOption) {
        _startPoiData = poiSearchResult.dataArray.firstObject;
    } else {
        _endPoiData = poiSearchResult.dataArray.firstObject;
    }
    
    
    // 添加起点终点前,先消除之前的大头针
    [self.mapView removeAnnotations:self.mapView.annotations];
    
    // 设置起点和终点
    QPointAnnotation *startPointAnnotation = [[QPointAnnotation alloc] init];
    startPointAnnotation.coordinate = _startPoiData.location;
    [self.mapView addAnnotation:startPointAnnotation];
    
    QPointAnnotation *endPointAnnotation = [[QPointAnnotation alloc] init];
    endPointAnnotation.coordinate = _endPoiData.location;
    [self.mapView addAnnotation:endPointAnnotation];
    
    // 发起公交路线规划检索
    [self searchBusRoute];
}

2)通过起点和终点POI数据来发起公交路线规划检索

- (void)searchBusRoute {
    if (_startPoiData != nil && _endPoiData != nil) {
        QMSBusingRouteSearchOption *option = [[QMSBusingRouteSearchOption alloc] init];
        [option setFromCoordinate:_startPoiData.location];
        [option setToCoordinate:_endPoiData.location];
        
        [self.mapSearcher searchWithBusingRouteSearchOption:option];
    }
}

腾讯位置服务地图SDK公交路线规划应用示例

2、显示所有路线的基本信息

1)、获取方案的数量:planCount

NSInteger planCount = busingRouteSearchResult.routes.count;

2)、创建路线方案模型数组,在这里我在保存了路线的同事,提出了几样数据:

// 路线方案
@property (nonatomic, strong) QMSBusingRoutePlan *routePlan;
// 路线预估时间
@property (nonatomic, assign) NSInteger duration;
// 路线的步行距离
@property (nonatomic, assign) CGFloat distance;
// 途径的公交车站数
@property (nonatomic, assign) NSInteger stationCount;
// 上车站名称
@property (nonatomic, strong) NSString *startStationName;

3)、获取路线的步行距离:需要遍历方案中的所有分段信息,判断是否为步行,然后累加distance:

// 遍历方案中的步骤
for (int i = 0; i < plan.steps.count; i++) {
    QMSBusingSegmentRoutePlan *segmentRoutePlan = plan.steps[i];
    
    // 判断步骤为步行,累计距离
    if ([self routeIsWalkingPlan:segmentRoutePlan]) {
        walkingDistance += segmentRoutePlan.distance;
    }
}

4)、获取途径的公交站总数和上车站名称:由于同一分段可能有多个公交出行方案,在此只演示了默认第一条方案:

// 判断步骤为公交
if ([self routeIsTransitPlan:segmentRoutePlan]) {
    // 遍历经过的公交
    for (int j = 0; j < segmentRoutePlan.lines.count; j++) {
        QMSBusingRouteTransitLine *line = segmentRoutePlan.lines[j];
        // 公交站数
        stationCount += line.station_count;
        
        // 第一站名称
        if (j == 0) {
            QMSBusStation *station = line.stations.firstObject;
            startStationName = station.title;
        }
    }
}

5)、通过TableView来展示所有的方案:

腾讯位置服务地图SDK公交路线规划应用示例

3、选择方案,展示路线图

1)、先获取该方案总共的分段数:

NSInteger stepCount = routePlan.steps.count;

2)、通过判断分段方案的类型,来区分虚线和蚯蚓线:

if ([self routeIsWalkingPlan:plan]) {
    // 步行虚线
    CLLocationCoordinate2D coords[plan.polyline.count];
    for (int i = 0; i < plan.polyline.count; i++) {
        NSValue *value = plan.polyline[i];
        CLLocationCoordinate2D coord = [value coordinateValue];
        coords[i] = coord;
    }

    QPolyline *walkingPolyline = [[QPolyline alloc] initWithCoordinates:coords count:plan.polyline.count];
    // QPolyline中的userData属性可以用来添加自定义的内容去判断数据
    walkingPolyline.userData = @"WALKING";
    [self.mapView addOverlay:walkingPolyline];
    
} else {

    // 驾车蚯蚓线
    QMSBusingRouteTransitLine *line = plan.lines[0];
    CLLocationCoordinate2D coords[line.polyline.count];
    for (int i = 0; i < line.polyline.count; i++) {
        NSValue *value = line.polyline[i];
        CLLocationCoordinate2D coord = [value coordinateValue];
        coords[i] = coord;
    }

    QPolyline *busPolyline = [[QPolyline alloc] initWithCoordinates:coords count:line.polyline.count];
    busPolyline.userData = @"TRANSIT";
    [self.mapView addOverlay:busPolyline];
}

3)、最后,实现代理方法去绘制线路:

- (QOverlayView *)mapView:(QMapView *)mapView viewForOverlay:(id<QOverlay>)overlay {
    if ([overlay isKindOfClass:[QPolyline class]]) {
        QPolyline *polyline = (QPolyline *)overlay;
        NSString *userData = (NSString *)polyline.userData;
        
        if ([userData isEqualToString:@"WALKING"]) {
            // 步行虚线
            QPolylineView *polylineView = [[QPolylineView alloc] initWithPolyline:polyline];
            polylineView.lineWidth = 8;
            polylineView.lineDashPattern = @[@15, @10];
            polylineView.strokeColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.5];
            
            return polylineView;
        } else {
            // 驾车蚯蚓线
            QTexturePolylineView *polylineView = [[QTexturePolylineView alloc] initWithPolyline:polyline];
            polylineView.drawType = QTextureLineDrawType_ColorLine;
            // 路线箭头
            polylineView.drawSymbol = YES;
            polylineView.lineWidth = 8;
            polylineView.strokeColor = [UIColor colorWithRed:0 green:0 blue:1 alpha:0.8];
            
            return polylineView;
        }
    }
    
    return nil;
}

4、补充:当添加完毕之后,让地图的视野自动适配路线

1)、路线方案中的NSString *bounds属性标记了西南、东北两个方向的坐标,但是这个两个坐标组合成了一个字符串,还需要我们自己去解析:

- (QCoordinateBounds)boundsFromString:(NSString *)boundsString {
    NSArray *array = [boundsString componentsSeparatedByString:@","];
    NSString *southWestLatString = array[0];
    NSString *southWestLongString = array[1];
    NSString *northEastLatString = array[2];
    NSString *northEastLongString = array[3];
    CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(northEastLatString.floatValue, northEastLongString.floatValue);
    CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(southWestLatString.floatValue, southWestLongString.floatValue);
    
    QCoordinateBounds bounds;
    bounds.northEast = northEast;
    bounds.southWest = southWest;
    
    return bounds;
}

2)、最后调用地图接口,调整地图显示范围:

[self.mapView setVisibleMapRect:QMapRectForCoordinateBounds(bounds) edgePadding:UIEdgeInsetsMake(10, 10, 10, 10) animated:YES];

5、最终显示效果:

腾讯位置服务地图SDK公交路线规划应用示例

作者:面糊

链接:https://www.jianshu.com/p/12b...

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
OpenCV检测轮廓极点(Python C++)
    今天分享一个OpenCV检测轮廓极点实例,原图如下,我们需要检测出地图中最大轮廓的上下左右四个极点,并进行标注显示。!(https://oscimg.oschina.net/oscnet/ae374a72c5404b00b0e976e499eedf36.png)    第一步:阈值处理分割出地图轮廓!(ht
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
GeorgeGcs GeorgeGcs
19小时前
【HarmonyOS】鸿蒙应用实现调用系统地图导航或路径规划
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财前言在涉及地图业务中,调用地图导航和路径规划是三方应用中较为常见的功能。若只是子业务需要地图导航效果,整个APP内部集成地图去实现导航或者路径规划,会造成SDK集成冗余。毕竟很重。所以该效