[routing] Remove old implementation

This commit is contained in:
Denis Koronchik 2014-09-19 13:52:38 +03:00 committed by Alex Zolotarev
parent 1bc64eb7a9
commit d635406217
27 changed files with 0 additions and 1892 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -12,7 +12,6 @@
#include "../routing/route.hpp"
#include "../routing/osrm_router.hpp"
#include "../routing/dijkstra_router.hpp"
#include "../search/search_engine.hpp"
#include "../search/result.hpp"

View file

@ -21,8 +21,6 @@
#include "../search/search_engine.hpp"
#include "../routing/routing_engine.hpp"
#include "../storage/storage.hpp"
#include "../platform/location.hpp"

View file

@ -1,93 +0,0 @@
#include "dijkstra_router.hpp"
#include "../base/assert.hpp"
#include "../base/logging.hpp"
#include "../std/set.hpp"
namespace routing
{
DijkstraRouter::ShortestPath const * const DijkstraRouter::ShortestPath::FINAL_POS
= reinterpret_cast<ShortestPath const *>(1);
void DijkstraRouter::SetFinalRoadPos(vector<RoadPos> const & finalPos)
{
m_entries = PathSet();
m_queue = PossiblePathQueue();
for (size_t i = 0; i < finalPos.size(); ++i)
{
pair<PathSet::iterator, bool> t = m_entries.insert(ShortestPath(finalPos[i]));
ASSERT(t.second, ());
m_queue.push(PossiblePath(0.0, &*t.first, ShortestPath::FINAL_POS));
}
}
void DijkstraRouter::CalculateRoute(vector<RoadPos> const & startPos, vector<RoadPos> & route)
{
route.clear();
set<RoadPos> startSet(startPos.begin(), startPos.end());
set<uint32_t> startFeatureSet;
for (vector<RoadPos>::const_iterator it = startPos.begin(); it != startPos.end(); ++it)
startFeatureSet.insert(it->GetFeatureId());
while (!m_queue.empty())
{
double const cost = m_queue.top().m_cost;
ShortestPath const * const pEntry = m_queue.top().m_pEntry;
ShortestPath const * const pParentEntry = m_queue.top().m_pParentEntry;
m_queue.pop();
LOG(LDEBUG, ("Visiting", pEntry->GetPos(), "with cost", cost));
if (pEntry->IsVisited())
{
LOG(LDEBUG, ("Already visited before, skipping."));
continue;
}
pEntry->SetParentAndMarkVisited(pParentEntry);
#ifdef DEBUG
if (pParentEntry == ShortestPath::FINAL_POS)
{
LOG(LDEBUG, ("Setting parent to", "FINAL_POS"));
}
else
{
LOG(LDEBUG, ("Setting parent to", pParentEntry->GetPos()));
}
#endif
bool const bStartFeature = startFeatureSet.find(pEntry->GetPos().GetFeatureId()) != startFeatureSet.end();
if (bStartFeature && startSet.find(pEntry->GetPos()) != startSet.end())
{
LOG(LDEBUG, ("Found result!"));
// Reached one of the starting points!
for (ShortestPath const * pE = pEntry; pE != ShortestPath::FINAL_POS; pE = pE->GetParentEntry())
route.push_back(pE->GetPos());
LOG(LDEBUG, (route));
return;
}
IRoadGraph::TurnsVectorT turns;
m_pRoadGraph->GetPossibleTurns(pEntry->GetPos(), turns, bStartFeature);
LOG(LDEBUG, ("Getting all turns", turns));
for (IRoadGraph::TurnsVectorT::const_iterator iTurn = turns.begin(); iTurn != turns.end(); ++iTurn)
{
PossibleTurn const & turn = *iTurn;
pair<PathSet::iterator, bool> t = m_entries.insert(ShortestPath(turn.m_pos));
if (t.second || !t.first->IsVisited())
{
// We've either never pushed or never poped this road before.
double nextCost = cost + turn.m_secondsCovered;
m_queue.push(PossiblePath(nextCost, &*t.first, pEntry));
LOG(LDEBUG, ("Pushing", t.first->GetPos(), "with cost", nextCost));
}
}
}
LOG(LDEBUG, ("No route found!"));
// Route not found.
}
} // namespace routing

View file

@ -1,92 +0,0 @@
#pragma once
#include "road_graph_router.hpp"
#include "../geometry/point2d.hpp"
#include "../std/queue.hpp"
#include "../std/set.hpp"
#include "../std/vector.hpp"
namespace routing
{
class DijkstraRouter : public RoadGraphRouter
{
typedef RoadGraphRouter BaseT;
public:
DijkstraRouter(Index const * pIndex = 0) : BaseT(pIndex) {}
virtual string GetName() const { return "routeme"; }
virtual void SetFinalRoadPos(vector<RoadPos> const & finalPos);
virtual void CalculateRoute(vector<RoadPos> const & startPos, vector<RoadPos> & route);
private:
class ShortestPath
{
public:
explicit ShortestPath(RoadPos pos, ShortestPath const * pParentEntry = NULL)
: m_pos(pos), m_pParentEntry(pParentEntry) {}
bool operator < (ShortestPath const & e) const
{
return m_pos < e.m_pos;
}
RoadPos GetPos() const { return m_pos; }
ShortestPath const * GetParentEntry() const { return m_pParentEntry; }
bool IsVisited() const { return m_pParentEntry != NULL; }
void SetParentAndMarkVisited(ShortestPath const * pParentEntry) const { m_pParentEntry = pParentEntry; }
static ShortestPath const * const FINAL_POS;
private:
RoadPos m_pos;
mutable ShortestPath const * m_pParentEntry;
};
struct PossiblePath
{
double m_cost;
ShortestPath const * m_pEntry;
ShortestPath const * m_pParentEntry;
PossiblePath(double cost, ShortestPath const * pEntry, ShortestPath const * pParentEntry)
: m_cost(cost), m_pEntry(pEntry), m_pParentEntry(pParentEntry) {}
bool operator < (PossiblePath const & p) const
{
if (m_cost != p.m_cost)
return m_cost > p.m_cost;
// Comparisons below are used to make the algorithm stable.
if (m_pEntry->GetPos() < p.m_pEntry->GetPos())
return true;
if (p.m_pEntry->GetPos() < m_pEntry->GetPos())
return false;
if (!m_pParentEntry && p.m_pParentEntry)
return true;
if (!p.m_pParentEntry && m_pParentEntry)
return false;
if (!m_pParentEntry && !p.m_pParentEntry)
{
if (m_pParentEntry->GetPos() < p.m_pParentEntry->GetPos())
return true;
if (p.m_pParentEntry->GetPos() < m_pParentEntry->GetPos())
return false;
}
return false;
}
};
typedef set<ShortestPath> PathSet;
PathSet m_entries;
typedef priority_queue<PossiblePath> PossiblePathQueue;
PossiblePathQueue m_queue;
};
} // namespace routing

View file

