Add flag to edges that transition into restricted areas.

This commit is contained in:
Daniel Patterson 2019-01-03 11:59:28 -08:00
parent 2c78d862a3
commit da4f700f80
No known key found for this signature in database
GPG Key ID: 19C12BE1725A028B
10 changed files with 245 additions and 21 deletions

View File

@ -12,27 +12,30 @@ namespace contractor
struct ContractorEdgeData struct ContractorEdgeData
{ {
ContractorEdgeData() ContractorEdgeData()
: weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0), : weight(0), duration(0), distance(0), id(0), maneuver_restricted(false), originalEdges(0),
backward(0) shortcut(0), forward(0), backward(0)
{ {
} }
ContractorEdgeData(EdgeWeight weight, ContractorEdgeData(EdgeWeight weight,
EdgeWeight duration, EdgeDuration duration,
EdgeDistance distance, EdgeDistance distance,
unsigned original_edges, unsigned original_edges,
unsigned id, unsigned id,
bool maneuver_restricted,
bool shortcut, bool shortcut,
bool forward, bool forward,
bool backward) bool backward)
: weight(weight), duration(duration), distance(distance), id(id), : weight(weight), duration(duration), distance(distance), id(id),
maneuver_restricted(maneuver_restricted),
originalEdges(std::min((1u << 29) - 1u, original_edges)), shortcut(shortcut), originalEdges(std::min((1u << 29) - 1u, original_edges)), shortcut(shortcut),
forward(forward), backward(backward) forward(forward), backward(backward)
{ {
} }
EdgeWeight weight; EdgeWeight weight;
EdgeWeight duration; EdgeDuration duration;
EdgeDistance distance; EdgeDistance distance;
unsigned id; unsigned id : 31;
bool maneuver_restricted : 1;
unsigned originalEdges : 29; unsigned originalEdges : 29;
bool shortcut : 1; bool shortcut : 1;
bool forward : 1; bool forward : 1;

View File

@ -44,6 +44,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
input_edge.data.distance, input_edge.data.distance,
1, 1,
input_edge.data.turn_id, input_edge.data.turn_id,
input_edge.data.maneuver_restricted,
false, false,
input_edge.data.forward ? true : false, input_edge.data.forward ? true : false,
input_edge.data.backward ? true : false); input_edge.data.backward ? true : false);
@ -55,6 +56,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
input_edge.data.distance, input_edge.data.distance,
1, 1,
input_edge.data.turn_id, input_edge.data.turn_id,
input_edge.data.maneuver_restricted, // Note: inverted
false, false,
input_edge.data.backward ? true : false, input_edge.data.backward ? true : false,
input_edge.data.forward ? true : false); input_edge.data.forward ? true : false);
@ -85,6 +87,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT; forward_edge.data.weight = reverse_edge.data.weight = INVALID_EDGE_WEIGHT;
forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION; forward_edge.data.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
forward_edge.data.distance = reverse_edge.data.distance = MAXIMAL_EDGE_DISTANCE; forward_edge.data.distance = reverse_edge.data.distance = MAXIMAL_EDGE_DISTANCE;
forward_edge.data.maneuver_restricted = reverse_edge.data.maneuver_restricted = false;
// remove parallel edges // remove parallel edges
while (i < edges.size() && edges[i].source == source && edges[i].target == target) while (i < edges.size() && edges[i].source == source && edges[i].target == target)
{ {
@ -95,6 +98,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
std::min(edges[i].data.duration, forward_edge.data.duration); std::min(edges[i].data.duration, forward_edge.data.duration);
forward_edge.data.distance = forward_edge.data.distance =
std::min(edges[i].data.distance, forward_edge.data.distance); std::min(edges[i].data.distance, forward_edge.data.distance);
forward_edge.data.maneuver_restricted = edges[i].data.maneuver_restricted;
} }
if (edges[i].data.backward) if (edges[i].data.backward)
{ {
@ -103,11 +107,13 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
std::min(edges[i].data.duration, reverse_edge.data.duration); std::min(edges[i].data.duration, reverse_edge.data.duration);
reverse_edge.data.distance = reverse_edge.data.distance =
std::min(edges[i].data.distance, reverse_edge.data.distance); std::min(edges[i].data.distance, reverse_edge.data.distance);
reverse_edge.data.maneuver_restricted = edges[i].data.maneuver_restricted;
} }
++i; ++i;
} }
// merge edges (s,t) and (t,s) into bidirectional edge // merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.weight == reverse_edge.data.weight) if (forward_edge.data.weight == reverse_edge.data.weight &&
forward_edge.data.maneuver_restricted == reverse_edge.data.maneuver_restricted)
{ {
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT) if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
{ {
@ -165,6 +171,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
"edge id invalid"); "edge id invalid");
new_edge.data.forward = data.forward; new_edge.data.forward = data.forward;
new_edge.data.backward = data.backward; new_edge.data.backward = data.backward;
new_edge.data.maneuver_restricted = data.maneuver_restricted;
} }
} }
BOOST_ASSERT(edge_index == edges.size()); BOOST_ASSERT(edge_index == edges.size());

