Compare commits

...

23 Commits

Author SHA1 Message Date
Daniel Patterson c130012ed5 Set package.json to match tag for publishing. 2018-08-28 19:34:35 -07:00
Daniel Patterson 5fa90cd2d5 Set package.json to match tag for publishing. 2018-08-28 19:33:53 -07:00
Daniel Patterson 0499803f24 Increase allowed shared memory regions to 512 from 256. 2018-08-28 18:12:19 -07:00
Patrick Niklaus 9b779c704f Update changelog 2018-08-02 12:19:24 +02:00
Patrick Niklaus 5bd7d04fe3 Fix formating 2018-08-02 12:19:24 +02:00
Patrick Niklaus 0f78f7b2cc Fix bug in computation of distance offset for phantom node 2018-08-02 12:19:24 +02:00
Patrick Niklaus 8473be69d2 Adjust text cases for flightly different matching due to rounding 2018-08-02 12:19:24 +02:00
Patrick Niklaus c0124f7d77 Round network distance to deci-meter to retain previous behavior 2018-08-02 12:19:24 +02:00
Patrick Niklaus b630b4e32a Preserve heap state in map matching 2018-08-02 12:19:24 +02:00
Patrick Niklaus 89fabc1b9c Use distance functions from many to many 2018-08-02 12:19:24 +02:00
Patrick Niklaus a649a8a5cf Use FCC algorithm for map matching distance calculation 2018-08-02 12:19:24 +02:00
Frédéric Rodrigo f928956584 Support maxlength and maxweight in car profile 2018-07-11 18:33:30 +02:00
Frédéric Rodrigo 7ff68792d7 Add helper for maxlength into measure.lua 2018-07-11 18:33:30 +02:00
Frédéric Rodrigo 3088dd0342 Better and flexible weight parsing in measure.lua 2018-07-11 18:33:30 +02:00
Frédéric Rodrigo d2590989f5 Default maxspeed for fr:rural is now 80km/h 2018-07-11 17:54:46 +02:00
Antoine Giret 3a7b377586 Update profiles.md 2018-06-27 14:27:17 +02:00
Michael Krasnyk 82b5648c97 Don't collapse segregated intersections at roundabout exits, #5114 2018-06-21 15:24:03 +02:00
Antoine Giret 1628a3c4d5 Update profiles.md 2018-06-07 15:43:06 +02:00
Matthias Gilch e5d8319c43 Removed unused variable
The variable name_data_mutex is declared in a block but never used
within this block. So I've removed the variable.
2018-06-02 22:49:30 +02:00
MichalPP 06699132eb allow routing over barrier=some_tag 2018-05-29 16:56:15 +02:00
MichalPP 918e794d6a change barrier_whitelist to barrier blacklist
change barrier_whitelist to barrier blacklist  in foot profile
fix #5067 and #3890 and #4823
2018-05-29 16:56:15 +02:00
MichalPP 8dd8ee1fc2 blacklisting barriers allow routing
blacklisting barriers allow routing over barrier=some_tag
2018-05-28 17:21:08 +02:00
MichalPP c3d0efda93 change barrier_whitelist to barrier_blacklist 2018-05-28 17:21:08 +02:00
29 changed files with 415 additions and 300 deletions
+8
View File
@@ -1,4 +1,12 @@
# 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:
- Features:
- ADDED: `table` plugin now optionally returns `distance` matrix as part of response [#4990](https://github.com/Project-OSRM/osrm-backend/pull/4990)
+2 -2
View File
@@ -138,7 +138,7 @@ Given an OpenStreetMap way, the `process_way` function will either return nothin
Argument | Description
---------|-------------------------------------------------------
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.
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 | ""
target.lon | Read | Float | Co-ordinates of segment end
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
duration | Read/write | Float | Duration for this segment
+1 -1
View File
@@ -19,7 +19,7 @@ Feature: Barriers
| entrance | x |
| wall | |
| fence | |
| some_tag | |
| some_tag | x |
| block | x |
Scenario: Bike - Access tag trumphs barriers
+19
View File
@@ -48,3 +48,22 @@ Feature: Car - Handle physical limitation
| primary | | none | x |
| primary | | no-sign | 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 |
+1 -1
View File
@@ -19,7 +19,7 @@ Feature: Barriers
| entrance | x |
| wall | |
| fence | |
| some_tag | |
| some_tag | x |
| block | x |
Scenario: Foot - Access tag trumphs barriers
+1 -1
View File
@@ -792,4 +792,4 @@ Feature: Basic Map Matching
When I match I should get
| trace | geometry | a:distance | a:duration | a:weight | duration |
| 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 |
+13 -14
View File
@@ -449,6 +449,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
const auto forward_geometry = datafacade.GetUncompressedForwardGeometry(geometry_id);
const auto reverse_geometry = datafacade.GetUncompressedReverseGeometry(geometry_id);
const auto forward_weight_offset =
std::accumulate(forward_weights.begin(),
@@ -479,19 +480,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment);
const auto reverse_weight_offset =
std::accumulate(reverse_weights.begin(),
reverse_weights.end() - data.fwd_segment_position - 1,
EdgeWeight{0});
const auto rev_segment_position = reverse_weights.size() - data.fwd_segment_position - 1;
const auto reverse_weight_offset = std::accumulate(
reverse_weights.begin(), reverse_weights.begin() + rev_segment_position, EdgeWeight{0});
const auto reverse_duration_offset =
std::accumulate(reverse_durations.begin(),
reverse_durations.end() - data.fwd_segment_position - 1,
reverse_durations.begin() + rev_segment_position,
EdgeDuration{0});
EdgeDistance reverse_distance_offset = 0;
for (auto current = forward_geometry.begin();
current < forward_geometry.end() - data.fwd_segment_position - 2;
for (auto current = reverse_geometry.begin();
current < reverse_geometry.begin() + rev_segment_position;
++current)
{
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
@@ -499,13 +500,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
datafacade.GetCoordinateOfNode(*std::next(current)));
}
EdgeWeight reverse_weight =
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
EdgeDuration reverse_duration =
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
EdgeWeight reverse_weight = reverse_weights[rev_segment_position];
EdgeDuration reverse_duration = reverse_durations[rev_segment_position];
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance(
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));
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
@@ -693,7 +692,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const CoordinateList &coordinates;
DataFacadeT &datafacade;
};
}
}
} // namespace engine
} // namespace osrm
#endif
@@ -44,50 +44,19 @@ bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &ta
bool needsLoopForward(const PhantomNodes &phantoms);
bool needsLoopBackwards(const PhantomNodes &phantoms);
template <typename Heap>
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
namespace detail
{
const auto &source = nodes.source_phantom;
if (source.IsValidForwardSource())
{
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)
template <typename Algorithm>
void insertSourceInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
const PhantomNode &phantom_node)
{
if (phantom_node.IsValidForwardSource())
if (phantom_node.IsValidForwardTarget())
{
heap.Insert(phantom_node.forward_segment_id.id,
-phantom_node.GetForwardWeightPlusOffset(),
{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,
-phantom_node.GetReverseWeightPlusOffset(),
@@ -95,8 +64,9 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
}
}
template <typename ManyToManyQueryHeap>
void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
template <typename Algorithm>
void insertTargetInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
const PhantomNode &phantom_node)
{
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>
void annotatePath(const FacadeT &facade,
const PhantomNodes &phantom_node_pair,
@@ -321,58 +394,10 @@ void annotatePath(const FacadeT &facade,
}
}
template <typename Algorithm>
double getPathDistance(const DataFacade<Algorithm> &facade,
const std::vector<PathData> unpacked_path,
const PhantomNode &source_phantom,
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;
}
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
const EdgeDistance distance);
template <typename AlgorithmT>
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
@@ -97,7 +97,6 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
const std::vector<std::size_t> &phantom_indices)
{
auto min_level = [&partition, node](const PhantomNode &phantom_node) {
const auto &forward_segment = phantom_node.forward_segment_id;
const auto forward_level =
forward_segment.enabled ? partition.GetHighestDifferentLevel(node, forward_segment.id)
@@ -120,7 +119,7 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
}
return result;
}
}
} // namespace
// 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".
@@ -391,21 +390,27 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
EdgeWeight weight_upper_bound,
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>());
}
const auto &partition = facade.GetMultiLevelPartition();
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
BOOST_ASSERT(!reverse_heap.Empty() && reverse_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);
// run two-Target Dijkstra routing step.
NodeID middle = SPECIAL_NODEID;
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 &&
forward_heap_min + reverse_heap_min < weight)
{
@@ -657,11 +662,7 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
{
forward_heap.Clear();
reverse_heap.Clear();
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> unpacked_nodes;
@@ -680,11 +681,22 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
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
+9 -10
View File
@@ -26,7 +26,7 @@ namespace serialization
inline void read(io::BufferReader &reader, DataLayout &layout);
inline void write(io::BufferWriter &writer, const DataLayout &layout);
}
} // namespace serialization
namespace detail
{
@@ -52,7 +52,7 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n
return name;
}
}
}
} // namespace detail
class DataLayout
{
@@ -165,7 +165,7 @@ struct SharedRegion
static constexpr const int MAX_NAME_LENGTH = 254;
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}
{
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];
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
// for fast access and deserialization.
struct SharedRegionRegister
{
using RegionID = std::uint8_t;
using RegionID = std::uint16_t;
static constexpr const RegionID INVALID_REGION_ID = std::numeric_limits<RegionID>::max();
using ShmKey = decltype(SharedRegion::shm_key);
@@ -250,12 +250,11 @@ struct SharedRegionRegister
void ReleaseKey(ShmKey key) { shm_key_in_use[key] = false; }
static constexpr const std::uint8_t MAX_SHARED_REGIONS =
std::numeric_limits<RegionID>::max() - 1;
static constexpr const std::size_t MAX_SHARED_REGIONS = 512;
static_assert(MAX_SHARED_REGIONS < std::numeric_limits<RegionID>::max(),
"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";
@@ -263,7 +262,7 @@ struct SharedRegionRegister
std::array<SharedRegion, MAX_SHARED_REGIONS> regions;
std::array<bool, MAX_SHM_KEYS> shm_key_in_use;
};
}
}
} // namespace storage
} // namespace osrm
#endif /* SHARED_DATA_TYPE_HPP */
+10 -9
View File
@@ -34,10 +34,10 @@ namespace storage
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 lock_file = temp_dir / "osrm.lock";
boost::filesystem::path lock_file = temp_dir / ("osrm-" + std::to_string(id) + ".lock");
return lock_file;
}
};
@@ -93,7 +93,7 @@ class SharedMemory
try
{
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);
}
catch (...)
@@ -106,7 +106,7 @@ class SharedMemory
template <typename IdentifierT> static bool Remove(const IdentifierT id)
{
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);
}
@@ -287,10 +287,11 @@ class SharedMemory
template <typename IdentifierT, typename LockFileT = OSRMLockFile>
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
{
LockFileT lock_file;
if (!boost::filesystem::exists(lock_file()))
if (!boost::filesystem::exists(lock_file(id)))
{
if (0 == size)
{
@@ -298,10 +299,10 @@ std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint
}
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)
{
@@ -310,7 +311,7 @@ std::unique_ptr<SharedMemory> makeSharedMemory(const IdentifierT &id, const uint
throw util::exception(e.what() + SOURCE_REF);
}
}
}
}
} // namespace storage
} // namespace osrm
#endif // SHARED_MEMORY_HPP
+4 -4
View File
@@ -33,7 +33,7 @@ template <class Lock> class InvertedLock
InvertedLock(Lock &lock) : lock(lock) { lock.unlock(); }
~InvertedLock() { lock.lock(); }
};
}
} // namespace
// The shared monitor implementation based on a semaphore and mutex
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
// fail if a waiter is killed.
static constexpr int buffer_size = 256;
static constexpr int buffer_size = 4096;
struct InternalData
{
@@ -232,8 +232,8 @@ template <typename Data> struct SharedMonitor
bi::shared_memory_object shmem;
bi::mapped_region region;
};
}
}
} // namespace storage
} // namespace osrm
#undef USE_BOOST_INTERPROCESS_CONDITION
-3
View File
@@ -23,9 +23,6 @@ namespace detail
{
const constexpr double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
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)
{
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "osrm",
"version": "5.18.0-latest.1",
"version": "5.18.0-moarshm.2",
"private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {
+5 -15
View File
@@ -38,20 +38,10 @@ function setup()
mode.pushing_bike
},
barrier_whitelist = Set {
'sump_buster',
'bus_trap',
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'block'
barrier_blacklist = Set {
'yes',
'wall',
'fence'
},
access_tag_whitelist = Set {
@@ -245,7 +235,7 @@ function process_node(profile, node, result)
else
local barrier = node:get_value_by_key("barrier")
if barrier and "" ~= barrier then
if not profile.barrier_whitelist[barrier] then
if profile.barrier_blacklist[barrier] then
result.barrier = true
end
end
+7
View File
@@ -42,6 +42,10 @@ function setup()
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
-- 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
suffix_list = {
'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:motorway"] = 0,
["dk:rural"] = 80,
["fr:rural"] = 80,
["gb:nsl_single"] = (60*1609)/1000,
["gb:nsl_dual"] = (70*1609)/1000,
["gb:motorway"] = (70*1609)/1000,
@@ -387,6 +392,8 @@ function process_way(profile, way, result, relations)
WayHandlers.avoid_ways,
WayHandlers.handle_height,
WayHandlers.handle_width,
WayHandlers.handle_length,
WayHandlers.handle_weight,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
+5 -14
View File
@@ -24,19 +24,10 @@ function setup()
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
barrier_whitelist = Set {
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'kerb',
'block'
barrier_blacklist = Set {
'yes',
'wall',
'fence'
},
access_tag_whitelist = Set {
@@ -157,7 +148,7 @@ function process_node(profile, node, result)
local bollard = node:get_value_by_key("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
end
end
+20 -26
View File
@@ -5,6 +5,7 @@ Measure = {}
-- measurements conversion constants
local inch_to_meters = 0.0254
local feet_to_inches = 12
local pound_to_kilograms = 0.45359237
--- Parse string as a height in meters.
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
@@ -25,33 +26,19 @@ function Measure.parse_value_meters(value)
end
end
--- according to http://wiki.openstreetmap.org/wiki/Map_Features/Units#Explicit_specifications
local tonns_parse_patterns = Sequence {
"%d+",
"%d+.%d+",
"%d+.%d+ ?t"
}
local kg_parse_patterns = Sequence {
"%d+ ?kg"
}
--- Parse weight value in kilograms
--- Parse weight value in kilograms.
--- according to https://wiki.openstreetmap.org/wiki/Key:maxweight
function Measure.parse_value_kilograms(value)
-- try to parse kilograms
for i, templ in ipairs(kg_parse_patterns) do
m = string.match(value, templ)
if m then
return tonumber(m)
end
end
-- 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
local n = tonumber(value:gsub(",", "."):match("%d+%.?%d*"))
if n then
if string.match(value, "lbs") then
n = n * pound_to_kilograms
elseif string.match(value, "kg") then
-- n = n
else -- Default, metric tons
n = n * 1000
end
return n
end
end
@@ -83,7 +70,14 @@ function Measure.get_max_width(raw_value)
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)
if raw_value then
return Measure.parse_value_kilograms(raw_value)
+32
View File
@@ -511,6 +511,38 @@ function WayHandlers.handle_width(profile,way,result,data)
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
function WayHandlers.oneway(profile,way,result,data)
if not profile.oneway_handling then
+1
View File
@@ -621,6 +621,7 @@ RouteSteps collapseSegregatedTurnInstructions(RouteSteps steps)
// 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
else if (curr_step->is_segregated && !next_step->is_segregated &&
!hasRoundaboutType(curr_step->maneuver.instruction) &&
!hasRoundaboutType(next_step->maneuver.instruction))
{
// Determine if u-turn
@@ -240,74 +240,12 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
}
if (!packed_leg.empty())
{
auto annotation =
EdgeDistance annotation =
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;
// 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();
}
+16 -8
View File
@@ -227,6 +227,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
{
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()))
{
@@ -237,14 +240,19 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
continue;
}
double network_distance =
getNetworkDistance(engine_working_data,
facade,
forward_heap,
reverse_heap,
prev_unbroken_timestamps_list[s].phantom_node,
current_timestamps_list[s_prime].phantom_node,
weight_upper_bound);
reverse_heap.Clear();
const auto &target_phantom = current_timestamps_list[s_prime].phantom_node;
insertTargetInHeap(reverse_heap, target_phantom);
double network_distance = getNetworkDistance(engine_working_data,
facade,
forward_heap,
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
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);
}
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 engine
} // namespace osrm
@@ -100,7 +100,7 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
const PhantomNodes & /*phantom_nodes*/,
const EdgeWeight weight_upper_bound)
{
if (forward_heap.Empty() || reverse_heap.Empty())
if (forward_heap.Empty() && reverse_heap.Empty())
{
weight = INVALID_EDGE_WEIGHT;
return;
@@ -110,10 +110,14 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
weight = weight_upper_bound;
// get offset to account for offsets on phantom nodes on compressed edges
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
BOOST_ASSERT(min_edge_offset <= 0);
EdgeWeight 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
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() >= 0);
// run two-Target Dijkstra routing step.
while (0 < (forward_heap.Size() + reverse_heap.Size()))
@@ -176,11 +180,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> packed_path;
search(engine_working_data,
@@ -199,14 +198,31 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
return std::numeric_limits<double>::max();
}
std::vector<PathData> unpacked_path;
unpackPath(facade,
packed_path.begin(),
packed_path.end(),
{source_phantom, target_phantom},
unpacked_path);
EdgeDistance distance = 0;
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
-1
View File
@@ -430,7 +430,6 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
util::UnbufferedLog log;
log << "Sorting edges by renumbered start ... ";
TIMER_START(sort_edges_by_renumbered_start);
std::mutex name_data_mutex;
tbb::parallel_sort(all_edges_list.begin(),
all_edges_list.end(),
CmpEdgeByInternalSourceTargetAndName{
+1 -1
View File
@@ -66,7 +66,7 @@ struct RegionHandle
{
std::unique_ptr<SharedMemory> memory;
char *data_ptr;
std::uint8_t shm_key;
std::uint16_t shm_key;
};
auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout)
+1 -1
View File
@@ -82,7 +82,7 @@ void springClean()
}
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);
}
+7 -2
View File
@@ -22,6 +22,11 @@ namespace coordinate_calculation
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
{
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) +
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));
return detail::EARTH_RADIUS * charv;
return EARTH_RADIUS * charv;
}
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 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,
+1
View File
@@ -159,6 +159,7 @@
{"key": "maxspeed", "value": "DE:rural"},
{"key": "maxspeed", "value": "DE:motorway"},
{"key": "maxspeed", "value": "DK:rural"},
{"key": "maxspeed", "value": "FR:rural"},
{"key": "maxspeed", "value": "GB:nsl_single"},
{"key": "maxspeed", "value": "GB:nsl_dual"},
{"key": "maxspeed", "value": "GB:motorway"},