@ -1,285 +0,0 @@
#include "features_road_graph.hpp"
#include "route.hpp"
#include "vehicle_model.hpp"
#include "../indexer/index.hpp"
#include "../indexer/classificator.hpp"
#include "../indexer/feature_data.hpp"
#include "../indexer/ftypes_matcher.hpp"
#include "../geometry/distance_on_sphere.hpp"
#include "../base/logging.hpp"
namespace routing
{
uint32_t const READ_ROAD_SCALE = 13;
double const READ_CROSS_RADIUS = 10.0;
double const DEFAULT_SPEED_MS = 15.0;
FeaturesRoadGraph::FeaturesRoadGraph(Index const * pIndex, size_t mwmID)
: m_pIndex(pIndex), m_mwmID(mwmID), m_vehicleModel(new CarModel())
{
}
uint32_t FeaturesRoadGraph::GetStreetReadScale()
{
return READ_ROAD_SCALE;
}
class CrossFeaturesLoader
{
uint32_t m_featureID;
FeaturesRoadGraph & m_graph;
m2::PointD m_point;
IRoadGraph::TurnsVectorT & m_turns;
size_t m_count;
public:
CrossFeaturesLoader(uint32_t fID, FeaturesRoadGraph & graph,
m2::PointD const & pt, IRoadGraph::TurnsVectorT & turns)
: m_featureID(fID), m_graph(graph), m_point(pt), m_turns(turns), m_count(0)
{
}
size_t GetCount() const
{
return m_count;
}
void operator()(FeatureType const & ft)
{
FeatureID const fID = ft.GetID();
if (m_featureID == fID.m_offset || fID.m_mwm != m_graph.GetMwmID())
return;
feature::TypesHolder types(ft);
if (types.GetGeoType() != feature::GEOM_LINE)
return;
double const speed = m_graph.GetSpeed(ft);
if (speed <= 0.0)
return;
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
bool const isOneWay = m_graph.IsOneWay(ft);
size_t const count = ft.GetPointsCount();
PossibleTurn t;
t.m_startPoint = ft.GetPoint(0);
t.m_endPoint = ft.GetPoint(count - 1);
for (size_t i = 0; i < count; ++i)
{
m2::PointD const & p = ft.GetPoint(i);
/// @todo Is this a correct way to compare?
if (!m2::AlmostEqual(m_point, p))
continue;
if (i > 0)
{
++m_count;
t.m_pos = RoadPos(fID.m_offset, true, i - 1);
m_turns.push_back(t);
}
if (!isOneWay && (i < count - 1))
{
++m_count;
t.m_pos = RoadPos(fID.m_offset, false, i);
m_turns.push_back(t);
}
}
}
};
double CalcDistanceMeters(m2::PointD const & p1, m2::PointD const & p2)
{
return ms::DistanceOnEarth(MercatorBounds::YToLat(p1.y), MercatorBounds::XToLon(p1.x),
MercatorBounds::YToLat(p2.y), MercatorBounds::XToLon(p2.x));
}
void FeaturesRoadGraph::LoadFeature(uint32_t id, FeatureType & ft)
{
Index::FeaturesLoaderGuard loader(*m_pIndex, m_mwmID);
loader.GetFeature(id, ft);
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
ASSERT_EQUAL(ft.GetFeatureType(), feature::GEOM_LINE, (id));
ASSERT_GREATER(ft.GetPointsCount(), 1, (id));
}
void FeaturesRoadGraph::GetPossibleTurns(RoadPos const & pos, vector<PossibleTurn> & turns, bool noOptimize /*= true*/)
{
uint32_t const ftId = pos.GetFeatureId();
FeatureType ft;
LoadFeature(ftId, ft);
double const speed = GetSpeed(ft);
if (speed <= 0.0)
return;
int const count = static_cast<int>(ft.GetPointsCount());
bool const isForward = pos.IsForward();
bool const isOneWay = IsOneWay(ft);
int const inc = isForward ? -1 : 1;
int startID = pos.GetPointId();
ASSERT_LESS(startID, count, ());
if (!isForward)
++startID;
PossibleTurn thisTurn;
thisTurn.m_startPoint = ft.GetPoint(0);
thisTurn.m_endPoint = ft.GetPoint(count - 1);
double distance = 0.0;
double time = 0.0;
for (int i = startID; i >= 0 && i < count; i += inc)
{
ASSERT_GREATER(i - inc, -1, ());
ASSERT_LESS(i - inc, count, ());
double const segmentDistance = CalcDistanceMeters(ft.GetPoint(i), ft.GetPoint(i - inc));
distance += segmentDistance;
time += segmentDistance / speed;
m2::PointD const & pt = ft.GetPoint(i);
// Find possible turns to point[i] from other features.
size_t const last = turns.size();
CrossFeaturesLoader crossLoader(ftId, *this, pt, turns);
m_pIndex->ForEachInRect(crossLoader,
MercatorBounds::RectByCenterXYAndSizeInMeters(pt, READ_CROSS_RADIUS),
READ_ROAD_SCALE);
// Skip if there are no turns on point
if (crossLoader.GetCount() > 0 || noOptimize)
{
// Push turn points for this feature.
if (isForward)
{
if (i > 0)
{
thisTurn.m_pos = RoadPos(ftId, true, i - 1);
turns.push_back(thisTurn);
}
}
else
{
if (!isOneWay && (i != count - 1))
{
thisTurn.m_pos = RoadPos(ftId, false, i);
turns.push_back(thisTurn);
}
}
}
// Update distance and time information.
for (size_t j = last; j < turns.size(); ++j)
{
turns[j].m_metersCovered = distance;
turns[j].m_secondsCovered = time;
turns[j].m_speed = DEFAULT_SPEED_MS;
}
}
// Check cycle
if (m2::AlmostEqual(ft.GetPoint(0), ft.GetPoint(count - 1)))
{
/// @todo calculate distance and speed
if (isForward)
{
double distance = 0;
for (int i = pos.GetPointId(); i > 0; --i)
distance += CalcDistanceMeters(ft.GetPoint(i), ft.GetPoint(i - 1));
thisTurn.m_pos = RoadPos(ftId, true, count - 2);
thisTurn.m_metersCovered = distance;
thisTurn.m_secondsCovered = distance / DEFAULT_SPEED_MS;
turns.push_back(thisTurn);
}
else if (!isOneWay)
{
double distance = 0;
for (size_t i = pos.GetPointId(); i < count - 1; ++i)
distance += CalcDistanceMeters(ft.GetPoint(i), ft.GetPoint(i + 1));
thisTurn.m_pos = RoadPos(ftId, false, 0);
thisTurn.m_metersCovered = distance;
thisTurn.m_secondsCovered = distance / DEFAULT_SPEED_MS;
turns.push_back(thisTurn);
}
}
}
void FeaturesRoadGraph::ReconstructPath(RoadPosVectorT const & positions, Route & route)
{
size_t count = positions.size();
if (count < 2)
return;
FeatureType ft1;
vector<m2::PointD> poly;
// Initialize starting point.
LoadFeature(positions.back().GetFeatureId(), ft1);
for (size_t i = count-1; i > 0; --i)
{
RoadPos const & pos1 = positions[i];
RoadPos const & pos2 = positions[i-1];
FeatureType ft2;
// Find next connection point
m2::PointD lastPt;
bool const diffIDs = pos1.GetFeatureId() != pos2.GetFeatureId();
if (diffIDs)
{
LoadFeature(pos2.GetFeatureId(), ft2);
lastPt = ft2.GetPoint(pos2.GetPointId() + (pos2.IsForward() ? 1 : 0));
}
else
lastPt = ft1.GetPoint(pos2.GetPointId() + (pos1.IsForward() ? 1 : 0));
// Accumulate points from start point id to pt.
int const inc = pos1.IsForward() ? -1 : 1;
int ptID = pos1.GetPointId() + (pos1.IsForward() ? 0 : 1);
m2::PointD pt;
do
{
pt = ft1.GetPoint(ptID);
poly.push_back(pt);
LOG(LDEBUG, (pt, pos1.GetFeatureId(), ptID));
ptID += inc;
} while (!m2::AlmostEqual(pt, lastPt));
// Assign current processing feature.
if (diffIDs)
ft1.SwapGeometry(ft2);
}
route.SetGeometry(poly.rbegin(), poly.rend());
}
bool FeaturesRoadGraph::IsOneWay(FeatureType const & ft) const
{
return m_vehicleModel->IsOneWay(ft);
}
double FeaturesRoadGraph::GetSpeed(FeatureType const & ft) const
{
return m_vehicleModel->GetSpeed(ft);
}
} // namespace routing

