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:
Diffstat (limited to 'routing/index_graph_starter.cpp')
-rw-r--r--routing/index_graph_starter.cpp216
1 files changed, 112 insertions, 104 deletions
diff --git a/routing/index_graph_starter.cpp b/routing/index_graph_starter.cpp
index 53f64a7b1b..e58e63eec8 100644
--- a/routing/index_graph_starter.cpp
+++ b/routing/index_graph_starter.cpp
@@ -1,90 +1,27 @@
#include "routing/index_graph_starter.hpp"
+#include "routing/routing_exception.hpp"
+
namespace routing
{
IndexGraphStarter::IndexGraphStarter(IndexGraph const & graph, RoadPoint startPoint,
RoadPoint finishPoint)
: m_graph(graph)
- , m_startPoint(startPoint)
- , m_finishPoint(finishPoint)
- , m_startImplant(graph.GetNumJoints())
- , m_finishImplant(graph.GetNumJoints() + 1)
- , m_startJoint(CalcStartJoint())
- , m_finishJoint(CalcFinishJoint())
-{
-}
-
-Joint::Id IndexGraphStarter::CalcStartJoint() const
+ , m_start(graph, startPoint, graph.GetNumJoints(), graph.GetJointId(startPoint))
+ , m_finish(graph, finishPoint, graph.GetNumJoints() + 1,
+ startPoint == finishPoint ? m_start.m_jointId : graph.GetJointId(finishPoint))
{
- Joint::Id const jointId = m_graph.GetJointId(m_startPoint);
- if (jointId == Joint::kInvalidId)
- return m_startImplant;
-
- return jointId;
}
-Joint::Id IndexGraphStarter::CalcFinishJoint() const
+m2::PointD const & IndexGraphStarter::GetPoint(Joint::Id jointId) const
{
- if (m_startPoint == m_finishPoint)
- return CalcStartJoint();
+ if (jointId == m_start.m_fakeId)
+ return m_graph.GetGeometry().GetPoint(m_start.m_point);
- Joint::Id const jointId = m_graph.GetJointId(m_finishPoint);
- if (jointId == Joint::kInvalidId)
- return m_finishImplant;
+ if (jointId == m_finish.m_fakeId)
+ return m_graph.GetGeometry().GetPoint(m_finish.m_point);
- return jointId;
-}
-
-void IndexGraphStarter::GetEdgesList(Joint::Id jointId, bool isOutgoing,
- vector<JointEdge> & edges) const
-{
- edges.clear();
-
- if (jointId == m_startImplant)
- {
- m_graph.AddNeighboringEdges(m_startPoint, isOutgoing, edges);
-
- if (FinishIsImplant() && m_startPoint.GetFeatureId() == m_finishPoint.GetFeatureId())
- m_graph.AddDirectEdge(m_startPoint.GetFeatureId(), m_startPoint.GetPointId(),
- m_finishPoint.GetPointId(), m_finishJoint, isOutgoing, edges);
-
- return;
- }
-
- if (jointId == m_finishImplant)
- {
- m_graph.AddNeighboringEdges(m_finishPoint, isOutgoing, edges);
-
- if (StartIsImplant() && m_startPoint.GetFeatureId() == m_finishPoint.GetFeatureId())
- m_graph.AddDirectEdge(m_finishPoint.GetFeatureId(), m_finishPoint.GetPointId(),
- m_startPoint.GetPointId(), m_startJoint, isOutgoing, edges);
-
- return;
- }
-
- m_graph.GetEdgesList(jointId, isOutgoing, edges);
-
- if (StartIsImplant() && m_graph.JointLaysOnRoad(jointId, m_startPoint.GetFeatureId()))
- {
- vector<JointEdge> startEdges;
- m_graph.AddNeighboringEdges(m_startPoint, !isOutgoing, startEdges);
- for (JointEdge const & edge : startEdges)
- {
- if (edge.GetTarget() == jointId)
- edges.emplace_back(m_startJoint, edge.GetWeight());
- }
- }
-
- if (FinishIsImplant() && m_graph.JointLaysOnRoad(jointId, m_finishPoint.GetFeatureId()))
- {
- vector<JointEdge> finishEdges;
- m_graph.AddNeighboringEdges(m_finishPoint, !isOutgoing, finishEdges);
- for (JointEdge const & edge : finishEdges)
- {
- if (edge.GetTarget() == jointId)
- edges.emplace_back(m_finishJoint, edge.GetWeight());
- }
- }
+ return m_graph.GetPoint(jointId);
}
void IndexGraphStarter::RedressRoute(vector<Joint::Id> const & route,
@@ -93,7 +30,7 @@ void IndexGraphStarter::RedressRoute(vector<Joint::Id> const & route,
if (route.size() < 2)
{
if (route.size() == 1)
- roadPoints.emplace_back(m_startPoint);
+ roadPoints.emplace_back(m_start.m_point);
return;
}
@@ -126,7 +63,7 @@ void IndexGraphStarter::RedressRoute(vector<Joint::Id> const & route,
}
else
{
- MYTHROW(RootException,
+ MYTHROW(RoutingException,
("Wrong equality pointFrom = pointTo =", pointFrom, ", featureId = ", featureId));
}
@@ -134,6 +71,60 @@ void IndexGraphStarter::RedressRoute(vector<Joint::Id> const & route,
}
}
+void IndexGraphStarter::GetEdgesList(Joint::Id jointId, bool isOutgoing,
+ vector<JointEdge> & edges) const
+{
+ edges.clear();
+
+ if (jointId == m_start.m_fakeId)
+ {
+ GetFakeEdges(m_start, m_finish, isOutgoing, edges);
+ return;
+ }
+
+ if (jointId == m_finish.m_fakeId)
+ {
+ GetFakeEdges(m_finish, m_start, isOutgoing, edges);
+ return;
+ }
+
+ m_graph.GetEdgesList(jointId, isOutgoing, edges);
+ GetArrivalFakeEdges(jointId, m_start, isOutgoing, edges);
+ GetArrivalFakeEdges(jointId, m_finish, isOutgoing, edges);
+}
+
+void IndexGraphStarter::GetFakeEdges(IndexGraphStarter::FakeJoint const & from,
+ IndexGraphStarter::FakeJoint const & to, bool isOutgoing,
+ vector<JointEdge> & edges) const
+{
+ m_graph.GetNeighboringEdges(from.m_point, isOutgoing, edges);
+
+ if (to.IsFake() && from.m_point.GetFeatureId() == to.m_point.GetFeatureId())
+ {
+ m_graph.GetDirectedEdge(from.m_point.GetFeatureId(), from.m_point.GetPointId(),
+ to.m_point.GetPointId(), to.m_jointId, isOutgoing, edges);
+ }
+}
+
+inline void IndexGraphStarter::GetArrivalFakeEdges(Joint::Id jointId,
+ IndexGraphStarter::FakeJoint const & fakeJoint,
+ bool isOutgoing, vector<JointEdge> & edges) const
+{
+ if (!fakeJoint.IsFake())
+ return;
+
+ if (!m_graph.JointLiesOnRoad(jointId, fakeJoint.m_point.GetFeatureId()))
+ return;
+
+ vector<JointEdge> startEdges;
+ m_graph.GetNeighboringEdges(fakeJoint.m_point, !isOutgoing, startEdges);
+ for (JointEdge const & edge : startEdges)
+ {
+ if (edge.GetTarget() == jointId)
+ edges.emplace_back(fakeJoint.m_jointId, edge.GetWeight());
+ }
+}
+
void IndexGraphStarter::FindPointsWithCommonFeature(Joint::Id jointId0, Joint::Id jointId1,
RoadPoint & result0, RoadPoint & result1) const
{
@@ -142,46 +133,63 @@ void IndexGraphStarter::FindPointsWithCommonFeature(Joint::Id jointId0, Joint::I
ForEachPoint(jointId0, [&](RoadPoint const & rp0) {
ForEachPoint(jointId1, [&](RoadPoint const & rp1) {
- if (rp0.GetFeatureId() == rp1.GetFeatureId())
- {
- RoadGeometry const & road = m_graph.GetGeometry().GetRoad(rp0.GetFeatureId());
- if (!road.IsRoad())
- return;
+ if (rp0.GetFeatureId() != rp1.GetFeatureId())
+ return;
+
+ RoadGeometry const & road = m_graph.GetGeometry().GetRoad(rp0.GetFeatureId());
+ if (!road.IsRoad())
+ return;
- if (road.IsOneWay() && rp0.GetPointId() > rp1.GetPointId())
- return;
+ if (road.IsOneWay() && rp0.GetPointId() > rp1.GetPointId())
+ return;
- if (found)
+ if (found)
+ {
+ if (minWeight < 0.0)
{
- if (minWeight < 0.0)
- {
- // CalcEdgesWeight is very expensive.
- // So calculate it only if second common feature found.
- RoadGeometry const & prevRoad = m_graph.GetGeometry().GetRoad(result0.GetFeatureId());
- minWeight = m_graph.GetEstimator().CalcEdgesWeight(prevRoad, result0.GetPointId(),
- result1.GetPointId());
- }
-
- double const weight =
- m_graph.GetEstimator().CalcEdgesWeight(road, rp0.GetPointId(), rp1.GetPointId());
- if (weight < minWeight)
- {
- minWeight = weight;
- result0 = rp0;
- result1 = rp1;
- }
+ // CalcEdgesWeight is very expensive.
+ // So calculate it only if second common feature found.
+ RoadGeometry const & prevRoad = m_graph.GetGeometry().GetRoad(result0.GetFeatureId());
+ minWeight = m_graph.GetEstimator().CalcEdgesWeight(prevRoad, result0.GetPointId(),
+ result1.GetPointId());
}
- else
+
+ double const weight =
+ m_graph.GetEstimator().CalcEdgesWeight(road, rp0.GetPointId(), rp1.GetPointId());
+ if (weight < minWeight)
{
+ minWeight = weight;
result0 = rp0;
result1 = rp1;
- found = true;
}
}
+ else
+ {
+ result0 = rp0;
+ result1 = rp1;
+ found = true;
+ }
});
});
if (!found)
- MYTHROW(RootException, ("Can't find common feature for joints", jointId0, jointId1));
+ MYTHROW(RoutingException, ("Can't find common feature for joints", jointId0, jointId1));
+}
+
+// IndexGraphStarter::FakeJoint --------------------------------------------------------------------
+
+IndexGraphStarter::FakeJoint::FakeJoint(IndexGraph const & graph, RoadPoint point, Joint::Id fakeId,
+ Joint::Id suggestedId)
+ : m_point(point), m_fakeId(fakeId), m_jointId(CalcJointId(graph, suggestedId))
+{
+}
+
+Joint::Id IndexGraphStarter::FakeJoint::CalcJointId(IndexGraph const & graph,
+ Joint::Id suggestedId) const
+{
+ if (suggestedId == Joint::kInvalidId)
+ return m_fakeId;
+
+ return suggestedId;
}
} // namespace routing