OsmAnd::RouteCalculationResult OsmAnd::RoutePlanner::prepareResult( OsmAnd::RoutePlannerContext::CalculationContext* context, std::shared_ptr<RoutePlannerContext::RouteCalculationSegment> finalSegment, bool leftSideNavigation) { // Prepare result QVector< std::shared_ptr<RouteSegment> > route; auto pFinalSegment = dynamic_cast<RoutePlannerContext::RouteCalculationFinalSegment*>(finalSegment.get()); // Get results from opposite direction roads auto segment = pFinalSegment->_reverseWaySearch ? finalSegment : pFinalSegment->opposite->parent; auto parentSegmentStart = pFinalSegment->_reverseWaySearch ? pFinalSegment->opposite->pointIndex : pFinalSegment->opposite->parentEndPointIndex; int i = 0; while (segment) { std::shared_ptr<RouteSegment> routeSegment(new RouteSegment(segment->road, parentSegmentStart, segment->pointIndex)); parentSegmentStart = segment->parentEndPointIndex; segment = segment->parent; addRouteSegmentToRoute(route, routeSegment, false); i++; } // Reverse it just to attach good direction roads std::reverse(route.begin(), route.end()); i = 0; segment = pFinalSegment->_reverseWaySearch ? pFinalSegment->opposite->parent : finalSegment; auto parentSegmentEnd = pFinalSegment->_reverseWaySearch ? pFinalSegment->opposite->parentEndPointIndex : pFinalSegment->opposite->pointIndex; while (segment) { std::shared_ptr<RouteSegment> routeSegment(new RouteSegment(segment->road, segment->pointIndex, parentSegmentEnd)); parentSegmentEnd = segment->parentEndPointIndex; segment = segment->parent; addRouteSegmentToRoute(route, routeSegment, true); i++; } std::reverse(route.begin(), route.end()); if (!validateAllPointsConnected(route)) return OsmAnd::RouteCalculationResult("Calculated route has broken paths"); splitRoadsAndAttachRoadSegments(context, route); calculateTimeSpeedInRoute(context, route); addTurnInfoToRoute(leftSideNavigation, route); printRouteInfo(route); OsmAnd::RouteCalculationResult result; result.list = route.toList(); context->owner->_previouslyCalculatedRoute = result.list; return result; }
void OsmAnd::RoutePlannerContext::RoutingSubsectionContext::registerRoad( const std::shared_ptr<const Model::Road>& road ) { uint32_t idx = 0; for(auto itPoint = road->points.cbegin(); itPoint != road->points.cend(); ++itPoint, idx++) { const auto& x31 = itPoint->x; const auto& y31 = itPoint->y; uint64_t id = (static_cast<uint64_t>(x31) << 31) | y31; std::shared_ptr<RouteCalculationSegment> routeSegment(new RouteCalculationSegment(road, idx)); auto itRouteSegment = _roadSegments.constFind(id); if(itRouteSegment == _roadSegments.cend()) _roadSegments.insert(id, routeSegment); else { auto originalRouteSegment = *itRouteSegment; while(originalRouteSegment->_next) originalRouteSegment = originalRouteSegment->_next; originalRouteSegment->_next = routeSegment; } } }