View file

@ -1,44 +0,0 @@
#pragma once
#include "road_graph.hpp"
#include "../std/unique_ptr.hpp"
class Index;
class FeatureType;
namespace feature
{
class TypesHolder;
}
namespace routing
{
class IVehicleModel;
class FeaturesRoadGraph : public IRoadGraph
{
public:
FeaturesRoadGraph(Index const * pIndex, size_t mwmID);
virtual void GetPossibleTurns(RoadPos const & pos, vector<PossibleTurn> & turns, bool noOptimize = true);
virtual void ReconstructPath(RoadPosVectorT const & positions, Route & route);
static uint32_t GetStreetReadScale();
inline size_t GetMwmID() const { return m_mwmID; }
private:
friend class CrossFeaturesLoader;
bool IsOneWay(FeatureType const & ft) const;
double GetSpeed(FeatureType const & ft) const;
void LoadFeature(uint32_t id, FeatureType & ft);
private:
Index const * m_pIndex;
size_t m_mwmID;
unique_ptr<IVehicleModel> const m_vehicleModel;
};
} // namespace routing

View file

@ -1,22 +0,0 @@
#include "helicopter_router.hpp"
#include "route.hpp"
#include "../base/timer.hpp"
#include "../base/macros.hpp"
namespace routing
{
void HelicopterRouter::SetFinalPoint(m2::PointD const & finalPt)
{
m_finalPt = finalPt;
}
void HelicopterRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback)
{
m2::PointD points[] = { startingPt, m_finalPt };
Route route(GetName(), points, points + ARRAY_SIZE(points), my::FormatCurrentTime());
callback(route);
}
}

View file

@ -1,21 +0,0 @@
#pragma once
#include "router.hpp"
#include "../geometry/point2d.hpp"
namespace routing
{
class HelicopterRouter : public IRouter
{
m2::PointD m_finalPt;
public:
virtual string GetName() const { return "helicopter"; }
virtual void SetFinalPoint(m2::PointD const & finalPt);
virtual void CalculateRoute(m2::PointD const & startingPt, ReadyCallback const & callback);
};
} // routing

View file

@ -1,25 +0,0 @@
#include "road_graph.hpp"
#include "../base/assert.hpp"
#include "../std/sstream.hpp"
namespace routing
{
RoadPos::RoadPos(uint32_t featureId, bool bForward, size_t pointId)
: m_featureId((featureId << 1) + (bForward ? 1 : 0)), m_pointId(pointId)
{
ASSERT_LESS(featureId, 1U << 31, ());
ASSERT_LESS(pointId, 0xFFFFFFFF, ());
}
string DebugPrint(RoadPos const & r)
{
ostringstream ss;
ss << "{" << r.GetFeatureId() << ", " << r.IsForward() << ", " << r.m_pointId << "}";
return ss.str();
}
} // namespace routing

View file

@ -1,82 +0,0 @@
#pragma once
#include "../geometry/point2d.hpp"
#include "../base/string_utils.hpp"
#include "../std/vector.hpp"
namespace routing
{
class Route;
/// Defines position on a feature with direction.
class RoadPos
{
public:
RoadPos() : m_featureId(0), m_pointId(0) {}
RoadPos(uint32_t featureId, bool bForward, size_t pointId);
uint32_t GetFeatureId() const { return m_featureId >> 1; }
bool IsForward() const { return (m_featureId & 1) != 0; }
uint32_t GetPointId() const { return m_pointId; }
bool operator==(RoadPos const & r) const
{
return (m_featureId == r.m_featureId && m_pointId == r.m_pointId);
}
bool operator < (RoadPos const & r) const
{
if (m_featureId != r.m_featureId)
return m_featureId < r.m_featureId;
if (m_pointId != r.m_pointId)
return m_pointId < r.m_pointId;
return false;
}
private:
friend string DebugPrint(RoadPos const & r);
uint32_t m_featureId;
uint32_t m_pointId;
};
/// The turn from the old to the new road.
struct PossibleTurn
{
/// New road information.
RoadPos m_pos;
m2::PointD m_startPoint, m_endPoint;
double m_speed;
/// Distance and time to get to this turn on old road.
double m_metersCovered;
double m_secondsCovered;
PossibleTurn() : m_metersCovered(0.0), m_secondsCovered(0.0) {}
};
inline string DebugPrint(PossibleTurn const & r)
{
return DebugPrint(r.m_pos);
}
class IRoadGraph
{
public:
typedef vector<PossibleTurn> TurnsVectorT;
typedef vector<RoadPos> RoadPosVectorT;
typedef vector<m2::PointD> PointsVectorT;
virtual ~IRoadGraph() {}
/// Find all feature sections (turns), that route to the "pos" section.
virtual void GetPossibleTurns(RoadPos const & pos, TurnsVectorT & turns, bool noOptimize = true) = 0;
/// Construct route by road positions (doesn't include first and last section).
virtual void ReconstructPath(RoadPosVectorT const & positions, Route & route) = 0;
};
} // namespace routing

View file

@ -1,133 +0,0 @@
#include "road_graph_router.hpp"
#include "features_road_graph.hpp"
#include "route.hpp"
#include "vehicle_model.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/ftypes_matcher.hpp"
#include "../indexer/index.hpp"
#include "../geometry/distance.hpp"
namespace routing
{
class Point2RoadPos
{
m2::PointD m_point;
double m_minDist;
size_t m_segIdx;
bool m_isOneway;
FeatureID m_fID;
IVehicleModel const * m_vehicleModel;
public:
Point2RoadPos(m2::PointD const & pt, IVehicleModel const * vehicleModel)
: m_point(pt), m_minDist(numeric_limits<double>::max()), m_vehicleModel(vehicleModel)
{
}
void operator() (FeatureType const & ft)
{
if (ft.GetFeatureType() != feature::GEOM_LINE)
return;
double const speed = m_vehicleModel->GetSpeed(ft);
if (speed <= 0.0)
return;
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
size_t const count = ft.GetPointsCount() - 1;
for (size_t i = 0; i < count; ++i)
{
m2::DistanceToLineSquare<m2::PointD> segDist;
segDist.SetBounds(ft.GetPoint(i), ft.GetPoint(i + 1));
double const d = segDist(m_point);
if (d < m_minDist)
{
m_minDist = d;
m_segIdx = i;
m_fID = ft.GetID();
m_isOneway = m_vehicleModel->IsOneWay(ft);
}
}
}
size_t GetMwmID() const
{
return m_fID.m_mwm;
}
void GetResults(vector<RoadPos> & res)
{
if (m_fID.IsValid())
{
res.push_back(RoadPos(m_fID.m_offset, true, m_segIdx));
if (!m_isOneway)
res.push_back(RoadPos(m_fID.m_offset, false, m_segIdx));
}
}
};
RoadGraphRouter::~RoadGraphRouter()
{
}
RoadGraphRouter::RoadGraphRouter(Index const * pIndex) :
m_vehicleModel(new CarModel()), m_pIndex(pIndex)
{
}
size_t RoadGraphRouter::GetRoadPos(m2::PointD const & pt, vector<RoadPos> & pos)
{
Point2RoadPos getter(pt, m_vehicleModel.get());
m_pIndex->ForEachInRect(getter,
MercatorBounds::RectByCenterXYAndSizeInMeters(pt, 100.0),
FeaturesRoadGraph::GetStreetReadScale());
getter.GetResults(pos);
return getter.GetMwmID();
}
bool RoadGraphRouter::IsMyMWM(size_t mwmID) const
{
return (m_pRoadGraph && dynamic_cast<FeaturesRoadGraph const *>(m_pRoadGraph.get())->GetMwmID() == mwmID);
}
void RoadGraphRouter::SetFinalPoint(m2::PointD const & finalPt)
{
vector<RoadPos> finalPos;
size_t const mwmID = GetRoadPos(finalPt, finalPos);
if (!finalPos.empty())
{
if (!IsMyMWM(mwmID))
m_pRoadGraph.reset(new FeaturesRoadGraph(m_pIndex, mwmID));
SetFinalRoadPos(finalPos);
}
}
void RoadGraphRouter::CalculateRoute(m2::PointD const & startPt, ReadyCallback const & callback)
{
if (!m_pRoadGraph)
return;
vector<RoadPos> startPos;
size_t const mwmID = GetRoadPos(startPt, startPos);
if (startPos.empty() || !IsMyMWM(mwmID))
return;
vector<RoadPos> routePos;
CalculateRoute(startPos, routePos);
Route route(GetName());
m_pRoadGraph->ReconstructPath(routePos, route);
callback(route);
}
} // namespace routing

