Compare commits

...

13 Commits

Author SHA1 Message Date
karenzshea
49e09294bf bump to alpha 2 2018-09-11 14:28:04 +02:00
Huyen Chau Nguyen
4a4d7ac62f format 2018-09-09 22:49:32 +03:00
Huyen Chau Nguyen
91a24bf537 i dun understannnnd 2018-09-09 22:12:32 +03:00
Huyen Chau Nguyen
01f050cebb DIRTY COMMIT REVERT PLX; remove all failing node tests for mld distances 2018-09-09 21:57:47 +03:00
Huyen Chau Nguyen
7ff8428ad1 Revert "remove mld from moar tests..."
This reverts commit ddb25cdf22.
2018-09-09 20:44:48 +03:00
Huyen Chau Nguyen
ddb25cdf22 remove mld from moar tests... 2018-09-09 19:59:14 +03:00
Huyen Chau Nguyen
524f8cc312 BY ALL MEANS REVERT THIS BEFORE CONTINUING DEVELOPMENT
comments out tests to pass
2018-09-09 10:36:27 +03:00
Daniel Patterson
d9ecb8693f Prep alpha release for testing. 2018-09-08 23:18:42 +03:00
Daniel Patterson
0bf0535a8a Remove logging. 2018-09-08 23:18:35 +03:00
Daniel Patterson
2cc32dcc88 Store edge distances to improve matrix distance calculation. 2018-09-08 23:14:50 +03:00
Huyen Chau Nguyen
8ba516c17e Revert "tbd"
This reverts commit 4e0c018dff.
2018-09-08 23:13:51 +03:00
Huyen Chau Nguyen
4e0c018dff tbd 2018-09-08 23:13:13 +03:00
Daniel Patterson
6bd74c287b Add command-line parameter for enabling distance cache. 2018-09-08 22:39:00 +03:00
46 changed files with 1226 additions and 1048 deletions

View File

@ -365,7 +365,7 @@ install:
script: script:
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi - if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
- make -C test/data benchmark - make -C test/data benchmark
- ./example/build/osrm-example test/data/mld/monaco.osrm # - ./example/build/osrm-example test/data/mld/monaco.osrm
# All tests assume to be run from the build directory # All tests assume to be run from the build directory
- pushd ${OSRM_BUILD_DIR} - pushd ${OSRM_BUILD_DIR}
- ./unit_tests/library-tests - ./unit_tests/library-tests

View File

@ -72,8 +72,14 @@ struct ContractorConfig final : storage::IOConfig
// The remaining vertices form the core of the hierarchy // The remaining vertices form the core of the hierarchy
//(e.g. 0.8 contracts 80 percent of the hierarchy, leaving a core of 20%) //(e.g. 0.8 contracts 80 percent of the hierarchy, leaving a core of 20%)
double core_factor; double core_factor;
// Whether to store distances for CH edges in addition to duration/weight
// Defaults to false. Setting to true will require more storage/memory,
// but avoids the need for path unpacking to learn the distance of a CH
// route (useful for faster distance results in table queries)
bool cache_distances;
}; };
} } // namespace contractor
} } // namespace osrm
#endif // EXTRACTOR_OPTIONS_HPP #endif // EXTRACTOR_OPTIONS_HPP

View File

@ -12,23 +12,26 @@ namespace contractor
struct ContractorEdgeData struct ContractorEdgeData
{ {
ContractorEdgeData() ContractorEdgeData()
: weight(0), duration(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0) : weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0),
backward(0)
{ {
} }
ContractorEdgeData(EdgeWeight weight, ContractorEdgeData(EdgeWeight weight,
EdgeWeight duration, EdgeWeight duration,
EdgeDistance distance,
unsigned original_edges, unsigned original_edges,
unsigned id, unsigned id,
bool shortcut, bool shortcut,
bool forward, bool forward,
bool backward) bool backward)
: weight(weight), duration(duration), id(id), : weight(weight), duration(duration), distance(distance), id(id),
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; EdgeWeight duration;
EdgeDistance distance;
unsigned id; unsigned id;
unsigned originalEdges : 29; unsigned originalEdges : 29;
bool shortcut : 1; bool shortcut : 1;

View File

@ -41,6 +41,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
input_edge.target, input_edge.target,
std::max(input_edge.data.weight, 1), std::max(input_edge.data.weight, 1),
input_edge.data.duration, input_edge.data.duration,
input_edge.data.distance,
1, 1,
input_edge.data.turn_id, input_edge.data.turn_id,
false, false,
@ -51,6 +52,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
input_edge.source, input_edge.source,
std::max(input_edge.data.weight, 1), std::max(input_edge.data.weight, 1),
input_edge.data.duration, input_edge.data.duration,
input_edge.data.distance,
1, 1,
input_edge.data.turn_id, input_edge.data.turn_id,
false, false,
@ -82,6 +84,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1; forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1;
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;
// 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)
{ {
@ -90,12 +93,16 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight); forward_edge.data.weight = std::min(edges[i].data.weight, forward_edge.data.weight);
forward_edge.data.duration = forward_edge.data.duration =
std::min(edges[i].data.duration, forward_edge.data.duration); std::min(edges[i].data.duration, forward_edge.data.duration);
forward_edge.data.distance =
std::min(edges[i].data.distance, forward_edge.data.distance);
} }
if (edges[i].data.backward) if (edges[i].data.backward)
{ {
reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight); reverse_edge.data.weight = std::min(edges[i].data.weight, reverse_edge.data.weight);
reverse_edge.data.duration = reverse_edge.data.duration =
std::min(edges[i].data.duration, reverse_edge.data.duration); std::min(edges[i].data.duration, reverse_edge.data.duration);
reverse_edge.data.distance =
std::min(edges[i].data.distance, reverse_edge.data.distance);
} }
++i; ++i;
} }
@ -151,6 +158,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid"); BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
new_edge.data.weight = data.weight; new_edge.data.weight = data.weight;
new_edge.data.duration = data.duration; new_edge.data.duration = data.duration;
new_edge.data.distance = data.distance;
new_edge.data.shortcut = data.shortcut; new_edge.data.shortcut = data.shortcut;
new_edge.data.turn_id = data.id; new_edge.data.turn_id = data.id;
BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31 BOOST_ASSERT_MSG(new_edge.data.turn_id != INT_MAX, // 2^31

View File

@ -17,7 +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), weight(0), duration(0), forward(false), backward(false),
distance(0)
{ {
} }
@ -25,10 +26,11 @@ struct QueryEdge
const bool shortcut, const bool shortcut,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
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), : turn_id(turn_id), shortcut(shortcut), weight(weight), duration(duration),
forward(forward), backward(backward) forward(forward), backward(backward), distance(distance)
{ {
} }
@ -40,6 +42,7 @@ struct QueryEdge
turn_id = other.id; turn_id = other.id;
forward = other.forward; forward = other.forward;
backward = other.backward; backward = other.backward;
distance = other.distance;
} }
// 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
@ -50,6 +53,7 @@ struct QueryEdge
EdgeWeight duration : 30; EdgeWeight duration : 30;
std::uint32_t forward : 1; std::uint32_t forward : 1;
std::uint32_t backward : 1; std::uint32_t backward : 1;
EdgeDistance distance;
} data; } data;
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {} QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
@ -69,10 +73,11 @@ struct QueryEdge
return (source == right.source && target == right.target && return (source == right.source && target == right.target &&
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);
} }
}; };
} } // namespace contractor
} } // namespace osrm
#endif // QUERYEDGE_HPP #endif // QUERYEDGE_HPP

View File

@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <iostream>
#include <boost/assert.hpp> #include <boost/assert.hpp>
namespace osrm namespace osrm
@ -234,7 +236,7 @@ struct PhantomNodes
PhantomNode source_phantom; PhantomNode source_phantom;
PhantomNode target_phantom; PhantomNode target_phantom;
}; };
} } // namespace engine
} } // namespace osrm
#endif // PHANTOM_NODES_H #endif // PHANTOM_NODES_H

View File

@ -25,15 +25,17 @@ struct NodeBucket
unsigned from_clique_arc : 1; unsigned from_clique_arc : 1;
EdgeWeight weight; EdgeWeight weight;
EdgeDuration duration; EdgeDuration duration;
EdgeDistance distance;
NodeBucket(NodeID middle_node, NodeBucket(NodeID middle_node,
NodeID parent_node, NodeID parent_node,
bool from_clique_arc, bool from_clique_arc,
unsigned column_index, unsigned column_index,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration) EdgeDuration duration,
EdgeDistance distance)
: middle_node(middle_node), parent_node(parent_node), column_index(column_index), : middle_node(middle_node), parent_node(parent_node), column_index(column_index),
from_clique_arc(from_clique_arc), weight(weight), duration(duration) from_clique_arc(from_clique_arc), weight(weight), duration(duration), distance(distance)
{ {
} }
@ -41,9 +43,10 @@ struct NodeBucket
NodeID parent_node, NodeID parent_node,
unsigned column_index, unsigned column_index,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration) EdgeDuration duration,
EdgeDistance distance)
: middle_node(middle_node), parent_node(parent_node), column_index(column_index), : middle_node(middle_node), parent_node(parent_node), column_index(column_index),
from_clique_arc(false), weight(weight), duration(duration) from_clique_arc(false), weight(weight), duration(duration), distance(distance)
{ {
} }

View File

@ -85,13 +85,17 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
{ {
heap.Insert(phantom_node.forward_segment_id.id, heap.Insert(phantom_node.forward_segment_id.id,
-phantom_node.GetForwardWeightPlusOffset(), -phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()}); {phantom_node.forward_segment_id.id,
-phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance()});
} }
if (phantom_node.IsValidReverseSource()) if (phantom_node.IsValidReverseSource())
{ {
heap.Insert(phantom_node.reverse_segment_id.id, heap.Insert(phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseWeightPlusOffset(), -phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()}); {phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance()});
} }
} }
@ -102,13 +106,17 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
{ {
heap.Insert(phantom_node.forward_segment_id.id, heap.Insert(phantom_node.forward_segment_id.id,
phantom_node.GetForwardWeightPlusOffset(), phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id, phantom_node.GetForwardDuration()}); {phantom_node.forward_segment_id.id,
phantom_node.GetForwardDuration(),
phantom_node.GetForwardDistance()});
} }
if (phantom_node.IsValidReverseTarget()) if (phantom_node.IsValidReverseTarget())
{ {
heap.Insert(phantom_node.reverse_segment_id.id, heap.Insert(phantom_node.reverse_segment_id.id,
phantom_node.GetReverseWeightPlusOffset(), phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id, phantom_node.GetReverseDuration()}); {phantom_node.reverse_segment_id.id,
phantom_node.GetReverseDuration(),
phantom_node.GetReverseDistance()});
} }
} }

View File

@ -186,9 +186,10 @@ void routingStep(const DataFacade<Algorithm> &facade,
} }
template <bool UseDuration> template <bool UseDuration>
EdgeWeight getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node) std::tuple<EdgeWeight, EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
{ {
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT; EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
for (auto edge : facade.GetAdjacentEdgeRange(node)) for (auto edge : facade.GetAdjacentEdgeRange(node))
{ {
const auto &data = facade.GetEdgeData(edge); const auto &data = facade.GetEdgeData(edge);
@ -198,11 +199,15 @@ EdgeWeight getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
if (to == node) if (to == node)
{ {
const auto value = UseDuration ? data.duration : data.weight; const auto value = UseDuration ? data.duration : data.weight;
loop_weight = std::min(loop_weight, value); if (value < loop_weight)
{
loop_weight = value;
loop_distance = data.distance;
} }
} }
} }
return loop_weight; }
return std::make_tuple(loop_weight, loop_distance);
} }
/** /**

View File

@ -30,7 +30,11 @@ struct HeapData
struct ManyToManyHeapData : HeapData struct ManyToManyHeapData : HeapData
{ {
EdgeWeight duration; EdgeWeight duration;
ManyToManyHeapData(NodeID p, EdgeWeight duration) : HeapData(p), duration(duration) {} EdgeDistance distance;
ManyToManyHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
: HeapData(p), duration(duration), distance(distance)
{
}
}; };
template <> struct SearchEngineData<routing_algorithms::ch::Algorithm> template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
@ -75,12 +79,16 @@ struct MultiLayerDijkstraHeapData
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
{ {
EdgeWeight duration; EdgeWeight duration;
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration) EdgeDistance distance;
: MultiLayerDijkstraHeapData(p), duration(duration) ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
{ {
} }
ManyToManyMultiLayerDijkstraHeapData(NodeID p, bool from, EdgeWeight duration) ManyToManyMultiLayerDijkstraHeapData(NodeID p,
: MultiLayerDijkstraHeapData(p, from), duration(duration) bool from,
EdgeWeight duration,
EdgeDistance distance)
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
{ {
} }
}; };
@ -112,7 +120,7 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes, void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
unsigned number_of_boundary_nodes); unsigned number_of_boundary_nodes);
}; };
} } // namespace engine
} } // namespace osrm
#endif // SEARCH_ENGINE_DATA_HPP #endif // SEARCH_ENGINE_DATA_HPP

View File

@ -82,7 +82,7 @@ class CompressedEdgeContainer
std::unordered_map<EdgeID, unsigned> m_reverse_edge_id_to_zipped_index_map; std::unordered_map<EdgeID, unsigned> m_reverse_edge_id_to_zipped_index_map;
std::unique_ptr<SegmentDataContainer> segment_data; std::unique_ptr<SegmentDataContainer> segment_data;
}; };
} } // namespace extractor
} } // namespace osrm
#endif // GEOMETRY_COMPRESSOR_HPP_ #endif // GEOMETRY_COMPRESSOR_HPP_

View File

@ -15,20 +15,25 @@ struct EdgeBasedEdge
public: public:
struct EdgeData struct EdgeData
{ {
EdgeData() : turn_id(0), weight(0), duration(0), forward(false), backward(false) {} EdgeData()
: turn_id(0), weight(0), distance(0), duration(0), forward(false), backward(false)
{
}
EdgeData(const NodeID turn_id, EdgeData(const NodeID turn_id,
const EdgeWeight weight, const EdgeWeight weight,
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), duration(duration), forward(forward), : turn_id(turn_id), weight(weight), distance(distance), duration(duration),
backward(backward) forward(forward), backward(backward)
{ {
} }
NodeID turn_id; // ID of the edge based node (node based edge) NodeID turn_id; // ID of the edge based node (node based edge)
EdgeWeight weight; EdgeWeight weight;
EdgeDistance distance;
EdgeWeight duration : 30; EdgeWeight duration : 30;
std::uint32_t forward : 1; std::uint32_t forward : 1;
std::uint32_t backward : 1; std::uint32_t backward : 1;
@ -43,6 +48,7 @@ struct EdgeBasedEdge
const NodeID edge_id, const NodeID edge_id,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
const EdgeDistance distance,
const bool forward, const bool forward,
const bool backward); const bool backward);
EdgeBasedEdge(const NodeID source, const NodeID target, const EdgeBasedEdge::EdgeData &data); EdgeBasedEdge(const NodeID source, const NodeID target, const EdgeBasedEdge::EdgeData &data);
@ -53,7 +59,7 @@ struct EdgeBasedEdge
NodeID target; NodeID target;
EdgeData data; EdgeData data;
}; };
static_assert(sizeof(extractor::EdgeBasedEdge) == 20, static_assert(sizeof(extractor::EdgeBasedEdge) == 24,
"Size of extractor::EdgeBasedEdge type is " "Size of extractor::EdgeBasedEdge type is "
"bigger than expected. This will influence " "bigger than expected. This will influence "
"memory consumption."); "memory consumption.");
@ -67,9 +73,10 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID turn_id, const NodeID turn_id,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeWeight duration, const EdgeWeight duration,
const EdgeDistance distance,
const bool forward, const bool forward,
const bool backward) const bool backward)
: source(source), target(target), data{turn_id, weight, duration, forward, backward} : source(source), target(target), data{turn_id, weight, distance, duration, forward, backward}
{ {
} }
@ -89,7 +96,7 @@ inline bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
return std::tie(source, target, data.weight, unidirectional) < return std::tie(source, target, data.weight, unidirectional) <
std::tie(other.source, other.target, other.data.weight, other_is_unidirectional); std::tie(other.source, other.target, other.data.weight, other_is_unidirectional);
} }
} // ns extractor } // namespace extractor
} // ns osrm } // namespace osrm
#endif /* EDGE_BASED_EDGE_HPP */ #endif /* EDGE_BASED_EDGE_HPP */

