騰訊地圖SDK公交路線規劃Demo
前言
今天分享騰訊位置服務地圖SDK檢索功能的應用,使用公交路線規劃功能實現Demo,暫時還沒有做同一路線不同公交線路切換功能(後續完善此Demo)。
使用場景
公交路線規劃
準備
公交路線規劃檢索結果的資料說明
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];
}
}
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來展示所有的方案:
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、最終顯示效果:
作者:麵糊
連結:https://www.jianshu.com/p/12b569add049
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。