View file

@ -1,41 +0,0 @@
#pragma once
#include "router.hpp"
#include "road_graph.hpp"
#include "../geometry/point2d.hpp"
#include "../std/vector.hpp"
#include "../std/unique_ptr.hpp"
class Index;
namespace routing
{
class IVehicleModel;
class RoadGraphRouter : public IRouter
{
public:
RoadGraphRouter(Index const * pIndex);
~RoadGraphRouter();
virtual void SetFinalPoint(m2::PointD const & finalPt);
virtual void CalculateRoute(m2::PointD const & startPt, ReadyCallback const & callback);
virtual void SetFinalRoadPos(vector<RoadPos> const & finalPos) = 0;
virtual void CalculateRoute(vector<RoadPos> const & startPos, vector<RoadPos> & route) = 0;
virtual void SetRoadGraph(IRoadGraph * pRoadGraph) { m_pRoadGraph.reset(pRoadGraph); }
protected:
size_t GetRoadPos(m2::PointD const & pt, vector<RoadPos> & pos);
bool IsMyMWM(size_t mwmID) const;
unique_ptr<IRoadGraph> m_pRoadGraph;
unique_ptr<IVehicleModel> const m_vehicleModel;
Index const * m_pIndex;
};
} // namespace routing

View file

@ -13,28 +13,16 @@ INCLUDEPATH += $$ROOT_DIR/3party/jansson/src \
SOURCES += \
route.cpp \
routing_engine.cpp \
road_graph.cpp \
helicopter_router.cpp \
osrm_router.cpp \
osrm_online_router.cpp \
osrm2feature_map.cpp \
road_graph_router.cpp \
dijkstra_router.cpp \
features_road_graph.cpp \
vehicle_model.cpp \
HEADERS += \
route.hpp \
routing_engine.hpp \
router.hpp \
road_graph.hpp \
helicopter_router.hpp \
osrm_router.hpp \
osrm_online_router.hpp \
osrm_data_facade.hpp \
osrm2feature_map.hpp \
road_graph_router.hpp \
dijkstra_router.hpp \
features_road_graph.hpp \
vehicle_model.hpp \

View file

@ -1,121 +0,0 @@
#include "routing_engine.hpp"
#include "route.hpp"
#include "helicopter_router.hpp"
#include "osrm_online_router.hpp"
#include "dijkstra_router.hpp"
#include "../base/stl_add.hpp"
#include "../base/logging.hpp"
namespace routing
{
RoutingEngine::RoutingEngine()
{
m_pointStates[0] = m_pointStates[1] = INVALID;
}
RoutingEngine::~RoutingEngine()
{
for_each(m_routers.begin(), m_routers.end(), DeleteFunctor());
}
void RoutingEngine::AddRouter(string const & name)
{
if (!FindRouter(name))
{
if (name == "helicopter")
m_routers.push_back(new HelicopterRouter());
else if (name == "osrm-online")
m_routers.push_back(new OsrmOnlineRouter());
}
}
void RoutingEngine::AddRouter(IRouter * pRouter)
{
if (!FindRouter(pRouter->GetName()))
m_routers.push_back(pRouter);
}
void RoutingEngine::RemoveRouter(string const & name)
{
for (TRouters::iterator it = m_routers.begin(); it != m_routers.end(); ++it)
{
IRouter * router = *it;
if (router->GetName() == name)
{
m_routers.erase(it);
delete router;
break;
}
}
}
bool RoutingEngine::IsRoutingEnabled() const
{
return !m_routers.empty();
}
void RoutingEngine::SetStartingPoint(m2::PointD const & pt)
{
if (m_pointStates[0] == INVALID || !my::AlmostEqual(m_points[0], pt))
{
m_points[0] = pt;
m_pointStates[0] = MODIFIED;
}
}
void RoutingEngine::SetFinalPoint(m2::PointD const & pt)
{
if (m_pointStates[1] == INVALID || !my::AlmostEqual(m_points[1], pt))
{
m_points[1] = pt;
m_pointStates[1] = MODIFIED;
}
}
void RoutingEngine::Calculate(string const & name, IRouter::ReadyCallback const & callback)
{
if (name == "all")
{
for (size_t i = 0; i < m_routers.size(); ++i)
Calculate(m_routers[i]->GetName(), callback);
return;
}
IRouter * p = FindRouter(name);
if (!p)
{
LOG(LWARNING, ("Can't calculate route - router engine", name, "is not initialized."));
return;
}
if (m_pointStates[0] == INVALID || m_pointStates[1] == INVALID)
{
LOG(LINFO, ("Routing calculation cancelled - start and/or end points are not initialized."));
return;
}
if (m_pointStates[0] != MODIFIED || m_pointStates[1] != MODIFIED)
{
LOG(LINFO, ("Routing calculation cancelled - start and end points are the same."));
return;
}
if (m_pointStates[1] == MODIFIED)
p->SetFinalPoint(m_points[1]);
p->CalculateRoute(m_points[0], callback);
}
IRouter * RoutingEngine::FindRouter(string const & name)
{
for (size_t i = 0; i < m_routers.size(); ++i)
if (m_routers[i]->GetName() == name)
return m_routers[i];
return 0;
}
} // namespace routing

View file

@ -1,40 +0,0 @@
#pragma once
#include "router.hpp"
#include "../geometry/point2d.hpp"
#include "../std/vector.hpp"
namespace routing
{
class RoutingEngine
{
public:
RoutingEngine();
~RoutingEngine();
void AddRouter(string const & name);
void AddRouter(IRouter * pRouter);
void RemoveRouter(string const & name);
bool IsRoutingEnabled() const;
void SetStartingPoint(m2::PointD const & pt);
void SetFinalPoint(m2::PointD const & pt);
void Calculate(string const & name, IRouter::ReadyCallback const & callback);
private:
IRouter * FindRouter(string const & name);
m2::PointD m_points[2];
enum PointState { INVALID, MODIFIED, CALCULATED };
PointState m_pointStates[2];
typedef vector<IRouter *> TRouters;
TRouters m_routers;
};
} // namespace routing

