mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-23 22:53:43 +00:00
committed by
Konstantin Pastbin
parent
c9cbb64f12
commit
76ffc99abd
147
libs/routing/index_road_graph.cpp
Normal file
147
libs/routing/index_road_graph.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "routing/index_road_graph.hpp"
|
||||
|
||||
#include "routing/data_source.hpp"
|
||||
#include "routing/fake_feature_ids.hpp"
|
||||
#include "routing/index_graph_starter.hpp"
|
||||
#include "routing/latlon_with_altitude.hpp"
|
||||
#include "routing/routing_exceptions.hpp"
|
||||
#include "routing/transit_graph.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
IndexRoadGraph::IndexRoadGraph(IndexGraphStarter & starter, std::vector<Segment> const & segments,
|
||||
std::vector<geometry::PointWithAltitude> const & junctions,
|
||||
MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource), m_starter(starter), m_segments(segments)
|
||||
{
|
||||
// j0 j1 j2 j3
|
||||
// *--s0--*--s1--*--s2--*
|
||||
CHECK_EQUAL(segments.size() + 1, junctions.size(), ());
|
||||
|
||||
for (size_t i = 0; i < junctions.size(); ++i)
|
||||
{
|
||||
geometry::PointWithAltitude const & junction = junctions[i];
|
||||
if (i > 0)
|
||||
m_endToSegment[junction].push_back(segments[i - 1]);
|
||||
if (i < segments.size())
|
||||
m_beginToSegment[junction].push_back(segments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetOutgoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const
|
||||
{
|
||||
GetEdges(junction, true, edges);
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetIngoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const
|
||||
{
|
||||
GetEdges(junction, false, edges);
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetEdgeTypes(Edge const & edge, feature::TypesHolder & types) const
|
||||
{
|
||||
if (edge.IsFake())
|
||||
{
|
||||
types = feature::TypesHolder(feature::GeomType::Line);
|
||||
return;
|
||||
}
|
||||
|
||||
FeatureID const featureId = edge.GetFeatureId();
|
||||
if (FakeFeatureIds::IsGuidesFeature(featureId.m_index))
|
||||
{
|
||||
types = feature::TypesHolder(feature::GeomType::Line);
|
||||
return;
|
||||
}
|
||||
|
||||
auto ft = m_dataSource.GetFeature(featureId);
|
||||
if (!ft)
|
||||
{
|
||||
LOG(LERROR, ("Can't load types for feature", featureId));
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_EQUAL(ft->GetGeomType(), feature::GeomType::Line, ());
|
||||
types = feature::TypesHolder(*ft);
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const
|
||||
{
|
||||
types = feature::TypesHolder();
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetRouteEdges(EdgeVector & edges) const
|
||||
{
|
||||
edges.clear();
|
||||
edges.reserve(m_segments.size());
|
||||
|
||||
for (Segment const & segment : m_segments)
|
||||
{
|
||||
auto const & junctionFrom =
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude();
|
||||
auto const & junctionTo =
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude();
|
||||
|
||||
if (IndexGraphStarter::IsFakeSegment(segment) || TransitGraph::IsTransitSegment(segment))
|
||||
{
|
||||
Segment real = segment;
|
||||
if (m_starter.ConvertToReal(real))
|
||||
{
|
||||
edges.push_back(Edge::MakeFakeWithRealPart({ m_dataSource.GetMwmId(real.GetMwmId()), real.GetFeatureId() },
|
||||
segment.GetSegmentIdx(),
|
||||
real.IsForward(), real.GetSegmentIdx(),
|
||||
junctionFrom, junctionTo));
|
||||
}
|
||||
else
|
||||
{
|
||||
edges.push_back(Edge::MakeFake(junctionFrom, junctionTo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
segment.IsForward(), segment.GetSegmentIdx(), junctionFrom, junctionTo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetEdges(geometry::PointWithAltitude const & junction, bool isOutgoing,
|
||||
EdgeListT & edges) const
|
||||
{
|
||||
edges.clear();
|
||||
|
||||
for (Segment const & segment : GetSegments(junction, isOutgoing))
|
||||
{
|
||||
IndexGraphStarter::EdgeListT tmpEdges;
|
||||
m_starter.GetEdgesList(segment, isOutgoing, tmpEdges);
|
||||
|
||||
for (SegmentEdge const & segmentEdge : tmpEdges)
|
||||
{
|
||||
Segment const & segment = segmentEdge.GetTarget();
|
||||
if (IndexGraphStarter::IsFakeSegment(segment))
|
||||
continue;
|
||||
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
segment.IsForward(), segment.GetSegmentIdx(),
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude(),
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IndexRoadGraph::SegmentListT const & IndexRoadGraph::GetSegments(
|
||||
geometry::PointWithAltitude const & junction, bool isOutgoing) const
|
||||
{
|
||||
auto const & junctionToSegment = isOutgoing ? m_endToSegment : m_beginToSegment;
|
||||
|
||||
auto const it = junctionToSegment.find(junction);
|
||||
CHECK(it != junctionToSegment.cend(),
|
||||
("junctionToSegment doesn't contain", junction, ", isOutgoing =", isOutgoing));
|
||||
return it->second;
|
||||
}
|
||||
} // namespace routing
|
||||
Reference in New Issue
Block a user