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;
        }
    }
}