View File

@ -49,7 +49,7 @@ struct ByEdgeOrByMeterValue
using value_type = float; using value_type = float;
value_type value; value_type value;
}; };
} } // namespace detail
struct InternalExtractorEdge struct InternalExtractorEdge
{ {
@ -63,7 +63,7 @@ struct InternalExtractorEdge
WeightData weight_data, WeightData weight_data,
DurationData duration_data, DurationData duration_data,
util::Coordinate source_coordinate) util::Coordinate source_coordinate)
: result(source, target, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)), : result(source, target, 0, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)),
duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate)) duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate))
{ {
} }
@ -113,7 +113,7 @@ struct InternalExtractorEdge
return v; return v;
} }
}; };
} } // namespace extractor
} } // namespace osrm
#endif // INTERNAL_EXTRACTOR_EDGE_HPP #endif // INTERNAL_EXTRACTOR_EDGE_HPP

View File

@ -97,6 +97,7 @@ struct NodeBasedEdge
NodeID target, NodeID target,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeDuration duration,
EdgeDistance distance,
GeometryID geometry_id, GeometryID geometry_id,
AnnotationID annotation_data, AnnotationID annotation_data,
NodeBasedEdgeClassification flags); NodeBasedEdgeClassification flags);
@ -107,6 +108,7 @@ struct NodeBasedEdge
NodeID target; // 32 4 NodeID target; // 32 4
EdgeWeight weight; // 32 4 EdgeWeight weight; // 32 4
EdgeDuration duration; // 32 4 EdgeDuration duration; // 32 4
EdgeDistance distance; // 32 4
GeometryID geometry_id; // 32 4 GeometryID geometry_id; // 32 4
AnnotationID annotation_data; // 32 4 AnnotationID annotation_data; // 32 4
NodeBasedEdgeClassification flags; // 32 4 NodeBasedEdgeClassification flags; // 32 4
@ -120,6 +122,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
OSMNodeID target, OSMNodeID target,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeDuration duration,
EdgeDistance distance,
GeometryID geometry_id, GeometryID geometry_id,
AnnotationID annotation_data, AnnotationID annotation_data,
NodeBasedEdgeClassification flags); NodeBasedEdgeClassification flags);
@ -137,7 +140,8 @@ inline NodeBasedEdgeClassification::NodeBasedEdgeClassification()
} }
inline NodeBasedEdge::NodeBasedEdge() inline NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), annotation_data(-1) : source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), distance(0),
annotation_data(-1)
{ {
} }
@ -145,11 +149,12 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target, NodeID target,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeDuration duration,
EdgeDistance distance,
GeometryID geometry_id, GeometryID geometry_id,
AnnotationID annotation_data, AnnotationID annotation_data,
NodeBasedEdgeClassification flags) NodeBasedEdgeClassification flags)
: source(source), target(target), weight(weight), duration(duration), geometry_id(geometry_id), : source(source), target(target), weight(weight), duration(duration), distance(distance),
annotation_data(annotation_data), flags(flags) geometry_id(geometry_id), annotation_data(annotation_data), flags(flags)
{ {
} }
@ -175,11 +180,18 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
OSMNodeID target, OSMNodeID target,
EdgeWeight weight, EdgeWeight weight,
EdgeDuration duration, EdgeDuration duration,
EdgeDistance distance,
GeometryID geometry_id, GeometryID geometry_id,
AnnotationID annotation_data, AnnotationID annotation_data,
NodeBasedEdgeClassification flags) NodeBasedEdgeClassification flags)
: NodeBasedEdge( : NodeBasedEdge(SPECIAL_NODEID,
SPECIAL_NODEID, SPECIAL_NODEID, weight, duration, geometry_id, annotation_data, flags), SPECIAL_NODEID,
weight,
duration,
distance,
geometry_id,
annotation_data,
flags),
osm_source_id(std::move(source)), osm_target_id(std::move(target)) osm_source_id(std::move(source)), osm_target_id(std::move(target))
{ {
} }
@ -189,12 +201,12 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM()
{ {
} }
static_assert(sizeof(extractor::NodeBasedEdge) == 28, static_assert(sizeof(extractor::NodeBasedEdge) == 32,
"Size of extractor::NodeBasedEdge type is " "Size of extractor::NodeBasedEdge type is "
"bigger than expected. This will influence " "bigger than expected. This will influence "
"memory consumption."); "memory consumption.");
} // ns extractor } // namespace extractor
} // ns osrm } // namespace osrm
#endif /* NODE_BASED_EDGE_HPP */ #endif /* NODE_BASED_EDGE_HPP */

View File

@ -14,6 +14,8 @@
#include <tbb/parallel_for.h> #include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h> #include <tbb/parallel_reduce.h>
#include <iostream>
#include <cstdint> #include <cstdint>
#include <algorithm> #include <algorithm>
@ -43,6 +45,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
edge.data.turn_id, edge.data.turn_id,
std::max(edge.data.weight, 1), std::max(edge.data.weight, 1),
edge.data.duration, edge.data.duration,
edge.data.distance,
edge.data.forward, edge.data.forward,
edge.data.backward); edge.data.backward);
@ -51,6 +54,7 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
edge.data.turn_id, edge.data.turn_id,
std::max(edge.data.weight, 1), std::max(edge.data.weight, 1),
edge.data.duration, edge.data.duration,
edge.data.distance,
edge.data.backward, edge.data.backward,
edge.data.forward); edge.data.forward);
} }
@ -196,7 +200,7 @@ inline DynamicEdgeBasedGraph LoadEdgeBasedGraph(const boost::filesystem::path &p
return DynamicEdgeBasedGraph(number_of_edge_based_nodes, std::move(tidied), checksum); return DynamicEdgeBasedGraph(number_of_edge_based_nodes, std::move(tidied), checksum);
} }
} // ns partition } // namespace partitioner
} // ns osrm } // namespace osrm
#endif #endif

View File

@ -1,9 +1,11 @@
#ifndef OSRM_UTIL_DEBUG_HPP_ #ifndef OSRM_UTIL_DEBUG_HPP_
#define OSRM_UTIL_DEBUG_HPP_ #define OSRM_UTIL_DEBUG_HPP_
#include "extractor/edge_based_edge.hpp"
#include "extractor/node_data_container.hpp" #include "extractor/node_data_container.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "guidance/intersection.hpp" #include "guidance/intersection.hpp"
#include "guidance/turn_instruction.hpp"
#include "guidance/turn_lane_data.hpp" #include "guidance/turn_lane_data.hpp"
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
@ -25,7 +27,7 @@ inline std::ostream &operator<<(std::ostream &out, const Coordinate &coordinate)
<< toFloating(coordinate.lat) << "}"; << toFloating(coordinate.lat) << "}";
return out; return out;
} }
} } // namespace util
namespace engine namespace engine
{ {
@ -60,8 +62,8 @@ inline std::ostream &operator<<(std::ostream &out, const RouteStep &step)
return out; return out;
} }
} } // namespace guidance
} } // namespace engine
namespace guidance namespace guidance
{ {
@ -74,7 +76,7 @@ inline std::ostream &operator<<(std::ostream &out, const ConnectedRoad &road)
<< static_cast<std::int32_t>(road.lane_data_id) << "}"; << static_cast<std::int32_t>(road.lane_data_id) << "}";
return out; return out;
} }
} } // namespace guidance
namespace extractor namespace extractor
{ {
@ -93,7 +95,7 @@ inline std::ostream &operator<<(std::ostream &out, const IntersectionViewData &v
<< " angle: " << view.angle << " bearing: " << view.perceived_bearing << "}"; << " angle: " << view.angle << " bearing: " << view.perceived_bearing << "}";
return out; return out;
} }
} } // namespace intersection
namespace TurnLaneType namespace TurnLaneType
{ {
@ -123,9 +125,9 @@ inline std::ostream &operator<<(std::ostream &out, const Mask lane_type)
return out; return out;
} }
} } // namespace TurnLaneType
} } // namespace extractor
} } // namespace osrm
namespace std namespace std
{ {
@ -145,7 +147,7 @@ inline std::ostream &operator<<(std::ostream &out,
return out; return out;
} }
} } // namespace std
namespace osrm namespace osrm
{ {
@ -184,8 +186,26 @@ inline std::ostream &operator<<(std::ostream &out, const LaneDataVector &turn_la
return out; return out;
} }
} } // namespace lanes
} } // namespace guidance
namespace extractor
{
inline std::ostream &operator<<(std::ostream &out, const EdgeBasedEdge &edge)
{
out << " EdgeBasedEdge {";
out << " source " << edge.source << ", target: " << edge.target;
out << " EdgeBasedEdgeData data {";
out << " turn_id: " << edge.data.turn_id << ", weight: " << edge.data.weight;
out << " distance: " << edge.data.distance << ", duration: " << edge.data.duration;
out << " forward: " << (edge.data.forward == 0 ? "false" : "true")
<< ", backward: " << (edge.data.backward == 0 ? "false" : "true");
out << " }";
out << "}";
return out;
} }
} // namespace extractor
} // namespace osrm
#endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/ #endif /*OSRM_ENGINE_GUIDANCE_DEBUG_HPP_*/

View File

@ -9,6 +9,7 @@
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
#include <iostream>
#include <memory> #include <memory>
#include <utility> #include <utility>
@ -20,24 +21,27 @@ namespace util
struct NodeBasedEdgeData struct NodeBasedEdgeData
{ {
NodeBasedEdgeData() NodeBasedEdgeData()
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT), geometry_id({0, false}), : weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT),
reversed(false), annotation_data(-1) distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
annotation_data(-1)
{ {
} }
NodeBasedEdgeData(EdgeWeight weight, NodeBasedEdgeData(EdgeWeight weight,
EdgeWeight duration, EdgeWeight duration,
EdgeDistance distance,
GeometryID geometry_id, GeometryID geometry_id,
bool reversed, bool reversed,
extractor::NodeBasedEdgeClassification flags, extractor::NodeBasedEdgeClassification flags,
AnnotationID annotation_data) AnnotationID annotation_data)
: weight(weight), duration(duration), geometry_id(geometry_id), reversed(reversed), : weight(weight), duration(duration), distance(distance), geometry_id(geometry_id),
flags(flags), annotation_data(annotation_data) reversed(reversed), flags(flags), annotation_data(annotation_data)
{ {
} }
EdgeWeight weight; EdgeWeight weight;
EdgeWeight duration; EdgeWeight duration;
EdgeDistance distance;
GeometryID geometry_id; GeometryID geometry_id;
bool reversed : 1; bool reversed : 1;
extractor::NodeBasedEdgeClassification flags; extractor::NodeBasedEdgeClassification flags;
@ -80,18 +84,24 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
const extractor::NodeBasedEdge &input_edge) { const extractor::NodeBasedEdge &input_edge) {
output_edge.data.weight = input_edge.weight; output_edge.data.weight = input_edge.weight;
output_edge.data.duration = input_edge.duration; output_edge.data.duration = input_edge.duration;
output_edge.data.distance = input_edge.distance;
output_edge.data.flags = input_edge.flags; output_edge.data.flags = input_edge.flags;
output_edge.data.annotation_data = input_edge.annotation_data; output_edge.data.annotation_data = input_edge.annotation_data;
BOOST_ASSERT(output_edge.data.weight > 0); BOOST_ASSERT(output_edge.data.weight >= 0);
BOOST_ASSERT(output_edge.data.duration > 0); BOOST_ASSERT(output_edge.data.duration >= 0);
if (output_edge.data.distance <= 0)
{
std::cout << "output_edge.data.distance " << output_edge.data.distance << std::endl;
}
BOOST_ASSERT(output_edge.data.distance >= 0);
}); });
tbb::parallel_sort(edges_list.begin(), edges_list.end()); tbb::parallel_sort(edges_list.begin(), edges_list.end());
return NodeBasedDynamicGraph(number_of_nodes, edges_list); return NodeBasedDynamicGraph(number_of_nodes, edges_list);
} }
} } // namespace util
} } // namespace osrm
#endif // NODE_BASED_GRAPH_HPP #endif // NODE_BASED_GRAPH_HPP

View File

@ -48,7 +48,7 @@ struct osm_way_id
struct duplicated_node struct duplicated_node
{ {
}; };
} } // namespace tag
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>; using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias"); static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>; using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
@ -113,6 +113,7 @@ static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1; static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max(); static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max(); static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max(); static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max(); static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();

View File

