Esempio n. 1
0
OsrmRouter::ResultCode OsrmRouter::CalculateRoute(m2::PointD const & startPoint,
        m2::PointD const & startDirection,
        m2::PointD const & finalPoint,
        RouterDelegate const & delegate, Route & route)
{
    my::HighResTimer timer(true);
    m_indexManager.Clear();  // TODO (Dragunov) make proper index manager cleaning

    TRoutingMappingPtr startMapping = m_indexManager.GetMappingByPoint(startPoint);
    TRoutingMappingPtr targetMapping = m_indexManager.GetMappingByPoint(finalPoint);

    if (!startMapping->IsValid())
    {
        ResultCode const code = startMapping->GetError();
        if (code != NoError)
        {
            route.AddAbsentCountry(startMapping->GetCountryName());
            return code;
        }
        return IRouter::StartPointNotFound;
    }
    if (!targetMapping->IsValid())
    {
        ResultCode const code = targetMapping->GetError();
        if (code != NoError)
        {
            route.AddAbsentCountry(targetMapping->GetCountryName());
            return code;
        }
        return IRouter::EndPointNotFound;
    }

    MappingGuard startMappingGuard(startMapping);
    MappingGuard finalMappingGuard(targetMapping);
    UNUSED_VALUE(startMappingGuard);
    UNUSED_VALUE(finalMappingGuard);
    LOG(LINFO, ("Duration of the MWM loading", timer.ElapsedNano()));
    timer.Reset();

    delegate.OnProgress(kMwmLoadedProgress);

    // 3. Find start/end nodes.
    TFeatureGraphNodeVec startTask;

    {
        ResultCode const code = FindPhantomNodes(startPoint, startDirection,
                                startTask, kMaxNodeCandidatesCount, startMapping);
        if (code != NoError)
            return code;
    }
    {
        if (finalPoint != m_cachedTargetPoint)
        {
            ResultCode const code =
                FindPhantomNodes(finalPoint, m2::PointD::Zero(),
                                 m_cachedTargets, kMaxNodeCandidatesCount, targetMapping);
            if (code != NoError)
                return code;
            m_cachedTargetPoint = finalPoint;
        }
    }
    INTERRUPT_WHEN_CANCELLED(delegate);

    LOG(LINFO, ("Duration of the start/stop points lookup", timer.ElapsedNano()));
    timer.Reset();
    delegate.OnProgress(kPointsFoundProgress);

    // 4. Find route.
    RawRoutingResult routingResult;

    // 4.1 Single mwm case
    if (startMapping->GetMwmId() == targetMapping->GetMwmId())
    {
        LOG(LINFO, ("Single mwm routing case"));
        m_indexManager.ForEachMapping([](pair<string, TRoutingMappingPtr> const & indexPair)
        {
            indexPair.second->FreeCrossContext();
        });
        if (!FindRouteFromCases(startTask, m_cachedTargets, startMapping->m_dataFacade,
                                routingResult))
        {
            return RouteNotFound;
        }
        INTERRUPT_WHEN_CANCELLED(delegate);
        delegate.OnProgress(kPathFoundProgress);

        // 5. Restore route.

        Route::TTurns turnsDir;
        Route::TTimes times;
        vector<m2::PointD> points;

        MakeTurnAnnotation(routingResult, startMapping, delegate, points, turnsDir, times);

        route.SetGeometry(points.begin(), points.end());
        route.SetTurnInstructions(turnsDir);
        route.SetSectionTimes(times);

        return NoError;
    }
    else //4.2 Multiple mwm case
    {
        LOG(LINFO, ("Multiple mwm routing case"));
        TCheckedPath finalPath;
        ResultCode code = CalculateCrossMwmPath(startTask, m_cachedTargets, m_indexManager, delegate,
                                                finalPath);
        timer.Reset();
        INTERRUPT_WHEN_CANCELLED(delegate);
        delegate.OnProgress(kCrossPathFoundProgress);

        // 5. Make generate answer
        if (code == NoError)
        {
            auto code = MakeRouteFromCrossesPath(finalPath, delegate, route);
            // Manually free all cross context allocations before geometry unpacking.
            m_indexManager.ForEachMapping([](pair<string, TRoutingMappingPtr> const & indexPair)
            {
                indexPair.second->FreeCrossContext();
            });
            LOG(LINFO, ("Make final route", timer.ElapsedNano()));
            timer.Reset();
            return code;
        }
        return OsrmRouter::RouteNotFound;
    }
}
Esempio n. 2
0
// TODO (ldragunov) move this function to cross mwm router
// TODO (ldragunov) process case when the start and the finish points are placed on the same edge.
OsrmRouter::ResultCode OsrmRouter::MakeRouteFromCrossesPath(TCheckedPath const & path,
        RouterDelegate const & delegate,
        Route & route)
{
    Route::TTurns TurnsDir;
    Route::TTimes Times;
    vector<m2::PointD> Points;
    for (RoutePathCross cross : path)
    {
        ASSERT_EQUAL(cross.startNode.mwmId, cross.finalNode.mwmId, ());
        RawRoutingResult routingResult;
        TRoutingMappingPtr mwmMapping = m_indexManager.GetMappingById(cross.startNode.mwmId);
        ASSERT(mwmMapping->IsValid(), ());
        MappingGuard mwmMappingGuard(mwmMapping);
        UNUSED_VALUE(mwmMappingGuard);
        CalculatePhantomNodeForCross(mwmMapping, cross.startNode, m_pIndex, true /* forward */);
        CalculatePhantomNodeForCross(mwmMapping, cross.finalNode, m_pIndex, false /* forward */);
        if (!FindSingleRoute(cross.startNode, cross.finalNode, mwmMapping->m_dataFacade, routingResult))
            return OsrmRouter::RouteNotFound;

        if (!Points.empty())
        {
            // Remove road end point and turn instruction.
            Points.pop_back();
            TurnsDir.pop_back();
            Times.pop_back();
        }

        // Get annotated route.
        Route::TTurns mwmTurnsDir;
        Route::TTimes mwmTimes;
        vector<m2::PointD> mwmPoints;
        MakeTurnAnnotation(routingResult, mwmMapping, delegate, mwmPoints, mwmTurnsDir, mwmTimes);
        // Connect annotated route.
        auto const pSize = static_cast<uint32_t>(Points.size());
        for (auto turn : mwmTurnsDir)
        {
            if (turn.m_index == 0)
                continue;
            turn.m_index += pSize;
            TurnsDir.push_back(turn);
        }

        double const estimationTime = Times.size() ? Times.back().second : 0.0;
        for (auto time : mwmTimes)
        {
            if (time.first == 0)
                continue;
            time.first += pSize;
            time.second += estimationTime;
            Times.push_back(time);
        }

        Points.insert(Points.end(), mwmPoints.begin(), mwmPoints.end());
    }

    route.SetGeometry(Points.begin(), Points.end());
    route.SetTurnInstructions(TurnsDir);
    route.SetSectionTimes(Times);
    return OsrmRouter::NoError;
}