osrm-backend/src/extractor/restriction_compressor.cpp

194 lines
6.8 KiB
C++
Raw Normal View History

#include "extractor/restriction_compressor.hpp"
#include "extractor/restriction.hpp"
#include <algorithm>
#include <boost/assert.hpp>
#include <utility>
namespace osrm
{
namespace extractor
{
RestrictionCompressor::RestrictionCompressor(
std::vector<TurnRestriction> &restrictions,
2018-02-09 13:32:09 -05:00
std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides)
{
2017-07-27 05:42:13 -04:00
// add a node restriction ptr to the starts/ends maps, needs to be a reference!
auto index = [&](auto &element) {
2017-07-27 05:42:13 -04:00
starts.insert(std::make_pair(element.from, &element));
ends.insert(std::make_pair(element.to, &element));
};
// !needs to be reference, so we can get the correct address
2017-07-27 05:42:13 -04:00
const auto index_starts_and_ends = [&](auto &restriction) {
if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
{
auto &way_restriction = restriction.AsWayRestriction();
index(way_restriction.in_restriction);
index(way_restriction.out_restriction);
}
else
{
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
auto &node_restriction = restriction.AsNodeRestriction();
index(node_restriction);
}
};
2017-07-27 05:42:13 -04:00
// add all restrictions as their respective startend pointers
std::for_each(restrictions.begin(), restrictions.end(), index_starts_and_ends);
std::for_each(conditional_turn_restrictions.begin(),
conditional_turn_restrictions.end(),
index_starts_and_ends);
2018-02-09 13:32:09 -05:00
auto index_maneuver = [&](auto &maneuver) {
for (auto &turn : maneuver.turn_sequence)
{
maneuver_starts.insert(std::make_pair(turn.from, &turn));
maneuver_ends.insert(std::make_pair(turn.to, &turn));
}
};
// !needs to be reference, so we can get the correct address
std::for_each(maneuver_overrides.begin(), maneuver_overrides.end(), [&](auto &maneuver) {
index_maneuver(maneuver);
});
}
void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const NodeID to)
{
2018-02-09 13:32:09 -05:00
// handle turn restrictions
2017-07-27 05:42:13 -04:00
// extract all startptrs and move them from via to from.
auto all_starts_range = starts.equal_range(via);
std::vector<NodeRestriction *> start_ptrs;
std::transform(all_starts_range.first,
all_starts_range.second,
std::back_inserter(start_ptrs),
[](const auto pair) { return pair.second; });
const auto update_start = [&](auto ptr) {
// ____ | from - p.from | via - p.via | to - p.to | ____
BOOST_ASSERT(ptr->from == via);
if (ptr->via == to)
{
ptr->from = from;
}
// ____ | to - p.from | via - p.via | from - p.to | ____
else
{
BOOST_ASSERT(ptr->via == from);
ptr->from = to;
}
};
2017-07-27 05:42:13 -04:00
std::for_each(start_ptrs.begin(), start_ptrs.end(), update_start);
// update the ptrs in our mapping
2017-07-27 05:42:13 -04:00
starts.erase(via);
2017-07-27 05:42:13 -04:00
const auto reinsert_start = [&](auto ptr) { starts.insert(std::make_pair(ptr->from, ptr)); };
std::for_each(start_ptrs.begin(), start_ptrs.end(), reinsert_start);
2017-07-27 05:42:13 -04:00
// extract all end ptrs and move them from via to to
auto all_ends_range = ends.equal_range(via);
std::vector<NodeRestriction *> end_ptrs;
std::transform(all_ends_range.first,
all_ends_range.second,
std::back_inserter(end_ptrs),
[](const auto pair) { return pair.second; });
const auto update_end = [&](auto ptr) {
BOOST_ASSERT(ptr->to == via);
// p.from | ____ - p.via | from - p.to | via - ____ | to
if (ptr->via == from)
{
ptr->to = to;
}
// p.from | ____ - p.via | to - p.to | via - ____ | from
else
{
BOOST_ASSERT(ptr->via == to);
ptr->to = from;
}
};
2017-07-27 05:42:13 -04:00
std::for_each(end_ptrs.begin(), end_ptrs.end(), update_end);
2017-07-27 05:42:13 -04:00
// update end ptrs in mapping
ends.erase(via);
2017-07-27 05:42:13 -04:00
const auto reinsert_end = [&](auto ptr) { ends.insert(std::make_pair(ptr->to, ptr)); };
std::for_each(end_ptrs.begin(), end_ptrs.end(), reinsert_end);
2018-02-09 13:32:09 -05:00
/**********************************************************************************************/
// handle maneuver overrides from nodes
// extract all startptrs
auto maneuver_starts_range = maneuver_starts.equal_range(via);
std::vector<NodeBasedTurn *> mnv_start_ptrs;
std::transform(maneuver_starts_range.first,
maneuver_starts_range.second,
std::back_inserter(mnv_start_ptrs),
[](const auto pair) { return pair.second; });
// update from nodes of maneuver overrides
const auto update_start_mnv = [&](auto ptr) {
// ____ | from - p.from | via - p.via | to - p.to | ____
BOOST_ASSERT(ptr->from == via);
if (ptr->via == to)
{
ptr->from = from;
}
// ____ | to - p.from | via - p.via | from - p.to | ____
else
{
BOOST_ASSERT(ptr->via == from);
ptr->from = to;
}
};
std::for_each(mnv_start_ptrs.begin(), mnv_start_ptrs.end(), update_start_mnv);
// update the ptrs in our mapping
maneuver_starts.erase(via);
const auto reinsert_start_mnv = [&](auto ptr) {
maneuver_starts.insert(std::make_pair(ptr->from, ptr));
};
std::for_each(mnv_start_ptrs.begin(), mnv_start_ptrs.end(), reinsert_start_mnv);
/**********************************************************************************************/
// handle maneuver override to nodes
// extract all end ptrs and move them from via to to
auto maneuver_ends_range = maneuver_ends.equal_range(via);
std::vector<NodeBasedTurn *> mnv_end_ptrs;
std::transform(maneuver_ends_range.first,
maneuver_ends_range.second,
std::back_inserter(mnv_end_ptrs),
[](const auto pair) { return pair.second; });
const auto update_end_mnv = [&](auto ptr) {
BOOST_ASSERT(ptr->to == via);
// p.from | ____ - p.via | from - p.to | via - ____ | to
if (ptr->via == from)
{
ptr->to = to;
}
// p.from | ____ - p.via | to - p.to | via - ____ | from
else
{
BOOST_ASSERT(ptr->via == to);
ptr->to = from;
}
};
std::for_each(mnv_end_ptrs.begin(), mnv_end_ptrs.end(), update_end_mnv);
// update end ptrs in mapping
maneuver_ends.erase(via);
const auto reinsert_end_mnvs = [&](auto ptr) {
maneuver_ends.insert(std::make_pair(ptr->to, ptr));
};
std::for_each(mnv_end_ptrs.begin(), mnv_end_ptrs.end(), reinsert_end_mnvs);
}
} // namespace extractor
} // namespace osrm