{"version":"0.1.0","code":"0000","result":true,"message":"处理成功","errdetail":"","timestamp":1671508850236,"data":{"id":71714070,"title":"5.3.8 切换平行路自动重算","slug":"bxhvp8","format":"lake","bookId":26046811,"body":null,"body_draft":null,"body_html":"
考虑到过往SDK项目对接时,许多客户在“切换平行路”的对接环节,经常出现错误,SDK在>=610版本,提供了“切换平行路重算”功能,SDK自动接管切换平行路重算。区别于以往的HMI接管被动重算。需要注意的是,此功能有开关可选,开关见下方时序图和核心接口说明。HMI可根据自身业务需求,选择使用SDK的“切换平行路自动重算”,或者沿用之前的业务时序,HMI自行接管切换平行路重算。
特别注意:对接了多屏一致性的项目,不可使用此功能,,强行开启是无效的,请严格按照未开启“切换平行路自动重算”的前序文档进行对接实现。
未开启“切换平行路自动重算”的文档:《切换平行路》
为了方便开发者了解开关“切换平行路自动重算”的区别,在此列出功能关闭&开启的时序图对比。
public class LocParallelRoadInfo {\n public int status; /**< 主辅路切换状态:0 非平行路切换期间 1 平行路切换期间 */\n public int flag; /* 主辅路标识(默认0,离线数据计算/在线算路下发)\n * 0:无主辅路(车标所在道路旁无主辅路)\n * 1:车标在主路(车标所在道路旁有辅路)\n * 2:车标在辅路(车标所在道路旁有主路)*/\n public int hwFlag;/**< 高架上下标识(默认0,在线算路下发)\n * 0:无高架\n * 1:车标在高架上(车标所在道路有对应高架下)\n * 2:车标在高架下(车标所在道路有对应高架上) */\n public int count; /**< 主辅路条数(离线数据计算,用于离线算路) */\n public ArrayList<LocParallelRoad> parallelRoadList; /**< 主辅路信息(离线数据计算,用于离线算路) */\n}
void com.autonavi.gbl.route.RouteService.init(RouteInitParam param)
void com.autonavi.gbl.route.RouteService.addRerouteObserver(INaviRerouteObserver ob)
//添加平行路信息观察者\nvoid com.autonavi.gbl.pos.PosService.addParallelRoadObserver(IPosParallelRoadObserver pObserver)\n//删除平行路信息观察者\nvoid com.autonavi.gbl.pos.PosService.removeSwitchParallelRoadObserver(IPosSwitchParallelRoadObserver pObserver)
void com.autonavi.gbl.pos.observer.IPosParallelRoadObserver.onParallelRoadUpdate(LocParallelRoadInfo pstParallelRoad)
void com.autonavi.gbl.pos.PosService.switchParallelRoad(LocSwitchRoadType switchRoadType, java.math.BigInteger pstRoadID)
void com.autonavi.gbl.pos.observer.IPosSwitchParallelRoadObserver.onSwitchParallelRoadFinished()
void com.autonavi.gbl.route.observer.INaviRerouteObserver.onSwitchParallelRoadRerouteInfo(BLRerouteRequestInfo info);
void com.autonavi.gbl.route.observer.INaviRerouteObserver.onModifyRerouteOption(RouteOption rerouteOption);
说明:函数详情,请复制函数名称到在线API搜索
private PosService mPosService;\n// 初始化PosService\nprivate void initPosService() {\n mPosService = (PosService) ServiceMgr.getServiceMgrInstance().getBLService(SingleServiceID.PosSingleServiceID); \n // 定位模块初始化设置略,详见定位章节\n // 添加平行路信息观察者\n mPosService.addParallelRoadObserver(posParallelRoadObserver);\n // 添加切换平行路观察者\n mPosService.addSwitchParallelRoadObserver(posSwitchParallelRoadObserver);\n \n // 算路服务初始化\n\tmRouteService = (RouteService) ServiceMgr.getServiceMgrInstance().getBLService(SingleServiceID.RouteSingleServiceID);\n RouteInitParam routeInitParam;\n routeInitParam.rerouteParam.enableAutoSwitchParallelReroute = True; // 开启“切换平行路自动重算”\n mRouteService.init(routeInitParam); \n \n // 特别地,需要添加行中重算观察者\n mRouteService.addRerouteObserver(naviRerouteObserver); \n}\n\n// 行中重算回调观察者\nINaviRerouteObserver naviRerouteObserver = new INaviRerouteObserver(){\n @Override\n public void OnRerouteInfo(BLRerouteRequestInfo info) {\n // 此接口用于SDK向HMI通知发起的算路信息。\n long requestId = info.getRequestId(); // 算路请求requestId\n int errCode = info.getErrCode(); // 算路请求错误码\n RouteOption option = info.getOption(); // 算路请求参数\n } \n \n @Override\n public void onSwitchParallelRoadRerouteInfo(RouteOption rerouteOption) {\n // HMI 可在这个回调线程中,根据自身业务需要,修改rerouteOption\n // 起点终点:不建议客户端在此回调中修改算路起点&终点,容易改成问题,BL已内聚处理。\n // 途经点:HMI可根据自身业务需要进行途经点的增删,如无特殊业务需要,建议不改。\n \n // 特别注意:只有在当前回调线程中修改参数才会生效,转线程修改无效!\n \n // 举例:如有需要修改算路参数\n rerouteOption.setConstrainCode(...);\n } \n}\n\nIPosParallelRoadObserver posParallelRoadObserver = new IPosParallelRoadObserver() {\n @Override\n public void onParallelRoadUpdate(LocParallelRoadInfo locParallelRoadInfo) {\n if (locParallelRoadInfo.status != 1) //不在主辅路切换期间\n {\n // 监听平行路信息回调,实现显示 "主路/辅路" "桥上/桥下"切换的提示按钮\n if (locParallelRoadInfo.flag == 1) // 车标在主路(车标所在道路旁有辅路)\n {\n // todo: 显示 "切到辅路" 按钮\n }\n else if (locParallelRoadInfo.flag == 2) // 车标在辅路(车标所在道路旁有主路)\n {\n // todo: 显示 "切到主路" 按钮\n }\n if (locParallelRoadInfo.hwFlag == 1) // 车标在高架上(车标所在道路有对应高架下)\n {\n // if (net == true){}\n // todo: 显示 "切到桥下" 按钮,在线才显示\n }\n else if (locParallelRoadInfo.hwFlag == 2) // 车标在高架下(车标所在道路有对应高架上)\n {\n // if (net == true){}\n // todo: 显示 "切到桥上" 按钮,在线才显示\n }\n if (locParallelRoadInfo.flag == 0 || locParallelRoadInfo.hwFlag == 0)\n {\n // todo: 隐藏 主辅路、上下桥按钮\n }\n if (locParallelRoadInfo.parallelRoadList.size() > 0)\n {\n // 获取切换的roadid,后面重新算路时需要设置给起点\n BigInteger roadId = locParallelRoadInfo.parallelRoadList.get(0).roadId;\n }\n }\n else // 在主辅路切换期间,不要显示按钮\n {\n // todo: 隐藏 主辅路、上下桥按钮\n }\n }\n};\n\nPathInfo curPath; //当前路线\n\n// 算路结果观察者\nIRouteResultObserver routeResultObserver = new IRouteResultObserver() {\n @Override\n public void onNewRoute(PathResultData pathResultData, ArrayList<PathInfo> pathInfoList, java.lang.Object externData) {\n \n /* 转线程前,这边需要特殊处理。对SDK回调回来的PathInfo对象需重新构造创建一遍 */\n ArrayList<PathInfo> paths = new ArrayList<>();\n for(int i=0;i<pathInfoList.size();i++){\n PathInfo paths =new PathInfo(pathInfoList.get(i));\n paths.add(pathInfo);\n }\n // 根据情况决定是否将后续处理流程转为其他线程处理,如果转线程,只需将下面示例中的HandleNewRoute函数放在指定线程执行即可\n HandleNewRoute(pathResultData, paths);\n }\n\n @Override\n public void onNewRouteError(PathResultData pathResultData, java.lang.Object externData) {\n //code ...\n }\n};\n\n/* UI 线程逻辑 */\nvoid HandleNewRoute(PathResultData pathResultData, ArrayList<PathInfo> paths)\n{\n \tPathsMgr.getInstance().setPathsCache(paths);\n \n \t// 根据客户端逻辑配置当前选中的导航路线下标iCurPathIndex\n int iCurPathIndex = 0;\n // 当前路线\n curPath = paths.get(iCurPathIndex) \n \n // 若之后业务还需使用路线 通过PathsMgr.getPathsCache获取\n // 若不在需当前路线时回收路线 PathsMgr.destoryPathsCache() \n}\n\n\nIPosSwitchParallelRoadObserver posSwitchParallelRoadObserver = new IPosSwitchParallelRoadObserver() {\n @Override\n public void onSwitchParallelRoadFinished() {\n // 监听平行路切换完成的回调\n // TODO:发起新的路线请求,RouteService.requestRoute(RouteOption routeOption)\n // 这里需要把原来的routeOption信息重新设置\n // -->以下是伪代码>>>>>>\n // 由于篇幅关系,这里仅用于说明需要设置的项目清单\n \n // routeOption:拷贝自初始路线请求或最近一次重算的算路请求信息\n // 发生主辅路重算时,需要对上次的routeOption部分内容做如下设置:\n\t\t\n // 设置算路类型为 RouteTypeParallelRoad\n routeOption.setRouteType(RouteTypeParallelRoad)\n // 设置算路附加条件,根据现在的状态设置,一般是更新当前网络在/离线,其它参数保持上一次的不变\n routeOption.setConstrainCode(code);\n \n // 设置行程点信息poiForRequest\n // 对于平行路切换来说终点和途径点一般保持上一次的不变,但是起点需要重新设置,且必须设置起点的道路ID\n // 起点信息poiInfo,来源于定位回调 IPosLocInfoObserver.onLocInfoUpdate\n poiForRequest.reset()\n \n // 起点设置\n POIInfo startPoiInfo = new POIInfo();\n startPoiInfo.realPos.lon = pstLocInfo.matchInfo.get(0).stPos.lon;\n startPoiInfo.realPos.lat = pstLocInfo.matchInfo.get(0).stPos.lon;\n startPoiInfo.type = 0;//GPS点\n poiForRequest.addPoint(PointTypeStart, startPoiInfo)\n // 添加终点,同上一次设置的 \n poiForRequest.addPoint(PointTypeEnd, endPoiInfo); \n // 添加途径点\n for (vialist){\n // 判断是否途径点有效,需要客户端对接INaviObserver.onUpdateViaPass监听回调,剔除已经经过的途径点\n poiForRequest.addPoint(PointTypeVia, viaPoiInfo); //添加途径点\n }\n // 定位回调onLocInfoUpdate的最近一次信息pstLocInfo\n // 添加起点抓路优化信息\n poiForRequest.SetDirection(pstLocInfo.matchRoadCourse);\n poiForRequest.SetReliability(pstLocInfo.courseAcc);\n poiForRequest.SetAngleType(pstLocInfo.startDirType);\n poiForRequest.SetAngleGps(pstLocInfo.gpsDir);\n poiForRequest.SetAngleComp(pstLocInfo.compassDir);\n poiForRequest.SetSpeed(pstLocInfo.speed);\n poiForRequest.SetLinkType(pstLocInfo.matchInfo.get(0).linkType);\n poiForRequest.SetFormWay(pstLocInfo.matchInfo.get(0).formway);\n poiForRequest.SetSigType(pstLocInfo.startPosType);\n poiForRequest.SetFittingDir(pstLocInfo.fittingCourse);\n poiForRequest.SetMatchingDir(pstLocInfo.roadDir);\n poiForRequest.SetFittingCredit(pstLocInfo.fittingCourseAcc);\n poiForRequest.SetPrecision(pstLocInfo.posAcc);\n\t\t\n // 平行路切换必须使用定位onParallelRoadUpdate回调的内容\n roadId = locParallelRoadInfo.parallelRoadList.get(0).roadId\n poiForRequest.setPointRoadID(PointTypeStart, 0, roadId)\n \n // 更新行程点信息\n routeOption.setPOIForRequest(poiForRequest)\n \n // 设置当前导航位置信息\n // 定位回调onLocInfoUpdate的最近一次信息pstLocInfo\n CurrentPositionInfo curLocation;\n curLocation.linkIndex = pstLocInfo.vecPathMatchInfo.get(0).nLinkCur;\n curLocation.pointIndex = pstLocInfo.vecPathMatchInfo.get(0).nPostCur;\n curLocation.segmentIndex = pstLocInfo.vecPathMatchInfo.get(0).nSegmCur; \n curLocation.overheadFlag = locParallelRoadInfo.hwFlag; //0:无高架 1:车标在高架上(车标所在道路有对应高架下) 2:车标在高架下(车标所在道路有对应高架上)\n curLocation.parallelRoadFlag = locParallelRoadInfo.flag; //0:无主辅路(车标所在道路旁无主辅路) 1:车标在主路(车标所在道路旁有辅路) 2:车标在辅路(车标所在道路旁有主路)\n routeOption.setCurrentLocation(curLocation);\n \n // 设置切换类型:高架切换 paralleTypeOverhead 还是 主辅路切换 paralleTypeMainSide,根据主辅路切换信息决定的\n if(locParallelRoadInfo.hwFlag != 0)\n \trouteOption.setParalleType(paralleTypeOverhead);\n if (locParallelRoadInfo.flag != 0)\n routeOption.setParalleType(paralleTypeMainSide);\n\n // 设置当前导航剩余信息接口,来源:最近一次的Guide回调onUpdateNaviInfo \n CurrentNaviInfo curNaviInfo;\n curNaviInfo.remainRouteTime = naviInfo.routeRemain.time;\n curNaviInfo.remainRouteDist = naviInfo.routeRemain.dist;\n curNaviInfo.remainSegmentDist = naviInfo.NaviInfoData[naviInfo.NaviInfoFlag].segmentRemain.dist;\n curNaviInfo.drivingRouteDist = naviInfo.driveDist;\n routeOption.setRemainNaviInfo(curNaviInfo);\n \n // 设置上一次路线进来\n routeOption.setNaviPath(curPath)\n \n // 发起路线重算\n routeService.requestRoute(routeOption)\t\n }\n};