View File

@ -17,8 +17,8 @@ struct QueryEdge
struct EdgeData struct EdgeData
{ {
explicit EdgeData() explicit EdgeData()
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false), : turn_id(0), shortcut(false), maneuver_restricted(false), weight(0), duration(0),
distance(0) forward(false), backward(false), distance(0)
{ {
} }
@ -28,9 +28,11 @@ struct QueryEdge
const EdgeWeight duration, const EdgeWeight duration,
const EdgeDistance distance, const EdgeDistance distance,
const bool forward, const bool forward,
const bool backward) const bool backward,
: turn_id(turn_id), shortcut(shortcut), weight(weight), duration(duration), const bool maneuver_restricted)
forward(forward), backward(backward), distance(distance) : turn_id(turn_id), shortcut(shortcut), maneuver_restricted(maneuver_restricted),
weight(weight), duration(duration), forward(forward), backward(backward),
distance(distance)
{ {
} }
@ -43,12 +45,14 @@ struct QueryEdge
forward = other.forward; forward = other.forward;
backward = other.backward; backward = other.backward;
distance = other.distance; distance = other.distance;
maneuver_restricted = other.maneuver_restricted;
} }
// this ID is either the middle node of the shortcut, or the ID of the edge based node (node // this ID is either the middle node of the shortcut, or the ID of the edge based node (node
// based edge) storing the appropriate data. If `shortcut` is set to true, we get the middle // based edge) storing the appropriate data. If `shortcut` is set to true, we get the middle
// node. Otherwise we see the edge based node to access node data. // node. Otherwise we see the edge based node to access node data.
NodeID turn_id : 31; NodeID turn_id : 30;
bool shortcut : 1; bool shortcut : 1;
bool maneuver_restricted : 1;
EdgeWeight weight; EdgeWeight weight;
EdgeWeight duration : 30; EdgeWeight duration : 30;
std::uint32_t forward : 1; std::uint32_t forward : 1;
@ -74,7 +78,8 @@ struct QueryEdge
data.weight == right.data.weight && data.duration == right.data.duration && data.weight == right.data.weight && data.duration == right.data.duration &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.shortcut == right.data.shortcut && data.forward == right.data.forward &&
data.backward == right.data.backward && data.turn_id == right.data.turn_id && data.backward == right.data.backward && data.turn_id == right.data.turn_id &&
data.distance == right.data.distance); data.distance == right.data.distance &&
data.maneuver_restricted == data.maneuver_restricted);
} }
}; };
} }

View File

