forked from organicmaps/organicmaps
[routing] Remove old implementation
This commit is contained in:
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.
|
@ -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"
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include "../search/search_engine.hpp"
|
||||
|
||||
#include "../routing/routing_engine.hpp"
|
||||
|
||||
#include "../storage/storage.hpp"
|
||||
|
||||
#include "../platform/location.hpp"
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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, ());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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), ());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#include "../../testing/testing.hpp"
|
||||
|
||||
#include "../routing_engine.hpp"
|
||||
|
||||
UNIT_TEST(Routing_Smoke)
|
||||
{
|
||||
|
|
|
@ -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 \
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue