Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15a41edcb0 | |||
| 82ab43d4df | |||
| c130012ed5 | |||
| 5fa90cd2d5 | |||
| 0499803f24 | |||
| 9b779c704f | |||
| 5bd7d04fe3 | |||
| 0f78f7b2cc | |||
| 8473be69d2 | |||
| c0124f7d77 | |||
| b630b4e32a | |||
| 89fabc1b9c | |||
| a649a8a5cf | |||
| f928956584 | |||
| 7ff68792d7 | |||
| 3088dd0342 | |||
| d2590989f5 | |||
| 3a7b377586 | |||
| 82b5648c97 | |||
| 1628a3c4d5 | |||
| e5d8319c43 | |||
| 06699132eb | |||
| 918e794d6a | |||
| 8dd8ee1fc2 | |||
| c3d0efda93 |
@@ -1,4 +1,12 @@
|
|||||||
# UNRELEASED
|
# UNRELEASED
|
||||||
|
- Changes from 5.18.0:
|
||||||
|
- Optimizations:
|
||||||
|
- CHANGED: Map matching is now almost twice as fast. [#5060](https://github.com/Project-OSRM/osrm-backend/pull/5060)
|
||||||
|
- Bugfixes:
|
||||||
|
- FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114)
|
||||||
|
- FIXED: negative distances in table plugin annotation [#5106](https://github.com/Project-OSRM/osrm-backend/issues/5106)
|
||||||
|
|
||||||
|
# 5.18.0
|
||||||
- Changes from 5.17.0:
|
- Changes from 5.17.0:
|
||||||
- Features:
|
- Features:
|
||||||
- ADDED: `table` plugin now optionally returns `distance` matrix as part of response [#4990](https://github.com/Project-OSRM/osrm-backend/pull/4990)
|
- ADDED: `table` plugin now optionally returns `distance` matrix as part of response [#4990](https://github.com/Project-OSRM/osrm-backend/pull/4990)
|
||||||
|
|||||||
+2
-2
@@ -138,7 +138,7 @@ Given an OpenStreetMap way, the `process_way` function will either return nothin
|
|||||||
Argument | Description
|
Argument | Description
|
||||||
---------|-------------------------------------------------------
|
---------|-------------------------------------------------------
|
||||||
profile | The configuration table you returned in `setup`.
|
profile | The configuration table you returned in `setup`.
|
||||||
node | The input way to process (read-only).
|
way | The input way to process (read-only).
|
||||||
result | The output that you will modify.
|
result | The output that you will modify.
|
||||||
relations| Storage of relations to access relations, where `way` is a member.
|
relations| Storage of relations to access relations, where `way` is a member.
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ source.lon | Read | Float | Co-ordinates of segment start
|
|||||||
source.lat | Read | Float | ""
|
source.lat | Read | Float | ""
|
||||||
target.lon | Read | Float | Co-ordinates of segment end
|
target.lon | Read | Float | Co-ordinates of segment end
|
||||||
target.lat | Read | Float | ""
|
target.lat | Read | Float | ""
|
||||||
target.distance | Read | Float | Length of segment
|
distance | Read | Float | Length of segment
|
||||||
weight | Read/write | Float | Routing weight for this segment
|
weight | Read/write | Float | Routing weight for this segment
|
||||||
duration | Read/write | Float | Duration for this segment
|
duration | Read/write | Float | Duration for this segment
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Feature: Barriers
|
|||||||
| entrance | x |
|
| entrance | x |
|
||||||
| wall | |
|
| wall | |
|
||||||
| fence | |
|
| fence | |
|
||||||
| some_tag | |
|
| some_tag | x |
|
||||||
| block | x |
|
| block | x |
|
||||||
|
|
||||||
Scenario: Bike - Access tag trumphs barriers
|
Scenario: Bike - Access tag trumphs barriers
|
||||||
|
|||||||
@@ -48,3 +48,22 @@ Feature: Car - Handle physical limitation
|
|||||||
| primary | | none | x |
|
| primary | | none | x |
|
||||||
| primary | | no-sign | x |
|
| primary | | no-sign | x |
|
||||||
| primary | | unsigned | x |
|
| primary | | unsigned | x |
|
||||||
|
|
||||||
|
Scenario: Car - Limited by length
|
||||||
|
Then routability should be
|
||||||
|
| highway | maxlength | bothw |
|
||||||
|
| primary | | x |
|
||||||
|
| primary | 1 | |
|
||||||
|
| primary | 5 | x |
|
||||||
|
| primary | unsigned | x |
|
||||||
|
|
||||||
|
Scenario: Car - Limited by weight
|
||||||
|
Then routability should be
|
||||||
|
| highway | maxweight | bothw |
|
||||||
|
| primary | | x |
|
||||||
|
| primary | 1 | |
|
||||||
|
| primary | 3.5 | x |
|
||||||
|
| primary | 35000 kg | x |
|
||||||
|
| primary | 8.9t | x |
|
||||||
|
| primary | 0.1 lbs | |
|
||||||
|
| primary | unsigned | x |
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Feature: Barriers
|
|||||||
| entrance | x |
|
| entrance | x |
|
||||||
| wall | |
|
| wall | |
|
||||||
| fence | |
|
| fence | |
|
||||||
| some_tag | |
|
| some_tag | x |
|
||||||
| block | x |
|
| block | x |
|
||||||
|
|
||||||
Scenario: Foot - Access tag trumphs barriers
|
Scenario: Foot - Access tag trumphs barriers
|
||||||
|
|||||||
@@ -792,4 +792,4 @@ Feature: Basic Map Matching
|
|||||||
When I match I should get
|
When I match I should get
|
||||||
| trace | geometry | a:distance | a:duration | a:weight | duration |
|
| trace | geometry | a:distance | a:duration | a:weight | duration |
|
||||||
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
|
|||||||
@@ -449,6 +449,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
|
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
|
||||||
|
|
||||||
const auto forward_geometry = datafacade.GetUncompressedForwardGeometry(geometry_id);
|
const auto forward_geometry = datafacade.GetUncompressedForwardGeometry(geometry_id);
|
||||||
|
const auto reverse_geometry = datafacade.GetUncompressedReverseGeometry(geometry_id);
|
||||||
|
|
||||||
const auto forward_weight_offset =
|
const auto forward_weight_offset =
|
||||||
std::accumulate(forward_weights.begin(),
|
std::accumulate(forward_weights.begin(),
|
||||||
@@ -479,19 +480,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
||||||
point_on_segment);
|
point_on_segment);
|
||||||
|
|
||||||
const auto reverse_weight_offset =
|
const auto rev_segment_position = reverse_weights.size() - data.fwd_segment_position - 1;
|
||||||
std::accumulate(reverse_weights.begin(),
|
|
||||||
reverse_weights.end() - data.fwd_segment_position - 1,
|
const auto reverse_weight_offset = std::accumulate(
|
||||||
EdgeWeight{0});
|
reverse_weights.begin(), reverse_weights.begin() + rev_segment_position, EdgeWeight{0});
|
||||||
|
|
||||||
const auto reverse_duration_offset =
|
const auto reverse_duration_offset =
|
||||||
std::accumulate(reverse_durations.begin(),
|
std::accumulate(reverse_durations.begin(),
|
||||||
reverse_durations.end() - data.fwd_segment_position - 1,
|
reverse_durations.begin() + rev_segment_position,
|
||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance reverse_distance_offset = 0;
|
EdgeDistance reverse_distance_offset = 0;
|
||||||
for (auto current = forward_geometry.begin();
|
for (auto current = reverse_geometry.begin();
|
||||||
current < forward_geometry.end() - data.fwd_segment_position - 2;
|
current < reverse_geometry.begin() + rev_segment_position;
|
||||||
++current)
|
++current)
|
||||||
{
|
{
|
||||||
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
||||||
@@ -499,13 +500,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
datafacade.GetCoordinateOfNode(*std::next(current)));
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight reverse_weight =
|
EdgeWeight reverse_weight = reverse_weights[rev_segment_position];
|
||||||
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
|
EdgeDuration reverse_duration = reverse_durations[rev_segment_position];
|
||||||
EdgeDuration reverse_duration =
|
|
||||||
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
|
|
||||||
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance(
|
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance(
|
||||||
point_on_segment,
|
point_on_segment,
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
datafacade.GetCoordinateOfNode(reverse_geometry(rev_segment_position)));
|
||||||
|
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
@@ -693,7 +692,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const CoordinateList &coordinates;
|
const CoordinateList &coordinates;
|
||||||
DataFacadeT &datafacade;
|
DataFacadeT &datafacade;
|
||||||
};
|
};
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,50 +44,19 @@ bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &ta
|
|||||||
bool needsLoopForward(const PhantomNodes &phantoms);
|
bool needsLoopForward(const PhantomNodes &phantoms);
|
||||||
bool needsLoopBackwards(const PhantomNodes &phantoms);
|
bool needsLoopBackwards(const PhantomNodes &phantoms);
|
||||||
|
|
||||||
template <typename Heap>
|
namespace detail
|
||||||
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
|
|
||||||
{
|
{
|
||||||
const auto &source = nodes.source_phantom;
|
template <typename Algorithm>
|
||||||
if (source.IsValidForwardSource())
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
{
|
const PhantomNode &phantom_node)
|
||||||
forward_heap.Insert(source.forward_segment_id.id,
|
|
||||||
-source.GetForwardWeightPlusOffset(),
|
|
||||||
source.forward_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source.IsValidReverseSource())
|
|
||||||
{
|
|
||||||
forward_heap.Insert(source.reverse_segment_id.id,
|
|
||||||
-source.GetReverseWeightPlusOffset(),
|
|
||||||
source.reverse_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &target = nodes.target_phantom;
|
|
||||||
if (target.IsValidForwardTarget())
|
|
||||||
{
|
|
||||||
reverse_heap.Insert(target.forward_segment_id.id,
|
|
||||||
target.GetForwardWeightPlusOffset(),
|
|
||||||
target.forward_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.IsValidReverseTarget())
|
|
||||||
{
|
|
||||||
reverse_heap.Insert(target.reverse_segment_id.id,
|
|
||||||
target.GetReverseWeightPlusOffset(),
|
|
||||||
target.reverse_segment_id.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ManyToManyQueryHeap>
|
|
||||||
void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
|
||||||
{
|
{
|
||||||
if (phantom_node.IsValidForwardSource())
|
if (phantom_node.IsValidForwardTarget())
|
||||||
{
|
{
|
||||||
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()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseSource())
|
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(),
|
||||||
@@ -95,8 +64,9 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ManyToManyQueryHeap>
|
template <typename Algorithm>
|
||||||
void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
void insertTargetInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
{
|
{
|
||||||
if (phantom_node.IsValidForwardTarget())
|
if (phantom_node.IsValidForwardTarget())
|
||||||
{
|
{
|
||||||
@@ -112,6 +82,109 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
phantom_node.forward_segment_id.id);
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
phantom_node.reverse_segment_id.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertTargetInHeap(typename SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardTarget())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
phantom_node.forward_segment_id.id);
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseTarget())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
phantom_node.reverse_segment_id.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<mld::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<ch::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<mld::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<ch::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Heap>
|
||||||
|
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
|
||||||
|
{
|
||||||
|
insertSourceInHeap(forward_heap, nodes.source_phantom);
|
||||||
|
insertTargetInHeap(reverse_heap, nodes.target_phantom);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()});
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename FacadeT>
|
template <typename FacadeT>
|
||||||
void annotatePath(const FacadeT &facade,
|
void annotatePath(const FacadeT &facade,
|
||||||
const PhantomNodes &phantom_node_pair,
|
const PhantomNodes &phantom_node_pair,
|
||||||
@@ -321,58 +394,10 @@ void annotatePath(const FacadeT &facade,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Algorithm>
|
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||||
double getPathDistance(const DataFacade<Algorithm> &facade,
|
const PhantomNode &source_phantom,
|
||||||
const std::vector<PathData> unpacked_path,
|
const PhantomNode &target_phantom,
|
||||||
const PhantomNode &source_phantom,
|
const EdgeDistance distance);
|
||||||
const PhantomNode &target_phantom)
|
|
||||||
{
|
|
||||||
using util::coordinate_calculation::detail::DEGREE_TO_RAD;
|
|
||||||
using util::coordinate_calculation::detail::EARTH_RADIUS;
|
|
||||||
|
|
||||||
double distance = 0;
|
|
||||||
double prev_lat =
|
|
||||||
static_cast<double>(util::toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD;
|
|
||||||
double prev_lon =
|
|
||||||
static_cast<double>(util::toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
|
|
||||||
double prev_cos = std::cos(prev_lat);
|
|
||||||
for (const auto &p : unpacked_path)
|
|
||||||
{
|
|
||||||
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
|
|
||||||
|
|
||||||
const double current_lat =
|
|
||||||
static_cast<double>(util::toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
|
|
||||||
const double current_lon =
|
|
||||||
static_cast<double>(util::toFloating(current_coordinate.lon)) * DEGREE_TO_RAD;
|
|
||||||
const double current_cos = std::cos(current_lat);
|
|
||||||
|
|
||||||
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
|
|
||||||
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
|
|
||||||
|
|
||||||
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
|
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
|
||||||
distance += EARTH_RADIUS * charv;
|
|
||||||
|
|
||||||
prev_lat = current_lat;
|
|
||||||
prev_lon = current_lon;
|
|
||||||
prev_cos = current_cos;
|
|
||||||
}
|
|
||||||
|
|
||||||
const double current_lat =
|
|
||||||
static_cast<double>(util::toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD;
|
|
||||||
const double current_lon =
|
|
||||||
static_cast<double>(util::toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD;
|
|
||||||
const double current_cos = std::cos(current_lat);
|
|
||||||
|
|
||||||
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
|
|
||||||
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
|
|
||||||
|
|
||||||
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
|
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
|
||||||
distance += EARTH_RADIUS * charv;
|
|
||||||
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename AlgorithmT>
|
template <typename AlgorithmT>
|
||||||
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
|
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
const std::vector<std::size_t> &phantom_indices)
|
const std::vector<std::size_t> &phantom_indices)
|
||||||
{
|
{
|
||||||
auto min_level = [&partition, node](const PhantomNode &phantom_node) {
|
auto min_level = [&partition, node](const PhantomNode &phantom_node) {
|
||||||
|
|
||||||
const auto &forward_segment = phantom_node.forward_segment_id;
|
const auto &forward_segment = phantom_node.forward_segment_id;
|
||||||
const auto forward_level =
|
const auto forward_level =
|
||||||
forward_segment.enabled ? partition.GetHighestDifferentLevel(node, forward_segment.id)
|
forward_segment.enabled ? partition.GetHighestDifferentLevel(node, forward_segment.id)
|
||||||
@@ -120,7 +119,7 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
// Heaps only record for each node its predecessor ("parent") on the shortest path.
|
// Heaps only record for each node its predecessor ("parent") on the shortest path.
|
||||||
// For re-constructing the actual path we need to trace back all parent "pointers".
|
// For re-constructing the actual path we need to trace back all parent "pointers".
|
||||||
@@ -391,21 +390,27 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
EdgeWeight weight_upper_bound,
|
EdgeWeight weight_upper_bound,
|
||||||
Args... args)
|
Args... args)
|
||||||
{
|
{
|
||||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
if (forward_heap.Empty() && reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
const auto &partition = facade.GetMultiLevelPartition();
|
||||||
|
|
||||||
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(forward_heap.Empty() || forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
// run two-Target Dijkstra routing step.
|
// run two-Target Dijkstra routing step.
|
||||||
NodeID middle = SPECIAL_NODEID;
|
NodeID middle = SPECIAL_NODEID;
|
||||||
EdgeWeight weight = weight_upper_bound;
|
EdgeWeight weight = weight_upper_bound;
|
||||||
EdgeWeight forward_heap_min = forward_heap.MinKey();
|
|
||||||
EdgeWeight reverse_heap_min = reverse_heap.MinKey();
|
EdgeWeight forward_heap_min = 0;
|
||||||
|
if (!forward_heap.Empty())
|
||||||
|
forward_heap_min = forward_heap.MinKey();
|
||||||
|
EdgeWeight reverse_heap_min = 0;
|
||||||
|
if (!reverse_heap.Empty())
|
||||||
|
reverse_heap_min = reverse_heap.MinKey();
|
||||||
|
|
||||||
while (forward_heap.Size() + reverse_heap.Size() > 0 &&
|
while (forward_heap.Size() + reverse_heap.Size() > 0 &&
|
||||||
forward_heap_min + reverse_heap_min < weight)
|
forward_heap_min + reverse_heap_min < weight)
|
||||||
{
|
{
|
||||||
@@ -657,11 +662,7 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
forward_heap.Clear();
|
|
||||||
reverse_heap.Clear();
|
|
||||||
|
|
||||||
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
|
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
|
||||||
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
|
|
||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||||
std::vector<NodeID> unpacked_nodes;
|
std::vector<NodeID> unpacked_nodes;
|
||||||
@@ -680,11 +681,22 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PathData> unpacked_path;
|
EdgeDistance distance = 0;
|
||||||
|
|
||||||
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path);
|
if (!unpacked_nodes.empty())
|
||||||
|
{
|
||||||
|
distance = std::accumulate(unpacked_nodes.begin(),
|
||||||
|
std::prev(unpacked_nodes.end()),
|
||||||
|
EdgeDistance{0},
|
||||||
|
[&](const EdgeDistance distance, const auto node_id) {
|
||||||
|
return distance + computeEdgeDistance(facade, node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
|
distance = adjustPathDistanceToPhantomNodes(
|
||||||
|
unpacked_nodes, phantom_nodes.source_phantom, phantom_nodes.target_phantom, distance);
|
||||||
|
|
||||||
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mld
|
} // namespace mld
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace serialization
|
|||||||
inline void read(io::BufferReader &reader, DataLayout &layout);
|
inline void read(io::BufferReader &reader, DataLayout &layout);
|
||||||
|
|
||||||
inline void write(io::BufferWriter &writer, const DataLayout &layout);
|
inline void write(io::BufferWriter &writer, const DataLayout &layout);
|
||||||
}
|
} // namespace serialization
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@@ -52,7 +52,7 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace detail
|
||||||
|
|
||||||
class DataLayout
|
class DataLayout
|
||||||
{
|
{
|
||||||
@@ -165,7 +165,7 @@ struct SharedRegion
|
|||||||
static constexpr const int MAX_NAME_LENGTH = 254;
|
static constexpr const int MAX_NAME_LENGTH = 254;
|
||||||
|
|
||||||
SharedRegion() : name{0}, timestamp{0} {}
|
SharedRegion() : name{0}, timestamp{0} {}
|
||||||
SharedRegion(const std::string &name_, std::uint64_t timestamp, std::uint8_t shm_key)
|
SharedRegion(const std::string &name_, std::uint64_t timestamp, std::uint16_t shm_key)
|
||||||
: name{0}, timestamp{timestamp}, shm_key{shm_key}
|
: name{0}, timestamp{timestamp}, shm_key{shm_key}
|
||||||
{
|
{
|
||||||
std::copy_n(name_.begin(), std::min<std::size_t>(MAX_NAME_LENGTH, name_.size()), name);
|
std::copy_n(name_.begin(), std::min<std::size_t>(MAX_NAME_LENGTH, name_.size()), name);
|
||||||
@@ -175,14 +175,14 @@ struct SharedRegion
|
|||||||
|
|
||||||
char name[MAX_NAME_LENGTH + 1];
|
char name[MAX_NAME_LENGTH + 1];
|
||||||
std::uint64_t timestamp;
|
std::uint64_t timestamp;
|
||||||
std::uint8_t shm_key;
|
std::uint16_t shm_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keeps a list of all shared regions in a fixed-sized struct
|
// Keeps a list of all shared regions in a fixed-sized struct
|
||||||
// for fast access and deserialization.
|
// for fast access and deserialization.
|
||||||
struct SharedRegionRegister
|
struct SharedRegionRegister
|
||||||
{
|
{
|
||||||
using RegionID = std::uint8_t;
|
using RegionID = std::uint16_t;
|
||||||
static constexpr const RegionID INVALID_REGION_ID = std::numeric_limits<RegionID>::max();
|
static constexpr const RegionID INVALID_REGION_ID = std::numeric_limits<RegionID>::max();
|
||||||
using ShmKey = decltype(SharedRegion::shm_key);
|
using ShmKey = decltype(SharedRegion::shm_key);
|
||||||
|
|
||||||
@@ -250,12 +250,11 @@ struct SharedRegionRegister
|
|||||||
|
|
||||||
void ReleaseKey(ShmKey key) { shm_key_in_use[key] = false; }
|
void ReleaseKey(ShmKey key) { shm_key_in_use[key] = false; }
|
||||||
|
|
||||||
static constexpr const std::uint8_t MAX_SHARED_REGIONS =
|
static constexpr const std::size_t MAX_SHARED_REGIONS = 512;
|
||||||
std::numeric_limits<RegionID>::max() - 1;
|
|
||||||
static_assert(MAX_SHARED_REGIONS < std::numeric_limits<RegionID>::max(),
|
static_assert(MAX_SHARED_REGIONS < std::numeric_limits<RegionID>::max(),
|
||||||
"Number of shared memory regions needs to be less than the region id size.");
|
"Number of shared memory regions needs to be less than the region id size.");
|
||||||
|
|
||||||
static constexpr const std::uint8_t MAX_SHM_KEYS = std::numeric_limits<std::uint8_t>::max() - 1;
|
static constexpr const std::size_t MAX_SHM_KEYS = MAX_SHARED_REGIONS * 2;
|
||||||
|
|
||||||
static constexpr const char *name = "osrm-region";
|
static constexpr const char *name = "osrm-region";
|
||||||
|
|
||||||
@@ -263,7 +262,7 @@ struct SharedRegionRegister
|
|||||||
std::array<SharedRegion, MAX_SHARED_REGIONS> regions;
|
std::array<SharedRegion, MAX_SHARED_REGIONS> regions;
|
||||||
std::array<bool, MAX_SHM_KEYS> shm_key_in_use;
|
std::array<bool, MAX_SHM_KEYS> shm_key_in_use;
|
||||||
};
|
};
|
||||||
}
|
} // namespace storage
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif /* SHARED_DATA_TYPE_HPP */
|
#endif /* SHARED_DATA_TYPE_HPP */
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ namespace storage
|
|||||||
|
|
||||||
struct OSRMLockFile
|
struct OSRMLockFile
|
||||||
{
|
{
|
||||||
boost::filesystem::path operator()()
|
template <typename IdentifierT> boost::filesystem::path operator()(const IdentifierT &id)
|
||||||
{
|
{
|
||||||
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
|
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
|
||||||
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
boost::filesystem::path lock_file = temp_dir / ("osrm-" + std::to_string(id) + ".lock");
|
||||||
return lock_file;
|
return lock_file;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -93,7 +93,7 @@ class SharedMemory
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
OSRMLockFile lock_file;
|
OSRMLockFile lock_file;
|
||||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
boost::interprocess::xsi_key key(lock_file(id).string().c_str(), id);
|
||||||
result = RegionExists(key);
|
result = RegionExists(key);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@@ -106,7 +106,7 @@ class SharedMemory
|
|||||||
template <typename IdentifierT> static bool Remove(const IdentifierT id)
|
template <typename IdentifierT> static bool Remove(const IdentifierT id)
|
||||||
{
|
{
|
||||||
OSRMLockFile lock_file;
|
OSRMLockFile lock_file;
|
||||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
boost::interprocess::xsi_key key(lock_file(id).string().c_str(), id);
|
||||||
return Remove(key);
|
return Remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,10 +287,11 @@ class SharedMemory
|
|||||||
template <typename IdentifierT, typename LockFileT = OSRMLockFile>
|
template <typename IdentifierT, typename LockFileT = OSRMLockFile>
|
||||||
std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint64_t size = 0)
|
std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint64_t size = 0)
|
||||||
{
|
{
|
||||||
|
static_assert(sizeof(id) == sizeof(std::uint16_t), "Key type is not 16 bits");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LockFileT lock_file;
|
LockFileT lock_file;
|
||||||
if (!boost::filesystem::exists(lock_file()))
|
if (!boost::filesystem::exists(lock_file(id)))
|
||||||
{
|
{
|
||||||
if (0 == size)
|
if (0 == size)
|
||||||
{
|
{
|
||||||
@@ -298,10 +299,10 @@ std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::filesystem::ofstream ofs(lock_file());
|
boost::filesystem::ofstream ofs(lock_file(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_unique<SharedMemory>(lock_file(), id, size);
|
return std::make_unique<SharedMemory>(lock_file(id), id, size);
|
||||||
}
|
}
|
||||||
catch (const boost::interprocess::interprocess_exception &e)
|
catch (const boost::interprocess::interprocess_exception &e)
|
||||||
{
|
{
|
||||||
@@ -310,7 +311,7 @@ std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint
|
|||||||
throw util::exception(e.what() + SOURCE_REF);
|
throw util::exception(e.what() + SOURCE_REF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace storage
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif // SHARED_MEMORY_HPP
|
#endif // SHARED_MEMORY_HPP
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ template <class Lock> class InvertedLock
|
|||||||
InvertedLock(Lock &lock) : lock(lock) { lock.unlock(); }
|
InvertedLock(Lock &lock) : lock(lock) { lock.unlock(); }
|
||||||
~InvertedLock() { lock.lock(); }
|
~InvertedLock() { lock.lock(); }
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
// The shared monitor implementation based on a semaphore and mutex
|
// The shared monitor implementation based on a semaphore and mutex
|
||||||
template <typename Data> struct SharedMonitor
|
template <typename Data> struct SharedMonitor
|
||||||
@@ -146,7 +146,7 @@ template <typename Data> struct SharedMonitor
|
|||||||
// like two-turnstile reusable barrier or boost/interprocess/sync/spin/condition.hpp
|
// like two-turnstile reusable barrier or boost/interprocess/sync/spin/condition.hpp
|
||||||
// fail if a waiter is killed.
|
// fail if a waiter is killed.
|
||||||
|
|
||||||
static constexpr int buffer_size = 256;
|
static constexpr int buffer_size = 4096 * 4;
|
||||||
|
|
||||||
struct InternalData
|
struct InternalData
|
||||||
{
|
{
|
||||||
@@ -232,8 +232,8 @@ template <typename Data> struct SharedMonitor
|
|||||||
bi::shared_memory_object shmem;
|
bi::shared_memory_object shmem;
|
||||||
bi::mapped_region region;
|
bi::mapped_region region;
|
||||||
};
|
};
|
||||||
}
|
} // namespace storage
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#undef USE_BOOST_INTERPROCESS_CONDITION
|
#undef USE_BOOST_INTERPROCESS_CONDITION
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace detail
|
|||||||
{
|
{
|
||||||
const constexpr double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
|
const constexpr double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
|
||||||
const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
||||||
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
|
||||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
|
||||||
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
|
||||||
|
|
||||||
inline double degToRad(const double degree)
|
inline double degToRad(const double degree)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.18.0-latest.1",
|
"version": "5.18.0-moarshm.3",
|
||||||
"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": {
|
||||||
|
|||||||
+5
-15
@@ -38,20 +38,10 @@ function setup()
|
|||||||
mode.pushing_bike
|
mode.pushing_bike
|
||||||
},
|
},
|
||||||
|
|
||||||
barrier_whitelist = Set {
|
barrier_blacklist = Set {
|
||||||
'sump_buster',
|
'yes',
|
||||||
'bus_trap',
|
'wall',
|
||||||
'cycle_barrier',
|
'fence'
|
||||||
'bollard',
|
|
||||||
'entrance',
|
|
||||||
'cattle_grid',
|
|
||||||
'border_control',
|
|
||||||
'toll_booth',
|
|
||||||
'sally_port',
|
|
||||||
'gate',
|
|
||||||
'lift_gate',
|
|
||||||
'no',
|
|
||||||
'block'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
access_tag_whitelist = Set {
|
access_tag_whitelist = Set {
|
||||||
@@ -245,7 +235,7 @@ function process_node(profile, node, result)
|
|||||||
else
|
else
|
||||||
local barrier = node:get_value_by_key("barrier")
|
local barrier = node:get_value_by_key("barrier")
|
||||||
if barrier and "" ~= barrier then
|
if barrier and "" ~= barrier then
|
||||||
if not profile.barrier_whitelist[barrier] then
|
if profile.barrier_blacklist[barrier] then
|
||||||
result.barrier = true
|
result.barrier = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ function setup()
|
|||||||
vehicle_height = 2.5, -- in meters, 2.5m is the height of van
|
vehicle_height = 2.5, -- in meters, 2.5m is the height of van
|
||||||
vehicle_width = 1.9, -- in meters, ways with narrow tag are considered narrower than 2.2m
|
vehicle_width = 1.9, -- in meters, ways with narrow tag are considered narrower than 2.2m
|
||||||
|
|
||||||
|
-- Size of the vehicle, to be limited mostly by legal restriction of the way
|
||||||
|
vehicle_length = 4.8, -- in meters, 4.8m is the length of large or familly car
|
||||||
|
vehicle_weight = 3500, -- in kilograms
|
||||||
|
|
||||||
-- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other
|
-- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other
|
||||||
suffix_list = {
|
suffix_list = {
|
||||||
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East', 'Nor', 'Sou', 'We', 'Ea'
|
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East', 'Nor', 'Sou', 'We', 'Ea'
|
||||||
@@ -276,6 +280,7 @@ function setup()
|
|||||||
["de:rural"] = 100,
|
["de:rural"] = 100,
|
||||||
["de:motorway"] = 0,
|
["de:motorway"] = 0,
|
||||||
["dk:rural"] = 80,
|
["dk:rural"] = 80,
|
||||||
|
["fr:rural"] = 80,
|
||||||
["gb:nsl_single"] = (60*1609)/1000,
|
["gb:nsl_single"] = (60*1609)/1000,
|
||||||
["gb:nsl_dual"] = (70*1609)/1000,
|
["gb:nsl_dual"] = (70*1609)/1000,
|
||||||
["gb:motorway"] = (70*1609)/1000,
|
["gb:motorway"] = (70*1609)/1000,
|
||||||
@@ -387,6 +392,8 @@ function process_way(profile, way, result, relations)
|
|||||||
WayHandlers.avoid_ways,
|
WayHandlers.avoid_ways,
|
||||||
WayHandlers.handle_height,
|
WayHandlers.handle_height,
|
||||||
WayHandlers.handle_width,
|
WayHandlers.handle_width,
|
||||||
|
WayHandlers.handle_length,
|
||||||
|
WayHandlers.handle_weight,
|
||||||
|
|
||||||
-- determine access status by checking our hierarchy of
|
-- determine access status by checking our hierarchy of
|
||||||
-- access tags, e.g: motorcar, motor_vehicle, vehicle
|
-- access tags, e.g: motorcar, motor_vehicle, vehicle
|
||||||
|
|||||||
+5
-14
@@ -24,19 +24,10 @@ function setup()
|
|||||||
default_speed = walking_speed,
|
default_speed = walking_speed,
|
||||||
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
|
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
|
||||||
|
|
||||||
barrier_whitelist = Set {
|
barrier_blacklist = Set {
|
||||||
'cycle_barrier',
|
'yes',
|
||||||
'bollard',
|
'wall',
|
||||||
'entrance',
|
'fence'
|
||||||
'cattle_grid',
|
|
||||||
'border_control',
|
|
||||||
'toll_booth',
|
|
||||||
'sally_port',
|
|
||||||
'gate',
|
|
||||||
'lift_gate',
|
|
||||||
'no',
|
|
||||||
'kerb',
|
|
||||||
'block'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
access_tag_whitelist = Set {
|
access_tag_whitelist = Set {
|
||||||
@@ -157,7 +148,7 @@ function process_node(profile, node, result)
|
|||||||
local bollard = node:get_value_by_key("bollard")
|
local bollard = node:get_value_by_key("bollard")
|
||||||
local rising_bollard = bollard and "rising" == bollard
|
local rising_bollard = bollard and "rising" == bollard
|
||||||
|
|
||||||
if not profile.barrier_whitelist[barrier] and not rising_bollard then
|
if profile.barrier_blacklist[barrier] and not rising_bollard then
|
||||||
result.barrier = true
|
result.barrier = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+20
-26
@@ -5,6 +5,7 @@ Measure = {}
|
|||||||
-- measurements conversion constants
|
-- measurements conversion constants
|
||||||
local inch_to_meters = 0.0254
|
local inch_to_meters = 0.0254
|
||||||
local feet_to_inches = 12
|
local feet_to_inches = 12
|
||||||
|
local pound_to_kilograms = 0.45359237
|
||||||
|
|
||||||
--- Parse string as a height in meters.
|
--- Parse string as a height in meters.
|
||||||
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
|
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
|
||||||
@@ -25,33 +26,19 @@ function Measure.parse_value_meters(value)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- according to http://wiki.openstreetmap.org/wiki/Map_Features/Units#Explicit_specifications
|
--- Parse weight value in kilograms.
|
||||||
local tonns_parse_patterns = Sequence {
|
--- according to https://wiki.openstreetmap.org/wiki/Key:maxweight
|
||||||
"%d+",
|
|
||||||
"%d+.%d+",
|
|
||||||
"%d+.%d+ ?t"
|
|
||||||
}
|
|
||||||
|
|
||||||
local kg_parse_patterns = Sequence {
|
|
||||||
"%d+ ?kg"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Parse weight value in kilograms
|
|
||||||
function Measure.parse_value_kilograms(value)
|
function Measure.parse_value_kilograms(value)
|
||||||
-- try to parse kilograms
|
local n = tonumber(value:gsub(",", "."):match("%d+%.?%d*"))
|
||||||
for i, templ in ipairs(kg_parse_patterns) do
|
if n then
|
||||||
m = string.match(value, templ)
|
if string.match(value, "lbs") then
|
||||||
if m then
|
n = n * pound_to_kilograms
|
||||||
return tonumber(m)
|
elseif string.match(value, "kg") then
|
||||||
end
|
-- n = n
|
||||||
end
|
else -- Default, metric tons
|
||||||
|
n = n * 1000
|
||||||
-- try to parse tonns
|
|
||||||
for i, templ in ipairs(tonns_parse_patterns) do
|
|
||||||
m = string.match(value, templ)
|
|
||||||
if m then
|
|
||||||
return tonumber(m) * 1000
|
|
||||||
end
|
end
|
||||||
|
return n
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -83,7 +70,14 @@ function Measure.get_max_width(raw_value)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get maxweight of specified way in kilogramms
|
--- Get maxlength of specified way in meters.
|
||||||
|
function Measure.get_max_length(raw_value)
|
||||||
|
if raw_value then
|
||||||
|
return Measure.parse_value_meters(raw_value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get maxweight of specified way in kilogramms.
|
||||||
function Measure.get_max_weight(raw_value)
|
function Measure.get_max_weight(raw_value)
|
||||||
if raw_value then
|
if raw_value then
|
||||||
return Measure.parse_value_kilograms(raw_value)
|
return Measure.parse_value_kilograms(raw_value)
|
||||||
|
|||||||
@@ -511,6 +511,38 @@ function WayHandlers.handle_width(profile,way,result,data)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- handle maxweight tags
|
||||||
|
function WayHandlers.handle_weight(profile,way,result,data)
|
||||||
|
local keys = Sequence { 'maxweight' }
|
||||||
|
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
|
||||||
|
forward = Measure.get_max_weight(forward)
|
||||||
|
backward = Measure.get_max_weight(backward)
|
||||||
|
|
||||||
|
if forward and forward < profile.vehicle_weight then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if backward and backward < profile.vehicle_weight then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- handle maxlength tags
|
||||||
|
function WayHandlers.handle_length(profile,way,result,data)
|
||||||
|
local keys = Sequence { 'maxlength' }
|
||||||
|
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
|
||||||
|
forward = Measure.get_max_length(forward)
|
||||||
|
backward = Measure.get_max_length(backward)
|
||||||
|
|
||||||
|
if forward and forward < profile.vehicle_length then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if backward and backward < profile.vehicle_length then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- handle oneways tags
|
-- handle oneways tags
|
||||||
function WayHandlers.oneway(profile,way,result,data)
|
function WayHandlers.oneway(profile,way,result,data)
|
||||||
if not profile.oneway_handling then
|
if not profile.oneway_handling then
|
||||||
|
|||||||
@@ -621,6 +621,7 @@ RouteSteps collapseSegregatedTurnInstructions(RouteSteps steps)
|
|||||||
// else if the current step is segregated and the next step is not segregated
|
// else if the current step is segregated and the next step is not segregated
|
||||||
// and the next step is not a roundabout then combine with turn adjustment
|
// and the next step is not a roundabout then combine with turn adjustment
|
||||||
else if (curr_step->is_segregated && !next_step->is_segregated &&
|
else if (curr_step->is_segregated && !next_step->is_segregated &&
|
||||||
|
!hasRoundaboutType(curr_step->maneuver.instruction) &&
|
||||||
!hasRoundaboutType(next_step->maneuver.instruction))
|
!hasRoundaboutType(next_step->maneuver.instruction))
|
||||||
{
|
{
|
||||||
// Determine if u-turn
|
// Determine if u-turn
|
||||||
|
|||||||
@@ -240,74 +240,12 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
|
|||||||
}
|
}
|
||||||
if (!packed_leg.empty())
|
if (!packed_leg.empty())
|
||||||
{
|
{
|
||||||
auto annotation =
|
EdgeDistance annotation =
|
||||||
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
|
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
|
||||||
|
annotation = adjustPathDistanceToPhantomNodes(
|
||||||
|
packed_leg, source_phantom, target_phantom, annotation);
|
||||||
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = annotation;
|
distances_table[row_index * number_of_targets + column_index] = annotation;
|
||||||
|
|
||||||
// check the direction of travel to figure out how to calculate the offset to/from
|
|
||||||
// the source/target
|
|
||||||
if (source_phantom.forward_segment_id.id == packed_leg.front())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// -->s <-- subtract offset to start at source
|
|
||||||
// ......... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = source_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] -= offset;
|
|
||||||
}
|
|
||||||
else if (source_phantom.reverse_segment_id.id == packed_leg.front())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// s<------- <-- subtract offset to start at source
|
|
||||||
// ... <-- want this distance
|
|
||||||
// entry 0---1---2---3 <-- 3 is exit node
|
|
||||||
EdgeDistance offset = source_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] -= offset;
|
|
||||||
}
|
|
||||||
if (target_phantom.forward_segment_id.id == packed_leg.back())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// ++>t <-- add offset to get to target
|
|
||||||
// ................ <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = target_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] += offset;
|
|
||||||
}
|
|
||||||
else if (target_phantom.reverse_segment_id.id == packed_leg.back())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// <++t <-- add offset to get from target
|
|
||||||
// ................ <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = target_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] += offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// there is no shortcut to unpack. source and target are on the same EBG Node.
|
|
||||||
// if the offset of the target is greater than the offset of the source, subtract it
|
|
||||||
if (target_phantom.GetForwardDistance() > source_phantom.GetForwardDistance())
|
|
||||||
{
|
|
||||||
// --------->t <-- offsets
|
|
||||||
// ->s <-- subtract source offset from target offset
|
|
||||||
// ......... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset =
|
|
||||||
target_phantom.GetForwardDistance() - source_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// s<--- <-- offsets
|
|
||||||
// t<--------- <-- subtract source offset from target offset
|
|
||||||
// ...... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset =
|
|
||||||
target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = offset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
packed_leg.clear();
|
packed_leg.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
forward_heap.Clear();
|
||||||
|
const auto &source_phantom = prev_unbroken_timestamps_list[s].phantom_node;
|
||||||
|
insertSourceInHeap(forward_heap, source_phantom);
|
||||||
|
|
||||||
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
||||||
{
|
{
|
||||||
@@ -237,14 +240,19 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double network_distance =
|
reverse_heap.Clear();
|
||||||
getNetworkDistance(engine_working_data,
|
const auto &target_phantom = current_timestamps_list[s_prime].phantom_node;
|
||||||
facade,
|
insertTargetInHeap(reverse_heap, target_phantom);
|
||||||
forward_heap,
|
|
||||||
reverse_heap,
|
double network_distance = getNetworkDistance(engine_working_data,
|
||||||
prev_unbroken_timestamps_list[s].phantom_node,
|
facade,
|
||||||
current_timestamps_list[s_prime].phantom_node,
|
forward_heap,
|
||||||
weight_upper_bound);
|
reverse_heap,
|
||||||
|
source_phantom,
|
||||||
|
target_phantom,
|
||||||
|
weight_upper_bound);
|
||||||
|
|
||||||
|
network_distance = std::round(network_distance * 10) / 10;
|
||||||
|
|
||||||
// get distance diff between loc1/2 and locs/s_prime
|
// get distance diff between loc1/2 and locs/s_prime
|
||||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||||
|
|||||||
@@ -33,6 +33,79 @@ bool needsLoopBackwards(const PhantomNodes &phantoms)
|
|||||||
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
|
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||||
|
const PhantomNode &source_phantom,
|
||||||
|
const PhantomNode &target_phantom,
|
||||||
|
const EdgeDistance uncorrected_distance)
|
||||||
|
{
|
||||||
|
EdgeDistance distance = uncorrected_distance;
|
||||||
|
if (!path.empty())
|
||||||
|
{
|
||||||
|
|
||||||
|
// check the direction of travel to figure out how to calculate the offset to/from
|
||||||
|
// the source/target
|
||||||
|
if (source_phantom.forward_segment_id.id == path.front())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// -->s <-- subtract offset to start at source
|
||||||
|
// ......... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance -= source_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else if (source_phantom.reverse_segment_id.id == path.front())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// s<------- <-- subtract offset to start at source
|
||||||
|
// ... <-- want this distance
|
||||||
|
// entry 0---1---2---3 <-- 3 is exit node
|
||||||
|
distance -= source_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
if (target_phantom.forward_segment_id.id == path.back())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// ++>t <-- add offset to get to target
|
||||||
|
// ................ <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance += target_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else if (target_phantom.reverse_segment_id.id == path.back())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// <++t <-- add offset to get from target
|
||||||
|
// ................ <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance += target_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// there is no shortcut to unpack. source and target are on the same EBG Node.
|
||||||
|
// if the offset of the target is greater than the offset of the source, subtract it
|
||||||
|
if (target_phantom.GetForwardDistance() > source_phantom.GetForwardDistance())
|
||||||
|
{
|
||||||
|
// --------->t <-- offsets
|
||||||
|
// ->s <-- subtract source offset from target offset
|
||||||
|
// ......... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance = target_phantom.GetForwardDistance() - source_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// s<--- <-- offsets
|
||||||
|
// t<--------- <-- subtract source offset from target offset
|
||||||
|
// ...... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance = target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT_MSG(distance >= 0 || distance > -1.0f,
|
||||||
|
"Distance correction generated negative number");
|
||||||
|
// guard against underflow errors caused by rounding
|
||||||
|
distance = std::max(EdgeDistance{0}, distance);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
|||||||
const PhantomNodes & /*phantom_nodes*/,
|
const PhantomNodes & /*phantom_nodes*/,
|
||||||
const EdgeWeight weight_upper_bound)
|
const EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
if (forward_heap.Empty() && reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
weight = INVALID_EDGE_WEIGHT;
|
weight = INVALID_EDGE_WEIGHT;
|
||||||
return;
|
return;
|
||||||
@@ -110,10 +110,14 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
|||||||
weight = weight_upper_bound;
|
weight = weight_upper_bound;
|
||||||
|
|
||||||
// get offset to account for offsets on phantom nodes on compressed edges
|
// get offset to account for offsets on phantom nodes on compressed edges
|
||||||
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
|
EdgeWeight min_edge_offset = 0;
|
||||||
BOOST_ASSERT(min_edge_offset <= 0);
|
if (forward_heap.Size() > 0)
|
||||||
|
{
|
||||||
|
min_edge_offset = std::min(min_edge_offset, forward_heap.MinKey());
|
||||||
|
BOOST_ASSERT(min_edge_offset <= 0);
|
||||||
|
}
|
||||||
// we only every insert negative offsets for nodes in the forward heap
|
// we only every insert negative offsets for nodes in the forward heap
|
||||||
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
|
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() >= 0);
|
||||||
|
|
||||||
// run two-Target Dijkstra routing step.
|
// run two-Target Dijkstra routing step.
|
||||||
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
||||||
@@ -176,11 +180,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound)
|
EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
forward_heap.Clear();
|
|
||||||
reverse_heap.Clear();
|
|
||||||
|
|
||||||
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
|
|
||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||||
std::vector<NodeID> packed_path;
|
std::vector<NodeID> packed_path;
|
||||||
search(engine_working_data,
|
search(engine_working_data,
|
||||||
@@ -199,14 +198,31 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PathData> unpacked_path;
|
EdgeDistance distance = 0;
|
||||||
unpackPath(facade,
|
|
||||||
packed_path.begin(),
|
|
||||||
packed_path.end(),
|
|
||||||
{source_phantom, target_phantom},
|
|
||||||
unpacked_path);
|
|
||||||
|
|
||||||
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
|
std::vector<NodeID> unpacked_nodes;
|
||||||
|
unpacked_nodes.reserve(packed_path.size());
|
||||||
|
if (!packed_path.empty())
|
||||||
|
{
|
||||||
|
unpacked_nodes.push_back(packed_path.front());
|
||||||
|
unpackPath(
|
||||||
|
facade, packed_path.begin(), packed_path.end(), [&](const auto &edge, const auto &) {
|
||||||
|
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||||
|
unpacked_nodes.push_back(edge.second);
|
||||||
|
});
|
||||||
|
|
||||||
|
distance = std::accumulate(unpacked_nodes.begin(),
|
||||||
|
std::prev(unpacked_nodes.end()),
|
||||||
|
EdgeDistance{0},
|
||||||
|
[&](const EdgeDistance distance, const auto node_id) {
|
||||||
|
return distance + computeEdgeDistance(facade, node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
distance =
|
||||||
|
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
|
||||||
|
|
||||||
|
return distance;
|
||||||
}
|
}
|
||||||
} // namespace ch
|
} // namespace ch
|
||||||
|
|
||||||
|
|||||||
@@ -430,7 +430,6 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
|||||||
util::UnbufferedLog log;
|
util::UnbufferedLog log;
|
||||||
log << "Sorting edges by renumbered start ... ";
|
log << "Sorting edges by renumbered start ... ";
|
||||||
TIMER_START(sort_edges_by_renumbered_start);
|
TIMER_START(sort_edges_by_renumbered_start);
|
||||||
std::mutex name_data_mutex;
|
|
||||||
tbb::parallel_sort(all_edges_list.begin(),
|
tbb::parallel_sort(all_edges_list.begin(),
|
||||||
all_edges_list.end(),
|
all_edges_list.end(),
|
||||||
CmpEdgeByInternalSourceTargetAndName{
|
CmpEdgeByInternalSourceTargetAndName{
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ struct RegionHandle
|
|||||||
{
|
{
|
||||||
std::unique_ptr<SharedMemory> memory;
|
std::unique_ptr<SharedMemory> memory;
|
||||||
char *data_ptr;
|
char *data_ptr;
|
||||||
std::uint8_t shm_key;
|
std::uint16_t shm_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout)
|
auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout)
|
||||||
|
|||||||
+2
-1
@@ -82,7 +82,8 @@ void springClean()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (auto key : util::irange<std::uint8_t>(0, storage::SharedRegionRegister::MAX_SHM_KEYS))
|
for (auto key : util::irange<storage::SharedRegionRegister::RegionID>(
|
||||||
|
0, storage::SharedRegionRegister::MAX_SHM_KEYS))
|
||||||
{
|
{
|
||||||
deleteRegion(key);
|
deleteRegion(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ namespace coordinate_calculation
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
||||||
|
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||||
|
const constexpr double EARTH_RADIUS = 6372797.560856;
|
||||||
|
|
||||||
class CheapRulerContainer
|
class CheapRulerContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -112,7 +117,7 @@ double haversineDistance(const Coordinate coordinate_1, const Coordinate coordin
|
|||||||
const double aharv = std::pow(std::sin(dlat / 2.0), 2.0) +
|
const double aharv = std::pow(std::sin(dlat / 2.0), 2.0) +
|
||||||
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dlong / 2.), 2);
|
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dlong / 2.), 2);
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
||||||
return detail::EARTH_RADIUS * charv;
|
return EARTH_RADIUS * charv;
|
||||||
}
|
}
|
||||||
|
|
||||||
double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
|
double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
|
||||||
@@ -133,7 +138,7 @@ double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coord
|
|||||||
|
|
||||||
const double x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.0);
|
const double x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.0);
|
||||||
const double y_value = float_lat2 - float_lat1;
|
const double y_value = float_lat2 - float_lat1;
|
||||||
return std::hypot(x_value, y_value) * detail::EARTH_RADIUS;
|
return std::hypot(x_value, y_value) * EARTH_RADIUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
double perpendicularDistance(const Coordinate segment_source,
|
double perpendicularDistance(const Coordinate segment_source,
|
||||||
|
|||||||
@@ -159,6 +159,7 @@
|
|||||||
{"key": "maxspeed", "value": "DE:rural"},
|
{"key": "maxspeed", "value": "DE:rural"},
|
||||||
{"key": "maxspeed", "value": "DE:motorway"},
|
{"key": "maxspeed", "value": "DE:motorway"},
|
||||||
{"key": "maxspeed", "value": "DK:rural"},
|
{"key": "maxspeed", "value": "DK:rural"},
|
||||||
|
{"key": "maxspeed", "value": "FR:rural"},
|
||||||
{"key": "maxspeed", "value": "GB:nsl_single"},
|
{"key": "maxspeed", "value": "GB:nsl_single"},
|
||||||
{"key": "maxspeed", "value": "GB:nsl_dual"},
|
{"key": "maxspeed", "value": "GB:nsl_dual"},
|
||||||
{"key": "maxspeed", "value": "GB:motorway"},
|
{"key": "maxspeed", "value": "GB:motorway"},
|
||||||
|
|||||||
Reference in New Issue
Block a user