@ -16,22 +16,25 @@ struct EdgeBasedEdge
struct EdgeData struct EdgeData
{ {
EdgeData() EdgeData()
: turn_id(0), weight(0), distance(0), duration(0), forward(false), backward(false) : turn_id(0), maneuver_restricted(false), weight(0), distance(0), duration(0),
forward(false), backward(false)
{ {
} }
EdgeData(const NodeID turn_id, EdgeData(const NodeID turn_id,
const bool maneuver_restricted,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeDistance distance, const EdgeDistance distance,
const EdgeWeight duration, const EdgeWeight duration,
const bool forward, const bool forward,
const bool backward) const bool backward)
: turn_id(turn_id), weight(weight), distance(distance), duration(duration), : turn_id(turn_id), maneuver_restricted(maneuver_restricted), weight(weight),
forward(forward), backward(backward) distance(distance), duration(duration), forward(forward), backward(backward)
{ {
} }
NodeID turn_id; // ID of the edge based node (node based edge) NodeID turn_id : 31; // ID of the edge based node (node based edge)
bool maneuver_restricted : 1;
EdgeWeight weight; EdgeWeight weight;
EdgeDistance distance; EdgeDistance distance;
EdgeWeight duration : 30; EdgeWeight duration : 30;
@ -46,6 +49,7 @@ struct EdgeBasedEdge
EdgeBasedEdge(const NodeID source, EdgeBasedEdge(const NodeID source,
const NodeID target, const NodeID target,
const NodeID edge_id, const NodeID edge_id,
const bool maneuver_restricted,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
const EdgeDistance distance, const EdgeDistance distance,
@ -71,12 +75,14 @@ inline EdgeBasedEdge::EdgeBasedEdge() : source(0), target(0) {}
inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source, inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target, const NodeID target,
const NodeID turn_id, const NodeID turn_id,
const bool maneuver_restricted,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
const EdgeDistance distance, const EdgeDistance distance,
const bool forward, const bool forward,
const bool backward) const bool backward)
: source(source), target(target), data{turn_id, weight, distance, duration, forward, backward} : source(source), target(target),
data{turn_id, maneuver_restricted, weight, distance, duration, forward, backward}
{ {
} }

View File

@ -41,6 +41,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.source, directed.emplace_back(edge.source,
edge.target, edge.target,
edge.data.turn_id, edge.data.turn_id,
edge.data.maneuver_restricted,
std::max(edge.data.weight, 1), std::max(edge.data.weight, 1),
edge.data.duration, edge.data.duration,
edge.data.distance, edge.data.distance,
@ -50,6 +51,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.target, directed.emplace_back(edge.target,
edge.source, edge.source,
edge.data.turn_id, edge.data.turn_id,
edge.data.maneuver_restricted,
std::max(edge.data.weight, 1), std::max(edge.data.weight, 1),
edge.data.duration, edge.data.duration,
edge.data.distance, edge.data.distance,

View File

@ -372,6 +372,45 @@ inline auto make_filtered_graph_view(const SharedDataIndex &index,
auto edge_list = make_vector_view<contractor::QueryGraphView::EdgeArrayEntry>( auto edge_list = make_vector_view<contractor::QueryGraphView::EdgeArrayEntry>(
index, name + "/contracted_graph/edge_array"); index, name + "/contracted_graph/edge_array");
// DEBUG - dump CH
std::cout << "digraph {" << std::endl;
for (std::size_t i = 0; i < node_list.size(); i++)
{
for (auto edge = node_list[i].first_edge;
edge < (i == node_list.size() - 1 ? edge_list.size() : node_list[i + 1].first_edge);
edge++)
{
const auto &e = edge_list[edge];
if (e.data.forward)
{
std::cout << i << " -> " << e.target;
std::cout << "[";
std::cout << "label=\"" << e.data.weight << "\",weight=\"" << e.data.weight
<< "\"";
if (e.data.maneuver_restricted)
{
std::cout << ",color=red,penwidth=3.0";
}
std::cout << "];";
std::cout << std::endl;
}
if (e.data.backward)
{
std::cout << e.target << " -> " << i;
std::cout << "[";
std::cout << "label=\"" << e.data.weight << "\",weight=\"" << e.data.weight
<< "\"";
if (e.data.maneuver_restricted)
{
std::cout << ",color=red,penwidth=3.0";
}
std::cout << "];";
std::cout << std::endl;
}
}
}
std::cout << "}" << std::endl;
return util::FilteredGraphView<contractor::QueryGraphView>({node_list, edge_list}, edge_filter); return util::FilteredGraphView<contractor::QueryGraphView>({node_list, edge_list}, edge_filter);
} }
} }

View File

@ -483,9 +483,9 @@ function process_turn(profile, turn)
if profile.properties.weight_name == 'routability' then if profile.properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags -- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then -- if not turn.source_restricted and turn.target_restricted then
turn.weight = constants.max_turn_weight -- turn.weight = constants.max_turn_weight
end -- end
end end
end end

View File

@ -218,6 +218,8 @@ void ContractNode(ContractorThreadData *data,
in_data.distance + out_data.distance, in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
in_data.maneuver_restricted ||
out_data.maneuver_restricted,
SHORTCUT_ARC, SHORTCUT_ARC,
FORWARD_DIRECTION_ENABLED, FORWARD_DIRECTION_ENABLED,
REVERSE_DIRECTION_DISABLED); REVERSE_DIRECTION_DISABLED);
@ -229,6 +231,8 @@ void ContractNode(ContractorThreadData *data,
in_data.distance + out_data.distance, in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
in_data.maneuver_restricted ||
out_data.maneuver_restricted,
SHORTCUT_ARC, SHORTCUT_ARC,
FORWARD_DIRECTION_DISABLED, FORWARD_DIRECTION_DISABLED,
REVERSE_DIRECTION_ENABLED); REVERSE_DIRECTION_ENABLED);
@ -285,6 +289,8 @@ void ContractNode(ContractorThreadData *data,
in_data.distance + out_data.distance, in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
in_data.maneuver_restricted ||
out_data.maneuver_restricted,
SHORTCUT_ARC, SHORTCUT_ARC,
FORWARD_DIRECTION_ENABLED, FORWARD_DIRECTION_ENABLED,
REVERSE_DIRECTION_DISABLED); REVERSE_DIRECTION_DISABLED);
@ -296,6 +302,8 @@ void ContractNode(ContractorThreadData *data,
in_data.distance + out_data.distance, in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
in_data.maneuver_restricted ||
out_data.maneuver_restricted,
SHORTCUT_ARC, SHORTCUT_ARC,
FORWARD_DIRECTION_DISABLED, FORWARD_DIRECTION_DISABLED,
REVERSE_DIRECTION_ENABLED); REVERSE_DIRECTION_ENABLED);
@ -329,6 +337,11 @@ void ContractNode(ContractorThreadData *data,
{ {
continue; continue;
} }
if (inserted_edges[other].data.maneuver_restricted !=
inserted_edges[i].data.maneuver_restricted)
{
continue;
}
inserted_edges[other].data.forward |= inserted_edges[i].data.forward; inserted_edges[other].data.forward |= inserted_edges[i].data.forward;
inserted_edges[other].data.backward |= inserted_edges[i].data.backward; inserted_edges[other].data.backward |= inserted_edges[i].data.backward;
found = true; found = true;

View File

@ -656,6 +656,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_from]); BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_from]);
BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_to]); BOOST_ASSERT(SPECIAL_NODEID != nbe_to_ebn_mapping[node_based_edge_to]);
// If a source is not restricted, and the target is restricted, then we
// call this a "restricted maneuver"
const bool restricted_maneuver =
!edge_data1.flags.restricted && edge_data2.flags.restricted;
// auto turn_id = m_edge_based_edge_list.size(); // auto turn_id = m_edge_based_edge_list.size();
auto weight = boost::numeric_cast<EdgeWeight>(edge_data1.weight + weight_penalty); auto weight = boost::numeric_cast<EdgeWeight>(edge_data1.weight + weight_penalty);
auto duration = boost::numeric_cast<EdgeWeight>(edge_data1.duration + duration_penalty); auto duration = boost::numeric_cast<EdgeWeight>(edge_data1.duration + duration_penalty);
@ -665,6 +670,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_based_node_to, edge_based_node_to,
SPECIAL_NODEID, // This will be updated once the main SPECIAL_NODEID, // This will be updated once the main
// loop completes! // loop completes!
restricted_maneuver,
weight, weight,
duration, duration,
distance, distance,