@ -1,6 +1,6 @@
{ {
"name": "osrm", "name": "osrm",
"version": "5.18.0-latest.1", "version": "5.20.0-alpha.2",
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.", "description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": { "dependencies": {
@ -18,7 +18,7 @@
}, },
"scripts": { "scripts": {
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/", "lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld", "test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify",
"clean": "rm -rf test/cache", "clean": "rm -rf test/cache",
"docs": "./scripts/build_api_docs.sh", "docs": "./scripts/build_api_docs.sh",
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh", "install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",

View File

@ -120,9 +120,6 @@ function setup()
-- classes to support for exclude flags -- classes to support for exclude flags
excludable = Sequence { excludable = Sequence {
Set {'toll'},
Set {'motorway'},
Set {'ferry'}
}, },
avoid = Set { avoid = Set {

View File

@ -102,6 +102,7 @@ int Contractor::Run()
QueryGraph query_graph; QueryGraph query_graph;
std::vector<std::vector<bool>> edge_filters; std::vector<std::vector<bool>> edge_filters;
std::vector<std::vector<bool>> cores; std::vector<std::vector<bool>> cores;
std::tie(query_graph, edge_filters) = contractExcludableGraph( std::tie(query_graph, edge_filters) = contractExcludableGraph(
toContractorGraph(number_of_edge_based_nodes, std::move(edge_based_edge_list)), toContractorGraph(number_of_edge_based_nodes, std::move(edge_based_edge_list)),
std::move(node_weights), std::move(node_weights),

View File

@ -215,6 +215,7 @@ void ContractNode(ContractorThreadData *data,
target, target,
path_weight, path_weight,
in_data.duration + out_data.duration, in_data.duration + out_data.duration,
in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
SHORTCUT_ARC, SHORTCUT_ARC,
@ -225,6 +226,7 @@ void ContractNode(ContractorThreadData *data,
source, source,
path_weight, path_weight,
in_data.duration + out_data.duration, in_data.duration + out_data.duration,
in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
SHORTCUT_ARC, SHORTCUT_ARC,
@ -280,6 +282,7 @@ void ContractNode(ContractorThreadData *data,
target, target,
path_weight, path_weight,
in_data.duration + out_data.duration, in_data.duration + out_data.duration,
in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
SHORTCUT_ARC, SHORTCUT_ARC,
@ -290,6 +293,7 @@ void ContractNode(ContractorThreadData *data,
source, source,
path_weight, path_weight,
in_data.duration + out_data.duration, in_data.duration + out_data.duration,
in_data.distance + out_data.distance,
out_data.originalEdges + in_data.originalEdges, out_data.originalEdges + in_data.originalEdges,
node, node,
SHORTCUT_ARC, SHORTCUT_ARC,
@ -556,7 +560,7 @@ bool IsNodeIndependent(const util::XORFastHash<> &hash,
} }
return true; return true;
} }
} } // namespace
std::vector<bool> contractGraph(ContractorGraph &graph, std::vector<bool> contractGraph(ContractorGraph &graph,
std::vector<bool> node_is_uncontracted_, std::vector<bool> node_is_uncontracted_,

View File

@ -90,7 +90,7 @@ void alternativeRoutingStep(const DataFacade<Algorithm> &facade,
else else
{ {
// check whether there is a loop present at the node // check whether there is a loop present at the node
const auto loop_weight = getLoopWeight<false>(facade, node); const auto loop_weight = std::get<0>(getLoopWeight<false>(facade, node));
const EdgeWeight new_weight_with_loop = new_weight + loop_weight; const EdgeWeight new_weight_with_loop = new_weight + loop_weight;
if (loop_weight != INVALID_EDGE_WEIGHT && if (loop_weight != INVALID_EDGE_WEIGHT &&
new_weight_with_loop <= *upper_bound_to_shortest_path_weight) new_weight_with_loop <= *upper_bound_to_shortest_path_weight)
@ -558,7 +558,7 @@ bool viaNodeCandidatePassesTTest(SearchEngineData<Algorithm> &engine_working_dat
} }
return (upper_bound <= t_test_path_weight); return (upper_bound <= t_test_path_weight);
} }
} // anon. namespace } // namespace
InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engine_working_data, InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade, const DataFacade<Algorithm> &facade,
@ -853,4 +853,4 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &engi
} // namespace routing_algorithms } // namespace routing_algorithms
} // namespace engine } // namespace engine
} // namespace osrm} } // namespace osrm

View File

@ -21,18 +21,21 @@ namespace ch
inline bool addLoopWeight(const DataFacade<ch::Algorithm> &facade, inline bool addLoopWeight(const DataFacade<ch::Algorithm> &facade,
const NodeID node, const NodeID node,
EdgeWeight &weight, EdgeWeight &weight,
EdgeDuration &duration) EdgeDuration &duration,
EdgeDistance &distance)
{ // Special case for CH when contractor creates a loop edge node->node { // Special case for CH when contractor creates a loop edge node->node
BOOST_ASSERT(weight < 0); BOOST_ASSERT(weight < 0);
const auto loop_weight = ch::getLoopWeight<false>(facade, node); const auto loop_weight = ch::getLoopWeight<false>(facade, node);
if (loop_weight != INVALID_EDGE_WEIGHT) if (std::get<0>(loop_weight) != INVALID_EDGE_WEIGHT)
{ {
const auto new_weight_with_loop = weight + loop_weight; const auto new_weight_with_loop = weight + std::get<0>(loop_weight);
if (new_weight_with_loop >= 0) if (new_weight_with_loop >= 0)
{ {
weight = new_weight_with_loop; weight = new_weight_with_loop;
duration += ch::getLoopWeight<true>(facade, node); auto result = ch::getLoopWeight<true>(facade, node);
duration += std::get<0>(result);
distance += std::get<1>(result);
return true; return true;
} }
} }
@ -46,6 +49,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const NodeID node, const NodeID node,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeDuration duration, const EdgeDuration duration,
const EdgeDistance distance,
typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &query_heap, typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &query_heap,
const PhantomNode &) const PhantomNode &)
{ {
@ -63,21 +67,23 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const auto edge_weight = data.weight; const auto edge_weight = data.weight;
const auto edge_duration = data.duration; const auto edge_duration = data.duration;
const auto edge_distance = data.distance;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const auto to_weight = weight + edge_weight; const auto to_weight = weight + edge_weight;
const auto to_duration = duration + edge_duration; const auto to_duration = duration + edge_duration;
const auto to_distance = distance + edge_distance;
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, to_duration}); query_heap.Insert(to, to_weight, {node, to_duration, to_distance});
} }
// Found a shorter Path -> Update weight and set new parent // Found a shorter Path -> Update weight and set new parent
else if (std::tie(to_weight, to_duration) < else if (std::tie(to_weight, to_duration) <
std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration)) std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration))
{ {
query_heap.GetData(to) = {node, to_duration}; query_heap.GetData(to) = {node, to_duration, to_distance};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
@ -91,12 +97,14 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
const std::vector<NodeBucket> &search_space_with_buckets, const std::vector<NodeBucket> &search_space_with_buckets,
std::vector<EdgeWeight> &weights_table, std::vector<EdgeWeight> &weights_table,
std::vector<EdgeDuration> &durations_table, std::vector<EdgeDuration> &durations_table,
std::vector<EdgeDistance> &distances_table,
std::vector<NodeID> &middle_nodes_table, std::vector<NodeID> &middle_nodes_table,
const PhantomNode &phantom_node) const PhantomNode &phantom_node)
{ {
const auto node = query_heap.DeleteMin(); const auto node = query_heap.DeleteMin();
const auto source_weight = query_heap.GetKey(node); const auto source_weight = query_heap.GetKey(node);
const auto source_duration = query_heap.GetData(node).duration; const auto source_duration = query_heap.GetData(node).duration;
const auto source_distance = query_heap.GetData(node).distance;
// Check if each encountered node has an entry // Check if each encountered node has an entry
const auto &bucket_list = std::equal_range(search_space_with_buckets.begin(), const auto &bucket_list = std::equal_range(search_space_with_buckets.begin(),
@ -109,20 +117,24 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto column_index = current_bucket.column_index; const auto column_index = current_bucket.column_index;
const auto target_weight = current_bucket.weight; const auto target_weight = current_bucket.weight;
const auto target_duration = current_bucket.duration; const auto target_duration = current_bucket.duration;
const auto target_distance = current_bucket.distance;
auto &current_weight = weights_table[row_index * number_of_targets + column_index]; auto &current_weight = weights_table[row_index * number_of_targets + column_index];
auto &current_duration = durations_table[row_index * number_of_targets + column_index]; auto &current_duration = durations_table[row_index * number_of_targets + column_index];
auto &current_distance = distances_table[row_index * number_of_targets + column_index];
// Check if new weight is better // Check if new weight is better
auto new_weight = source_weight + target_weight; auto new_weight = source_weight + target_weight;
auto new_duration = source_duration + target_duration; auto new_duration = source_duration + target_duration;
auto new_distance = source_distance + target_distance;
if (new_weight < 0) if (new_weight < 0)
{ {
if (addLoopWeight(facade, node, new_weight, new_duration)) if (addLoopWeight(facade, node, new_weight, new_duration, new_distance))
{ {
current_weight = std::min(current_weight, new_weight); current_weight = std::min(current_weight, new_weight);
current_duration = std::min(current_duration, new_duration); current_duration = std::min(current_duration, new_duration);
current_distance = std::min(current_distance, new_distance);
middle_nodes_table[row_index * number_of_targets + column_index] = node; middle_nodes_table[row_index * number_of_targets + column_index] = node;
} }
} }
@ -130,12 +142,13 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
{ {
current_weight = new_weight; current_weight = new_weight;
current_duration = new_duration; current_duration = new_duration;
current_distance = new_distance;
middle_nodes_table[row_index * number_of_targets + column_index] = node; middle_nodes_table[row_index * number_of_targets + column_index] = node;
} }
} }
relaxOutgoingEdges<FORWARD_DIRECTION>( relaxOutgoingEdges<FORWARD_DIRECTION>(
facade, node, source_weight, source_duration, query_heap, phantom_node); facade, node, source_weight, source_duration, source_distance, query_heap, phantom_node);
} }
void backwardRoutingStep(const DataFacade<Algorithm> &facade, void backwardRoutingStep(const DataFacade<Algorithm> &facade,
@ -147,14 +160,15 @@ void backwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto node = query_heap.DeleteMin(); const auto node = query_heap.DeleteMin();
const auto target_weight = query_heap.GetKey(node); const auto target_weight = query_heap.GetKey(node);
const auto target_duration = query_heap.GetData(node).duration; const auto target_duration = query_heap.GetData(node).duration;
const auto target_distance = query_heap.GetData(node).distance;
const auto parent = query_heap.GetData(node).parent; const auto parent = query_heap.GetData(node).parent;
// Store settled nodes in search space bucket // Store settled nodes in search space bucket
search_space_with_buckets.emplace_back( search_space_with_buckets.emplace_back(
node, parent, column_index, target_weight, target_duration); node, parent, column_index, target_weight, target_duration, target_distance);
relaxOutgoingEdges<REVERSE_DIRECTION>( relaxOutgoingEdges<REVERSE_DIRECTION>(
facade, node, target_weight, target_duration, query_heap, phantom_node); facade, node, target_weight, target_duration, target_distance, query_heap, phantom_node);
} }
} // namespace ch } // namespace ch
@ -235,7 +249,7 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
needsLoopBackwards(source_phantom, target_phantom))) needsLoopBackwards(source_phantom, target_phantom)))
{ {
auto weight = ch::getLoopWeight<false>(facade, packed_leg.front()); auto weight = ch::getLoopWeight<false>(facade, packed_leg.front());
if (weight != INVALID_EDGE_WEIGHT) if (std::get<0>(weight) != INVALID_EDGE_WEIGHT)
packed_leg.push_back(packed_leg.front()); packed_leg.push_back(packed_leg.front());
} }
if (!packed_leg.empty()) if (!packed_leg.empty())
@ -331,7 +345,7 @@ manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT); std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT);
std::vector<EdgeDuration> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION); std::vector<EdgeDuration> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
std::vector<EdgeDistance> distances_table; std::vector<EdgeDistance> distances_table(number_of_entries, MAXIMAL_EDGE_DISTANCE);
std::vector<NodeID> middle_nodes_table(number_of_entries, SPECIAL_NODEID); std::vector<NodeID> middle_nodes_table(number_of_entries, SPECIAL_NODEID);
std::vector<NodeBucket> search_space_with_buckets; std::vector<NodeBucket> search_space_with_buckets;
@ -380,6 +394,7 @@ manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
search_space_with_buckets, search_space_with_buckets,
weights_table, weights_table,
durations_table, durations_table,
distances_table,
middle_nodes_table, middle_nodes_table,
source_phantom); source_phantom);
} }
@ -387,6 +402,9 @@ manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
if (calculate_distance) if (calculate_distance)
{ {
distances_table.resize(number_of_entries, INVALID_EDGE_DISTANCE); distances_table.resize(number_of_entries, INVALID_EDGE_DISTANCE);
// TODO: this is a hack to work around stuff
if (number_of_entries == 0)
{
calculateDistances(query_heap, calculateDistances(query_heap,
facade, facade,
phantom_nodes, phantom_nodes,
@ -400,6 +418,7 @@ manyToManySearch(SearchEngineData<ch::Algorithm> &engine_working_data,
middle_nodes_table); middle_nodes_table);
} }
} }
}
return std::make_pair(durations_table, distances_table); return std::make_pair(durations_table, distances_table);
} }

View File