View file

@ -1,115 +0,0 @@
#include "../../testing/testing.hpp"
#include "road_graph_builder.hpp"
#include "features_road_graph_test.hpp"
#include "../dijkstra_router.hpp"
#include "../features_road_graph.hpp"
#include "../route.hpp"
#include "../../base/logging.hpp"
#include "../../base/macros.hpp"
using namespace routing;
using namespace routing_test;
// Use mock graph source.
template <size_t finalPosSize, size_t startPosSize, size_t expectedSize>
void TestDijkstraRouterMock(RoadPos (&finalPos)[finalPosSize],
RoadPos (&startPos)[startPosSize],
RoadPos (&expected)[expectedSize])
{
RoadGraphMockSource * graph = new RoadGraphMockSource();
InitRoadGraphMockSourceWithTest2(*graph);
DijkstraRouter router;
router.SetRoadGraph(graph);
router.SetFinalRoadPos(vector<RoadPos>(&finalPos[0], &finalPos[0] + ARRAY_SIZE(finalPos)));
vector<RoadPos> result;
router.CalculateRoute(vector<RoadPos>(&startPos[0], &startPos[0] + ARRAY_SIZE(startPos)), result);
TEST_EQUAL(vector<RoadPos>(&expected[0], &expected[0] + ARRAY_SIZE(expected)), result, ());
}
// Use mwm features graph source.
template <size_t finalPosSize, size_t startPosSize, size_t expectedSize>
void TestDijkstraRouterMWM(RoadPos (&finalPos)[finalPosSize],
RoadPos (&startPos)[startPosSize],
RoadPos (&expected)[expectedSize],
size_t pointsCount)
{
FeatureRoadGraphTester tester("route_test2.mwm");
DijkstraRouter router;
router.SetRoadGraph(tester.GetGraph());
vector<RoadPos> finalV(&finalPos[0], &finalPos[0] + ARRAY_SIZE(finalPos));
tester.Name2FeatureID(finalV);
router.SetFinalRoadPos(finalV);
vector<RoadPos> startV(&startPos[0], &startPos[0] + ARRAY_SIZE(startPos));
tester.Name2FeatureID(startV);
vector<RoadPos> result;
router.CalculateRoute(startV, result);
LOG(LDEBUG, (result));
Route route(router.GetName());
tester.GetGraph()->ReconstructPath(result, route);
LOG(LDEBUG, (route));
TEST_EQUAL(route.GetPoly().GetSize(), pointsCount, ());
tester.FeatureID2Name(result);
TEST_EQUAL(vector<RoadPos>(&expected[0], &expected[0] + ARRAY_SIZE(expected)), result, ());
}
UNIT_TEST(Dijkstra_Router_City_Simple)
{
// Uncomment to see debug log.
//my::g_LogLevel = LDEBUG;
RoadPos finalPos[] = { RoadPos(7, true, 0) };
RoadPos startPos[] = { RoadPos(1, true, 0) };
RoadPos expected1[] = { RoadPos(1, true, 0),
RoadPos(1, true, 1),
RoadPos(8, true, 0),
RoadPos(8, true, 1),
RoadPos(7, true, 0) };
TestDijkstraRouterMock(finalPos, startPos, expected1);
RoadPos expected2[] = { RoadPos(1, true, 0),
RoadPos(1, true, 1),
RoadPos(8, true, 1),
RoadPos(7, true, 0) };
TestDijkstraRouterMWM(finalPos, startPos, expected2, 4);
}
UNIT_TEST(Dijkstra_Router_City_ReallyFunnyLoop)
{
// Uncomment to see debug log.
//my::g_LogLevel = LDEBUG;
RoadPos finalPos[] = { RoadPos(1, true, 0) };
RoadPos startPos[] = { RoadPos(1, true, 1) };
RoadPos expected1[] = { RoadPos(1, true, 1),
RoadPos(8, true, 0),
RoadPos(8, true, 1),
RoadPos(8, true, 3), // algorithm skips 8,2 segment
RoadPos(4, false, 0),
RoadPos(0, false, 1),
RoadPos(0, false, 0),
RoadPos(1, true, 0) };
TestDijkstraRouterMock(finalPos, startPos, expected1);
RoadPos expected2[] = { RoadPos(1, true, 1),
RoadPos(8, true, 4),
RoadPos(2, true, 1),
RoadPos(0, false, 0),
RoadPos(1, true, 0) };
TestDijkstraRouterMWM(finalPos, startPos, expected2, 9);
}

View file

