Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Koronchik <denis@mapswithme.com>2014-11-26 18:24:34 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:34:47 +0300
commit49ff59a35b064574e9e6657a447ae33a3ec2deee (patch)
treeac65de3391aabdd7244c948fb6b98d8c8e41b9a0 /routing
parent300497fc53e3eb5d8af27d41c051f03d4cbb5cae (diff)
Improve turns calculation
Diffstat (limited to 'routing')
-rw-r--r--routing/osrm_data_facade.hpp6
-rw-r--r--routing/osrm_router.cpp117
-rw-r--r--routing/osrm_router.hpp32
3 files changed, 141 insertions, 14 deletions
diff --git a/routing/osrm_data_facade.hpp b/routing/osrm_data_facade.hpp
index 6c166d1e57..f70d8eeb0d 100644
--- a/routing/osrm_data_facade.hpp
+++ b/routing/osrm_data_facade.hpp
@@ -111,11 +111,9 @@ public:
return res;
}
- //! TODO: Remove static variable
- EdgeDataT & GetEdgeData(const EdgeID e, NodeID node)
+ EdgeDataT GetEdgeData(const EdgeID e, NodeID node)
{
- static EdgeDataT res;
-
+ EdgeDataT res;
res.shortcut = m_shortcuts[e];
res.id = res.shortcut ? (node - bits::ZigZagDecode(m_edgeId[m_shortcuts.rank(e)])) : 0;
diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp
index f1e1dbd0d3..9a0a2ef363 100644
--- a/routing/osrm_router.cpp
+++ b/routing/osrm_router.cpp
@@ -684,9 +684,9 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
return NoError;
}
-m2::PointD OsrmRouter::GetPointForTurnAngle(const OsrmFtSegMapping::FtSeg &seg,
- const FeatureType &ft, const m2::PointD &turnPnt,
- size_t (*GetPndInd)(const size_t, const size_t, const size_t)) const
+m2::PointD OsrmRouter::GetPointForTurnAngle(OsrmFtSegMapping::FtSeg const &seg,
+ FeatureType const &ft, m2::PointD const &turnPnt,
+ size_t (*GetPndInd)(const size_t, const size_t, const size_t)) const
{
const size_t maxPntsNum = 5;
const double maxDistMeter = 250.f;
@@ -698,10 +698,12 @@ m2::PointD OsrmRouter::GetPointForTurnAngle(const OsrmFtSegMapping::FtSeg &seg,
("GetPntForTurnAngle(). The start and the end pnt of a segment are too far from each other"));
const size_t usedFtPntNum = min(maxPntsNum, segDist);
- for(size_t i=1; i<= usedFtPntNum; ++i){
+ for (size_t i = 1; i <= usedFtPntNum; ++i)
+ {
nextPnt = ft.GetPoint(GetPndInd(seg.m_pointStart, seg.m_pointEnd, i));
curDist += MercatorBounds::DistanceOnEarth(pnt, nextPnt);
- if(curDist > maxDistMeter){
+ if (curDist > maxDistMeter)
+ {
return nextPnt;
}
pnt = nextPnt;
@@ -709,6 +711,93 @@ m2::PointD OsrmRouter::GetPointForTurnAngle(const OsrmFtSegMapping::FtSeg &seg,
return nextPnt;
}
+NodeID OsrmRouter::GetTurnTargetNode(NodeID src, NodeID trg, QueryEdge::EdgeData const & edgeData)
+{
+ ASSERT_NOT_EQUAL(src, SPECIAL_NODEID, ());
+ ASSERT_NOT_EQUAL(trg, SPECIAL_NODEID, ());
+ if (!edgeData.shortcut)
+ return trg;
+
+ ASSERT_LESS(edgeData.id, m_dataFacade.GetNumberOfNodes(), ());
+ EdgeID edge = SPECIAL_EDGEID;
+ QueryEdge::EdgeData d;
+ for (EdgeID e : m_dataFacade.GetAdjacentEdgeRange(edgeData.id))
+ {
+ if (m_dataFacade.GetTarget(e) == src )
+ {
+ d = m_dataFacade.GetEdgeData(e, edgeData.id);
+ if (d.backward)
+ {
+ edge = e;
+ break;
+ }
+ }
+ }
+
+ if (edge == SPECIAL_EDGEID)
+ {
+ for (EdgeID e : m_dataFacade.GetAdjacentEdgeRange(src))
+ {
+ if (m_dataFacade.GetTarget(e) == edgeData.id)
+ {
+ d = m_dataFacade.GetEdgeData(e, src);
+ if (d.forward)
+ {
+ edge = e;
+ break;
+ }
+ }
+ }
+ }
+ ASSERT_NOT_EQUAL(edge, SPECIAL_EDGEID, ());
+
+ if (d.shortcut)
+ return GetTurnTargetNode(src, edgeData.id, d);
+
+ return edgeData.id;
+}
+
+void OsrmRouter::GetPossibleTurns(NodeID node,
+ m2::PointD const & p1,
+ m2::PointD const & p,
+ uint32_t mwmId,
+ OsrmRouter::TurnCandidatesT & candidates)
+{
+
+ for (EdgeID e : m_dataFacade.GetAdjacentEdgeRange(node))
+ {
+ QueryEdge::EdgeData const data = m_dataFacade.GetEdgeData(e, node);
+ if (!data.forward)
+ continue;
+
+ NodeID trg = GetTurnTargetNode(node, m_dataFacade.GetTarget(e), data);
+ ASSERT_NOT_EQUAL(trg, SPECIAL_NODEID, ());
+
+ auto const range = m_mapping.GetSegmentsRange(trg);
+ OsrmFtSegMapping::FtSeg seg;
+ m_mapping.GetSegmentByIndex(range.first, seg);
+
+ FeatureType ft;
+ Index::FeaturesLoaderGuard loader(*m_pIndex, mwmId);
+ loader.GetFeature(seg.m_fid, ft);
+ ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
+
+ m2::PointD const p2 = ft.GetPoint(seg.m_pointStart < seg.m_pointEnd ? seg.m_pointStart + 1 : seg.m_pointStart - 1);
+ ASSERT_EQUAL(p, ft.GetPoint(seg.m_pointStart), ());
+
+ double a = my::RadToDeg(ang::AngleTo(p, p2) - ang::AngleTo(p, p1));
+ while (a < 0)
+ a += 360;
+
+ candidates.emplace_back(a, trg);
+ }
+
+ sort(candidates.begin(), candidates.end(), [](TurnCandidate const & t1, TurnCandidate const & t2) { return t1.m_angle < t2.m_angle; });
+ auto last = unique(candidates.begin(), candidates.end());
+ candidates.erase(last, candidates.end());
+}
+
+
void OsrmRouter::GetTurnDirection(PathData const & node1,
PathData const & node2,
uint32_t mwmId, Route::TurnItem & turn)
@@ -737,11 +826,13 @@ void OsrmRouter::GetTurnDirection(PathData const & node1,
m2::PointD p = ft1.GetPoint(seg1.m_pointEnd);
m2::PointD p1 = GetPointForTurnAngle(seg1, ft1, p,
- [](const size_t start, const size_t end, const size_t i){
+ [](const size_t start, const size_t end, const size_t i)
+ {
return end > start ? end - i : end + i;
});
m2::PointD p2 = GetPointForTurnAngle(seg2, ft2, p,
- [](const size_t start, const size_t end, const size_t i){
+ [](const size_t start, const size_t end, const size_t i)
+ {
return end > start ? start + i : start - i;
});
@@ -749,6 +840,18 @@ void OsrmRouter::GetTurnDirection(PathData const & node1,
while (a < 0)
a += 360;
+#ifdef _DEBUG
+ TurnCandidatesT nodes;
+ GetPossibleTurns(node1.node, p1, p, mwmId, nodes);
+
+ LOG(LDEBUG, ("Possible turns: ", nodes.size()));
+ for (size_t i = 0; i < nodes.size(); ++i)
+ {
+ TurnCandidate const &t = nodes[i];
+ LOG(LDEBUG, ("Angle:", t.m_angle, "Node:", t.m_node));
+ }
+#endif
+
turn.m_turn = turns::NoTurn;
if (a >= 23 && a < 67)
turn.m_turn = turns::TurnSharpRight;
diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp
index 942b806132..95c56aba0f 100644
--- a/routing/osrm_router.hpp
+++ b/routing/osrm_router.hpp
@@ -37,6 +37,24 @@ public:
};
typedef vector<FeatureGraphNode> FeatureGraphNodeVecT;
+ struct TurnCandidate
+ {
+ double m_angle;
+ NodeID m_node;
+
+ TurnCandidate(double a, NodeID n)
+ : m_angle(a), m_node(n)
+ {
+ }
+
+ bool operator == (TurnCandidate const & other) const
+ {
+ return m_node == other.m_node;
+ }
+ };
+ typedef vector<TurnCandidate> TurnCandidatesT;
+
+
OsrmRouter(Index const * index, CountryFileFnT const & fn);
virtual string GetName() const;
@@ -53,13 +71,21 @@ protected:
void CalculateRouteAsync(ReadyCallback const & callback);
ResultCode CalculateRouteImpl(m2::PointD const & startPt, m2::PointD const & startDr, m2::PointD const & finalPt, Route & route);
+private:
+ NodeID GetTurnTargetNode(NodeID src, NodeID trg, QueryEdge::EdgeData const & edgeData);
+
+ void GetPossibleTurns(NodeID node,
+ m2::PointD const & p1,
+ m2::PointD const & p,
+ uint32_t mwmId,
+ TurnCandidatesT & candidates);
+
void GetTurnDirection(PathData const & node1,
PathData const & node2,
uint32_t mwmId, Route::TurnItem & turn);
void FixupTurns(vector<m2::PointD> const & points, Route::TurnsT & turnsDir) const;
-private:
- m2::PointD GetPointForTurnAngle(const OsrmFtSegMapping::FtSeg &seg,
- const FeatureType &ft, const m2::PointD &turnPnt,
+ m2::PointD GetPointForTurnAngle(OsrmFtSegMapping::FtSeg const &seg,
+ FeatureType const &ft, m2::PointD const &turnPnt,
size_t (*GetPndInd)(const size_t, const size_t, const size_t)) const;
Index const * m_pIndex;