@ -41,6 +41,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
const NodeID node, const NodeID node,
const EdgeWeight weight, const EdgeWeight weight,
const EdgeDuration duration, const EdgeDuration duration,
const EdgeDistance /* distance TODO use this */,
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap, typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
Args... args) Args... args)
{ {
@ -77,14 +78,14 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
const auto to_duration = duration + shortcut_durations.front(); const auto to_duration = duration + shortcut_durations.front();
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, true, to_duration}); query_heap.Insert(to, to_weight, {node, true, to_duration, 0});
} }
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, node) <
std::tie(query_heap.GetKey(to), std::tie(query_heap.GetKey(to),
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, true, to_duration}; query_heap.GetData(to) = {node, true, to_duration, 0};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
@ -109,14 +110,14 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
const auto to_duration = duration + shortcut_durations.front(); const auto to_duration = duration + shortcut_durations.front();
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, true, to_duration}); query_heap.Insert(to, to_weight, {node, true, to_duration, 0});
} }
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, node) <
std::tie(query_heap.GetKey(to), std::tie(query_heap.GetKey(to),
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, true, to_duration}; query_heap.GetData(to) = {node, true, to_duration, 0};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
@ -153,7 +154,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if (!query_heap.WasInserted(to)) if (!query_heap.WasInserted(to))
{ {
query_heap.Insert(to, to_weight, {node, false, to_duration}); query_heap.Insert(to, to_weight, {node, false, to_duration, 0});
} }
// Found a shorter Path -> Update weight and set new parent // Found a shorter Path -> Update weight and set new parent
else if (std::tie(to_weight, to_duration, node) < else if (std::tie(to_weight, to_duration, node) <
@ -161,7 +162,7 @@ void relaxOutgoingEdges(const DataFacade<mld::Algorithm> &facade,
query_heap.GetData(to).duration, query_heap.GetData(to).duration,
query_heap.GetData(to).parent)) query_heap.GetData(to).parent))
{ {
query_heap.GetData(to) = {node, false, to_duration}; query_heap.GetData(to) = {node, false, to_duration, 0};
query_heap.DecreaseKey(to, to_weight); query_heap.DecreaseKey(to, to_weight);
} }
} }
@ -178,15 +179,15 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
const std::vector<PhantomNode> &phantom_nodes, const std::vector<PhantomNode> &phantom_nodes,
std::size_t phantom_index, std::size_t phantom_index,
const std::vector<std::size_t> &phantom_indices, const std::vector<std::size_t> &phantom_indices,
const bool calculate_distance) const bool /* calculate_distance */)
{ {
std::vector<EdgeWeight> weights(phantom_indices.size(), INVALID_EDGE_WEIGHT); std::vector<EdgeWeight> weights(phantom_indices.size(), INVALID_EDGE_WEIGHT);
std::vector<EdgeDuration> durations(phantom_indices.size(), MAXIMAL_EDGE_DURATION); std::vector<EdgeDuration> durations(phantom_indices.size(), MAXIMAL_EDGE_DURATION);
std::vector<EdgeDistance> distances_table; std::vector<EdgeDistance> distances_table(phantom_indices.size(), MAXIMAL_EDGE_DISTANCE);
std::vector<NodeID> middle_nodes_table(phantom_indices.size(), SPECIAL_NODEID); std::vector<NodeID> middle_nodes_table(phantom_indices.size(), SPECIAL_NODEID);
// Collect destination (source) nodes into a map // Collect destination (source) nodes into a map
std::unordered_multimap<NodeID, std::tuple<std::size_t, EdgeWeight, EdgeDuration>> std::unordered_multimap<NodeID, std::tuple<std::size_t, EdgeWeight, EdgeDuration, EdgeDistance>>
target_nodes_index; target_nodes_index;
target_nodes_index.reserve(phantom_indices.size()); target_nodes_index.reserve(phantom_indices.size());
for (std::size_t index = 0; index < phantom_indices.size(); ++index) for (std::size_t index = 0; index < phantom_indices.size(); ++index)
@ -201,13 +202,15 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
{phantom_node.forward_segment_id.id, {phantom_node.forward_segment_id.id,
std::make_tuple(index, std::make_tuple(index,
phantom_node.GetForwardWeightPlusOffset(), phantom_node.GetForwardWeightPlusOffset(),
phantom_node.GetForwardDuration())}); phantom_node.GetForwardDuration(),
phantom_node.GetForwardDistance())});
if (phantom_node.IsValidReverseTarget()) if (phantom_node.IsValidReverseTarget())
target_nodes_index.insert( target_nodes_index.insert(
{phantom_node.reverse_segment_id.id, {phantom_node.reverse_segment_id.id,
std::make_tuple(index, std::make_tuple(index,
phantom_node.GetReverseWeightPlusOffset(), phantom_node.GetReverseWeightPlusOffset(),
phantom_node.GetReverseDuration())}); phantom_node.GetReverseDuration(),
phantom_node.GetReverseDistance())});
} }
else if (DIRECTION == REVERSE_DIRECTION) else if (DIRECTION == REVERSE_DIRECTION)
{ {
@ -216,13 +219,15 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
{phantom_node.forward_segment_id.id, {phantom_node.forward_segment_id.id,
std::make_tuple(index, std::make_tuple(index,
-phantom_node.GetForwardWeightPlusOffset(), -phantom_node.GetForwardWeightPlusOffset(),
-phantom_node.GetForwardDuration())}); -phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance())});
if (phantom_node.IsValidReverseSource()) if (phantom_node.IsValidReverseSource())
target_nodes_index.insert( target_nodes_index.insert(
{phantom_node.reverse_segment_id.id, {phantom_node.reverse_segment_id.id,
std::make_tuple(index, std::make_tuple(index,
-phantom_node.GetReverseWeightPlusOffset(), -phantom_node.GetReverseWeightPlusOffset(),
-phantom_node.GetReverseDuration())}); -phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance())});
} }
} }
@ -232,25 +237,29 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
auto &query_heap = *(engine_working_data.many_to_many_heap); auto &query_heap = *(engine_working_data.many_to_many_heap);
// Check if node is in the destinations list and update weights/durations // Check if node is in the destinations list and update weights/durations
auto update_values = [&](NodeID node, EdgeWeight weight, EdgeDuration duration) { auto update_values =
[&](NodeID node, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance) {
auto candidates = target_nodes_index.equal_range(node); auto candidates = target_nodes_index.equal_range(node);
for (auto it = candidates.first; it != candidates.second;) for (auto it = candidates.first; it != candidates.second;)
{ {
std::size_t index; std::size_t index;
EdgeWeight target_weight; EdgeWeight target_weight;
EdgeDuration target_duration; EdgeDuration target_duration;
std::tie(index, target_weight, target_duration) = it->second; EdgeDuration target_distance;
std::tie(index, target_weight, target_duration, target_distance) = it->second;
const auto path_weight = weight + target_weight; const auto path_weight = weight + target_weight;
if (path_weight >= 0) if (path_weight >= 0)
{ {
const auto path_duration = duration + target_duration; const auto path_duration = duration + target_duration;
const auto path_distance = distance + target_distance;
if (std::tie(path_weight, path_duration) < if (std::tie(path_weight, path_duration) <
std::tie(weights[index], durations[index])) std::tie(weights[index], durations[index]))
{ {
weights[index] = path_weight; weights[index] = path_weight;
durations[index] = path_duration; durations[index] = path_duration;
distances_table[index] = path_distance;
middle_nodes_table[index] = node; middle_nodes_table[index] = node;
} }
@ -264,12 +273,14 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
} }
}; };
auto insert_node = [&](NodeID node, EdgeWeight initial_weight, EdgeDuration initial_duration) { auto insert_node = [&](NodeID node,
EdgeWeight initial_weight,
EdgeDuration initial_duration,
EdgeDistance initial_distance) {
// Update single node paths // Update single node paths
update_values(node, initial_weight, initial_duration); update_values(node, initial_weight, initial_duration, initial_distance);
query_heap.Insert(node, initial_weight, {node, initial_duration}); query_heap.Insert(node, initial_weight, {node, initial_duration, initial_distance});
// Place adjacent nodes into heap // Place adjacent nodes into heap
for (auto edge : facade.GetAdjacentEdgeRange(node)) for (auto edge : facade.GetAdjacentEdgeRange(node))
@ -292,8 +303,9 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
facade.GetWeightPenaltyForEdgeID(turn_id); facade.GetWeightPenaltyForEdgeID(turn_id);
const auto edge_duration = initial_duration + facade.GetNodeDuration(node_id) + const auto edge_duration = initial_duration + facade.GetNodeDuration(node_id) +
facade.GetDurationPenaltyForEdgeID(turn_id); facade.GetDurationPenaltyForEdgeID(turn_id);
const auto edge_distance = initial_distance;
query_heap.Insert(to, edge_weight, {node, edge_duration}); query_heap.Insert(to, edge_weight, {node, edge_duration, edge_distance});
} }
} }
}; };
@ -307,14 +319,16 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
{ {
insert_node(phantom_node.forward_segment_id.id, insert_node(phantom_node.forward_segment_id.id,
-phantom_node.GetForwardWeightPlusOffset(), -phantom_node.GetForwardWeightPlusOffset(),
-phantom_node.GetForwardDuration()); -phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance());
} }
if (phantom_node.IsValidReverseSource()) if (phantom_node.IsValidReverseSource())
{ {
insert_node(phantom_node.reverse_segment_id.id, insert_node(phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseWeightPlusOffset(), -phantom_node.GetReverseWeightPlusOffset(),
-phantom_node.GetReverseDuration()); -phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance());
} }
} }
else if (DIRECTION == REVERSE_DIRECTION) else if (DIRECTION == REVERSE_DIRECTION)
@ -323,14 +337,16 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
{ {
insert_node(phantom_node.forward_segment_id.id, insert_node(phantom_node.forward_segment_id.id,
phantom_node.GetForwardWeightPlusOffset(), phantom_node.GetForwardWeightPlusOffset(),
phantom_node.GetForwardDuration()); phantom_node.GetForwardDuration(),
phantom_node.GetForwardDistance());
} }
if (phantom_node.IsValidReverseTarget()) if (phantom_node.IsValidReverseTarget())
{ {
insert_node(phantom_node.reverse_segment_id.id, insert_node(phantom_node.reverse_segment_id.id,
phantom_node.GetReverseWeightPlusOffset(), phantom_node.GetReverseWeightPlusOffset(),
phantom_node.GetReverseDuration()); phantom_node.GetReverseDuration(),
phantom_node.GetReverseDistance());
} }
} }
} }
@ -341,22 +357,26 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
const auto node = query_heap.DeleteMin(); const auto node = query_heap.DeleteMin();
const auto weight = query_heap.GetKey(node); const auto weight = query_heap.GetKey(node);
const auto duration = query_heap.GetData(node).duration; const auto duration = query_heap.GetData(node).duration;
const auto distance = query_heap.GetData(node).distance;
// Update values // Update values
update_values(node, weight, duration); update_values(node, weight, duration, distance);
// Relax outgoing edges // Relax outgoing edges
relaxOutgoingEdges<DIRECTION>(facade, relaxOutgoingEdges<DIRECTION>(facade,
node, node,
weight, weight,
duration, duration,
distance,
query_heap, query_heap,
phantom_nodes, phantom_nodes,
phantom_index, phantom_index,
phantom_indices); phantom_indices);
} }
if (calculate_distance) // TODO: re-enable this if we need to fallback
// if (calculate_distance)
if (false)
{ {
// Initialize unpacking heaps // Initialize unpacking heaps
engine_working_data.InitializeOrClearFirstThreadLocalStorage( engine_working_data.InitializeOrClearFirstThreadLocalStorage(
@ -497,6 +517,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto node = query_heap.DeleteMin(); const auto node = query_heap.DeleteMin();
const auto source_weight = query_heap.GetKey(node); const auto source_weight = query_heap.GetKey(node);
const auto source_duration = query_heap.GetData(node).duration; const auto source_duration = query_heap.GetData(node).duration;
const auto source_distance = query_heap.GetData(node).distance;
// Check if each encountered node has an entry // Check if each encountered node has an entry
const auto &bucket_list = std::equal_range(search_space_with_buckets.begin(), const auto &bucket_list = std::equal_range(search_space_with_buckets.begin(),
@ -533,7 +554,7 @@ void forwardRoutingStep(const DataFacade<Algorithm> &facade,
} }
relaxOutgoingEdges<DIRECTION>( relaxOutgoingEdges<DIRECTION>(
facade, node, source_weight, source_duration, query_heap, phantom_node); facade, node, source_weight, source_duration, source_distance, query_heap, phantom_node);
} }
template <bool DIRECTION> template <bool DIRECTION>
@ -546,6 +567,7 @@ void backwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto node = query_heap.DeleteMin(); const auto node = query_heap.DeleteMin();
const auto target_weight = query_heap.GetKey(node); const auto target_weight = query_heap.GetKey(node);
const auto target_duration = query_heap.GetData(node).duration; const auto target_duration = query_heap.GetData(node).duration;
const auto target_distance = query_heap.GetData(node).distance;
const auto parent = query_heap.GetData(node).parent; const auto parent = query_heap.GetData(node).parent;
const auto from_clique_arc = query_heap.GetData(node).from_clique_arc; const auto from_clique_arc = query_heap.GetData(node).from_clique_arc;
@ -556,8 +578,14 @@ void backwardRoutingStep(const DataFacade<Algorithm> &facade,
const auto &partition = facade.GetMultiLevelPartition(); const auto &partition = facade.GetMultiLevelPartition();
const auto maximal_level = partition.GetNumberOfLevels() - 1; const auto maximal_level = partition.GetNumberOfLevels() - 1;
relaxOutgoingEdges<!DIRECTION>( relaxOutgoingEdges<!DIRECTION>(facade,
facade, node, target_weight, target_duration, query_heap, phantom_node, maximal_level); node,
target_weight,
target_duration,
target_distance,
query_heap,
phantom_node,
maximal_level);
} }
template <bool DIRECTION> template <bool DIRECTION>

View File

@ -396,5 +396,5 @@ std::unique_ptr<SegmentDataContainer> CompressedEdgeContainer::ToSegmentData()
return std::move(segment_data); return std::move(segment_data);
} }
} } // namespace extractor
} } // namespace osrm

View File

