Add flag to edges that transition into restricted areas.
This commit is contained in:
parent
2c78d862a3
commit
da4f700f80
@ -12,27 +12,30 @@ namespace contractor
|
||||
struct ContractorEdgeData
|
||||
{
|
||||
ContractorEdgeData()
|
||||
: weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0),
|
||||
backward(0)
|
||||
: weight(0), duration(0), distance(0), id(0), maneuver_restricted(false), originalEdges(0),
|
||||
shortcut(0), forward(0), backward(0)
|
||||
{
|
||||
}
|
||||
ContractorEdgeData(EdgeWeight weight,
|
||||
EdgeWeight duration,
|
||||
EdgeDuration duration,
|
||||
EdgeDistance distance,
|
||||
unsigned original_edges,
|
||||
unsigned id,
|
||||
bool maneuver_restricted,
|
||||
bool shortcut,
|
||||
bool forward,
|
||||
bool backward)
|
||||
: weight(weight), duration(duration), distance(distance), id(id),
|
||||
maneuver_restricted(maneuver_restricted),
|
||||
originalEdges(std::min((1u << 29) - 1u, original_edges)), shortcut(shortcut),
|
||||
forward(forward), backward(backward)
|
||||
{
|
||||
}
|
||||
EdgeWeight weight;
|
||||
EdgeWeight duration;
|
||||
EdgeDuration duration;
|
||||
EdgeDistance distance;
|
||||
unsigned id;
|
||||
unsigned id : 31;
|
||||
bool maneuver_restricted : 1;
|
||||
unsigned originalEdges : 29;
|
||||
bool shortcut : 1;
|
||||
bool forward : 1;
|
||||
|
||||
@ -44,6 +44,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
||||
input_edge.data.distance,
|
||||
1,
|
||||
input_edge.data.turn_id,
|
||||
input_edge.data.maneuver_restricted,
|
||||
false,
|
||||
input_edge.data.forward ? true : false,
|
||||
input_edge.data.backward ? true : false);
|
||||
@ -55,6 +56,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
||||
input_edge.data.distance,
|
||||
1,
|
||||
input_edge.data.turn_id,
|
||||
input_edge.data.maneuver_restricted, // Note: inverted
|
||||
false,
|
||||
input_edge.data.backward ? 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.duration = reverse_edge.data.duration = MAXIMAL_EDGE_DURATION;
|
||||
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
|
||||
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);
|
||||
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)
|
||||
{
|
||||
@ -103,11 +107,13 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
|
||||
std::min(edges[i].data.duration, reverse_edge.data.duration);
|
||||
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;
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
@ -165,6 +171,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
|
||||
"edge id invalid");
|
||||
new_edge.data.forward = data.forward;
|
||||
new_edge.data.backward = data.backward;
|
||||
new_edge.data.maneuver_restricted = data.maneuver_restricted;
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(edge_index == edges.size());
|
||||
|
||||
@ -17,8 +17,8 @@ struct QueryEdge
|
||||
struct EdgeData
|
||||
{
|
||||
explicit EdgeData()
|
||||
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false),
|
||||
distance(0)
|
||||
: turn_id(0), shortcut(false), maneuver_restricted(false), weight(0), duration(0),
|
||||
forward(false), backward(false), distance(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,9 +28,11 @@ struct QueryEdge
|
||||
const EdgeWeight duration,
|
||||
const EdgeDistance distance,
|
||||
const bool forward,
|
||||
const bool backward)
|
||||
: turn_id(turn_id), shortcut(shortcut), weight(weight), duration(duration),
|
||||
forward(forward), backward(backward), distance(distance)
|
||||
const bool backward,
|
||||
const bool maneuver_restricted)
|
||||
: 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;
|
||||
backward = other.backward;
|
||||
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
|
||||
// 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.
|
||||
NodeID turn_id : 31;
|
||||
NodeID turn_id : 30;
|
||||
bool shortcut : 1;
|
||||
bool maneuver_restricted : 1;
|
||||
EdgeWeight weight;
|
||||
EdgeWeight duration : 30;
|
||||
std::uint32_t forward : 1;
|
||||
@ -74,7 +78,8 @@ struct QueryEdge
|
||||
data.weight == right.data.weight && data.duration == right.data.duration &&
|
||||
data.shortcut == right.data.shortcut && data.forward == right.data.forward &&
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -16,22 +16,25 @@ struct EdgeBasedEdge
|
||||
struct 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,
|
||||
const bool maneuver_restricted,
|
||||
const EdgeWeight weight,
|
||||
const EdgeDistance distance,
|
||||
const EdgeWeight duration,
|
||||
const bool forward,
|
||||
const bool backward)
|
||||
: turn_id(turn_id), weight(weight), distance(distance), duration(duration),
|
||||
forward(forward), backward(backward)
|
||||
: turn_id(turn_id), maneuver_restricted(maneuver_restricted), weight(weight),
|
||||
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;
|
||||
EdgeDistance distance;
|
||||
EdgeWeight duration : 30;
|
||||
@ -46,6 +49,7 @@ struct EdgeBasedEdge
|
||||
EdgeBasedEdge(const NodeID source,
|
||||
const NodeID target,
|
||||
const NodeID edge_id,
|
||||
const bool maneuver_restricted,
|
||||
const EdgeWeight weight,
|
||||
const EdgeWeight duration,
|
||||
const EdgeDistance distance,
|
||||
@ -71,12 +75,14 @@ inline EdgeBasedEdge::EdgeBasedEdge() : source(0), target(0) {}
|
||||
inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
||||
const NodeID target,
|
||||
const NodeID turn_id,
|
||||
const bool maneuver_restricted,
|
||||
const EdgeWeight weight,
|
||||
const EdgeWeight duration,
|
||||
const EdgeDistance distance,
|
||||
const bool forward,
|
||||
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}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
||||
directed.emplace_back(edge.source,
|
||||
edge.target,
|
||||
edge.data.turn_id,
|
||||
edge.data.maneuver_restricted,
|
||||
std::max(edge.data.weight, 1),
|
||||
edge.data.duration,
|
||||
edge.data.distance,
|
||||
@ -50,6 +51,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
|
||||
directed.emplace_back(edge.target,
|
||||
edge.source,
|
||||
edge.data.turn_id,
|
||||
edge.data.maneuver_restricted,
|
||||
std::max(edge.data.weight, 1),
|
||||
edge.data.duration,
|
||||
edge.data.distance,
|
||||
|
||||
@ -372,6 +372,45 @@ inline auto make_filtered_graph_view(const SharedDataIndex &index,
|
||||
auto edge_list = make_vector_view<contractor::QueryGraphView::EdgeArrayEntry>(
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,9 +483,9 @@ function process_turn(profile, turn)
|
||||
|
||||
if profile.properties.weight_name == 'routability' then
|
||||
-- penalize turns from non-local access only segments onto local access only tags
|
||||
if not turn.source_restricted and turn.target_restricted then
|
||||
turn.weight = constants.max_turn_weight
|
||||
end
|
||||
-- if not turn.source_restricted and turn.target_restricted then
|
||||
-- turn.weight = constants.max_turn_weight
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -218,6 +218,8 @@ void ContractNode(ContractorThreadData *data,
|
||||
in_data.distance + out_data.distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node,
|
||||
in_data.maneuver_restricted ||
|
||||
out_data.maneuver_restricted,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_ENABLED,
|
||||
REVERSE_DIRECTION_DISABLED);
|
||||
@ -229,6 +231,8 @@ void ContractNode(ContractorThreadData *data,
|
||||
in_data.distance + out_data.distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node,
|
||||
in_data.maneuver_restricted ||
|
||||
out_data.maneuver_restricted,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_DISABLED,
|
||||
REVERSE_DIRECTION_ENABLED);
|
||||
@ -285,6 +289,8 @@ void ContractNode(ContractorThreadData *data,
|
||||
in_data.distance + out_data.distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node,
|
||||
in_data.maneuver_restricted ||
|
||||
out_data.maneuver_restricted,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_ENABLED,
|
||||
REVERSE_DIRECTION_DISABLED);
|
||||
@ -296,6 +302,8 @@ void ContractNode(ContractorThreadData *data,
|
||||
in_data.distance + out_data.distance,
|
||||
out_data.originalEdges + in_data.originalEdges,
|
||||
node,
|
||||
in_data.maneuver_restricted ||
|
||||
out_data.maneuver_restricted,
|
||||
SHORTCUT_ARC,
|
||||
FORWARD_DIRECTION_DISABLED,
|
||||
REVERSE_DIRECTION_ENABLED);
|
||||
@ -329,6 +337,11 @@ void ContractNode(ContractorThreadData *data,
|
||||
{
|
||||
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.backward |= inserted_edges[i].data.backward;
|
||||
found = true;
|
||||
|
||||
@ -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_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 weight = boost::numeric_cast<EdgeWeight>(edge_data1.weight + weight_penalty);
|
||||
auto duration = boost::numeric_cast<EdgeWeight>(edge_data1.duration + duration_penalty);
|
||||
@ -665,6 +670,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
edge_based_node_to,
|
||||
SPECIAL_NODEID, // This will be updated once the main
|
||||
// loop completes!
|
||||
restricted_maneuver,
|
||||
weight,
|
||||
duration,
|
||||
distance,
|
||||
|
||||
143
src/tools/dump.cpp
Normal file
143
src/tools/dump.cpp
Normal 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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user