@ -1,264 +0,0 @@
#include "../../testing/testing.hpp"
#include "features_road_graph_test.hpp"
#include "../route.hpp"
#include "../../indexer/classificator_loader.hpp"
#include "../../indexer/feature.hpp"
#include "../../indexer/ftypes_matcher.hpp"
#include "../../base/logging.hpp"
using namespace routing;
namespace routing_test
{
class EqualPos
{
RoadPos m_pos;
double m_distance;
public:
EqualPos(RoadPos const & pos, double d) : m_pos(pos), m_distance(d) {}
bool operator() (PossibleTurn const & r) const
{
return r.m_pos == m_pos;
}
};
bool TestResult(IRoadGraph::TurnsVectorT const & vec, RoadPos const & pos, double d)
{
return find_if(vec.begin(), vec.end(), EqualPos(pos, d)) != vec.end();
}
void Name2IdMapping::operator()(FeatureType const & ft)
{
if (!ftypes::IsStreetChecker::Instance()(ft))
return;
string name;
VERIFY(ft.GetName(0, name), ());
m_name2Id[name] = ft.GetID().m_offset;
m_id2Name[ft.GetID().m_offset] = name;
}
uint32_t Name2IdMapping::GetId(string const & name)
{
ASSERT(m_name2Id.find(name) != m_name2Id.end(), ());
return m_name2Id[name];
}
string const & Name2IdMapping::GetName(uint32_t id)
{
ASSERT(m_id2Name.find(id) != m_id2Name.end(), ());
return m_id2Name[id];
}
FeatureRoadGraphTester::FeatureRoadGraphTester(string const & name)
{
classificator::Load();
m2::RectD rect;
if (!m_index.Add(name, rect))
{
LOG(LERROR, ("MWM file not found"));
return;
}
m_graph = new FeaturesRoadGraph(&m_index, 0);
m_index.ForEachInRect(m_mapping, MercatorBounds::FullRect(), m_graph->GetStreetReadScale());
}
void FeatureRoadGraphTester::FeatureID2Name(routing::RoadPos & pos)
{
string const & name = m_mapping.GetName(pos.GetFeatureId());
int id = 0;
VERIFY(strings::to_int(name, id), (name));
pos = RoadPos(static_cast<uint32_t>(id), pos.IsForward(), pos.GetPointId());
}
void FeatureRoadGraphTester::FeatureID2Name(IRoadGraph::TurnsVectorT & vec)
{
for (size_t i = 0; i < vec.size(); ++i)
FeatureID2Name(vec[i].m_pos);
}
void FeatureRoadGraphTester::FeatureID2Name(vector<routing::RoadPos> & vec)
{
for (size_t i = 0; i < vec.size(); ++i)
FeatureID2Name(vec[i]);
}
void FeatureRoadGraphTester::Name2FeatureID(vector<routing::RoadPos> & vec)
{
for (size_t i = 0; i < vec.size(); ++i)
vec[i] = RoadPos(m_mapping.GetId(strings::to_string(vec[i].GetFeatureId())),
vec[i].IsForward(),
vec[i].GetPointId());
}
void FeatureRoadGraphTester::GetPossibleTurns(RoadPos const & pos, IRoadGraph::TurnsVectorT & vec, bool noOptimize/* = true*/)
{
m_graph->GetPossibleTurns(RoadPos(m_mapping.GetId(strings::to_string(pos.GetFeatureId())),
pos.IsForward(), pos.GetPointId()), vec, noOptimize);
FeatureID2Name(vec);
}
template <size_t N>
void FeatureRoadGraphTester::ReconstructPath(routing::RoadPos (&arr)[N], vector<m2::PointD> & vec)
{
vector<RoadPos> positions(arr, arr + N);
Name2FeatureID(positions);
Route route("dummy");
m_graph->ReconstructPath(positions, route);
vec.assign(route.GetPoly().Begin(), route.GetPoly().End());
}
}
using namespace routing_test;
UNIT_TEST(FRG_TurnsTest_MWM1)
{
FeatureRoadGraphTester tester("route_test1.mwm");
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(0, true, 1), vec);
TEST_EQUAL(vec.size(), 1, ());
TEST(TestResult(vec, RoadPos(0, true, 0), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(0, false, 1), vec);
TEST_EQUAL(vec.size(), 7, ());
TEST(TestResult(vec, RoadPos(0, false, 2), -1), ());
TEST(TestResult(vec, RoadPos(0, false, 3), -1), ());
TEST(TestResult(vec, RoadPos(1, true, 1), -1), ());
TEST(TestResult(vec, RoadPos(1, false, 2), -1), ());
TEST(TestResult(vec, RoadPos(2, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(3, false, 0), -1), ());
TEST(TestResult(vec, RoadPos(3, true, 2), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(1, true, 0), vec);
TEST_EQUAL(vec.size(), 0, ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(1, false, 0), vec, false);
TEST_EQUAL(vec.size(), 3, ());
TEST(TestResult(vec, RoadPos(1, false, 2), 10), ());
TEST(TestResult(vec, RoadPos(0, true, 1), 10), ());
TEST(TestResult(vec, RoadPos(0, false, 2), 10), ());
}
}
UNIT_TEST(FRG_TurnsTest_MWM2)
{
FeatureRoadGraphTester tester("route_test2.mwm");
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(0, false, 0), vec, false);
TEST_EQUAL(vec.size(), 8, ());
TEST(TestResult(vec, RoadPos(0, false, 1), -1), ());
TEST(TestResult(vec, RoadPos(0, false, 2), -1), ());
TEST(TestResult(vec, RoadPos(0, false, 3), -1), ());
TEST(TestResult(vec, RoadPos(0, false, 4), -1), ());
TEST(TestResult(vec, RoadPos(2, true, 1), -1), ());
TEST(TestResult(vec, RoadPos(5, false, 0), -1), ());
TEST(TestResult(vec, RoadPos(6, false, 0), -1), ());
TEST(TestResult(vec, RoadPos(4, false, 0), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(8, true, 0), vec, false);
TEST_EQUAL(vec.size(), 2, ());
TEST(TestResult(vec, RoadPos(1, true, 1), -1), ());
TEST(TestResult(vec, RoadPos(8, true, 5), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(2, true, 1), vec, false);
TEST_EQUAL(vec.size(), 4, ());
TEST(TestResult(vec, RoadPos(3, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(3, false, 1), -1), ());
TEST(TestResult(vec, RoadPos(2, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(8, true, 4), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(3, false, 0), vec, false);
TEST_EQUAL(vec.size(), 5, ());
TEST(TestResult(vec, RoadPos(3, false, 1), -1), ());
TEST(TestResult(vec, RoadPos(3, false, 2), -1), ());
TEST(TestResult(vec, RoadPos(2, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(6, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(6, false, 1), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(7, false, 0), vec);
TEST_EQUAL(vec.size(), 0, ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(7, true, 0), vec);
TEST_EQUAL(vec.size(), 1, ());
TEST(TestResult(vec, RoadPos(8, true, 1), -1), ());
}
{
IRoadGraph::TurnsVectorT vec;
tester.GetPossibleTurns(RoadPos(8, true, 3), vec, false);
TEST_EQUAL(vec.size(), 7, ());
TEST(TestResult(vec, RoadPos(8, true, 2), -1), ());
TEST(TestResult(vec, RoadPos(5, true, 0), -1), ());
TEST(TestResult(vec, RoadPos(5, false, 1), -1), ());
TEST(TestResult(vec, RoadPos(7, false, 0), -1), ());
TEST(TestResult(vec, RoadPos(8, true, 1), -1), ());
TEST(TestResult(vec, RoadPos(1, true, 1), -1), ());
TEST(TestResult(vec, RoadPos(8, true, 5), -1), ());
}
}
UNIT_TEST(FRG_ReconstructTest_MWM2)
{
// Uncomment to see debug log.
//my::g_LogLevel = LDEBUG;
FeatureRoadGraphTester tester("route_test2.mwm");
{
RoadPos arr[] = {
RoadPos(8, true, 4),
RoadPos(2, true, 0),
RoadPos(3, true, 2)
};
vector<m2::PointD> vec;
tester.ReconstructPath(arr, vec);
TEST_EQUAL(vec.size(), 3, ());
}
}

View file

@ -1,48 +0,0 @@
#pragma once
#include "../features_road_graph.hpp"
#include "../../indexer/index.hpp"
#include "../../std/scoped_ptr.hpp"
namespace routing_test
{
class Name2IdMapping
{
map<string, uint32_t> m_name2Id;
map<uint32_t, string> m_id2Name;
public:
void operator()(FeatureType const & ft);
uint32_t GetId(string const & name);
string const & GetName(uint32_t id);
};
class FeatureRoadGraphTester
{
routing::FeaturesRoadGraph * m_graph;
Name2IdMapping m_mapping;
Index m_index;
void FeatureID2Name(routing::RoadPos & pos);
public:
FeatureRoadGraphTester(string const & name);
routing::FeaturesRoadGraph * GetGraph() { return m_graph; }
void FeatureID2Name(routing::IRoadGraph::TurnsVectorT & vec);
void FeatureID2Name(vector<routing::RoadPos> & vec);
void Name2FeatureID(vector<routing::RoadPos> & vec);
void GetPossibleTurns(routing::RoadPos const & pos, routing::IRoadGraph::TurnsVectorT & vec, bool noOptimize = true);
template <size_t N>
void ReconstructPath(routing::RoadPos (&arr)[N], vector<m2::PointD> & vec);
};
}

View file

@ -1,232 +0,0 @@
#include "road_graph_builder.hpp"
#include "../../std/algorithm.hpp"
using namespace routing;
namespace routing_test
{
void RoadInfo::Swap(RoadInfo & r)
{
m_points.swap(r.m_points);
std::swap(m_speedMS, r.m_speedMS);
std::swap(m_bothSides, r.m_bothSides);
}
void RoadGraphMockSource::AddRoad(RoadInfo & rd)
{
/// @todo Do ASSERT for RoadInfo params.
uint32_t const id = m_roads.size();
// Count of sections! (not points)
size_t count = rd.m_points.size();
ASSERT_GREATER(count, 1, ());
for (size_t i = 0; i < count; ++i)
{
TurnsMapT::iterator j = m_turns.insert(make_pair(rd.m_points[i], TurnsVectorT())).first;
PossibleTurn t;
t.m_startPoint = rd.m_points.front();
t.m_endPoint = rd.m_points.back();
t.m_speed = rd.m_speedMS;
if (i > 0)
{
t.m_pos = RoadPos(id, true, i - 1);
j->second.push_back(t);
}
if (rd.m_bothSides && (i < count - 1))
{
t.m_pos = RoadPos(id, false, i);
j->second.push_back(t);
}
}
m_roads.push_back(RoadInfo());
m_roads.back().Swap(rd);
}
void RoadGraphMockSource::GetPossibleTurns(RoadPos const & pos, TurnsVectorT & turns, bool /*noOptimize = true*/)
{
uint32_t const fID = pos.GetFeatureId();
ASSERT_LESS(fID, m_roads.size(), ());
vector<m2::PointD> const & points = m_roads[fID].m_points;
int const inc = pos.IsForward() ? -1 : 1;
int startID = pos.GetPointId();
int const count = static_cast<int>(points.size());
if (!pos.IsForward())
++startID;
double const speed = m_roads[fID].m_speedMS;
double distance = 0.0;
double time = 0.0;
for (int i = startID; i >= 0 && i < count; i += inc)
{
double const len = points[i - inc].Length(points[i]);
distance += len;
time += len / speed;
TurnsMapT::const_iterator j = m_turns.find(points[i]);
if (j != m_turns.end())
{
vector<PossibleTurn> const & vec = j->second;
for (size_t k = 0; k < vec.size(); ++k)
{
if (vec[k].m_pos.GetFeatureId() != pos.GetFeatureId() ||
vec[k].m_pos.IsForward() == pos.IsForward())
{
PossibleTurn t = vec[k];
t.m_metersCovered = distance;
t.m_secondsCovered = time;
turns.push_back(t);
}
}
}
}
}
void RoadGraphMockSource::ReconstructPath(RoadPosVectorT const &, routing::Route &)
{
}
void InitRoadGraphMockSourceWithTest1(RoadGraphMockSource & src)
{
{
RoadInfo ri;
ri.m_bothSides = true;
ri.m_speedMS = 40;
ri.m_points.push_back(m2::PointD(0, 0));
ri.m_points.push_back(m2::PointD(5, 0));
ri.m_points.push_back(m2::PointD(10, 0));
ri.m_points.push_back(m2::PointD(15, 0));
ri.m_points.push_back(m2::PointD(20, 0));
src.AddRoad(ri);
}
{
RoadInfo ri;
ri.m_bothSides = true;
ri.m_speedMS = 40;
ri.m_points.push_back(m2::PointD(10, -10));
ri.m_points.push_back(m2::PointD(10, -5));
ri.m_points.push_back(m2::PointD(10, 0));
ri.m_points.push_back(m2::PointD(10, 5));
ri.m_points.push_back(m2::PointD(10, 10));
src.AddRoad(ri);
}
{
RoadInfo ri;
ri.m_bothSides = true;
ri.m_speedMS = 40;
ri.m_points.push_back(m2::PointD(15, -5));
ri.m_points.push_back(m2::PointD(15, 0));
src.AddRoad(ri);
}
{
RoadInfo ri;
ri.m_bothSides = true;
ri.m_speedMS = 40;
ri.m_points.push_back(m2::PointD(20, 0));
ri.m_points.push_back(m2::PointD(25, 5));
ri.m_points.push_back(m2::PointD(15, 5));
ri.m_points.push_back(m2::PointD(20, 0));
src.AddRoad(ri);
}
}
void InitRoadGraphMockSourceWithTest2(RoadGraphMockSource & graph)
{
RoadInfo ri0;
ri0.m_bothSides = true;
ri0.m_speedMS = 40;
ri0.m_points.push_back(m2::PointD(0, 0));
ri0.m_points.push_back(m2::PointD(10, 0));
ri0.m_points.push_back(m2::PointD(25, 0));
ri0.m_points.push_back(m2::PointD(35, 0));
ri0.m_points.push_back(m2::PointD(70, 0));
ri0.m_points.push_back(m2::PointD(80, 0));
RoadInfo ri1;
ri1.m_bothSides = false;
ri1.m_speedMS = 40;
ri1.m_points.push_back(m2::PointD(0, 0));
ri1.m_points.push_back(m2::PointD(5, 10));
ri1.m_points.push_back(m2::PointD(5, 40));
RoadInfo ri2;
ri2.m_bothSides = false;
ri2.m_speedMS = 40;
ri2.m_points.push_back(m2::PointD(12, 25));
ri2.m_points.push_back(m2::PointD(10, 10));
ri2.m_points.push_back(m2::PointD(10, 0));
RoadInfo ri3;
ri3.m_bothSides = true;
ri3.m_speedMS = 40;
ri3.m_points.push_back(m2::PointD(5, 10));
ri3.m_points.push_back(m2::PointD(10, 10));
ri3.m_points.push_back(m2::PointD(70, 10));
ri3.m_points.push_back(m2::PointD(80, 10));
RoadInfo ri4;
ri4.m_bothSides = true;
ri4.m_speedMS = 40;
ri4.m_points.push_back(m2::PointD(25, 0));
ri4.m_points.push_back(m2::PointD(27, 25));
RoadInfo ri5;
ri5.m_bothSides = true;
ri5.m_speedMS = 40;
ri5.m_points.push_back(m2::PointD(35, 0));
ri5.m_points.push_back(m2::PointD(37, 30));
ri5.m_points.push_back(m2::PointD(70, 30));
ri5.m_points.push_back(m2::PointD(80, 30));
RoadInfo ri6;
ri6.m_bothSides = true;
ri6.m_speedMS = 40;
ri6.m_points.push_back(m2::PointD(70, 0));
ri6.m_points.push_back(m2::PointD(70, 10));
ri6.m_points.push_back(m2::PointD(70, 30));
RoadInfo ri7;
ri7.m_bothSides = true;
ri7.m_speedMS = 40;
ri7.m_points.push_back(m2::PointD(39, 55));
ri7.m_points.push_back(m2::PointD(80, 55));
RoadInfo ri8;
ri8.m_bothSides = false;
ri8.m_speedMS = 40;
ri8.m_points.push_back(m2::PointD(5, 40));
ri8.m_points.push_back(m2::PointD(18, 55));
ri8.m_points.push_back(m2::PointD(39, 55));
ri8.m_points.push_back(m2::PointD(37, 30));
ri8.m_points.push_back(m2::PointD(27, 25));
ri8.m_points.push_back(m2::PointD(12, 25));
ri8.m_points.push_back(m2::PointD(5, 40));
graph.AddRoad(ri0);
graph.AddRoad(ri1);
graph.AddRoad(ri2);
graph.AddRoad(ri3);
graph.AddRoad(ri4);
graph.AddRoad(ri5);
graph.AddRoad(ri6);
graph.AddRoad(ri7);
graph.AddRoad(ri8);
}
} // namespace routing_test

View file

@ -1,56 +0,0 @@
#pragma once
#include "../road_graph.hpp"
namespace routing_test
{
struct RoadInfo
{
vector<m2::PointD> m_points;
double m_speedMS;
bool m_bothSides;
RoadInfo() : m_speedMS(0.0), m_bothSides(false) {}
void Swap(RoadInfo & r);
};
inline void swap(RoadInfo & r1, RoadInfo & r2)
{
r1.Swap(r2);
}
class RoadGraphMockSource : public routing::IRoadGraph
{
vector<RoadInfo> m_roads;
struct LessPoint
{
bool operator() (m2::PointD const & p1, m2::PointD const & p2) const
{
double const eps = 1.0E-6;
if (p1.x + eps < p2.x)
return true;
else if (p1.x > p2.x + eps)
return false;
return (p1.y + eps < p2.y);
}
};
typedef vector<routing::PossibleTurn> TurnsVectorT;
typedef map<m2::PointD, TurnsVectorT, LessPoint> TurnsMapT;
TurnsMapT m_turns;
public:
void AddRoad(RoadInfo & rd);
virtual void GetPossibleTurns(routing::RoadPos const & pos, TurnsVectorT & turns, bool noOptimize = true);
virtual void ReconstructPath(RoadPosVectorT const & positions, routing::Route & route);
};
void InitRoadGraphMockSourceWithTest1(RoadGraphMockSource & graphMock);
void InitRoadGraphMockSourceWithTest2(RoadGraphMockSource & graphMock);
} // namespace routing_test

View file

@ -1,154 +0,0 @@
#include "../../testing/testing.hpp"
#include "road_graph_builder.hpp"
#include "../../base/logging.hpp"
using namespace routing;
using namespace routing_test;
namespace
{
class EqualPos
{
RoadPos m_pos;
double m_distance;
public:
EqualPos(RoadPos const & pos, double d) : m_pos(pos), m_distance(d) {}
bool operator() (PossibleTurn const & r) const { return (r.m_pos == m_pos && r.m_metersCovered == m_distance); }
};
bool TestResult(IRoadGraph::TurnsVectorT const & vec, RoadPos const & pos, double d)
{
return find_if(vec.begin(), vec.end(), EqualPos(pos, d)) != vec.end();
}
}
UNIT_TEST(RG_Builder_Test1)
{
RoadGraphMockSource src;
InitRoadGraphMockSourceWithTest1(src);
{
IRoadGraph::TurnsVectorT vec;
src.GetPossibleTurns(RoadPos(0, true, 1), vec);
TEST_EQUAL(vec.size(), 1, ());
TEST_EQUAL(vec[0].m_pos, RoadPos(0, true, 0), ());
}
{
IRoadGraph::TurnsVectorT vec;
src.GetPossibleTurns(RoadPos(0, false, 1), vec);
TEST_EQUAL(vec.size(), 7, ());
TEST(TestResult(vec, RoadPos(0, false, 2), 5), ());
TEST(TestResult(vec, RoadPos(0, false, 3), 10), ());
TEST(TestResult(vec, RoadPos(1, true, 1), 5), ());
TEST(TestResult(vec, RoadPos(1, false, 2), 5), ());
TEST(TestResult(vec, RoadPos(2, true, 0), 10), ());
TEST(TestResult(vec, RoadPos(3, false, 0), 15), ());
TEST(TestResult(vec, RoadPos(3, true, 2), 15), ());
}
{
IRoadGraph::TurnsVectorT vec;
src.GetPossibleTurns(RoadPos(1, true, 0), vec);
TEST_EQUAL(vec.size(), 0, ());
}
{
IRoadGraph::TurnsVectorT vec;
src.GetPossibleTurns(RoadPos(1, false, 0), vec);
TEST_EQUAL(vec.size(), 5, ());
TEST(TestResult(vec, RoadPos(1, false, 1), 5), ());
TEST(TestResult(vec, RoadPos(1, false, 2), 10), ());
TEST(TestResult(vec, RoadPos(1, false, 3), 15), ());
TEST(TestResult(vec, RoadPos(0, true, 1), 10), ());
TEST(TestResult(vec, RoadPos(0, false, 2), 10), ());
}
}
UNIT_TEST(RG_Builder_Test2)
{
RoadGraphMockSource graph;
InitRoadGraphMockSourceWithTest2(graph);
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(0, false, 0), vec);
TEST_EQUAL(vec.size(), 8, ());
TEST(TestResult(vec, RoadPos(0, false, 1), 10), ());
TEST(TestResult(vec, RoadPos(0, false, 2), 25), ());
TEST(TestResult(vec, RoadPos(0, false, 3), 35), ());
TEST(TestResult(vec, RoadPos(0, false, 4), 70), ());
TEST(TestResult(vec, RoadPos(2, true, 1), 10), ());
TEST(TestResult(vec, RoadPos(5, false, 0), 35), ());
TEST(TestResult(vec, RoadPos(6, false, 0), 70), ());
TEST(TestResult(vec, RoadPos(4, false, 0), 25), ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(8, true, 0), vec);
double const d = m2::PointD(18, 55).Length(m2::PointD(5, 40));
TEST_EQUAL(vec.size(), 2, ());
TEST(TestResult(vec, RoadPos(1, true, 1), d), ());
TEST(TestResult(vec, RoadPos(8, true, 5), d), ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(2, true, 1), vec);
TEST_EQUAL(vec.size(), 4, ());
TEST(TestResult(vec, RoadPos(3, true, 0), 10), ());
TEST(TestResult(vec, RoadPos(3, false, 1), 10), ());
TEST(TestResult(vec, RoadPos(2, true, 0), 10), ());
TEST(TestResult(vec, RoadPos(8, true, 4), 10 + m2::PointD(10, 10).Length(m2::PointD(12, 25))), ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(3, false, 0), vec);
TEST_EQUAL(vec.size(), 5, ());
TEST(TestResult(vec, RoadPos(3, false, 1), 5), ());
TEST(TestResult(vec, RoadPos(3, false, 2), 65), ());
TEST(TestResult(vec, RoadPos(2, true, 0), 5), ());
TEST(TestResult(vec, RoadPos(6, true, 0), 65), ());
TEST(TestResult(vec, RoadPos(6, false, 1), 65), ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(7, false, 0), vec);
TEST_EQUAL(vec.size(), 0, ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(7, true, 0), vec);
TEST_EQUAL(vec.size(), 1, ());
TEST(TestResult(vec, RoadPos(8, true, 1), 41), ());
}
{
IRoadGraph::TurnsVectorT vec;
graph.GetPossibleTurns(RoadPos(8, true, 3), vec);
double d = m2::PointD(27, 25).Length(m2::PointD(37, 30));
TEST_EQUAL(vec.size(), 8, ());
TEST(TestResult(vec, RoadPos(8, true, 2), d), ());
TEST(TestResult(vec, RoadPos(5, true, 0), d), ());
TEST(TestResult(vec, RoadPos(5, false, 1), d), ());
d += m2::PointD(37, 30).Length(m2::PointD(39, 55));
TEST(TestResult(vec, RoadPos(7, false, 0), d), ());
TEST(TestResult(vec, RoadPos(8, true, 1), d), ());
d += m2::PointD(18, 55).Length(m2::PointD(39, 55));
TEST(TestResult(vec, RoadPos(8, true, 0), d), ());
d += m2::PointD(5, 40).Length(m2::PointD(18, 55));
TEST(TestResult(vec, RoadPos(1, true, 1), d), ());
TEST(TestResult(vec, RoadPos(8, true, 5), d), ());
}
}

View file

@ -1,6 +1,5 @@
#include "../../testing/testing.hpp"
#include "../routing_engine.hpp"
UNIT_TEST(Routing_Smoke)
{

View file

@ -16,15 +16,7 @@ linux*: QT *= core
SOURCES += \
../../testing/testingmain.cpp \
features_road_graph_test.cpp \
routing_smoke.cpp \
road_graph_builder.cpp \
road_graph_builder_test.cpp \
dijkstra_router_test.cpp \
osrm_router_test.cpp \
vehicle_model_test.cpp \
HEADERS += \
road_graph_builder.hpp \
features_road_graph_test.hpp \