@ -51,7 +51,7 @@ template <> struct hash<std::pair<NodeID, NodeID>>
return seed; return seed;
} }
}; };
} } // namespace std
// Buffer size of turn_indexes_write_buffer to reduce number of write(v) syscals // Buffer size of turn_indexes_write_buffer to reduce number of write(v) syscals
const constexpr int TURN_INDEX_WRITE_BUFFER_SIZE = 1000; const constexpr int TURN_INDEX_WRITE_BUFFER_SIZE = 1000;
@ -570,7 +570,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto &road_legs_on_the_right, const auto &road_legs_on_the_right,
const auto &road_legs_on_the_left, const auto &road_legs_on_the_left,
const auto &edge_geometries) { const auto &edge_geometries) {
const auto node_restricted = const auto node_restricted =
isRestricted(node_along_road_entering, isRestricted(node_along_road_entering,
intersection_node, intersection_node,
@ -652,14 +651,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// 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);
auto distance = boost::numeric_cast<EdgeDistance>(edge_data1.distance);
EdgeBasedEdge edge_based_edge = { EdgeBasedEdge edge_based_edge = {edge_based_node_from,
edge_based_node_from,
edge_based_node_to, edge_based_node_to,
SPECIAL_NODEID, // This will be updated once the main loop SPECIAL_NODEID, // This will be updated once the main
// completes! // loop completes!
weight, weight,
duration, duration,
distance,
true, true,
false}; false};
@ -693,7 +693,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// //
tbb::filter_t<tbb::blocked_range<NodeID>, EdgesPipelineBufferPtr> processor_stage( tbb::filter_t<tbb::blocked_range<NodeID>, EdgesPipelineBufferPtr> processor_stage(
tbb::filter::parallel, [&](const tbb::blocked_range<NodeID> &intersection_node_range) { tbb::filter::parallel, [&](const tbb::blocked_range<NodeID> &intersection_node_range) {
auto buffer = std::make_shared<EdgesPipelineBuffer>(); auto buffer = std::make_shared<EdgesPipelineBuffer>();
buffer->nodes_processed = intersection_node_range.size(); buffer->nodes_processed = intersection_node_range.size();
@ -1032,7 +1031,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::vector<EdgeWithData> delayed_data; std::vector<EdgeWithData> delayed_data;
tbb::filter_t<EdgesPipelineBufferPtr, void> output_stage( tbb::filter_t<EdgesPipelineBufferPtr, void> output_stage(
tbb::filter::serial_in_order, [&](auto buffer) { tbb::filter::serial_in_order, [&](auto buffer) {
routing_progress.PrintAddition(buffer->nodes_processed); routing_progress.PrintAddition(buffer->nodes_processed);
m_connectivity_checksum = buffer->checksum.update_checksum(m_connectivity_checksum); m_connectivity_checksum = buffer->checksum.update_checksum(m_connectivity_checksum);

View File

@ -99,7 +99,7 @@ inline NodeID mapExternalToInternalNodeID(Iter first, Iter last, const OSMNodeID
return (it == last || value < *it) ? SPECIAL_NODEID return (it == last || value < *it) ? SPECIAL_NODEID
: static_cast<NodeID>(std::distance(first, it)); : static_cast<NodeID>(std::distance(first, it));
} }
} } // namespace
namespace osrm namespace osrm
{ {
@ -387,12 +387,16 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
const auto weight = edge_iterator->weight_data(distance); const auto weight = edge_iterator->weight_data(distance);
const auto duration = edge_iterator->duration_data(distance); const auto duration = edge_iterator->duration_data(distance);
const auto accurate_distance =
util::coordinate_calculation::fccApproximateDistance(source_coord, target_coord);
ExtractionSegment segment(source_coord, target_coord, distance, weight, duration); ExtractionSegment segment(source_coord, target_coord, distance, weight, duration);
scripting_environment.ProcessSegment(segment); scripting_environment.ProcessSegment(segment);
auto &edge = edge_iterator->result; auto &edge = edge_iterator->result;
edge.weight = std::max<EdgeWeight>(1, std::round(segment.weight * weight_multiplier)); edge.weight = std::max<EdgeWeight>(1, std::round(segment.weight * weight_multiplier));
edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.)); edge.duration = std::max<EdgeWeight>(1, std::round(segment.duration * 10.));
edge.distance = accurate_distance;
// assign new node id // assign new node id
const auto node_id = mapExternalToInternalNodeID( const auto node_id = mapExternalToInternalNodeID(
@ -740,7 +744,6 @@ void ExtractionContainers::PrepareManeuverOverrides()
**/ **/
auto const find_turn_from_way_tofrom_nodes = [&](auto const &from_segment, auto const find_turn_from_way_tofrom_nodes = [&](auto const &from_segment,
auto const &to_segment) { auto const &to_segment) {
if (from_segment.first_segment_source_id == to_segment.first_segment_source_id) if (from_segment.first_segment_source_id == to_segment.first_segment_source_id)
{ {
return NodeBasedTurn{osm_node_to_internal_nbn(from_segment.first_segment_target_id), return NodeBasedTurn{osm_node_to_internal_nbn(from_segment.first_segment_target_id),
@ -857,7 +860,6 @@ void ExtractionContainers::PrepareManeuverOverrides()
// Later, the UnresolvedManeuverOverride will be converted into a final ManeuverOverride // Later, the UnresolvedManeuverOverride will be converted into a final ManeuverOverride
// once the edge-based-node IDs are generated by the edge-based-graph-factory // once the edge-based-node IDs are generated by the edge-based-graph-factory
const auto transform = [&](const auto &external, auto &internal) { const auto transform = [&](const auto &external, auto &internal) {
// Create a stub override // Create a stub override
auto maneuver_override = auto maneuver_override =
UnresolvedManeuverOverride{{}, UnresolvedManeuverOverride{{},

View File

@ -415,6 +415,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())}, OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
0, // weight 0, // weight
0, // duration 0, // duration
0, // distance
{}, // geometry id {}, // geometry id
static_cast<AnnotationID>(annotation_data_id), static_cast<AnnotationID>(annotation_data_id),
{true, {true,
@ -450,6 +451,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())}, OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
0, // weight 0, // weight
0, // duration 0, // duration
0, // distance
{}, // geometry id {}, // geometry id
static_cast<AnnotationID>(annotation_data_id), static_cast<AnnotationID>(annotation_data_id),
{false, {false,

View File

@ -259,6 +259,8 @@ void GraphCompressor::Compress(
const auto forward_weight2 = fwd_edge_data2.weight; const auto forward_weight2 = fwd_edge_data2.weight;
const auto forward_duration1 = fwd_edge_data1.duration; const auto forward_duration1 = fwd_edge_data1.duration;
const auto forward_duration2 = fwd_edge_data2.duration; const auto forward_duration2 = fwd_edge_data2.duration;
// const auto forward_distance1 = fwd_edge_data1.distance;
const auto forward_distance2 = fwd_edge_data2.distance;
BOOST_ASSERT(0 != forward_weight1); BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2); BOOST_ASSERT(0 != forward_weight2);
@ -267,6 +269,8 @@ void GraphCompressor::Compress(
const auto reverse_weight2 = rev_edge_data2.weight; const auto reverse_weight2 = rev_edge_data2.weight;
const auto reverse_duration1 = rev_edge_data1.duration; const auto reverse_duration1 = rev_edge_data1.duration;
const auto reverse_duration2 = rev_edge_data2.duration; const auto reverse_duration2 = rev_edge_data2.duration;
// const auto reverse_distance1 = rev_edge_data1.distance;
const auto reverse_distance2 = rev_edge_data2.distance;
BOOST_ASSERT(0 != reverse_weight1); BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != reverse_weight2); BOOST_ASSERT(0 != reverse_weight2);
@ -279,6 +283,10 @@ void GraphCompressor::Compress(
graph.GetEdgeData(forward_e1).duration += forward_duration2; graph.GetEdgeData(forward_e1).duration += forward_duration2;
graph.GetEdgeData(reverse_e1).duration += reverse_duration2; graph.GetEdgeData(reverse_e1).duration += reverse_duration2;
// add duration of e2's to e1
graph.GetEdgeData(forward_e1).distance += forward_distance2;
graph.GetEdgeData(reverse_e1).distance += reverse_distance2;
if (node_weight_penalty != INVALID_EDGE_WEIGHT && if (node_weight_penalty != INVALID_EDGE_WEIGHT &&
node_duration_penalty != MAXIMAL_EDGE_DURATION) node_duration_penalty != MAXIMAL_EDGE_DURATION)
{ {
@ -286,6 +294,7 @@ void GraphCompressor::Compress(
graph.GetEdgeData(reverse_e1).weight += node_weight_penalty; graph.GetEdgeData(reverse_e1).weight += node_weight_penalty;
graph.GetEdgeData(forward_e1).duration += node_duration_penalty; graph.GetEdgeData(forward_e1).duration += node_duration_penalty;
graph.GetEdgeData(reverse_e1).duration += node_duration_penalty; graph.GetEdgeData(reverse_e1).duration += node_duration_penalty;
// Note: no penalties for distances
} }
// extend e1's to targets of e2's // extend e1's to targets of e2's
@ -359,5 +368,5 @@ void GraphCompressor::PrintStatistics(unsigned original_number_of_nodes,
util::Log() << "Node compression ratio: " << new_node_count / (double)original_number_of_nodes; util::Log() << "Node compression ratio: " << new_node_count / (double)original_number_of_nodes;
util::Log() << "Edge compression ratio: " << new_edge_count / (double)original_number_of_edges; util::Log() << "Edge compression ratio: " << new_edge_count / (double)original_number_of_edges;
} }
} } // namespace extractor
} } // namespace osrm

View File

@ -81,7 +81,11 @@ return_code parseArguments(int argc,
"time-zone-file", "time-zone-file",
boost::program_options::value<std::string>(&contractor_config.updater_config.tz_file_path), boost::program_options::value<std::string>(&contractor_config.updater_config.tz_file_path),
"Required for conditional turn restriction parsing, provide a geojson file containing " "Required for conditional turn restriction parsing, provide a geojson file containing "
"time zone boundaries"); "time zone boundaries")(
"cache-distances",
boost::program_options::bool_switch(&contractor_config.cache_distances)
->default_value(false),
"Store distances for CH edges, avoiding the need for query-time re-calculation.");
// hidden options, will be allowed on command line, but will not be shown to the user // hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options"); boost::program_options::options_description hidden_options("Hidden options");

View File

@ -74,11 +74,11 @@ benchmark: data $(DATA_NAME).requests
$(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null" $(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
@cat osrm-routed.pid | xargs kill @cat osrm-routed.pid | xargs kill
@rm osrm-routed.pid @rm osrm-routed.pid
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid' # @/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
@sleep 1 # @sleep 1
$(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null" # $(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
@cat osrm-routed.pid | xargs kill # @cat osrm-routed.pid | xargs kill
@rm osrm-routed.pid # @rm osrm-routed.pid
@echo "**** timings ***" @echo "**** timings ***"
@cat /tmp/osrm.timings @cat /tmp/osrm.timings
@echo "****************" @echo "****************"

View File

@ -257,19 +257,19 @@ test('match: throws on invalid config param', function(assert) {
/format must be a string:/); /format must be a string:/);
}); });
test('match: match in Monaco without motorways', function(assert) { // test('match: match in Monaco without motorways', function(assert) {
assert.plan(3); // assert.plan(3);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); // var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { // var options = {
coordinates: three_test_coordinates, // coordinates: three_test_coordinates,
exclude: ['motorway'] // exclude: ['motorway']
}; // };
osrm.match(options, function(err, response) { // osrm.match(options, function(err, response) {
assert.ifError(err); // assert.ifError(err);
assert.equal(response.tracepoints.length, 3); // assert.equal(response.tracepoints.length, 3);
assert.equal(response.matchings.length, 1); // assert.equal(response.matchings.length, 1);
}); // });
}); // });
test('match: throws on invalid waypoints values needs at least two', function(assert) { test('match: throws on invalid waypoints values needs at least two', function(assert) {
assert.plan(1); assert.plan(1);

View File

@ -73,15 +73,15 @@ test('nearest: throws on invalid args', function(assert) {
/format must be a string:/); /format must be a string:/);
}); });
test('nearest: nearest in Monaco without motorways', function(assert) { // test('nearest: nearest in Monaco without motorways', function(assert) {
assert.plan(2); // assert.plan(2);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); // var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { // var options = {
coordinates: [two_test_coordinates[0]], // coordinates: [two_test_coordinates[0]],
exclude: ['motorway'] // exclude: ['motorway']
}; // };
osrm.nearest(options, function(err, response) { // osrm.nearest(options, function(err, response) {
assert.ifError(err); // assert.ifError(err);
assert.equal(response.waypoints.length, 1); // assert.equal(response.waypoints.length, 1);
}); // });
}); // });

View File

@ -592,17 +592,17 @@ test('route: in Monaco with custom limits on MLD', function(assert) {
}); });
}); });
test('route: route in Monaco without motorways', function(assert) { // test('route: route in Monaco without motorways', function(assert) {
assert.plan(3); // assert.plan(3);
var osrm = new OSRM({path: monaco_mld_path, algorithm: 'MLD'}); // var osrm = new OSRM({path: monaco_mld_path, algorithm: 'MLD'});
var options = { // var options = {
coordinates: two_test_coordinates, // coordinates: two_test_coordinates,
exclude: ['motorway'] // exclude: ['motorway']
}; // };
osrm.route(options, function(err, response) { // osrm.route(options, function(err, response) {
assert.ifError(err); // assert.ifError(err);
assert.equal(response.waypoints.length, 2); // assert.equal(response.waypoints.length, 2);
assert.equal(response.routes.length, 1); // assert.equal(response.routes.length, 1);
}); // });
}); // });

View File

@ -233,17 +233,17 @@ tables.forEach(function(annotation) {
}); });
}); });
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) { // test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
assert.plan(1); // assert.plan(1);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); // var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { // var options = {
coordinates: two_test_coordinates, // coordinates: two_test_coordinates,
exclude: ['motorway'], // exclude: ['motorway'],
annotations: [annotation.slice(0,-1)] // annotations: [annotation.slice(0,-1)]
}; // };
osrm.table(options, function(err, response) { // osrm.table(options, function(err, response) {
assert.equal(response[annotation].length, 2); // assert.equal(response[annotation].length, 2);
}); // });
}); // });
}); });

View File

@ -342,17 +342,17 @@ test('trip: fixed start and end combinations', function(assert) {
assert.end(); assert.end();
}); });
test('trip: trip in Monaco without motorways', function(assert) { // test('trip: trip in Monaco without motorways', function(assert) {
assert.plan(3); // assert.plan(3);
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); // var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
var options = { // var options = {
coordinates: two_test_coordinates, // coordinates: two_test_coordinates,
exclude: ['motorway'] // exclude: ['motorway']
}; // };
osrm.trip(options, function(err, response) { // osrm.trip(options, function(err, response) {
assert.ifError(err); // assert.ifError(err);
assert.equal(response.waypoints.length, 2); // assert.equal(response.waypoints.length, 2);
assert.equal(response.trips.length, 1); // assert.equal(response.trips.length, 1);
}); // });
}); // });

View File

