Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
198
libs/routing/fake_graph.cpp
Normal file
198
libs/routing/fake_graph.cpp
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
#include "routing/fake_graph.hpp"
|
||||
|
||||
#include "routing/fake_feature_ids.hpp"
|
||||
#include "routing/latlon_with_altitude.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace routing
|
||||
{
|
||||
void FakeGraph::AddStandaloneVertex(Segment const & newSegment, FakeVertex const & newVertex)
|
||||
{
|
||||
m_segmentToVertex[newSegment] = newVertex;
|
||||
m_vertexToSegment[newVertex] = newSegment;
|
||||
}
|
||||
|
||||
void FakeGraph::AddVertex(Segment const & existentSegment, Segment const & newSegment, FakeVertex const & newVertex,
|
||||
bool isOutgoing, bool isPartOfReal, Segment const & real)
|
||||
{
|
||||
AddStandaloneVertex(newSegment, newVertex);
|
||||
auto const & segmentFrom = isOutgoing ? existentSegment : newSegment;
|
||||
auto const & segmentTo = isOutgoing ? newSegment : existentSegment;
|
||||
m_outgoing[segmentFrom].insert(segmentTo);
|
||||
m_ingoing[segmentTo].insert(segmentFrom);
|
||||
if (isPartOfReal)
|
||||
{
|
||||
m_realToFake[real].insert(newSegment);
|
||||
m_fakeToReal[newSegment] = real;
|
||||
}
|
||||
}
|
||||
|
||||
void FakeGraph::AddConnection(Segment const & from, Segment const & to)
|
||||
{
|
||||
ASSERT(m_segmentToVertex.find(from) != m_segmentToVertex.end(), ("Segment", from, "does not exist in fake graph."));
|
||||
ASSERT(m_segmentToVertex.find(to) != m_segmentToVertex.end(), ("Segment", to, "does not exist in fake graph."));
|
||||
m_outgoing[from].insert(to);
|
||||
m_ingoing[to].insert(from);
|
||||
}
|
||||
|
||||
void FakeGraph::Append(FakeGraph const & rhs)
|
||||
{
|
||||
std::map<Segment, FakeVertex> intersection;
|
||||
typename std::map<Segment, FakeVertex>::iterator intersectionIt(intersection.begin());
|
||||
|
||||
std::set_intersection(m_segmentToVertex.begin(), m_segmentToVertex.end(), rhs.m_segmentToVertex.begin(),
|
||||
rhs.m_segmentToVertex.end(), std::inserter(intersection, intersectionIt),
|
||||
base::LessBy(&std::pair<Segment, FakeVertex>::first));
|
||||
|
||||
size_t countEqual = 0;
|
||||
for (auto const & segmentVertexPair : intersection)
|
||||
{
|
||||
auto const it = m_fakeToReal.find(segmentVertexPair.first);
|
||||
if (it == m_fakeToReal.cend() || !FakeFeatureIds::IsGuidesFeature(it->second.GetFeatureId()))
|
||||
countEqual++;
|
||||
}
|
||||
|
||||
CHECK_EQUAL(countEqual, 0, ("Fake segments are not unique."));
|
||||
|
||||
m_segmentToVertex.insert(rhs.m_segmentToVertex.begin(), rhs.m_segmentToVertex.end());
|
||||
m_vertexToSegment.insert(rhs.m_vertexToSegment.begin(), rhs.m_vertexToSegment.end());
|
||||
|
||||
for (auto const & kv : rhs.m_outgoing)
|
||||
m_outgoing[kv.first].insert(kv.second.begin(), kv.second.end());
|
||||
|
||||
for (auto const & kv : rhs.m_ingoing)
|
||||
m_ingoing[kv.first].insert(kv.second.begin(), kv.second.end());
|
||||
|
||||
for (auto const & kv : rhs.m_realToFake)
|
||||
m_realToFake[kv.first].insert(kv.second.begin(), kv.second.end());
|
||||
|
||||
m_fakeToReal.insert(rhs.m_fakeToReal.begin(), rhs.m_fakeToReal.end());
|
||||
}
|
||||
|
||||
FakeVertex const & FakeGraph::GetVertex(Segment const & segment) const
|
||||
{
|
||||
auto const it = m_segmentToVertex.find(segment);
|
||||
CHECK(it != m_segmentToVertex.end(), ("Vertex for invalid fake segment requested."));
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::set<Segment> const & FakeGraph::GetEdges(Segment const & segment, bool isOutgoing) const
|
||||
{
|
||||
auto const & adjacentEdges = isOutgoing ? m_outgoing : m_ingoing;
|
||||
|
||||
auto const it = adjacentEdges.find(segment);
|
||||
if (it != adjacentEdges.end())
|
||||
return it->second;
|
||||
|
||||
return kEmptySet;
|
||||
}
|
||||
|
||||
size_t FakeGraph::GetSize() const
|
||||
{
|
||||
return m_segmentToVertex.size();
|
||||
}
|
||||
|
||||
std::set<Segment> const & FakeGraph::GetFake(Segment const & real) const
|
||||
{
|
||||
auto const it = m_realToFake.find(real);
|
||||
if (it != m_realToFake.end())
|
||||
return it->second;
|
||||
|
||||
return kEmptySet;
|
||||
}
|
||||
|
||||
bool FakeGraph::FindReal(Segment const & fake, Segment & real) const
|
||||
{
|
||||
auto const it = m_fakeToReal.find(fake);
|
||||
if (it == m_fakeToReal.end())
|
||||
return false;
|
||||
|
||||
real = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeGraph::FindSegment(FakeVertex const & vertex, Segment & segment) const
|
||||
{
|
||||
auto const it = m_vertexToSegment.find(vertex);
|
||||
if (it == m_vertexToSegment.end())
|
||||
return false;
|
||||
|
||||
segment = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeGraph::ConnectLoopToGuideSegments(FakeVertex const & loop, Segment const & guidesSegment,
|
||||
LatLonWithAltitude const & guidesSegmentFrom,
|
||||
LatLonWithAltitude const & guidesSegmentTo,
|
||||
std::vector<std::pair<FakeVertex, Segment>> const & partsOfReal)
|
||||
{
|
||||
auto itLoop = m_vertexToSegment.find(loop);
|
||||
CHECK(itLoop != m_vertexToSegment.end(), (loop));
|
||||
|
||||
auto const & loopSegment = itLoop->second;
|
||||
auto const & loopPoint = loop.GetPointTo();
|
||||
|
||||
auto const backwardReal = Segment(guidesSegment.GetMwmId(), guidesSegment.GetFeatureId(),
|
||||
guidesSegment.GetSegmentIdx(), !guidesSegment.IsForward());
|
||||
|
||||
ConnectLoopToExistentPartsOfReal(loop, guidesSegment, backwardReal);
|
||||
|
||||
for (auto & [newVertex, newSegment] : partsOfReal)
|
||||
{
|
||||
auto const [it, inserted] = m_vertexToSegment.emplace(newVertex, newSegment);
|
||||
Segment const & segment = it->second;
|
||||
|
||||
Segment const & directedReal = (newVertex.GetPointFrom() == guidesSegmentTo.GetLatLon() ||
|
||||
newVertex.GetPointTo() == guidesSegmentFrom.GetLatLon())
|
||||
? backwardReal
|
||||
: guidesSegment;
|
||||
|
||||
m_realToFake[directedReal].insert(segment);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
m_fakeToReal[segment] = directedReal;
|
||||
m_segmentToVertex[segment] = newVertex;
|
||||
m_vertexToSegment[newVertex] = segment;
|
||||
}
|
||||
|
||||
CHECK((newVertex.GetPointFrom() == loopPoint || newVertex.GetPointTo() == loopPoint), (newVertex, loopPoint));
|
||||
|
||||
auto const & to = (newVertex.GetPointTo() == loopPoint) ? loopSegment : segment;
|
||||
auto const & from = (newVertex.GetPointFrom() == loopPoint) ? loopSegment : segment;
|
||||
|
||||
m_ingoing[to].insert(from);
|
||||
m_outgoing[from].insert(to);
|
||||
}
|
||||
}
|
||||
|
||||
void FakeGraph::ConnectLoopToExistentPartsOfReal(FakeVertex const & loop, Segment const & guidesSegment,
|
||||
Segment const & directedGuidesSegment)
|
||||
{
|
||||
auto const & loopSegment = m_vertexToSegment[loop];
|
||||
auto const & loopPoint = loop.GetPointTo();
|
||||
|
||||
for (auto const & real : {guidesSegment, directedGuidesSegment})
|
||||
{
|
||||
for (auto const & partOfReal : GetFake(real))
|
||||
{
|
||||
auto const & partOfRealVertex = m_segmentToVertex[partOfReal];
|
||||
if (partOfRealVertex.GetPointTo() == loopPoint)
|
||||
{
|
||||
m_outgoing[partOfReal].insert(loopSegment);
|
||||
m_ingoing[loopSegment].insert(partOfReal);
|
||||
}
|
||||
|
||||
if (partOfRealVertex.GetPointFrom() == loopPoint)
|
||||
{
|
||||
m_outgoing[loopSegment].insert(partOfReal);
|
||||
m_ingoing[partOfReal].insert(loopSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace routing
|
||||
Loading…
Add table
Add a link
Reference in a new issue