143
src/tools/dump.cpp Normal file
View File

@ -0,0 +1,143 @@
#include "storage/serialization.hpp"
#include "storage/shared_memory.hpp"
#include "storage/shared_monitor.hpp"
#include "storage/storage.hpp"
#include "osrm/exception.hpp"
#include "util/log.hpp"
#include "util/meminfo.hpp"
#include "util/typedefs.hpp"
#include "util/version.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <csignal>
#include <cstdlib>
using namespace osrm;
// generate boost::program_options object for the routing part
bool generateDataStoreOptions(const int argc,
const char *argv[],
std::string &verbosity,
boost::filesystem::path &base_path,
int &max_wait,
std::string &dataset_name,
bool &list_datasets,
bool &list_blocks,
bool &only_metric)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options() //
("contraction-heirarchy,ch", "Dump CH graph")("cells,c", "Dump partition structure");
try
{
boost::program_options::store(
boost::program_options::command_line_parser(argc, argv, generic_options),
option_variables);
}
catch (const boost::program_options::error &e)
{
util::Log(logERROR) << e.what();
return false;
}
if (option_variables.count("version"))
{
util::Log() << OSRM_VERSION;
return false;
}
if (option_variables.count("help"))
{
util::Log() << visible_options;
return false;
}
if (option_variables.count("remove-locks"))
{
removeLocks();
return false;
}
if (option_variables.count("spring-clean"))
{
springClean();
return false;
}
boost::program_options::notify(option_variables);
return true;
}
[[noreturn]] void CleanupSharedBarriers(int signum)
{ // Here the lock state of named mutexes is unknown, make a hard cleanup
removeLocks();
std::_Exit(128 + signum);
}
int main(const int argc, const char *argv[]) try
{
int signals[] = {SIGTERM, SIGSEGV, SIGINT, SIGILL, SIGABRT, SIGFPE};
for (auto sig : signals)
{
std::signal(sig, CleanupSharedBarriers);
}
util::LogPolicy::GetInstance().Unmute();
std::string verbosity;
boost::filesystem::path base_path;
int max_wait = -1;
std::string dataset_name;
bool list_datasets = false;
bool list_blocks = false;
bool only_metric = false;
if (!generateDataStoreOptions(argc,
argv,
verbosity,
base_path,
max_wait,
dataset_name,
list_datasets,
list_blocks,
only_metric))
{
return EXIT_SUCCESS;
}
util::LogPolicy::GetInstance().SetLevel(verbosity);
if (list_datasets || list_blocks)
{
listRegions(list_blocks);
return EXIT_SUCCESS;
}
storage::StorageConfig config(base_path);
if (!config.IsValid())
{
util::Log(logERROR) << "Config contains invalid file paths. Exiting!";
return EXIT_FAILURE;
}
storage::Storage storage(std::move(config));
return storage.Run(max_wait, dataset_name, only_metric);
}
catch (const osrm::RuntimeError &e)
{
util::Log(logERROR) << e.what();
return e.GetCode();
}
catch (const std::bad_alloc &e)
{
util::DumpMemoryStats();
util::Log(logERROR) << "[exception] " << e.what();
util::Log(logERROR) << "Please provide more memory or disable locking the virtual "
"address space (note: this makes OSRM swap, i.e. slow)";
return EXIT_FAILURE;
}