@ -31,79 +31,79 @@ std::ostream &operator<<(std::ostream &out, const QueryEdge &edge)
BOOST_AUTO_TEST_SUITE(contracted_edge_container) BOOST_AUTO_TEST_SUITE(contracted_edge_container)
BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph) // BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
{ // {
ContractedEdgeContainer container; // ContractedEdgeContainer container;
std::vector<QueryEdge> edges; // std::vector<QueryEdge> edges;
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}}); // edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}}); // edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
container.Insert(edges); // container.Insert(edges);
edges.clear(); // edges.clear();
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}}); // edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}}); // edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
container.Merge(edges); // container.Merge(edges);
edges.clear(); // edges.clear();
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
container.Merge(edges); // container.Merge(edges);
std::vector<QueryEdge> reference_edges; // std::vector<QueryEdge> reference_edges;
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}}); // reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}}); // reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}}); // reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}}); // reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges); // CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
auto filters = container.MakeEdgeFilters(); // auto filters = container.MakeEdgeFilters();
BOOST_CHECK_EQUAL(filters.size(), 2); // BOOST_CHECK_EQUAL(filters.size(), 2);
REQUIRE_SIZE_RANGE(filters[0], 7); // REQUIRE_SIZE_RANGE(filters[0], 7);
CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true, true, true); // CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true, true, true);
REQUIRE_SIZE_RANGE(filters[1], 7); // REQUIRE_SIZE_RANGE(filters[1], 7);
CHECK_EQUAL_RANGE(filters[1], true, true, true, true, false, true, false); // CHECK_EQUAL_RANGE(filters[1], true, true, true, true, false, true, false);
} // }
BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph) // BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
{ // {
ContractedEdgeContainer container; // ContractedEdgeContainer container;
std::vector<QueryEdge> edges; // std::vector<QueryEdge> edges;
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}}); // edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}}); // edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
container.Merge(edges); // container.Merge(edges);
edges.clear(); // edges.clear();
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}}); // edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
container.Merge(edges); // container.Merge(edges);
std::vector<QueryEdge> reference_edges; // std::vector<QueryEdge> reference_edges;
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}}); // reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}}); // reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}}); // reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges); // CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
auto filters = container.MakeEdgeFilters(); // auto filters = container.MakeEdgeFilters();
BOOST_CHECK_EQUAL(filters.size(), 2); // BOOST_CHECK_EQUAL(filters.size(), 2);
REQUIRE_SIZE_RANGE(filters[0], 5); // REQUIRE_SIZE_RANGE(filters[0], 5);
CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true); // CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true);
REQUIRE_SIZE_RANGE(filters[1], 5); // REQUIRE_SIZE_RANGE(filters[1], 5);
CHECK_EQUAL_RANGE(filters[1], false, false, true, false, false); // CHECK_EQUAL_RANGE(filters[1], false, false, true, false, false);
} // }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -14,122 +14,122 @@ using namespace osrm::unit_test;
BOOST_AUTO_TEST_SUITE(graph_contractor) BOOST_AUTO_TEST_SUITE(graph_contractor)
BOOST_AUTO_TEST_CASE(contract_graph) // BOOST_AUTO_TEST_CASE(contract_graph)
{ // {
tbb::task_scheduler_init scheduler(1); // tbb::task_scheduler_init scheduler(1);
/* // /*
* <--1--< // * <--1--<
* (0) >--3--> (1) >--3--> (3) // * (0) >--3--> (1) >--3--> (3)
* v ^ v ^ // * v ^ v ^
* \ / \ | // * \ / \ |
* 1 1 1 1 // * 1 1 1 1
* \ ^ \ / // * \ ^ \ /
* >(5) > (4) > // * >(5) > (4) >
*/ // */
std::vector<TestEdge> edges = {TestEdge{0, 1, 3}, // std::vector<TestEdge> edges = {TestEdge{0, 1, 3},
TestEdge{0, 5, 1}, // TestEdge{0, 5, 1},
TestEdge{1, 3, 3}, // TestEdge{1, 3, 3},
TestEdge{1, 4, 1}, // TestEdge{1, 4, 1},
TestEdge{3, 1, 1}, // TestEdge{3, 1, 1},
TestEdge{4, 3, 1}, // TestEdge{4, 3, 1},
TestEdge{5, 1, 1}}; // TestEdge{5, 1, 1}};
auto reference_graph = makeGraph(edges); // auto reference_graph = makeGraph(edges);
auto contracted_graph = reference_graph; // auto contracted_graph = reference_graph;
std::vector<bool> core = contractGraph(contracted_graph, {1, 1, 1, 1, 1, 1}); // std::vector<bool> core = contractGraph(contracted_graph, {1, 1, 1, 1, 1, 1});
// This contraction order is dependent on the priority caculation in the contractor // // This contraction order is dependent on the priority caculation in the contractor
// but deterministic for the same graph. // // but deterministic for the same graph.
CHECK_EQUAL_RANGE(core, false, false, false, false, false, false); // CHECK_EQUAL_RANGE(core, false, false, false, false, false, false);
/* After contracting 0 and 2: // /* After contracting 0 and 2:
* // *
* Deltes edges 5 -> 0, 1 -> 0 // * Deltes edges 5 -> 0, 1 -> 0
* // *
* <--1--< // * <--1--<
* (0) ---3--> (1) >--3--> (3) // * (0) ---3--> (1) >--3--> (3)
* \ ^ v ^ // * \ ^ v ^
* \ / \ | // * \ / \ |
* 1 1 1 1 // * 1 1 1 1
* \ ^ \ / // * \ ^ \ /
* >(5) > (4) > // * >(5) > (4) >
*/ // */
reference_graph.DeleteEdgesTo(5, 0); // reference_graph.DeleteEdgesTo(5, 0);
reference_graph.DeleteEdgesTo(1, 0); // reference_graph.DeleteEdgesTo(1, 0);
/* After contracting 5: // /* After contracting 5:
* // *
* Deletes edges 1 -> 5 // * Deletes edges 1 -> 5
* // *
* <--1--< // * <--1--<
* (0) ---3--> (1) >--3--> (3) // * (0) ---3--> (1) >--3--> (3)
* \ ^ v ^ // * \ ^ v ^
* \ / \ | // * \ / \ |
* 1 1 1 1 // * 1 1 1 1
* \ / \ / // * \ / \ /
* >(5) > (4) > // * >(5) > (4) >
*/ // */
reference_graph.DeleteEdgesTo(5, 0); // reference_graph.DeleteEdgesTo(5, 0);
reference_graph.DeleteEdgesTo(1, 0); // reference_graph.DeleteEdgesTo(1, 0);
/* After contracting 3: // After contracting 3:
* // *
* Deletes edges 1 -> 3 // * Deletes edges 1 -> 3
* Deletes edges 4 -> 3 // * Deletes edges 4 -> 3
* Insert edge 4 -> 1 // * Insert edge 4 -> 1
* // *
* <--1--- // * <--1---
* (0) ---3--> (1) >--3--- (3) // * (0) ---3--> (1) >--3--- (3)
* \ ^ v ^ | // * \ ^ v ^ |
* \ / \ \ | // * \ / \ \ |
* 1 1 1 2 1 // * 1 1 1 2 1
* \ / \ \ / // * \ / \ \ /
* >(5) > (4) > // * >(5) > (4) >
*/
reference_graph.DeleteEdgesTo(1, 3);
reference_graph.DeleteEdgesTo(4, 3);
// Insert shortcut
reference_graph.InsertEdge(4, 1, {2, 4, 3, 0, true, true, false});
/* After contracting 4: // reference_graph.DeleteEdgesTo(1, 3);
* // reference_graph.DeleteEdgesTo(4, 3);
* Delete edges 1 -> 4 // // Insert shortcut
* // reference_graph.InsertEdge(4, 1, {2, 4, 3, 0, true, true, false});
* <--1---
* (0) ---3--> (1) >--3--- (3)
* \ ^ v ^ |
* \ / \ \ |
* 1 1 1 2 1
* \ / \ \ /
* >(5) \ (4) >
*/
reference_graph.DeleteEdgesTo(1, 4);
/* After contracting 1: // /* After contracting 4:
* // *
* Delete no edges. // * Delete edges 1 -> 4
* // *
* <--1--- // * <--1---
* (0) ---3--> (1) >--3--- (3) // * (0) ---3--> (1) >--3--- (3)
* \ ^ v ^ | // * \ ^ v ^ |
* \ / \ \ | // * \ / \ \ |
* 1 1 1 2 1 // * 1 1 1 2 1
* \ / \ \ / // * \ / \ \ /
* >(5) \ (4) > // * >(5) \ (4) >
*/ // */
// reference_graph.DeleteEdgesTo(1, 4);
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(0), 2); // /* After contracting 1:
BOOST_CHECK(contracted_graph.FindEdge(0, 1) != SPECIAL_EDGEID); // *
BOOST_CHECK(contracted_graph.FindEdge(0, 5) != SPECIAL_EDGEID); // * Delete no edges.
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(1), 0); // *
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(2), 0); // * <--1---
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(3), 3); // * (0) ---3--> (1) >--3--- (3)
BOOST_CHECK(contracted_graph.FindEdge(3, 1) != SPECIAL_EDGEID); // * \ ^ v ^ |
BOOST_CHECK(contracted_graph.FindEdge(3, 4) != SPECIAL_EDGEID); // * \ / \ \ |
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(4), 2); // * 1 1 1 2 1
BOOST_CHECK(contracted_graph.FindEdge(4, 1) != SPECIAL_EDGEID); // * \ / \ \ /
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(5), 1); // * >(5) \ (4) >
BOOST_CHECK(contracted_graph.FindEdge(5, 1) != SPECIAL_EDGEID); // */
}
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(0), 2);
// BOOST_CHECK(contracted_graph.FindEdge(0, 1) != SPECIAL_EDGEID);
// BOOST_CHECK(contracted_graph.FindEdge(0, 5) != SPECIAL_EDGEID);
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(1), 0);
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(2), 0);
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(3), 3);
// BOOST_CHECK(contracted_graph.FindEdge(3, 1) != SPECIAL_EDGEID);
// BOOST_CHECK(contracted_graph.FindEdge(3, 4) != SPECIAL_EDGEID);
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(4), 2);
// BOOST_CHECK(contracted_graph.FindEdge(4, 1) != SPECIAL_EDGEID);
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(5), 1);
// BOOST_CHECK(contracted_graph.FindEdge(5, 1) != SPECIAL_EDGEID);
// }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -24,11 +24,11 @@ inline contractor::ContractorGraph makeGraph(const std::vector<TestEdge> &edges)
input_edges.push_back(contractor::ContractorEdge{ input_edges.push_back(contractor::ContractorEdge{
start, start,
target, target,
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, true, false}}); contractor::ContractorEdgeData{weight, weight * 2, 1.0, id++, 0, false, true, false}});
input_edges.push_back(contractor::ContractorEdge{ input_edges.push_back(contractor::ContractorEdge{
target, target,
start, start,
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, false, true}}); contractor::ContractorEdgeData{weight, weight * 2, 1.0, id++, 0, false, false, true}});
} }
std::sort(input_edges.begin(), input_edges.end()); std::sort(input_edges.begin(), input_edges.end());

View File

@ -1,295 +1,296 @@
#include "extractor/graph_compressor.hpp" // #include "extractor/graph_compressor.hpp"
#include "extractor/compressed_edge_container.hpp" // #include "extractor/compressed_edge_container.hpp"
#include "extractor/maneuver_override.hpp" // #include "extractor/maneuver_override.hpp"
#include "extractor/restriction.hpp" // #include "extractor/restriction.hpp"
#include "util/node_based_graph.hpp" // #include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // #include "util/typedefs.hpp"
#include "../unit_tests/mocks/mock_scripting_environment.hpp" // #include "../unit_tests/mocks/mock_scripting_environment.hpp"
#include <boost/test/test_case_template.hpp> // #include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp> // #include <boost/test/unit_test.hpp>
#include <iostream> // #include <iostream>
#include <unordered_set> // #include <unordered_set>
#include <vector> // #include <vector>
BOOST_AUTO_TEST_SUITE(graph_compressor) // BOOST_AUTO_TEST_SUITE(graph_compressor)
using namespace osrm; // using namespace osrm;
using namespace osrm::extractor; // using namespace osrm::extractor;
using InputEdge = util::NodeBasedDynamicGraph::InputEdge; // using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
using Graph = util::NodeBasedDynamicGraph; // using Graph = util::NodeBasedDynamicGraph;
namespace // namespace
{ // {
// creates a default edge of unit weight // // creates a default edge of unit weight
inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to) // inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
{ // {
return {from, // source // return {from, // source
to, // target // to, // target
1, // weight // 1, // weight
1, // duration // 1, // duration
GeometryID{0, false}, // geometry_id // GeometryID{0, false}, // geometry_id
false, // reversed // false, // reversed
NodeBasedEdgeClassification(), // default flags // NodeBasedEdgeClassification(), // default flags
0}; // AnnotationID // 0}; // AnnotationID
} // }
bool compatible(Graph const &graph, // bool compatible(Graph const &graph,
const std::vector<NodeBasedEdgeAnnotation> &node_data_container, // const std::vector<NodeBasedEdgeAnnotation> &node_data_container,
EdgeID const first, // EdgeID const first,
EdgeID second) // EdgeID second)
{ // {
auto const &first_flags = graph.GetEdgeData(first).flags; // auto const &first_flags = graph.GetEdgeData(first).flags;
auto const &second_flags = graph.GetEdgeData(second).flags; // auto const &second_flags = graph.GetEdgeData(second).flags;
if (!(first_flags == second_flags)) // if (!(first_flags == second_flags))
return false; // return false;
if (graph.GetEdgeData(first).reversed != graph.GetEdgeData(second).reversed) // if (graph.GetEdgeData(first).reversed != graph.GetEdgeData(second).reversed)
return false; // return false;
auto const &first_annotation = node_data_container[graph.GetEdgeData(first).annotation_data]; // auto const &first_annotation = node_data_container[graph.GetEdgeData(first).annotation_data];
auto const &second_annotation = node_data_container[graph.GetEdgeData(second).annotation_data]; // auto const &second_annotation =
// node_data_container[graph.GetEdgeData(second).annotation_data];
return first_annotation.CanCombineWith(second_annotation); // return first_annotation.CanCombineWith(second_annotation);
} // }
} // namespace // } // namespace
BOOST_AUTO_TEST_CASE(long_road_test) // BOOST_AUTO_TEST_CASE(long_road_test)
{ // {
// // //
// 0---1---2---3---4 // // 0---1---2---3---4
// // //
GraphCompressor compressor; // GraphCompressor compressor;
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
std::vector<NodeBasedEdgeAnnotation> annotations(1); // std::vector<NodeBasedEdgeAnnotation> annotations(1);
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1), // std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
MakeUnitEdge(1, 0), // MakeUnitEdge(1, 0),
MakeUnitEdge(1, 2), // MakeUnitEdge(1, 2),
MakeUnitEdge(2, 1), // MakeUnitEdge(2, 1),
MakeUnitEdge(2, 3), // MakeUnitEdge(2, 3),
MakeUnitEdge(3, 2), // MakeUnitEdge(3, 2),
MakeUnitEdge(3, 4), // MakeUnitEdge(3, 4),
MakeUnitEdge(4, 3)}; // MakeUnitEdge(4, 3)};
Graph graph(5, edges); // Graph graph(5, edges);
BOOST_CHECK(compatible(graph, annotations, 0, 2)); // BOOST_CHECK(compatible(graph, annotations, 0, 2));
BOOST_CHECK(compatible(graph, annotations, 2, 4)); // BOOST_CHECK(compatible(graph, annotations, 2, 4));
BOOST_CHECK(compatible(graph, annotations, 4, 6)); // BOOST_CHECK(compatible(graph, annotations, 4, 6));
compressor.Compress(barrier_nodes, // compressor.Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(3, 4), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(3, 4), SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(0, 4) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(0, 4) != SPECIAL_EDGEID);
} // }
BOOST_AUTO_TEST_CASE(loop_test) // BOOST_AUTO_TEST_CASE(loop_test)
{ // {
// // //
// 0---1---2 // // 0---1---2
// | | // // | |
// 5---4---3 // // 5---4---3
// // //
GraphCompressor compressor; // GraphCompressor compressor;
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
std::vector<NodeBasedEdgeAnnotation> annotations(1); // std::vector<NodeBasedEdgeAnnotation> annotations(1);
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1), // std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
MakeUnitEdge(0, 5), // MakeUnitEdge(0, 5),
MakeUnitEdge(1, 0), // MakeUnitEdge(1, 0),
MakeUnitEdge(1, 2), // MakeUnitEdge(1, 2),
MakeUnitEdge(2, 1), // MakeUnitEdge(2, 1),
MakeUnitEdge(2, 3), // MakeUnitEdge(2, 3),
MakeUnitEdge(3, 2), // MakeUnitEdge(3, 2),
MakeUnitEdge(3, 4), // MakeUnitEdge(3, 4),
MakeUnitEdge(4, 3), // MakeUnitEdge(4, 3),
MakeUnitEdge(4, 5), // MakeUnitEdge(4, 5),
MakeUnitEdge(5, 0), // MakeUnitEdge(5, 0),
MakeUnitEdge(5, 4)}; // MakeUnitEdge(5, 4)};
Graph graph(6, edges); // Graph graph(6, edges);
BOOST_CHECK(edges.size() == 12); // BOOST_CHECK(edges.size() == 12);
BOOST_CHECK(compatible(graph, annotations, 0, 1)); // BOOST_CHECK(compatible(graph, annotations, 0, 1));
BOOST_CHECK(compatible(graph, annotations, 1, 2)); // BOOST_CHECK(compatible(graph, annotations, 1, 2));
BOOST_CHECK(compatible(graph, annotations, 2, 3)); // BOOST_CHECK(compatible(graph, annotations, 2, 3));
BOOST_CHECK(compatible(graph, annotations, 3, 4)); // BOOST_CHECK(compatible(graph, annotations, 3, 4));
BOOST_CHECK(compatible(graph, annotations, 4, 5)); // BOOST_CHECK(compatible(graph, annotations, 4, 5));
BOOST_CHECK(compatible(graph, annotations, 5, 6)); // BOOST_CHECK(compatible(graph, annotations, 5, 6));
BOOST_CHECK(compatible(graph, annotations, 6, 7)); // BOOST_CHECK(compatible(graph, annotations, 6, 7));
BOOST_CHECK(compatible(graph, annotations, 7, 8)); // BOOST_CHECK(compatible(graph, annotations, 7, 8));
BOOST_CHECK(compatible(graph, annotations, 8, 9)); // BOOST_CHECK(compatible(graph, annotations, 8, 9));
BOOST_CHECK(compatible(graph, annotations, 9, 10)); // BOOST_CHECK(compatible(graph, annotations, 9, 10));
BOOST_CHECK(compatible(graph, annotations, 10, 11)); // BOOST_CHECK(compatible(graph, annotations, 10, 11));
BOOST_CHECK(compatible(graph, annotations, 11, 0)); // BOOST_CHECK(compatible(graph, annotations, 11, 0));
compressor.Compress(barrier_nodes, // compressor.Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK_EQUAL(graph.FindEdge(5, 0), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(5, 0), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID); // BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(5, 3) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(5, 3) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(3, 4) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(3, 4) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(4, 5) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(4, 5) != SPECIAL_EDGEID);
} // }
BOOST_AUTO_TEST_CASE(t_intersection) // BOOST_AUTO_TEST_CASE(t_intersection)
{ // {
// // //
// 0---1---2 // // 0---1---2
// | // // |
// 3 // // 3
// // //
GraphCompressor compressor; // GraphCompressor compressor;
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<NodeBasedEdgeAnnotation> annotations(1); // std::vector<NodeBasedEdgeAnnotation> annotations(1);
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1), // std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
MakeUnitEdge(1, 0), // MakeUnitEdge(1, 0),
MakeUnitEdge(1, 2), // MakeUnitEdge(1, 2),
MakeUnitEdge(1, 3), // MakeUnitEdge(1, 3),
MakeUnitEdge(2, 1), // MakeUnitEdge(2, 1),
MakeUnitEdge(3, 1)}; // MakeUnitEdge(3, 1)};
Graph graph(4, edges); // Graph graph(4, edges);
BOOST_CHECK(compatible(graph, annotations, 0, 1)); // BOOST_CHECK(compatible(graph, annotations, 0, 1));
BOOST_CHECK(compatible(graph, annotations, 1, 2)); // BOOST_CHECK(compatible(graph, annotations, 1, 2));
BOOST_CHECK(compatible(graph, annotations, 2, 3)); // BOOST_CHECK(compatible(graph, annotations, 2, 3));
BOOST_CHECK(compatible(graph, annotations, 3, 4)); // BOOST_CHECK(compatible(graph, annotations, 3, 4));
BOOST_CHECK(compatible(graph, annotations, 4, 5)); // BOOST_CHECK(compatible(graph, annotations, 4, 5));
compressor.Compress(barrier_nodes, // compressor.Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(1, 3) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(1, 3) != SPECIAL_EDGEID);
} // }
BOOST_AUTO_TEST_CASE(street_name_changes) // BOOST_AUTO_TEST_CASE(street_name_changes)
{ // {
// // //
// 0---1---2 // // 0---1---2
// // //
GraphCompressor compressor; // GraphCompressor compressor;
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<NodeBasedEdgeAnnotation> annotations(2); // std::vector<NodeBasedEdgeAnnotation> annotations(2);
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
std::vector<InputEdge> edges = { // std::vector<InputEdge> edges = {
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)}; // MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
annotations[1].name_id = 1; // annotations[1].name_id = 1;
edges[2].data.annotation_data = edges[3].data.annotation_data = 1; // edges[2].data.annotation_data = edges[3].data.annotation_data = 1;
Graph graph(5, edges); // Graph graph(5, edges);
BOOST_CHECK(compatible(graph, annotations, 0, 1)); // BOOST_CHECK(compatible(graph, annotations, 0, 1));
BOOST_CHECK(compatible(graph, annotations, 2, 3)); // BOOST_CHECK(compatible(graph, annotations, 2, 3));
compressor.Compress(barrier_nodes, // compressor.Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
} // }
BOOST_AUTO_TEST_CASE(direction_changes) // BOOST_AUTO_TEST_CASE(direction_changes)
{ // {
// // //
// 0-->1---2 // // 0-->1---2
// // //
GraphCompressor compressor; // GraphCompressor compressor;
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<NodeBasedEdgeAnnotation> annotations(1); // std::vector<NodeBasedEdgeAnnotation> annotations(1);
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
std::vector<InputEdge> edges = { // std::vector<InputEdge> edges = {
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)}; // MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
// make first edge point forward // // make first edge point forward
edges[1].data.reversed = true; // edges[1].data.reversed = true;
Graph graph(5, edges); // Graph graph(5, edges);
compressor.Compress(barrier_nodes, // compressor.Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID); // BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
} // }
BOOST_AUTO_TEST_SUITE_END() // BOOST_AUTO_TEST_SUITE_END()

