Implement re-enabling of PhantomNode directions after bearing filtering
This commit is contained in:
parent
5829bbe22d
commit
fda4656630
@ -244,8 +244,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, bearing, bearing_range, &has_big_component, &has_small_component](
|
[this, bearing, bearing_range, &has_big_component,
|
||||||
const EdgeData &data)
|
&has_small_component](const EdgeData &data)
|
||||||
{
|
{
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !data.component.is_tiny));
|
(!has_small_component || (!has_big_component && !data.component.is_tiny));
|
||||||
@ -290,8 +290,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
bool has_big_component = false;
|
bool has_big_component = false;
|
||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, bearing, bearing_range, &has_big_component, &has_small_component](
|
[this, bearing, bearing_range, &has_big_component,
|
||||||
const EdgeData &data)
|
&has_small_component](const EdgeData &data)
|
||||||
{
|
{
|
||||||
auto use_segment =
|
auto use_segment =
|
||||||
(!has_small_component || (!has_big_component && !data.component.is_tiny));
|
(!has_small_component || (!has_big_component && !data.component.is_tiny));
|
||||||
@ -384,22 +384,18 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (SPECIAL_NODEID != data.forward_edge_based_node_id)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
forward_weight *= ratio;
|
forward_weight *= ratio;
|
||||||
}
|
}
|
||||||
if (SPECIAL_NODEID != data.reverse_edge_based_node_id)
|
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
reverse_weight *= 1.0 - ratio;
|
reverse_weight *= 1.0 - ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transformed = PhantomNodeWithDistance{PhantomNode{data,
|
auto transformed = PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset,
|
||||||
forward_weight,
|
reverse_weight, reverse_offset,
|
||||||
forward_offset,
|
point_on_segment, input_coordinate},
|
||||||
reverse_weight,
|
|
||||||
reverse_offset,
|
|
||||||
point_on_segment,
|
|
||||||
input_coordinate},
|
|
||||||
current_perpendicular_distance};
|
current_perpendicular_distance};
|
||||||
|
|
||||||
return transformed;
|
return transformed;
|
||||||
@ -409,6 +405,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const int filter_bearing,
|
const int filter_bearing,
|
||||||
const int filter_bearing_range)
|
const int filter_bearing_range)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(segment.forward_segment_id.id != SPECIAL_SEGMENTID || !segment.forward_segment_id.enabled);
|
||||||
|
BOOST_ASSERT(segment.reverse_segment_id.id != SPECIAL_SEGMENTID || !segment.reverse_segment_id.enabled);
|
||||||
|
|
||||||
const double forward_edge_bearing = util::coordinate_calculation::bearing(
|
const double forward_edge_bearing = util::coordinate_calculation::bearing(
|
||||||
coordinates->at(segment.u), coordinates->at(segment.v));
|
coordinates->at(segment.u), coordinates->at(segment.v));
|
||||||
|
|
||||||
@ -419,11 +418,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const bool forward_bearing_valid =
|
const bool forward_bearing_valid =
|
||||||
util::bearing::CheckInBounds(std::round(forward_edge_bearing), filter_bearing,
|
util::bearing::CheckInBounds(std::round(forward_edge_bearing), filter_bearing,
|
||||||
filter_bearing_range) &&
|
filter_bearing_range) &&
|
||||||
segment.forward_edge_based_node_id != SPECIAL_NODEID;
|
segment.forward_segment_id.enabled;
|
||||||
const bool backward_bearing_valid =
|
const bool backward_bearing_valid =
|
||||||
util::bearing::CheckInBounds(std::round(backward_edge_bearing), filter_bearing,
|
util::bearing::CheckInBounds(std::round(backward_edge_bearing), filter_bearing,
|
||||||
filter_bearing_range) &&
|
filter_bearing_range) &&
|
||||||
segment.reverse_edge_based_node_id != SPECIAL_NODEID;
|
segment.reverse_segment_id.enabled;
|
||||||
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
|
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "extractor/travel_mode.hpp"
|
#include "extractor/travel_mode.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include "osrm/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -44,8 +46,8 @@ namespace engine
|
|||||||
|
|
||||||
struct PhantomNode
|
struct PhantomNode
|
||||||
{
|
{
|
||||||
PhantomNode(NodeID forward_node_id,
|
PhantomNode(SegmentID forward_segment_id,
|
||||||
NodeID reverse_node_id,
|
SegmentID reverse_segment_id,
|
||||||
unsigned name_id,
|
unsigned name_id,
|
||||||
int forward_weight,
|
int forward_weight,
|
||||||
int reverse_weight,
|
int reverse_weight,
|
||||||
@ -60,8 +62,8 @@ struct PhantomNode
|
|||||||
unsigned short fwd_segment_position,
|
unsigned short fwd_segment_position,
|
||||||
extractor::TravelMode forward_travel_mode,
|
extractor::TravelMode forward_travel_mode,
|
||||||
extractor::TravelMode backward_travel_mode)
|
extractor::TravelMode backward_travel_mode)
|
||||||
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
|
: forward_segment_id(forward_segment_id), reverse_segment_id(reverse_segment_id),
|
||||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
name_id(name_id), forward_weight(forward_weight), reverse_weight(reverse_weight),
|
||||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
||||||
forward_packed_geometry_id(forward_packed_geometry_id_),
|
forward_packed_geometry_id(forward_packed_geometry_id_),
|
||||||
reverse_packed_geometry_id(reverse_packed_geometry_id_),
|
reverse_packed_geometry_id(reverse_packed_geometry_id_),
|
||||||
@ -72,7 +74,8 @@ struct PhantomNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhantomNode()
|
PhantomNode()
|
||||||
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
|
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
||||||
|
reverse_segment_id{SPECIAL_SEGMENTID, false},
|
||||||
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
|
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
|
||||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
|
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
|
||||||
forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID),
|
forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID),
|
||||||
@ -84,33 +87,22 @@ struct PhantomNode
|
|||||||
|
|
||||||
int GetForwardWeightPlusOffset() const
|
int GetForwardWeightPlusOffset() const
|
||||||
{
|
{
|
||||||
if (SPECIAL_NODEID == forward_node_id)
|
BOOST_ASSERT(forward_segment_id.enabled);
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return forward_offset + forward_weight;
|
return forward_offset + forward_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetReverseWeightPlusOffset() const
|
int GetReverseWeightPlusOffset() const
|
||||||
{
|
{
|
||||||
if (SPECIAL_NODEID == reverse_node_id)
|
BOOST_ASSERT(reverse_segment_id.enabled);
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return reverse_offset + reverse_weight;
|
return reverse_offset + reverse_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBidirected() const
|
bool IsBidirected() const { return forward_segment_id.enabled && reverse_segment_id.enabled; }
|
||||||
{
|
|
||||||
return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCompressed() const { return (forward_offset != 0) || (reverse_offset != 0); }
|
|
||||||
|
|
||||||
bool IsValid(const unsigned number_of_nodes) const
|
bool IsValid(const unsigned number_of_nodes) const
|
||||||
{
|
{
|
||||||
return location.IsValid() &&
|
return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
|
||||||
((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) &&
|
(reverse_segment_id.id < number_of_nodes)) &&
|
||||||
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
||||||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||||
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
|
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
|
||||||
@ -133,33 +125,21 @@ struct PhantomNode
|
|||||||
int reverse_offset_,
|
int reverse_offset_,
|
||||||
const util::Coordinate location_,
|
const util::Coordinate location_,
|
||||||
const util::Coordinate input_location_)
|
const util::Coordinate input_location_)
|
||||||
|
: forward_segment_id{other.forward_segment_id},
|
||||||
|
reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id},
|
||||||
|
forward_weight{forward_weight_}, reverse_weight{reverse_weight_},
|
||||||
|
forward_offset{forward_offset_}, reverse_offset{reverse_offset_},
|
||||||
|
forward_packed_geometry_id{other.forward_packed_geometry_id},
|
||||||
|
reverse_packed_geometry_id{other.reverse_packed_geometry_id},
|
||||||
|
component{other.component.id, other.component.is_tiny}, location{location_},
|
||||||
|
input_location{input_location_}, fwd_segment_position{other.fwd_segment_position},
|
||||||
|
forward_travel_mode{other.forward_travel_mode},
|
||||||
|
backward_travel_mode{other.backward_travel_mode}
|
||||||
{
|
{
|
||||||
forward_node_id = other.forward_edge_based_node_id;
|
|
||||||
reverse_node_id = other.reverse_edge_based_node_id;
|
|
||||||
name_id = other.name_id;
|
|
||||||
|
|
||||||
forward_weight = forward_weight_;
|
|
||||||
reverse_weight = reverse_weight_;
|
|
||||||
|
|
||||||
forward_offset = forward_offset_;
|
|
||||||
reverse_offset = reverse_offset_;
|
|
||||||
|
|
||||||
forward_packed_geometry_id = other.forward_packed_geometry_id;
|
|
||||||
reverse_packed_geometry_id = other.reverse_packed_geometry_id;
|
|
||||||
|
|
||||||
component.id = other.component.id;
|
|
||||||
component.is_tiny = other.component.is_tiny;
|
|
||||||
|
|
||||||
location = location_;
|
|
||||||
input_location = input_location_;
|
|
||||||
fwd_segment_position = other.fwd_segment_position;
|
|
||||||
|
|
||||||
forward_travel_mode = other.forward_travel_mode;
|
|
||||||
backward_travel_mode = other.backward_travel_mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID forward_node_id;
|
SegmentID forward_segment_id;
|
||||||
NodeID reverse_node_id;
|
SegmentID reverse_segment_id;
|
||||||
unsigned name_id;
|
unsigned name_id;
|
||||||
int forward_weight;
|
int forward_weight;
|
||||||
int reverse_weight;
|
int reverse_weight;
|
||||||
@ -174,7 +154,7 @@ struct PhantomNode
|
|||||||
} component;
|
} component;
|
||||||
// bit-fields are broken on Windows
|
// bit-fields are broken on Windows
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to 4 bytes big");
|
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big");
|
||||||
#endif
|
#endif
|
||||||
util::Coordinate location;
|
util::Coordinate location;
|
||||||
util::Coordinate input_location;
|
util::Coordinate input_location;
|
||||||
@ -214,8 +194,8 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
|
|||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
||||||
{
|
{
|
||||||
out << "node1: " << pn.forward_node_id << ", "
|
out << "node1: " << pn.forward_segment_id.id << ", "
|
||||||
<< "node2: " << pn.reverse_node_id << ", "
|
<< "node2: " << pn.reverse_segment_id.id << ", "
|
||||||
<< "name: " << pn.name_id << ", "
|
<< "name: " << pn.name_id << ", "
|
||||||
<< "fwd-w: " << pn.forward_weight << ", "
|
<< "fwd-w: " << pn.forward_weight << ", "
|
||||||
<< "rev-w: " << pn.reverse_weight << ", "
|
<< "rev-w: " << pn.reverse_weight << ", "
|
||||||
|
@ -84,45 +84,37 @@ class AlternativeRouting final
|
|||||||
int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT;
|
int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT;
|
||||||
NodeID middle_node = SPECIAL_NODEID;
|
NodeID middle_node = SPECIAL_NODEID;
|
||||||
const EdgeWeight min_edge_offset =
|
const EdgeWeight min_edge_offset =
|
||||||
std::min(-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
|
std::min(phantom_node_pair.source_phantom.forward_segment_id.enabled ? -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset() : 0,
|
||||||
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
|
phantom_node_pair.source_phantom.reverse_segment_id.enabled ? -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset() : 0);
|
||||||
|
|
||||||
if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
|
if (phantom_node_pair.source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// util::SimpleLogger().Write(logDEBUG) << "fwd-a insert: " <<
|
BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id != SPECIAL_SEGMENTID);
|
||||||
// phantom_node_pair.source_phantom.forward_node_id << ", w: " <<
|
forward_heap1.Insert(phantom_node_pair.source_phantom.forward_segment_id.id,
|
||||||
// -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
|
|
||||||
forward_heap1.Insert(phantom_node_pair.source_phantom.forward_node_id,
|
|
||||||
-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
|
-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
|
||||||
phantom_node_pair.source_phantom.forward_node_id);
|
phantom_node_pair.source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (phantom_node_pair.source_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// util::SimpleLogger().Write(logDEBUG) << "fwd-b insert: " <<
|
BOOST_ASSERT(phantom_node_pair.source_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID);
|
||||||
// phantom_node_pair.source_phantom.reverse_node_id << ", w: " <<
|
forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_segment_id.id,
|
||||||
// -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
|
|
||||||
forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id,
|
|
||||||
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
|
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
|
||||||
phantom_node_pair.source_phantom.reverse_node_id);
|
phantom_node_pair.source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID)
|
if (phantom_node_pair.target_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// util::SimpleLogger().Write(logDEBUG) << "rev-a insert: " <<
|
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id != SPECIAL_SEGMENTID);
|
||||||
// phantom_node_pair.target_phantom.forward_node_id << ", w: " <<
|
reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_segment_id.id,
|
||||||
// phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
|
|
||||||
reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id,
|
|
||||||
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
|
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
|
||||||
phantom_node_pair.target_phantom.forward_node_id);
|
phantom_node_pair.target_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (phantom_node_pair.target_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
// util::SimpleLogger().Write(logDEBUG) << "rev-b insert: " <<
|
BOOST_ASSERT(phantom_node_pair.target_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID);
|
||||||
// phantom_node_pair.target_phantom.reverse_node_id << ", w: " <<
|
reverse_heap1.Insert(phantom_node_pair.target_phantom.reverse_segment_id.id,
|
||||||
// phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
|
|
||||||
reverse_heap1.Insert(phantom_node_pair.target_phantom.reverse_node_id,
|
|
||||||
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
|
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
|
||||||
phantom_node_pair.target_phantom.reverse_node_id);
|
phantom_node_pair.target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// search from s and t till new_min/(1+epsilon) > length_of_shortest_path
|
// search from s and t till new_min/(1+epsilon) > length_of_shortest_path
|
||||||
@ -316,9 +308,9 @@ class AlternativeRouting final
|
|||||||
BOOST_ASSERT(!packed_shortest_path.empty());
|
BOOST_ASSERT(!packed_shortest_path.empty());
|
||||||
raw_route_data.unpacked_path_segments.resize(1);
|
raw_route_data.unpacked_path_segments.resize(1);
|
||||||
raw_route_data.source_traversed_in_reverse.push_back(
|
raw_route_data.source_traversed_in_reverse.push_back(
|
||||||
(packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_node_id));
|
(packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_segment_id.id));
|
||||||
raw_route_data.target_traversed_in_reverse.push_back(
|
raw_route_data.target_traversed_in_reverse.push_back(
|
||||||
(packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_node_id));
|
(packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_segment_id.id));
|
||||||
|
|
||||||
super::UnpackPath(
|
super::UnpackPath(
|
||||||
// -- packed input
|
// -- packed input
|
||||||
@ -338,9 +330,9 @@ class AlternativeRouting final
|
|||||||
s_v_middle, v_t_middle, packed_alternate_path);
|
s_v_middle, v_t_middle, packed_alternate_path);
|
||||||
|
|
||||||
raw_route_data.alt_source_traversed_in_reverse.push_back((
|
raw_route_data.alt_source_traversed_in_reverse.push_back((
|
||||||
packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id));
|
packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_segment_id.id));
|
||||||
raw_route_data.alt_target_traversed_in_reverse.push_back(
|
raw_route_data.alt_target_traversed_in_reverse.push_back(
|
||||||
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id));
|
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_segment_id.id));
|
||||||
|
|
||||||
// unpack the alternate path
|
// unpack the alternate path
|
||||||
super::UnpackPath(packed_alternate_path.begin(), packed_alternate_path.end(),
|
super::UnpackPath(packed_alternate_path.begin(), packed_alternate_path.end(),
|
||||||
|
@ -60,31 +60,31 @@ class DirectShortestPathRouting final
|
|||||||
BOOST_ASSERT(source_phantom.IsValid());
|
BOOST_ASSERT(source_phantom.IsValid());
|
||||||
BOOST_ASSERT(target_phantom.IsValid());
|
BOOST_ASSERT(target_phantom.IsValid());
|
||||||
|
|
||||||
if (source_phantom.forward_node_id != SPECIAL_NODEID)
|
if (source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
-source_phantom.GetForwardWeightPlusOffset(),
|
-source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (source_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (source_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
-source_phantom.GetReverseWeightPlusOffset(),
|
-source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_phantom.forward_node_id != SPECIAL_NODEID)
|
if (target_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.forward_node_id,
|
reverse_heap.Insert(target_phantom.forward_segment_id.id,
|
||||||
target_phantom.GetForwardWeightPlusOffset(),
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
target_phantom.forward_node_id);
|
target_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (target_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.reverse_node_id,
|
reverse_heap.Insert(target_phantom.reverse_segment_id.id,
|
||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_node_id);
|
target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int distance = INVALID_EDGE_WEIGHT;
|
int distance = INVALID_EDGE_WEIGHT;
|
||||||
@ -124,9 +124,9 @@ class DirectShortestPathRouting final
|
|||||||
raw_route_data.shortest_path_length = distance;
|
raw_route_data.shortest_path_length = distance;
|
||||||
raw_route_data.unpacked_path_segments.resize(1);
|
raw_route_data.unpacked_path_segments.resize(1);
|
||||||
raw_route_data.source_traversed_in_reverse.push_back(
|
raw_route_data.source_traversed_in_reverse.push_back(
|
||||||
(packed_leg.front() != phantom_node_pair.source_phantom.forward_node_id));
|
(packed_leg.front() != phantom_node_pair.source_phantom.forward_segment_id.id));
|
||||||
raw_route_data.target_traversed_in_reverse.push_back(
|
raw_route_data.target_traversed_in_reverse.push_back(
|
||||||
(packed_leg.back() != phantom_node_pair.target_phantom.forward_node_id));
|
(packed_leg.back() != phantom_node_pair.target_phantom.forward_segment_id.id));
|
||||||
|
|
||||||
super::UnpackPath(packed_leg.begin(), packed_leg.end(), phantom_node_pair,
|
super::UnpackPath(packed_leg.begin(), packed_leg.end(), phantom_node_pair,
|
||||||
raw_route_data.unpacked_path_segments.front());
|
raw_route_data.unpacked_path_segments.front());
|
||||||
|
@ -71,15 +71,17 @@ class ManyToManyRouting final
|
|||||||
query_heap.Clear();
|
query_heap.Clear();
|
||||||
// insert target(s) at distance 0
|
// insert target(s) at distance 0
|
||||||
|
|
||||||
if (SPECIAL_NODEID != phantom.forward_node_id)
|
if (phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
query_heap.Insert(phantom.forward_node_id, phantom.GetForwardWeightPlusOffset(),
|
query_heap.Insert(phantom.forward_segment_id.id,
|
||||||
phantom.forward_node_id);
|
phantom.GetForwardWeightPlusOffset(),
|
||||||
|
phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (SPECIAL_NODEID != phantom.reverse_node_id)
|
if (phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
query_heap.Insert(phantom.reverse_node_id, phantom.GetReverseWeightPlusOffset(),
|
query_heap.Insert(phantom.reverse_segment_id.id,
|
||||||
phantom.reverse_node_id);
|
phantom.GetReverseWeightPlusOffset(),
|
||||||
|
phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// explore search space
|
// explore search space
|
||||||
@ -97,15 +99,17 @@ class ManyToManyRouting final
|
|||||||
query_heap.Clear();
|
query_heap.Clear();
|
||||||
// insert target(s) at distance 0
|
// insert target(s) at distance 0
|
||||||
|
|
||||||
if (SPECIAL_NODEID != phantom.forward_node_id)
|
if (phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
query_heap.Insert(phantom.forward_node_id, -phantom.GetForwardWeightPlusOffset(),
|
query_heap.Insert(phantom.forward_segment_id.id,
|
||||||
phantom.forward_node_id);
|
-phantom.GetForwardWeightPlusOffset(),
|
||||||
|
phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (SPECIAL_NODEID != phantom.reverse_node_id)
|
if (phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
query_heap.Insert(phantom.reverse_node_id, -phantom.GetReverseWeightPlusOffset(),
|
query_heap.Insert(phantom.reverse_segment_id.id,
|
||||||
phantom.reverse_node_id);
|
-phantom.GetReverseWeightPlusOffset(),
|
||||||
|
phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// explore search space
|
// explore search space
|
||||||
|
@ -213,9 +213,9 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
std::vector<PathData> &unpacked_path) const
|
std::vector<PathData> &unpacked_path) const
|
||||||
{
|
{
|
||||||
const bool start_traversed_in_reverse =
|
const bool start_traversed_in_reverse =
|
||||||
(*packed_path_begin != phantom_node_pair.source_phantom.forward_node_id);
|
(*packed_path_begin != phantom_node_pair.source_phantom.forward_segment_id.id);
|
||||||
const bool target_traversed_in_reverse =
|
const bool target_traversed_in_reverse =
|
||||||
(*std::prev(packed_path_end) != phantom_node_pair.target_phantom.forward_node_id);
|
(*std::prev(packed_path_end) != phantom_node_pair.target_phantom.forward_segment_id.id);
|
||||||
|
|
||||||
BOOST_ASSERT(std::distance(packed_path_begin, packed_path_end) > 0);
|
BOOST_ASSERT(std::distance(packed_path_begin, packed_path_end) > 0);
|
||||||
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
|
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
|
||||||
@ -391,11 +391,12 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(i < id_vector.size());
|
BOOST_ASSERT(i < id_vector.size());
|
||||||
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
||||||
unpacked_path.emplace_back(PathData{
|
unpacked_path.emplace_back(
|
||||||
id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i],
|
PathData{id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i],
|
||||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||||
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
|
target_traversed_in_reverse
|
||||||
: phantom_node_pair.target_phantom.forward_travel_mode});
|
? phantom_node_pair.target_phantom.backward_travel_mode
|
||||||
|
: phantom_node_pair.target_phantom.forward_travel_mode});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_local_path && unpacked_path.size() > 0)
|
if (is_local_path && unpacked_path.size() > 0)
|
||||||
@ -520,8 +521,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
// A forced loop might be necessary, if source and target are on the same segment.
|
// A forced loop might be necessary, if source and target are on the same segment.
|
||||||
// If this is the case and the offsets of the respective direction are larger for the source
|
// If this is the case and the offsets of the respective direction are larger for the source
|
||||||
// than the target
|
// than the target
|
||||||
// then a force loop is required (e.g. source_phantom.forward_node_id ==
|
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
|
||||||
// target_phantom.forward_node_id
|
// target_phantom.forward_segment_id
|
||||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||||
// requires
|
// requires
|
||||||
// a force loop, if the heaps have been initialized with positive offsets.
|
// a force loop, if the heaps have been initialized with positive offsets.
|
||||||
@ -588,8 +589,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
// A forced loop might be necessary, if source and target are on the same segment.
|
// A forced loop might be necessary, if source and target are on the same segment.
|
||||||
// If this is the case and the offsets of the respective direction are larger for the source
|
// If this is the case and the offsets of the respective direction are larger for the source
|
||||||
// than the target
|
// than the target
|
||||||
// then a force loop is required (e.g. source_phantom.forward_node_id ==
|
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
|
||||||
// target_phantom.forward_node_id
|
// target_phantom.forward_segment_id
|
||||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||||
// requires
|
// requires
|
||||||
// a force loop, if the heaps have been initialized with positive offsets.
|
// a force loop, if the heaps have been initialized with positive offsets.
|
||||||
@ -760,7 +761,9 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
bool NeedsLoopForward(const PhantomNode &source_phantom,
|
bool NeedsLoopForward(const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom) const
|
const PhantomNode &target_phantom) const
|
||||||
{
|
{
|
||||||
return source_phantom.forward_node_id == target_phantom.forward_node_id &&
|
return source_phantom.forward_segment_id.enabled &&
|
||||||
|
target_phantom.forward_segment_id.enabled &&
|
||||||
|
source_phantom.forward_segment_id.id == target_phantom.forward_segment_id.id &&
|
||||||
source_phantom.GetForwardWeightPlusOffset() >
|
source_phantom.GetForwardWeightPlusOffset() >
|
||||||
target_phantom.GetForwardWeightPlusOffset();
|
target_phantom.GetForwardWeightPlusOffset();
|
||||||
}
|
}
|
||||||
@ -768,7 +771,9 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
bool NeedsLoopBackwards(const PhantomNode &source_phantom,
|
bool NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom) const
|
const PhantomNode &target_phantom) const
|
||||||
{
|
{
|
||||||
return source_phantom.reverse_node_id == target_phantom.reverse_node_id &&
|
return source_phantom.reverse_segment_id.enabled &&
|
||||||
|
target_phantom.reverse_segment_id.enabled &&
|
||||||
|
source_phantom.reverse_segment_id.id == target_phantom.reverse_segment_id.id &&
|
||||||
source_phantom.GetReverseWeightPlusOffset() >
|
source_phantom.GetReverseWeightPlusOffset() >
|
||||||
target_phantom.GetReverseWeightPlusOffset();
|
target_phantom.GetReverseWeightPlusOffset();
|
||||||
}
|
}
|
||||||
@ -812,30 +817,30 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
BOOST_ASSERT(forward_heap.Empty());
|
BOOST_ASSERT(forward_heap.Empty());
|
||||||
BOOST_ASSERT(reverse_heap.Empty());
|
BOOST_ASSERT(reverse_heap.Empty());
|
||||||
|
|
||||||
if (source_phantom.forward_node_id != SPECIAL_NODEID)
|
if (source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
-source_phantom.GetForwardWeightPlusOffset(),
|
-source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (source_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (source_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
-source_phantom.GetReverseWeightPlusOffset(),
|
-source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_phantom.forward_node_id != SPECIAL_NODEID)
|
if (target_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.forward_node_id,
|
reverse_heap.Insert(target_phantom.forward_segment_id.id,
|
||||||
target_phantom.GetForwardWeightPlusOffset(),
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
target_phantom.forward_node_id);
|
target_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (target_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (target_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.reverse_node_id,
|
reverse_heap.Insert(target_phantom.reverse_segment_id.id,
|
||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_node_id);
|
target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
const bool constexpr DO_NOT_FORCE_LOOPS =
|
||||||
@ -866,30 +871,30 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
|||||||
BOOST_ASSERT(forward_heap.Empty());
|
BOOST_ASSERT(forward_heap.Empty());
|
||||||
BOOST_ASSERT(reverse_heap.Empty());
|
BOOST_ASSERT(reverse_heap.Empty());
|
||||||
|
|
||||||
if (source_phantom.forward_node_id != SPECIAL_NODEID)
|
if (source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
-source_phantom.GetForwardWeightPlusOffset(),
|
-source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (source_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (source_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
-source_phantom.GetReverseWeightPlusOffset(),
|
-source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_phantom.forward_node_id != SPECIAL_NODEID)
|
if (target_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.forward_node_id,
|
reverse_heap.Insert(target_phantom.forward_segment_id.id,
|
||||||
target_phantom.GetForwardWeightPlusOffset(),
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
target_phantom.forward_node_id);
|
target_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (target_phantom.reverse_node_id != SPECIAL_NODEID)
|
if (target_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.reverse_node_id,
|
reverse_heap.Insert(target_phantom.reverse_segment_id.id,
|
||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_node_id);
|
target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
const bool constexpr DO_NOT_FORCE_LOOPS =
|
||||||
|
@ -56,29 +56,29 @@ class ShortestPathRouting final
|
|||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
if (search_from_forward_node)
|
if (search_from_forward_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
total_distance_to_forward -
|
total_distance_to_forward -
|
||||||
source_phantom.GetForwardWeightPlusOffset(),
|
source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (search_from_reverse_node)
|
if (search_from_reverse_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
total_distance_to_reverse -
|
total_distance_to_reverse -
|
||||||
source_phantom.GetReverseWeightPlusOffset(),
|
source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
if (search_to_forward_node)
|
if (search_to_forward_node)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.forward_node_id,
|
reverse_heap.Insert(target_phantom.forward_segment_id.id,
|
||||||
target_phantom.GetForwardWeightPlusOffset(),
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
target_phantom.forward_node_id);
|
target_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (search_to_reverse_node)
|
if (search_to_reverse_node)
|
||||||
{
|
{
|
||||||
reverse_heap.Insert(target_phantom.reverse_node_id,
|
reverse_heap.Insert(target_phantom.reverse_segment_id.id,
|
||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_node_id);
|
target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||||
@ -88,8 +88,10 @@ class ShortestPathRouting final
|
|||||||
auto is_oneway_source = !(search_from_forward_node && search_from_reverse_node);
|
auto is_oneway_source = !(search_from_forward_node && search_from_reverse_node);
|
||||||
auto is_oneway_target = !(search_to_forward_node && search_to_reverse_node);
|
auto is_oneway_target = !(search_to_forward_node && search_to_reverse_node);
|
||||||
// we only enable loops here if we can't search from forward to backward node
|
// we only enable loops here if we can't search from forward to backward node
|
||||||
auto needs_loop_forwad = is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom);
|
auto needs_loop_forwad =
|
||||||
auto needs_loop_backwards = is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom);
|
is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom);
|
||||||
|
auto needs_loop_backwards =
|
||||||
|
is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom);
|
||||||
if (super::facade->GetCoreSize() > 0)
|
if (super::facade->GetCoreSize() > 0)
|
||||||
{
|
{
|
||||||
forward_core_heap.Clear();
|
forward_core_heap.Clear();
|
||||||
@ -97,7 +99,8 @@ class ShortestPathRouting final
|
|||||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||||
super::SearchWithCore(forward_heap, reverse_heap, forward_core_heap, reverse_core_heap,
|
super::SearchWithCore(forward_heap, reverse_heap, forward_core_heap, reverse_core_heap,
|
||||||
new_total_distance, leg_packed_path, needs_loop_forwad, needs_loop_backwards);
|
new_total_distance, leg_packed_path, needs_loop_forwad,
|
||||||
|
needs_loop_backwards);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -130,23 +133,23 @@ class ShortestPathRouting final
|
|||||||
{
|
{
|
||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
reverse_heap.Insert(target_phantom.forward_node_id,
|
reverse_heap.Insert(target_phantom.forward_segment_id.id,
|
||||||
target_phantom.GetForwardWeightPlusOffset(),
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
target_phantom.forward_node_id);
|
target_phantom.forward_segment_id.id);
|
||||||
|
|
||||||
if (search_from_forward_node)
|
if (search_from_forward_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
total_distance_to_forward -
|
total_distance_to_forward -
|
||||||
source_phantom.GetForwardWeightPlusOffset(),
|
source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (search_from_reverse_node)
|
if (search_from_reverse_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
total_distance_to_reverse -
|
total_distance_to_reverse -
|
||||||
source_phantom.GetReverseWeightPlusOffset(),
|
source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||||
@ -176,22 +179,22 @@ class ShortestPathRouting final
|
|||||||
{
|
{
|
||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
reverse_heap.Insert(target_phantom.reverse_node_id,
|
reverse_heap.Insert(target_phantom.reverse_segment_id.id,
|
||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_node_id);
|
target_phantom.reverse_segment_id.id);
|
||||||
if (search_from_forward_node)
|
if (search_from_forward_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.forward_node_id,
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
total_distance_to_forward -
|
total_distance_to_forward -
|
||||||
source_phantom.GetForwardWeightPlusOffset(),
|
source_phantom.GetForwardWeightPlusOffset(),
|
||||||
source_phantom.forward_node_id);
|
source_phantom.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
if (search_from_reverse_node)
|
if (search_from_reverse_node)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source_phantom.reverse_node_id,
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
total_distance_to_reverse -
|
total_distance_to_reverse -
|
||||||
source_phantom.GetReverseWeightPlusOffset(),
|
source_phantom.GetReverseWeightPlusOffset(),
|
||||||
source_phantom.reverse_node_id);
|
source_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||||
@ -234,10 +237,11 @@ class ShortestPathRouting final
|
|||||||
raw_route_data.unpacked_path_segments[current_leg]);
|
raw_route_data.unpacked_path_segments[current_leg]);
|
||||||
|
|
||||||
raw_route_data.source_traversed_in_reverse.push_back(
|
raw_route_data.source_traversed_in_reverse.push_back(
|
||||||
(*leg_begin != phantom_nodes_vector[current_leg].source_phantom.forward_node_id));
|
(*leg_begin !=
|
||||||
|
phantom_nodes_vector[current_leg].source_phantom.forward_segment_id.id));
|
||||||
raw_route_data.target_traversed_in_reverse.push_back(
|
raw_route_data.target_traversed_in_reverse.push_back(
|
||||||
(*std::prev(leg_end) !=
|
(*std::prev(leg_end) !=
|
||||||
phantom_nodes_vector[current_leg].target_phantom.forward_node_id));
|
phantom_nodes_vector[current_leg].target_phantom.forward_segment_id.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +249,8 @@ class ShortestPathRouting final
|
|||||||
const boost::optional<bool> uturns,
|
const boost::optional<bool> uturns,
|
||||||
InternalRouteResult &raw_route_data) const
|
InternalRouteResult &raw_route_data) const
|
||||||
{
|
{
|
||||||
|
const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault();
|
||||||
|
|
||||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
|
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
|
||||||
super::facade->GetNumberOfNodes());
|
super::facade->GetNumberOfNodes());
|
||||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
|
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
|
||||||
@ -258,9 +264,9 @@ class ShortestPathRouting final
|
|||||||
int total_distance_to_forward = 0;
|
int total_distance_to_forward = 0;
|
||||||
int total_distance_to_reverse = 0;
|
int total_distance_to_reverse = 0;
|
||||||
bool search_from_forward_node =
|
bool search_from_forward_node =
|
||||||
phantom_nodes_vector.front().source_phantom.forward_node_id != SPECIAL_NODEID;
|
phantom_nodes_vector.front().source_phantom.forward_segment_id.enabled;
|
||||||
bool search_from_reverse_node =
|
bool search_from_reverse_node =
|
||||||
phantom_nodes_vector.front().source_phantom.reverse_node_id != SPECIAL_NODEID;
|
phantom_nodes_vector.front().source_phantom.reverse_segment_id.enabled;
|
||||||
|
|
||||||
std::vector<NodeID> prev_packed_leg_to_forward;
|
std::vector<NodeID> prev_packed_leg_to_forward;
|
||||||
std::vector<NodeID> prev_packed_leg_to_reverse;
|
std::vector<NodeID> prev_packed_leg_to_reverse;
|
||||||
@ -270,8 +276,6 @@ class ShortestPathRouting final
|
|||||||
std::vector<NodeID> total_packed_path_to_reverse;
|
std::vector<NodeID> total_packed_path_to_reverse;
|
||||||
std::vector<std::size_t> packed_leg_to_reverse_begin;
|
std::vector<std::size_t> packed_leg_to_reverse_begin;
|
||||||
|
|
||||||
const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault();
|
|
||||||
|
|
||||||
std::size_t current_leg = 0;
|
std::size_t current_leg = 0;
|
||||||
// this implements a dynamic program that finds the shortest route through
|
// this implements a dynamic program that finds the shortest route through
|
||||||
// a list of vias
|
// a list of vias
|
||||||
@ -286,13 +290,11 @@ class ShortestPathRouting final
|
|||||||
const auto &source_phantom = phantom_node_pair.source_phantom;
|
const auto &source_phantom = phantom_node_pair.source_phantom;
|
||||||
const auto &target_phantom = phantom_node_pair.target_phantom;
|
const auto &target_phantom = phantom_node_pair.target_phantom;
|
||||||
|
|
||||||
bool search_to_forward_node = target_phantom.forward_node_id != SPECIAL_NODEID;
|
bool search_to_forward_node = target_phantom.forward_segment_id.enabled;
|
||||||
bool search_to_reverse_node = target_phantom.reverse_node_id != SPECIAL_NODEID;
|
bool search_to_reverse_node = target_phantom.reverse_segment_id.enabled;
|
||||||
|
|
||||||
BOOST_ASSERT(!search_from_forward_node ||
|
BOOST_ASSERT(!search_from_forward_node || source_phantom.forward_segment_id.enabled);
|
||||||
source_phantom.forward_node_id != SPECIAL_NODEID);
|
BOOST_ASSERT(!search_from_reverse_node || source_phantom.reverse_segment_id.enabled);
|
||||||
BOOST_ASSERT(!search_from_reverse_node ||
|
|
||||||
source_phantom.reverse_node_id != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
BOOST_ASSERT(search_from_forward_node || search_from_reverse_node);
|
BOOST_ASSERT(search_from_forward_node || search_from_reverse_node);
|
||||||
|
|
||||||
@ -308,14 +310,14 @@ class ShortestPathRouting final
|
|||||||
new_total_distance_to_forward, packed_leg_to_forward);
|
new_total_distance_to_forward, packed_leg_to_forward);
|
||||||
// if only the reverse node is valid (e.g. when using the match plugin) we
|
// if only the reverse node is valid (e.g. when using the match plugin) we
|
||||||
// actually need to move
|
// actually need to move
|
||||||
if (target_phantom.forward_node_id == SPECIAL_NODEID)
|
if (target_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(target_phantom.reverse_node_id != SPECIAL_NODEID);
|
BOOST_ASSERT(target_phantom.reverse_segment_id.enabled);
|
||||||
new_total_distance_to_reverse = new_total_distance_to_forward;
|
new_total_distance_to_reverse = new_total_distance_to_forward;
|
||||||
packed_leg_to_reverse = std::move(packed_leg_to_forward);
|
packed_leg_to_reverse = std::move(packed_leg_to_forward);
|
||||||
new_total_distance_to_forward = INVALID_EDGE_WEIGHT;
|
new_total_distance_to_forward = INVALID_EDGE_WEIGHT;
|
||||||
}
|
}
|
||||||
else if (target_phantom.reverse_node_id != SPECIAL_NODEID)
|
else if (target_phantom.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
new_total_distance_to_reverse = new_total_distance_to_forward;
|
new_total_distance_to_reverse = new_total_distance_to_forward;
|
||||||
packed_leg_to_reverse = packed_leg_to_forward;
|
packed_leg_to_reverse = packed_leg_to_forward;
|
||||||
@ -346,16 +348,16 @@ class ShortestPathRouting final
|
|||||||
{
|
{
|
||||||
bool forward_to_forward =
|
bool forward_to_forward =
|
||||||
(new_total_distance_to_forward != INVALID_EDGE_WEIGHT) &&
|
(new_total_distance_to_forward != INVALID_EDGE_WEIGHT) &&
|
||||||
packed_leg_to_forward.front() == source_phantom.forward_node_id;
|
packed_leg_to_forward.front() == source_phantom.forward_segment_id.id;
|
||||||
bool reverse_to_forward =
|
bool reverse_to_forward =
|
||||||
(new_total_distance_to_forward != INVALID_EDGE_WEIGHT) &&
|
(new_total_distance_to_forward != INVALID_EDGE_WEIGHT) &&
|
||||||
packed_leg_to_forward.front() == source_phantom.reverse_node_id;
|
packed_leg_to_forward.front() == source_phantom.reverse_segment_id.id;
|
||||||
bool forward_to_reverse =
|
bool forward_to_reverse =
|
||||||
(new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) &&
|
(new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) &&
|
||||||
packed_leg_to_reverse.front() == source_phantom.forward_node_id;
|
packed_leg_to_reverse.front() == source_phantom.forward_segment_id.id;
|
||||||
bool reverse_to_reverse =
|
bool reverse_to_reverse =
|
||||||
(new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) &&
|
(new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) &&
|
||||||
packed_leg_to_reverse.front() == source_phantom.reverse_node_id;
|
packed_leg_to_reverse.front() == source_phantom.reverse_segment_id.id;
|
||||||
|
|
||||||
BOOST_ASSERT(!forward_to_forward || !reverse_to_forward);
|
BOOST_ASSERT(!forward_to_forward || !reverse_to_forward);
|
||||||
BOOST_ASSERT(!forward_to_reverse || !reverse_to_reverse);
|
BOOST_ASSERT(!forward_to_reverse || !reverse_to_reverse);
|
||||||
@ -390,7 +392,7 @@ class ShortestPathRouting final
|
|||||||
|
|
||||||
if (new_total_distance_to_forward != INVALID_EDGE_WEIGHT)
|
if (new_total_distance_to_forward != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(target_phantom.forward_node_id != SPECIAL_NODEID);
|
BOOST_ASSERT(target_phantom.forward_segment_id.enabled);
|
||||||
|
|
||||||
packed_leg_to_forward_begin.push_back(total_packed_path_to_forward.size());
|
packed_leg_to_forward_begin.push_back(total_packed_path_to_forward.size());
|
||||||
total_packed_path_to_forward.insert(total_packed_path_to_forward.end(),
|
total_packed_path_to_forward.insert(total_packed_path_to_forward.end(),
|
||||||
@ -407,7 +409,7 @@ class ShortestPathRouting final
|
|||||||
|
|
||||||
if (new_total_distance_to_reverse != INVALID_EDGE_WEIGHT)
|
if (new_total_distance_to_reverse != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(target_phantom.reverse_node_id != SPECIAL_NODEID);
|
BOOST_ASSERT(target_phantom.reverse_segment_id.enabled);
|
||||||
|
|
||||||
packed_leg_to_reverse_begin.push_back(total_packed_path_to_reverse.size());
|
packed_leg_to_reverse_begin.push_back(total_packed_path_to_reverse.size());
|
||||||
total_packed_path_to_reverse.insert(total_packed_path_to_reverse.end(),
|
total_packed_path_to_reverse.insert(total_packed_path_to_reverse.end(),
|
||||||
|
@ -20,44 +20,44 @@ namespace extractor
|
|||||||
struct EdgeBasedNode
|
struct EdgeBasedNode
|
||||||
{
|
{
|
||||||
EdgeBasedNode()
|
EdgeBasedNode()
|
||||||
: forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID),
|
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
||||||
u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0),
|
reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID),
|
||||||
forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID),
|
v(SPECIAL_NODEID), name_id(0), forward_packed_geometry_id(SPECIAL_EDGEID),
|
||||||
component{INVALID_COMPONENTID, false},
|
reverse_packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false},
|
||||||
fwd_segment_position(std::numeric_limits<unsigned short>::max()),
|
fwd_segment_position(std::numeric_limits<unsigned short>::max()),
|
||||||
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||||
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit EdgeBasedNode(NodeID forward_edge_based_node_id,
|
explicit EdgeBasedNode(const SegmentID forward_segment_id_,
|
||||||
NodeID reverse_edge_based_node_id,
|
const SegmentID reverse_segment_id_,
|
||||||
NodeID u,
|
NodeID u,
|
||||||
NodeID v,
|
NodeID v,
|
||||||
unsigned name_id,
|
unsigned name_id,
|
||||||
unsigned forward_weight_or_packed_geometry_id_,
|
unsigned forward_geometry_id_,
|
||||||
unsigned reverse_weight_or_packed_geometry_id_,
|
unsigned reverse_geometry_id_,
|
||||||
bool is_tiny_component,
|
bool is_tiny_component,
|
||||||
unsigned component_id,
|
unsigned component_id,
|
||||||
unsigned short fwd_segment_position,
|
unsigned short fwd_segment_position,
|
||||||
TravelMode forward_travel_mode,
|
TravelMode forward_travel_mode,
|
||||||
TravelMode backward_travel_mode)
|
TravelMode backward_travel_mode)
|
||||||
: forward_edge_based_node_id(forward_edge_based_node_id),
|
: forward_segment_id(forward_segment_id_),
|
||||||
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
|
reverse_segment_id(reverse_segment_id_), u(u), v(v), name_id(name_id),
|
||||||
forward_packed_geometry_id(forward_weight_or_packed_geometry_id_),
|
forward_packed_geometry_id(forward_geometry_id_),
|
||||||
reverse_packed_geometry_id(reverse_weight_or_packed_geometry_id_),
|
reverse_packed_geometry_id(reverse_geometry_id_),
|
||||||
component{component_id, is_tiny_component}, fwd_segment_position(fwd_segment_position),
|
component{component_id, is_tiny_component}, fwd_segment_position(fwd_segment_position),
|
||||||
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
|
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
|
BOOST_ASSERT(forward_segment_id.enabled ||
|
||||||
(reverse_edge_based_node_id != SPECIAL_NODEID));
|
reverse_segment_id.enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
|
SegmentID forward_segment_id; // needed for edge-expanded graph
|
||||||
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
|
SegmentID reverse_segment_id; // needed for edge-expanded graph
|
||||||
NodeID u; // indices into the coordinates array
|
NodeID u; // indices into the coordinates array
|
||||||
NodeID v; // indices into the coordinates array
|
NodeID v; // indices into the coordinates array
|
||||||
unsigned name_id; // id of the edge name
|
unsigned name_id; // id of the edge name
|
||||||
|
|
||||||
unsigned forward_packed_geometry_id;
|
unsigned forward_packed_geometry_id;
|
||||||
unsigned reverse_packed_geometry_id;
|
unsigned reverse_packed_geometry_id;
|
||||||
|
@ -440,14 +440,8 @@ class StaticRTree
|
|||||||
// store phantom node in result vector
|
// store phantom node in result vector
|
||||||
results.push_back(std::move(current_segment));
|
results.push_back(std::move(current_segment));
|
||||||
|
|
||||||
if (!use_segment.first)
|
results.back().forward_segment_id.enabled &= use_segment.first;
|
||||||
{
|
results.back().reverse_segment_id.enabled &= use_segment.second;
|
||||||
results.back().forward_edge_based_node_id = SPECIAL_NODEID;
|
|
||||||
}
|
|
||||||
else if (!use_segment.second)
|
|
||||||
{
|
|
||||||
results.back().reverse_edge_based_node_id = SPECIAL_NODEID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "util/strong_typedef.hpp"
|
#include "util/strong_typedef.hpp"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
@ -56,9 +58,26 @@ using EdgeID = unsigned int;
|
|||||||
using EdgeWeight = int;
|
using EdgeWeight = int;
|
||||||
|
|
||||||
static const NodeID SPECIAL_NODEID = std::numeric_limits<unsigned>::max();
|
static const NodeID SPECIAL_NODEID = std::numeric_limits<unsigned>::max();
|
||||||
|
static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<int>::max();
|
||||||
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<unsigned>::max();
|
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<unsigned>::max();
|
||||||
static const unsigned INVALID_NAMEID = std::numeric_limits<unsigned>::max();
|
static const unsigned INVALID_NAMEID = std::numeric_limits<unsigned>::max();
|
||||||
static const unsigned INVALID_COMPONENTID = 0;
|
static const unsigned INVALID_COMPONENTID = 0;
|
||||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<int>::max();
|
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
|
struct SegmentID
|
||||||
|
{
|
||||||
|
SegmentID(const NodeID id_, const bool enabled_) : id{id_}, enabled{enabled_}
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(!enabled || id != SPECIAL_SEGMENTID);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeID id : 31;
|
||||||
|
bool enabled : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// bit-fields are broken on Windows
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
static_assert(sizeof(SegmentID) == 4, "SegmentID needs to be 4 bytes big");
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* TYPEDEFS_H */
|
#endif /* TYPEDEFS_H */
|
||||||
|
@ -56,10 +56,10 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
|||||||
candidates.begin(), candidates.end(),
|
candidates.begin(), candidates.end(),
|
||||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
||||||
{
|
{
|
||||||
return lhs.phantom_node.forward_node_id < rhs.phantom_node.forward_node_id ||
|
return lhs.phantom_node.forward_segment_id.id < rhs.phantom_node.forward_segment_id.id ||
|
||||||
(lhs.phantom_node.forward_node_id == rhs.phantom_node.forward_node_id &&
|
(lhs.phantom_node.forward_segment_id.id == rhs.phantom_node.forward_segment_id.id &&
|
||||||
(lhs.phantom_node.reverse_node_id < rhs.phantom_node.reverse_node_id ||
|
(lhs.phantom_node.reverse_segment_id.id < rhs.phantom_node.reverse_segment_id.id ||
|
||||||
(lhs.phantom_node.reverse_node_id == rhs.phantom_node.reverse_node_id &&
|
(lhs.phantom_node.reverse_segment_id.id == rhs.phantom_node.reverse_segment_id.id &&
|
||||||
lhs.distance < rhs.distance)));
|
lhs.distance < rhs.distance)));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -67,8 +67,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
|||||||
candidates.begin(), candidates.end(),
|
candidates.begin(), candidates.end(),
|
||||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
||||||
{
|
{
|
||||||
return lhs.phantom_node.forward_node_id == rhs.phantom_node.forward_node_id &&
|
return lhs.phantom_node.forward_segment_id.id == rhs.phantom_node.forward_segment_id.id &&
|
||||||
lhs.phantom_node.reverse_node_id == rhs.phantom_node.reverse_node_id;
|
lhs.phantom_node.reverse_segment_id.id == rhs.phantom_node.reverse_segment_id.id;
|
||||||
});
|
});
|
||||||
candidates.resize(new_end - candidates.begin());
|
candidates.resize(new_end - candidates.begin());
|
||||||
|
|
||||||
@ -78,15 +78,15 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
|||||||
for (const auto i : util::irange<std::size_t>(0, compact_size))
|
for (const auto i : util::irange<std::size_t>(0, compact_size))
|
||||||
{
|
{
|
||||||
// Split edge if it is bidirectional and append reverse direction to end of list
|
// Split edge if it is bidirectional and append reverse direction to end of list
|
||||||
if (candidates[i].phantom_node.forward_node_id != SPECIAL_NODEID &&
|
if (candidates[i].phantom_node.forward_segment_id.enabled &&
|
||||||
candidates[i].phantom_node.reverse_node_id != SPECIAL_NODEID)
|
candidates[i].phantom_node.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
PhantomNode reverse_node(candidates[i].phantom_node);
|
PhantomNode reverse_node(candidates[i].phantom_node);
|
||||||
reverse_node.forward_node_id = SPECIAL_NODEID;
|
reverse_node.forward_segment_id.enabled = false;
|
||||||
candidates.push_back(
|
candidates.push_back(
|
||||||
PhantomNodeWithDistance{reverse_node, candidates[i].distance});
|
PhantomNodeWithDistance{reverse_node, candidates[i].distance});
|
||||||
|
|
||||||
candidates[i].phantom_node.reverse_node_id = SPECIAL_NODEID;
|
candidates[i].phantom_node.reverse_segment_id.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If this is a valid forward edge, go ahead and add it to the tile
|
// If this is a valid forward edge, go ahead and add it to the tile
|
||||||
if (forward_weight != 0 && edge.forward_edge_based_node_id != SPECIAL_NODEID)
|
if (forward_weight != 0 && edge.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
std::int32_t start_x = 0;
|
std::int32_t start_x = 0;
|
||||||
std::int32_t start_y = 0;
|
std::int32_t start_y = 0;
|
||||||
@ -383,7 +383,7 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str
|
|||||||
|
|
||||||
// Repeat the above for the coordinates reversed and using the `reverse`
|
// Repeat the above for the coordinates reversed and using the `reverse`
|
||||||
// properties
|
// properties
|
||||||
if (reverse_weight != 0 && edge.reverse_edge_based_node_id != SPECIAL_NODEID)
|
if (reverse_weight != 0 && edge.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
std::int32_t start_x = 0;
|
std::int32_t start_x = 0;
|
||||||
std::int32_t start_y = 0;
|
std::int32_t start_y = 0;
|
||||||
|
@ -50,20 +50,33 @@ Status ViaRoutePlugin::HandleRequest(const api::RouteParameters &route_parameter
|
|||||||
auto phantom_node_pairs = GetPhantomNodes(route_parameters);
|
auto phantom_node_pairs = GetPhantomNodes(route_parameters);
|
||||||
if (phantom_node_pairs.size() != route_parameters.coordinates.size())
|
if (phantom_node_pairs.size() != route_parameters.coordinates.size())
|
||||||
{
|
{
|
||||||
return Error("NoSegment",
|
return Error("NoSegment", std::string("Could not find a matching segment for coordinate ") +
|
||||||
std::string("Could not find a matching segment for coordinate ") +
|
std::to_string(phantom_node_pairs.size()),
|
||||||
std::to_string(phantom_node_pairs.size()),
|
|
||||||
json_result);
|
json_result);
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(phantom_node_pairs.size() == route_parameters.coordinates.size());
|
BOOST_ASSERT(phantom_node_pairs.size() == route_parameters.coordinates.size());
|
||||||
|
|
||||||
auto snapped_phantoms = SnapPhantomNodes(phantom_node_pairs);
|
auto snapped_phantoms = SnapPhantomNodes(phantom_node_pairs);
|
||||||
|
|
||||||
|
const bool allow_u_turn_at_via =
|
||||||
|
route_parameters.uturns ? *route_parameters.uturns : facade.GetUTurnsDefault();
|
||||||
|
|
||||||
InternalRouteResult raw_route;
|
InternalRouteResult raw_route;
|
||||||
auto build_phantom_pairs = [&raw_route](const PhantomNode &first_node,
|
auto build_phantom_pairs = [&raw_route, allow_u_turn_at_via](const PhantomNode &first_node,
|
||||||
const PhantomNode &second_node)
|
const PhantomNode &second_node)
|
||||||
{
|
{
|
||||||
raw_route.segment_end_coordinates.push_back(PhantomNodes{first_node, second_node});
|
raw_route.segment_end_coordinates.push_back(PhantomNodes{first_node, second_node});
|
||||||
|
auto &last_inserted = raw_route.segment_end_coordinates.back();
|
||||||
|
// enable forward direction if possible
|
||||||
|
if (last_inserted.source_phantom.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
|
{
|
||||||
|
last_inserted.source_phantom.forward_segment_id.enabled |= allow_u_turn_at_via;
|
||||||
|
}
|
||||||
|
// enable reverse direction if possible
|
||||||
|
if (last_inserted.source_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
|
{
|
||||||
|
last_inserted.source_phantom.reverse_segment_id.enabled |= allow_u_turn_at_via;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
util::for_each_pair(snapped_phantoms, build_phantom_pairs);
|
util::for_each_pair(snapped_phantoms, build_phantom_pairs);
|
||||||
|
|
||||||
|
@ -122,18 +122,30 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
|
|||||||
|
|
||||||
NodeID current_edge_source_coordinate_id = node_u;
|
NodeID current_edge_source_coordinate_id = node_u;
|
||||||
|
|
||||||
|
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
|
||||||
|
{
|
||||||
|
if (edge_based_node_id == SPECIAL_NODEID)
|
||||||
|
{
|
||||||
|
return SegmentID{SPECIAL_SEGMENTID, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
return SegmentID{edge_based_node_id, true};
|
||||||
|
};
|
||||||
|
|
||||||
// traverse arrays from start and end respectively
|
// traverse arrays from start and end respectively
|
||||||
for (const auto i : util::irange(std::size_t{ 0 }, geometry_size))
|
for (const auto i : util::irange(std::size_t{ 0 }, geometry_size))
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(current_edge_source_coordinate_id ==
|
BOOST_ASSERT(
|
||||||
m_compressed_edge_container.GetBucketReference(
|
current_edge_source_coordinate_id ==
|
||||||
edge_id_2)[geometry_size - 1 - i].node_id);
|
m_compressed_edge_container.GetBucketReference(edge_id_2)[geometry_size - 1 - i]
|
||||||
|
.node_id);
|
||||||
const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
|
const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
|
||||||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
||||||
|
|
||||||
// build edges
|
// build edges
|
||||||
m_edge_based_node_list.emplace_back(
|
m_edge_based_node_list.emplace_back(
|
||||||
forward_data.edge_id, reverse_data.edge_id, current_edge_source_coordinate_id,
|
edge_id_to_segment_id(forward_data.edge_id),
|
||||||
|
edge_id_to_segment_id(reverse_data.edge_id), current_edge_source_coordinate_id,
|
||||||
current_edge_target_coordinate_id, forward_data.name_id,
|
current_edge_target_coordinate_id, forward_data.name_id,
|
||||||
m_compressed_edge_container.GetPositionForID(edge_id_1),
|
m_compressed_edge_container.GetPositionForID(edge_id_1),
|
||||||
m_compressed_edge_container.GetPositionForID(edge_id_2), false, INVALID_COMPONENTID, i,
|
m_compressed_edge_container.GetPositionForID(edge_id_2), false, INVALID_COMPONENTID, i,
|
||||||
@ -208,7 +220,8 @@ unsigned EdgeBasedGraphFactory::RenumberEdges()
|
|||||||
// oneway streets always require this self-loop. Other streets only if a u-turn plus
|
// oneway streets always require this self-loop. Other streets only if a u-turn plus
|
||||||
// traversal
|
// traversal
|
||||||
// of the street takes longer than the loop
|
// of the street takes longer than the loop
|
||||||
m_edge_based_node_weights.push_back(edge_data.distance + profile_properties.u_turn_penalty);
|
m_edge_based_node_weights.push_back(edge_data.distance +
|
||||||
|
profile_properties.u_turn_penalty);
|
||||||
|
|
||||||
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
|
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
|
||||||
edge_data.edge_id = numbered_edges_count;
|
edge_data.edge_id = numbered_edges_count;
|
||||||
@ -344,7 +357,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
distance += profile_properties.traffic_signal_penalty;
|
distance += profile_properties.traffic_signal_penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int turn_penalty = use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0;
|
const int turn_penalty =
|
||||||
|
use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0;
|
||||||
const auto turn_instruction = turn.instruction;
|
const auto turn_instruction = turn.instruction;
|
||||||
|
|
||||||
if (guidance::isUturn(turn_instruction))
|
if (guidance::isUturn(turn_instruction))
|
||||||
|
@ -108,7 +108,7 @@ int Extractor::run()
|
|||||||
util::SimpleLogger().Write() << "Parsing in progress..";
|
util::SimpleLogger().Write() << "Parsing in progress..";
|
||||||
TIMER_START(parsing);
|
TIMER_START(parsing);
|
||||||
|
|
||||||
auto& main_context = scripting_environment.GetContex();
|
auto &main_context = scripting_environment.GetContex();
|
||||||
|
|
||||||
// setup raster sources
|
// setup raster sources
|
||||||
if (util::luaFunctionExists(main_context.state, "source_function"))
|
if (util::luaFunctionExists(main_context.state, "source_function"))
|
||||||
@ -163,7 +163,7 @@ int Extractor::run()
|
|||||||
{
|
{
|
||||||
ExtractionNode result_node;
|
ExtractionNode result_node;
|
||||||
ExtractionWay result_way;
|
ExtractionWay result_way;
|
||||||
auto& local_context = scripting_environment.GetContex();
|
auto &local_context = scripting_environment.GetContex();
|
||||||
|
|
||||||
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
||||||
{
|
{
|
||||||
@ -258,7 +258,7 @@ int Extractor::run()
|
|||||||
// movement (e.g. turn from A->B, and B->A) becomes an edge
|
// movement (e.g. turn from A->B, and B->A) becomes an edge
|
||||||
//
|
//
|
||||||
|
|
||||||
auto& main_context = scripting_environment.GetContex();
|
auto &main_context = scripting_environment.GetContex();
|
||||||
|
|
||||||
util::SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
util::SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
||||||
|
|
||||||
@ -269,8 +269,7 @@ int Extractor::run()
|
|||||||
std::vector<bool> node_is_startpoint;
|
std::vector<bool> node_is_startpoint;
|
||||||
std::vector<EdgeWeight> edge_based_node_weights;
|
std::vector<EdgeWeight> edge_based_node_weights;
|
||||||
std::vector<QueryNode> internal_to_external_node_map;
|
std::vector<QueryNode> internal_to_external_node_map;
|
||||||
auto graph_size = BuildEdgeExpandedGraph(main_context.state,
|
auto graph_size = BuildEdgeExpandedGraph(main_context.state, main_context.properties,
|
||||||
main_context.properties,
|
|
||||||
internal_to_external_node_map,
|
internal_to_external_node_map,
|
||||||
edge_based_node_list, node_is_startpoint,
|
edge_based_node_list, node_is_startpoint,
|
||||||
edge_based_node_weights, edge_based_edge_list);
|
edge_based_node_weights, edge_based_edge_list);
|
||||||
@ -317,7 +316,8 @@ int Extractor::run()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extractor::WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const
|
void Extractor::WriteProfileProperties(const std::string &output_path,
|
||||||
|
const ProfileProperties &properties) const
|
||||||
{
|
{
|
||||||
boost::filesystem::ofstream out_stream(output_path);
|
boost::filesystem::ofstream out_stream(output_path);
|
||||||
if (!out_stream)
|
if (!out_stream)
|
||||||
@ -325,7 +325,7 @@ void Extractor::WriteProfileProperties(const std::string& output_path, const Pro
|
|||||||
throw util::exception("Could not open " + output_path + " for writing.");
|
throw util::exception("Could not open " + output_path + " for writing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
out_stream.write(reinterpret_cast<const char*>(&properties), sizeof(properties));
|
out_stream.write(reinterpret_cast<const char *>(&properties), sizeof(properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extractor::FindComponents(unsigned max_edge_id,
|
void Extractor::FindComponents(unsigned max_edge_id,
|
||||||
@ -375,12 +375,12 @@ void Extractor::FindComponents(unsigned max_edge_id,
|
|||||||
// connect forward and backward nodes of each edge
|
// connect forward and backward nodes of each edge
|
||||||
for (const auto &node : input_nodes)
|
for (const auto &node : input_nodes)
|
||||||
{
|
{
|
||||||
if (node.reverse_edge_based_node_id != SPECIAL_NODEID)
|
if (node.reverse_segment_id.enabled)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(node.forward_edge_based_node_id <= max_edge_id);
|
BOOST_ASSERT(node.forward_segment_id.id <= max_edge_id);
|
||||||
BOOST_ASSERT(node.reverse_edge_based_node_id <= max_edge_id);
|
BOOST_ASSERT(node.reverse_segment_id.id <= max_edge_id);
|
||||||
edges.push_back({node.forward_edge_based_node_id, node.reverse_edge_based_node_id, {}});
|
edges.push_back({node.forward_segment_id.id, node.reverse_segment_id.id, {}});
|
||||||
edges.push_back({node.reverse_edge_based_node_id, node.forward_edge_based_node_id, {}});
|
edges.push_back({node.reverse_segment_id.id, node.forward_segment_id.id, {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,10 +396,10 @@ void Extractor::FindComponents(unsigned max_edge_id,
|
|||||||
|
|
||||||
for (auto &node : input_nodes)
|
for (auto &node : input_nodes)
|
||||||
{
|
{
|
||||||
auto forward_component = component_search.get_component_id(node.forward_edge_based_node_id);
|
auto forward_component = component_search.get_component_id(node.forward_segment_id.id);
|
||||||
BOOST_ASSERT(node.reverse_edge_based_node_id == SPECIAL_EDGEID ||
|
BOOST_ASSERT(!node.reverse_segment_id.enabled ||
|
||||||
forward_component ==
|
forward_component ==
|
||||||
component_search.get_component_id(node.reverse_edge_based_node_id));
|
component_search.get_component_id(node.reverse_segment_id.id));
|
||||||
|
|
||||||
const unsigned component_size = component_search.get_component_size(forward_component);
|
const unsigned component_size = component_search.get_component_size(forward_component);
|
||||||
node.component.is_tiny = component_size < config.small_component_size;
|
node.component.is_tiny = component_size < config.small_component_size;
|
||||||
@ -468,8 +468,8 @@ Extractor::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
|
|||||||
\brief Building an edge-expanded graph from node-based input and turn restrictions
|
\brief Building an edge-expanded graph from node-based input and turn restrictions
|
||||||
*/
|
*/
|
||||||
std::pair<std::size_t, std::size_t>
|
std::pair<std::size_t, std::size_t>
|
||||||
Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
|
Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||||
const ProfileProperties& profile_properties,
|
const ProfileProperties &profile_properties,
|
||||||
std::vector<QueryNode> &internal_to_external_node_map,
|
std::vector<QueryNode> &internal_to_external_node_map,
|
||||||
std::vector<EdgeBasedNode> &node_based_edge_list,
|
std::vector<EdgeBasedNode> &node_based_edge_list,
|
||||||
std::vector<bool> &node_is_startpoint,
|
std::vector<bool> &node_is_startpoint,
|
||||||
|
@ -160,8 +160,8 @@ struct GraphFixture
|
|||||||
// so we have something to test against. Because this isn't a real
|
// so we have something to test against. Because this isn't a real
|
||||||
// graph, the actual values aren't important, we just need something
|
// graph, the actual values aren't important, we just need something
|
||||||
// to examine during tests.
|
// to examine during tests.
|
||||||
d.forward_edge_based_node_id = pair.second;
|
d.forward_segment_id = {pair.second, true};
|
||||||
d.reverse_edge_based_node_id = pair.first;
|
d.reverse_segment_id = {pair.first, true};
|
||||||
edges.emplace_back(d);
|
edges.emplace_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,8 +416,8 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
|||||||
{
|
{
|
||||||
auto results = query.NearestPhantomNodes(input, 5);
|
auto results = query.NearestPhantomNodes(input, 5);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
BOOST_CHECK_EQUAL(results.back().phantom_node.forward_node_id, 0);
|
BOOST_CHECK_EQUAL(results.back().phantom_node.forward_segment_id.id, 0);
|
||||||
BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_node_id, 1);
|
BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_segment_id.id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -428,10 +428,10 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
|||||||
{
|
{
|
||||||
auto results = query.NearestPhantomNodes(input, 5, 45, 10);
|
auto results = query.NearestPhantomNodes(input, 5, 45, 10);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_node_id, 1);
|
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1);
|
||||||
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_node_id, SPECIAL_NODEID);
|
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID);
|
||||||
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_node_id, SPECIAL_NODEID);
|
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID);
|
||||||
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_node_id, 1);
|
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -447,10 +447,10 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
|||||||
{
|
{
|
||||||
auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10);
|
auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10);
|
||||||
BOOST_CHECK_EQUAL(results.size(), 2);
|
BOOST_CHECK_EQUAL(results.size(), 2);
|
||||||
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_node_id, 1);
|
BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1);
|
||||||
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_node_id, SPECIAL_NODEID);
|
BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID);
|
||||||
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_node_id, SPECIAL_NODEID);
|
BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID);
|
||||||
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_node_id, 1);
|
BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user