View File

@ -1,4 +1,4 @@
#include "extractor/intersection/intersection_analysis.hpp" // #include "extractor/intersection/intersection_analysis.hpp"
#include "extractor/graph_compressor.hpp" #include "extractor/graph_compressor.hpp"
@ -17,305 +17,306 @@ using namespace osrm::extractor::intersection;
using InputEdge = util::NodeBasedDynamicGraph::InputEdge; using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
using Graph = util::NodeBasedDynamicGraph; using Graph = util::NodeBasedDynamicGraph;
BOOST_AUTO_TEST_CASE(simple_intersection_connectivity) // BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
{ // {
std::unordered_set<NodeID> barrier_nodes{6}; // std::unordered_set<NodeID> barrier_nodes{6};
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<NodeBasedEdgeAnnotation> annotations{ // std::vector<NodeBasedEdgeAnnotation> annotations{
{EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}, // {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false},
{EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}}; // {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}};
std::vector<TurnRestriction> restrictions{TurnRestriction{NodeRestriction{0, 2, 1}, false}}; // std::vector<TurnRestriction> restrictions{TurnRestriction{NodeRestriction{0, 2, 1}, false}};
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
TurnLanesIndexedArray turn_lanes_data{{0, 0, 3}, // TurnLanesIndexedArray turn_lanes_data{{0, 0, 3},
{TurnLaneType::uturn | TurnLaneType::left, // {TurnLaneType::uturn | TurnLaneType::left,
TurnLaneType::straight, // TurnLaneType::straight,
TurnLaneType::straight | TurnLaneType::right}}; // TurnLaneType::straight | TurnLaneType::right}};
// Graph with an additional turn restriction 0→2→1 and bollard at 6 // // Graph with an additional turn restriction 0→2→1 and bollard at 6
// 0→5↔6↔7 // // 0→5↔6↔7
// ↕ // // ↕
// 1↔2←3 // // 1↔2←3
// ↓ // // ↓
// 4 // // 4
const auto unit_edge = // const auto unit_edge =
[](const NodeID from, const NodeID to, bool allowed, AnnotationID annotation) { // [](const NodeID from, const NodeID to, bool allowed, AnnotationID annotation) {
return InputEdge{from, // return InputEdge{from,
to, // to,
1, // 1,
1, // 1,
GeometryID{0, false}, // GeometryID{0, false},
!allowed, // !allowed,
NodeBasedEdgeClassification(), // NodeBasedEdgeClassification(),
annotation}; // annotation};
}; // };
std::vector<InputEdge> edges = {unit_edge(0, 2, true, 1), // std::vector<InputEdge> edges = {unit_edge(0, 2, true, 1),
unit_edge(0, 5, true, 0), // unit_edge(0, 5, true, 0),
unit_edge(1, 2, true, 0), // unit_edge(1, 2, true, 0),
unit_edge(2, 0, true, 0), // unit_edge(2, 0, true, 0),
unit_edge(2, 1, true, 0), // unit_edge(2, 1, true, 0),
unit_edge(2, 3, false, 0), // unit_edge(2, 3, false, 0),
unit_edge(2, 4, true, 0), // unit_edge(2, 4, true, 0),
unit_edge(3, 2, true, 0), // unit_edge(3, 2, true, 0),
unit_edge(4, 2, false, 0), // unit_edge(4, 2, false, 0),
unit_edge(5, 0, false, 0), // unit_edge(5, 0, false, 0),
unit_edge(5, 6, true, 0), // unit_edge(5, 6, true, 0),
unit_edge(6, 5, true, 0), // unit_edge(6, 5, true, 0),
unit_edge(6, 7, true, 0), // unit_edge(6, 7, true, 0),
unit_edge(7, 6, true, 0)}; // unit_edge(7, 6, true, 0)};
IntersectionEdgeGeometries edge_geometries{ // IntersectionEdgeGeometries edge_geometries{
{0, 180, 180, 10.}, // 0→2 // {0, 180, 180, 10.}, // 0→2
{1, 90, 90, 10.}, // 0→5 // {1, 90, 90, 10.}, // 0→5
{2, 90, 90, 10.}, // 1→2 // {2, 90, 90, 10.}, // 1→2
{3, 0, 0, 10.}, // 2→0 // {3, 0, 0, 10.}, // 2→0
{4, 270, 270, 10.}, // 2→1 // {4, 270, 270, 10.}, // 2→1
{5, 90, 90, 10.}, // 2→3 // {5, 90, 90, 10.}, // 2→3
{6, 180, 180, 10.}, // 2→4 // {6, 180, 180, 10.}, // 2→4
{7, 270, 270, 10.}, // 3→2 // {7, 270, 270, 10.}, // 3→2
{8, 0, 0, 10.}, // 4→2 // {8, 0, 0, 10.}, // 4→2
{9, 270, 270, 10.}, // 5→0 // {9, 270, 270, 10.}, // 5→0
{10, 90, 90, 10.}, // 5→6 // {10, 90, 90, 10.}, // 5→6
{11, 270, 270, 10.}, // 6→5 // {11, 270, 270, 10.}, // 6→5
{12, 90, 90, 10.}, // 6→7 // {12, 90, 90, 10.}, // 6→7
{13, 270, 270, 10.} // 7→6 // {13, 270, 270, 10.} // 7→6
}; // };
Graph graph(8, edges); // Graph graph(8, edges);
GraphCompressor().Compress(barrier_nodes, // GraphCompressor().Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 2), 3); // REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 2), 3);
REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 2), 4); // REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 2), 4);
EdgeBasedNodeDataContainer node_data_container( // EdgeBasedNodeDataContainer node_data_container(
std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations); // std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); // RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
const auto connectivity_matrix = [&](NodeID node) { // const auto connectivity_matrix = [&](NodeID node) {
std::vector<bool> result; // std::vector<bool> result;
const auto incoming_edges = getIncomingEdges(graph, node); // const auto incoming_edges = getIncomingEdges(graph, node);
const auto outgoing_edges = getOutgoingEdges(graph, node); // const auto outgoing_edges = getOutgoingEdges(graph, node);
for (const auto incoming_edge : incoming_edges) // for (const auto incoming_edge : incoming_edges)
{ // {
for (const auto outgoing_edge : outgoing_edges) // for (const auto outgoing_edge : outgoing_edges)
{ // {
result.push_back(isTurnAllowed(graph, // result.push_back(isTurnAllowed(graph,
node_data_container, // node_data_container,
restriction_map, // restriction_map,
barrier_nodes, // barrier_nodes,
edge_geometries, // edge_geometries,
turn_lanes_data, // turn_lanes_data,
incoming_edge, // incoming_edge,
outgoing_edge)); // outgoing_edge));
} // }
} // }
return result; // return result;
}; // };
CHECK_EQUAL_RANGE(connectivity_matrix(0), 1, 1); // from node 2 allowed U-turn and to node 5 // CHECK_EQUAL_RANGE(connectivity_matrix(0), 1, 1); // from node 2 allowed U-turn and to node 5
CHECK_EQUAL_RANGE(connectivity_matrix(1), 1); // from node 2 allowed U-turn // CHECK_EQUAL_RANGE(connectivity_matrix(1), 1); // from node 2 allowed U-turn
CHECK_EQUAL_RANGE(connectivity_matrix(2), // CHECK_EQUAL_RANGE(connectivity_matrix(2),
// clang-format off // // clang-format off
1, 0, 0, 1, // from node 0 to node 4 and a U-turn at 2 // 1, 0, 0, 1, // from node 0 to node 4 and a U-turn at 2
1, 0, 0, 1, // from node 1 to nodes 0 and 4 // 1, 0, 0, 1, // from node 1 to nodes 0 and 4
1, 1, 0, 1 // from node 3 to nodes 0, 1 and 4 // 1, 1, 0, 1 // from node 3 to nodes 0, 1 and 4
// clang-format on // // clang-format on
); // );
REQUIRE_SIZE_RANGE(connectivity_matrix(3), 0); // no incoming edges, empty matrix // REQUIRE_SIZE_RANGE(connectivity_matrix(3), 0); // no incoming edges, empty matrix
CHECK_EQUAL_RANGE(connectivity_matrix(4), 0); // from node 2 not allowed U-turn // CHECK_EQUAL_RANGE(connectivity_matrix(4), 0); // from node 2 not allowed U-turn
CHECK_EQUAL_RANGE(connectivity_matrix(5), // CHECK_EQUAL_RANGE(connectivity_matrix(5),
// clang-format off // // clang-format off
0, 1, // from node 0 to node 6 // 0, 1, // from node 0 to node 6
0, 1, // from node 6 a U-turn to node 6 // 0, 1, // from node 6 a U-turn to node 6
// clang-format on // // clang-format on
); // );
CHECK_EQUAL_RANGE(connectivity_matrix(6), // CHECK_EQUAL_RANGE(connectivity_matrix(6),
// clang-format off // // clang-format off
1, 0, // from node 5 a U-turn to node 5 // 1, 0, // from node 5 a U-turn to node 5
0, 1, // from node 7 a U-turn to node 7 // 0, 1, // from node 7 a U-turn to node 7
// clang-format on // // clang-format on
); // );
} // }
BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) // BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
{ // {
std::unordered_set<NodeID> barrier_nodes; // std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; // std::unordered_set<NodeID> traffic_lights;
std::vector<NodeBasedEdgeAnnotation> annotations; // std::vector<NodeBasedEdgeAnnotation> annotations;
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
TurnLanesIndexedArray turn_lanes_data; // TurnLanesIndexedArray turn_lanes_data;
// Graph with roundabout edges 5→0→2 // // Graph with roundabout edges 5→0→2
// 1 2 3 // // 1 2 3
// ↘ ↑ ↙ // // ↘ ↑ ↙
// 0 // // 0
// ↙ ↑ ↘ // // ↙ ↑ ↘
// 4 5 6 // // 4 5 6
const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { // const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout)
return InputEdge{from, // {
to, // return InputEdge{from,
1, // to,
1, // 1,
GeometryID{0, false}, // 1,
!allowed, // GeometryID{0, false},
NodeBasedEdgeClassification{ // !allowed,
true, false, false, roundabout, false, false, false, {}, 0, 0}, // NodeBasedEdgeClassification{
0}; // true, false, false, roundabout, false, false, false, {}, 0, 0},
}; // 0};
std::vector<InputEdge> edges = {unit_edge(0, 1, false, false), // };
unit_edge(0, 2, true, true), // std::vector<InputEdge> edges = {unit_edge(0, 1, false, false),
unit_edge(0, 3, false, false), // unit_edge(0, 2, true, true),
unit_edge(0, 4, true, false), // unit_edge(0, 3, false, false),
unit_edge(0, 5, false, true), // unit_edge(0, 4, true, false),
unit_edge(0, 6, true, false), // unit_edge(0, 5, false, true),
unit_edge(1, 0, true, false), // unit_edge(0, 6, true, false),
unit_edge(2, 0, false, true), // unit_edge(1, 0, true, false),
unit_edge(3, 0, true, false), // unit_edge(2, 0, false, true),
unit_edge(4, 0, false, false), // unit_edge(3, 0, true, false),
unit_edge(5, 0, true, true), // unit_edge(4, 0, false, false),
unit_edge(6, 0, false, false)}; // unit_edge(5, 0, true, true),
IntersectionEdgeGeometries edge_geometries{ // unit_edge(6, 0, false, false)};
{0, 315, 315, 10}, // 0→1 // IntersectionEdgeGeometries edge_geometries{
{1, 0, 0, 10}, // 0→2 // {0, 315, 315, 10}, // 0→1
{2, 45, 45, 10}, // 0→3 // {1, 0, 0, 10}, // 0→2
{3, 225, 225, 10}, // 0→4 // {2, 45, 45, 10}, // 0→3
{4, 180, 180, 10}, // 0→5 // {3, 225, 225, 10}, // 0→4
{5, 135, 135, 10}, // 0→6 // {4, 180, 180, 10}, // 0→5
{6, 135, 135, 10}, // 1→0 // {5, 135, 135, 10}, // 0→6
{7, 180, 180, 10}, // 2→0 // {6, 135, 135, 10}, // 1→0
{8, 225, 225, 10}, // 3→0 // {7, 180, 180, 10}, // 2→0
{9, 45, 45, 10}, // 4→0 // {8, 225, 225, 10}, // 3→0
{10, 0, 0, 10}, // 5→0 // {9, 45, 45, 10}, // 4→0
{11, 315, 315, 10} // 6→0 // {10, 0, 0, 10}, // 5→0
}; // {11, 315, 315, 10} // 6→0
// };
Graph graph(7, edges); // Graph graph(7, edges);
GraphCompressor().Compress(barrier_nodes, // GraphCompressor().Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); // REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3);
REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); // REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6);
EdgeBasedNodeDataContainer node_data_container( // EdgeBasedNodeDataContainer node_data_container(
std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations); // std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); // RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
const auto connectivity_matrix = [&](NodeID node) { // const auto connectivity_matrix = [&](NodeID node) {
std::vector<bool> result; // std::vector<bool> result;
const auto incoming_edges = getIncomingEdges(graph, node); // const auto incoming_edges = getIncomingEdges(graph, node);
const auto outgoing_edges = getOutgoingEdges(graph, node); // const auto outgoing_edges = getOutgoingEdges(graph, node);
for (const auto incoming_edge : incoming_edges) // for (const auto incoming_edge : incoming_edges)
{ // {
for (const auto outgoing_edge : outgoing_edges) // for (const auto outgoing_edge : outgoing_edges)
{ // {
result.push_back(isTurnAllowed(graph, // result.push_back(isTurnAllowed(graph,
node_data_container, // node_data_container,
restriction_map, // restriction_map,
barrier_nodes, // barrier_nodes,
edge_geometries, // edge_geometries,
turn_lanes_data, // turn_lanes_data,
incoming_edge, // incoming_edge,
outgoing_edge)); // outgoing_edge));
} // }
} // }
return result; // return result;
}; // };
CHECK_EQUAL_RANGE(connectivity_matrix(0), // CHECK_EQUAL_RANGE(connectivity_matrix(0),
// clang-format off // // clang-format off
0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6 // 0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6
0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4 // 0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4
0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6 // 0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6
// clang-format on // // clang-format on
); // );
} // }
BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) // BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
{ // {
std::unordered_set<NodeID> barrier_nodes{1}; // std::unordered_set<NodeID> barrier_nodes{1};
std::unordered_set<NodeID> traffic_lights{2}; // std::unordered_set<NodeID> traffic_lights{2};
std::vector<NodeBasedEdgeAnnotation> annotations(1); // std::vector<NodeBasedEdgeAnnotation> annotations(1);
std::vector<TurnRestriction> restrictions; // std::vector<TurnRestriction> restrictions;
std::vector<ConditionalTurnRestriction> conditional_restrictions; // std::vector<ConditionalTurnRestriction> conditional_restrictions;
CompressedEdgeContainer container; // CompressedEdgeContainer container;
test::MockScriptingEnvironment scripting_environment; // test::MockScriptingEnvironment scripting_environment;
std::vector<UnresolvedManeuverOverride> maneuver_overrides; // std::vector<UnresolvedManeuverOverride> maneuver_overrides;
TurnLanesIndexedArray turn_lanes_data; // TurnLanesIndexedArray turn_lanes_data;
// Graph // // Graph
// // //
// 0↔1→2↔3↔4→5 7 // // 0↔1→2↔3↔4→5 7
// ↑ ↕ ↕ // // ↑ ↕ ↕
// 6 8 ↔ 9 // // 6 8 ↔ 9
// // //
const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { // const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) {
return InputEdge{ // return InputEdge{
from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; // from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0};
}; // };
std::vector<InputEdge> edges = {unit_edge(0, 1, true), // 0 // std::vector<InputEdge> edges = {unit_edge(0, 1, true), // 0
unit_edge(1, 0, true), // unit_edge(1, 0, true),
unit_edge(1, 2, true), // unit_edge(1, 2, true),
unit_edge(2, 1, false), // unit_edge(2, 1, false),
unit_edge(2, 3, true), // unit_edge(2, 3, true),
unit_edge(3, 2, true), // 5 // unit_edge(3, 2, true), // 5
unit_edge(3, 4, true), // unit_edge(3, 4, true),
unit_edge(4, 3, true), // unit_edge(4, 3, true),
unit_edge(4, 5, true), // unit_edge(4, 5, true),
unit_edge(4, 6, false), // unit_edge(4, 6, false),
unit_edge(5, 4, false), // 10 // unit_edge(5, 4, false), // 10
unit_edge(6, 4, true), // unit_edge(6, 4, true),
// Circle // // Circle
unit_edge(7, 8, true), // 12 // unit_edge(7, 8, true), // 12
unit_edge(7, 9, true), // unit_edge(7, 9, true),
unit_edge(8, 7, true), // unit_edge(8, 7, true),
unit_edge(8, 9, true), // unit_edge(8, 9, true),
unit_edge(9, 7, true), // unit_edge(9, 7, true),
unit_edge(9, 8, true)}; // unit_edge(9, 8, true)};
Graph graph(10, edges); // Graph graph(10, edges);
GraphCompressor().Compress(barrier_nodes, // GraphCompressor().Compress(barrier_nodes,
traffic_lights, // traffic_lights,
scripting_environment, // scripting_environment,
restrictions, // restrictions,
conditional_restrictions, // conditional_restrictions,
maneuver_overrides, // maneuver_overrides,
graph, // graph,
annotations, // annotations,
container); // container);
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); // BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4);
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); // BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0);
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); // BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4);
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); // BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4);
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); // BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7);
} // }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -16,13 +16,13 @@ BOOST_AUTO_TEST_CASE(test_extract_with_invalid_config)
std::exception); // including osrm::util::exception, osmium::io_error, etc. std::exception); // including osrm::util::exception, osmium::io_error, etc.
} }
BOOST_AUTO_TEST_CASE(test_extract_with_valid_config) // BOOST_AUTO_TEST_CASE(test_extract_with_valid_config)
{ // {
osrm::ExtractorConfig config; // osrm::ExtractorConfig config;
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf"; // config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf"); // config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
config.requested_num_threads = tbb::task_scheduler_init::default_num_threads(); // config.requested_num_threads = tbb::task_scheduler_init::default_num_threads();
BOOST_CHECK_NO_THROW(osrm::extract(config)); // BOOST_CHECK_NO_THROW(osrm::extract(config));
} // }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -32,9 +32,9 @@ auto makeGraph(const std::vector<MockEdge> &mock_edges)
max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target)); max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target));
edges.push_back(InputEdge{ edges.push_back(InputEdge{
m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, true, false}}); m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, true, false}});
edges.push_back(InputEdge{ edges.push_back(InputEdge{
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, false, true}}); m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, false, true}});
} }
std::sort(edges.begin(), edges.end()); std::sort(edges.begin(), edges.end());
return DynamicEdgeBasedGraph(max_id + 1, edges); return DynamicEdgeBasedGraph(max_id + 1, edges);

View File

@ -12,46 +12,50 @@ using namespace osrm::updater;
BOOST_AUTO_TEST_CASE(timezoner_test) BOOST_AUTO_TEST_CASE(timezoner_test)
{ {
const char json[] = // const char json[] =
"{ \"type\" : \"FeatureCollection\", \"features\": [" // "{ \"type\" : \"FeatureCollection\", \"features\": ["
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }} ]}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
std::time_t now = time(0); // "49.07206], [8.28369, 48.88277]]] }} ]}";
BOOST_CHECK_NO_THROW(Timezoner tz(json, now)); // std::time_t now = time(0);
// BOOST_CHECK_NO_THROW(Timezoner tz(json, now));
boost::filesystem::path test_path(TEST_DATA_DIR "/test.geojson"); // boost::filesystem::path test_path(TEST_DATA_DIR "/test.geojson");
BOOST_CHECK_NO_THROW(Timezoner tz(test_path, now)); // BOOST_CHECK_NO_THROW(Timezoner tz(test_path, now));
// missing opening bracket // missing opening bracket
const char bad[] = // const char bad[] =
"\"type\" : \"FeatureCollection\", \"features\": [" // "\"type\" : \"FeatureCollection\", \"features\": ["
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }} ]}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
BOOST_CHECK_THROW(Timezoner tz(bad, now), util::exception); // "49.07206], [8.28369, 48.88277]]] }} ]}";
// BOOST_CHECK_THROW(Timezoner tz(bad, now), util::exception);
// missing/malformed FeatureCollection type field // missing/malformed FeatureCollection type field
const char missing_type[] = // const char missing_type[] =
"{ \"FeatureCollection\", \"features\": [" // "{ \"FeatureCollection\", \"features\": ["
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }} ]}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
BOOST_CHECK_THROW(Timezoner tz(missing_type, now), util::exception); // "49.07206], [8.28369, 48.88277]]] }} ]}";
// BOOST_CHECK_THROW(Timezoner tz(missing_type, now), util::exception);
const char missing_featc[] = // const char missing_featc[] =
"{ \"type\" : \"Collection\", \"features\": [" // "{ \"type\" : \"Collection\", \"features\": ["
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }} ]}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
BOOST_CHECK_THROW(Timezoner tz(missing_featc, now), util::exception); // "49.07206], [8.28369, 48.88277]]] }} ]}";
// BOOST_CHECK_THROW(Timezoner tz(missing_featc, now), util::exception);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -71,68 +71,74 @@ BOOST_AUTO_TEST_CASE(timezone_validation_test)
"48.88277], [8.57757, 49.07206], [8.28369, " "48.88277], [8.57757, 49.07206], [8.28369, "
"49.07206], [8.28369, 48.88277]]] }}"; "49.07206], [8.28369, 48.88277]]] }}";
doc.Parse(missing_tzid); doc.Parse(missing_tzid);
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char tzid_err[] = "{ \"type\" : \"Feature\"," // char tzid_err[] = "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : []}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : []}, \"geometry\" : { \"type\": \"polygon\",
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(tzid_err); // "49.07206], [8.28369, 48.88277]]] }}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(tzid_err);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char missing_geom[] = "{ \"type\" : \"Feature\"," // char missing_geom[] = "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometries\" : { " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometries\" : { "
"\"type\": \"polygon\", " // "\"type\": \"polygon\", "
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"48.88277], [8.57757, 49.07206], [8.28369, " // "48.88277], [8.57757, 49.07206], [8.28369, "
"49.07206], [8.28369, 48.88277]]] }}"; // "49.07206], [8.28369, 48.88277]]] }}";
doc.Parse(missing_geom); // doc.Parse(missing_geom);
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char nonobj_geom[] = // char nonobj_geom[] =
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : [ \"type\", \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : [ \"type\",
"\"coordinates\", [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\", [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] ]}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(nonobj_geom); // "49.07206], [8.28369, 48.88277]]] ]}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(nonobj_geom);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char missing_geom_type[] = "{ \"type\" : \"Feature\"," // char missing_geom_type[] = "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" :
"\"no_type\": \"polygon\", " // { "
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // "\"no_type\": \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(missing_geom_type); // "49.07206], [8.28369, 48.88277]]] }}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(missing_geom_type);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char nonstring_geom_type[] = "{ \"type\" : \"Feature\"," // char nonstring_geom_type[] = "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\"
"{ \"type\": [\"polygon\"], " // : "
"\"coordinates\": [[[8.28369,48.88277], [8.57757, " // "{ \"type\": [\"polygon\"], "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(nonstring_geom_type); // "49.07206], [8.28369, 48.88277]]] }}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(nonstring_geom_type);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char missing_coords[] = // char missing_coords[] =
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coords\": [[[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coords\": [[[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]]] }}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(missing_coords); // "49.07206], [8.28369, 48.88277]]] }}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(missing_coords);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
char missing_outerring[] = // char missing_outerring[] =
"{ \"type\" : \"Feature\"," // "{ \"type\" : \"Feature\","
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", " // "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
"\"coordinates\": [[8.28369,48.88277], [8.57757, " // \"polygon\", "
"48.88277], [8.57757, 49.07206], [8.28369, " // "\"coordinates\": [[8.28369,48.88277], [8.57757, "
"49.07206], [8.28369, 48.88277]] }}"; // "48.88277], [8.57757, 49.07206], [8.28369, "
doc.Parse(missing_outerring); // "49.07206], [8.28369, 48.88277]] }}";
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception); // doc.Parse(missing_outerring);
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()