reduce numbers of intersections in findNextIntersection, don't normalise for turn lanes
This commit is contained in:
parent
01a57ff1d8
commit
a1127c3e09
@ -338,10 +338,10 @@ Feature: Collapse
|
|||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
a f g
|
a f g
|
||||||
|
| | . '
|
||||||
b e
|
b-e '
|
||||||
|
/ /
|
||||||
|
/ /
|
||||||
c d
|
c d
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ Feature: Collapse
|
|||||||
| a,g | first,second,second | depart,turn left,arrive |
|
| a,g | first,second,second | depart,turn left,arrive |
|
||||||
| d,g | first,second,second | depart,turn right,arrive |
|
| d,g | first,second,second | depart,turn right,arrive |
|
||||||
| g,f | second,first,first | depart,turn right,arrive |
|
| g,f | second,first,first | depart,turn right,arrive |
|
||||||
| g,c | second,first,first | depart,end of road left,arrive |
|
| g,c | second,first,first | depart,turn left,arrive |
|
||||||
|
|
||||||
Scenario: Do not collapse turning roads
|
Scenario: Do not collapse turning roads
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
// implements all data storage when shared memory is _NOT_ used
|
// implements all data storage when shared memory is _NOT_ used
|
||||||
|
|
||||||
#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp"
|
|
||||||
#include "storage/storage.hpp"
|
#include "storage/storage.hpp"
|
||||||
|
#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp"
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
|
@ -15,8 +15,8 @@ namespace extractor
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
inline void maybeSetString(std::string &str, const char* value)
|
inline void maybeSetString(std::string &str, const char *value)
|
||||||
{
|
{
|
||||||
if (value == nullptr)
|
if (value == nullptr)
|
||||||
{
|
{
|
||||||
str.clear();
|
str.clear();
|
||||||
@ -25,9 +25,8 @@ namespace detail
|
|||||||
{
|
{
|
||||||
str = std::string(value);
|
str = std::string(value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct is the direct result of the call to ```way_function```
|
* This struct is the direct result of the call to ```way_function```
|
||||||
@ -67,18 +66,24 @@ struct ExtractionWay
|
|||||||
TravelMode get_backward_mode() const { return backward_travel_mode; }
|
TravelMode get_backward_mode() const { return backward_travel_mode; }
|
||||||
|
|
||||||
// wrappers to allow assigning nil (nullptr) to string values
|
// wrappers to allow assigning nil (nullptr) to string values
|
||||||
void SetName(const char* value) { detail::maybeSetString(name, value); }
|
void SetName(const char *value) { detail::maybeSetString(name, value); }
|
||||||
const char* GetName() const { return name.c_str(); }
|
const char *GetName() const { return name.c_str(); }
|
||||||
void SetRef(const char* value) { detail::maybeSetString(ref, value); }
|
void SetRef(const char *value) { detail::maybeSetString(ref, value); }
|
||||||
const char* GetRef() const { return ref.c_str(); }
|
const char *GetRef() const { return ref.c_str(); }
|
||||||
void SetDestinations(const char* value) { detail::maybeSetString(destinations, value); }
|
void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); }
|
||||||
const char* GetDestinations() const { return destinations.c_str(); }
|
const char *GetDestinations() const { return destinations.c_str(); }
|
||||||
void SetPronunciation(const char* value) { detail::maybeSetString(pronunciation, value); }
|
void SetPronunciation(const char *value) { detail::maybeSetString(pronunciation, value); }
|
||||||
const char* GetPronunciation() const { return pronunciation.c_str(); }
|
const char *GetPronunciation() const { return pronunciation.c_str(); }
|
||||||
void SetTurnLanesForward(const char* value) { detail::maybeSetString(turn_lanes_forward, value); }
|
void SetTurnLanesForward(const char *value)
|
||||||
const char* GetTurnLanesForward() const { return turn_lanes_forward.c_str(); }
|
{
|
||||||
void SetTurnLanesBackward(const char* value) { detail::maybeSetString(turn_lanes_backward, value); }
|
detail::maybeSetString(turn_lanes_forward, value);
|
||||||
const char* GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
|
}
|
||||||
|
const char *GetTurnLanesForward() const { return turn_lanes_forward.c_str(); }
|
||||||
|
void SetTurnLanesBackward(const char *value)
|
||||||
|
{
|
||||||
|
detail::maybeSetString(turn_lanes_backward, value);
|
||||||
|
}
|
||||||
|
const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
|
||||||
|
|
||||||
double forward_speed;
|
double forward_speed;
|
||||||
double backward_speed;
|
double backward_speed;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
#ifndef OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
||||||
#define OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
#define OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
@ -28,6 +29,7 @@ class CoordinateExtractor
|
|||||||
/* Find a interpolated coordinate a long the compressed geometries. The desired coordinate
|
/* Find a interpolated coordinate a long the compressed geometries. The desired coordinate
|
||||||
* should be in a certain distance. This method is dedicated to find representative coordinates
|
* should be in a certain distance. This method is dedicated to find representative coordinates
|
||||||
* at turns.
|
* at turns.
|
||||||
|
* Since we are computing the length of the segment anyhow, we also return it.
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
OSRM_ATTR_WARN_UNUSED
|
||||||
util::Coordinate GetCoordinateAlongRoad(const NodeID intersection_node,
|
util::Coordinate GetCoordinateAlongRoad(const NodeID intersection_node,
|
||||||
@ -36,9 +38,20 @@ class CoordinateExtractor
|
|||||||
const NodeID to_node,
|
const NodeID to_node,
|
||||||
const std::uint8_t number_of_in_lanes) const;
|
const std::uint8_t number_of_in_lanes) const;
|
||||||
|
|
||||||
// instead of finding only a single coordinate, we can also list all coordinates along a road.
|
// same as above, only with precomputed coordinate vector (move it in)
|
||||||
OSRM_ATTR_WARN_UNUSED
|
OSRM_ATTR_WARN_UNUSED
|
||||||
std::vector<util::Coordinate> GetCoordinatesAlongRoad(const NodeID intersection_node,
|
util::Coordinate
|
||||||
|
ExtractRepresentativeCoordinate(const NodeID intersection_node,
|
||||||
|
const EdgeID turn_edge,
|
||||||
|
const bool traversed_in_reverse,
|
||||||
|
const NodeID to_node,
|
||||||
|
const std::uint8_t intersection_lanes,
|
||||||
|
std::vector<util::Coordinate> coordinates) const;
|
||||||
|
|
||||||
|
// instead of finding only a single coordinate, we can also list all coordinates along a
|
||||||
|
// road.
|
||||||
|
OSRM_ATTR_WARN_UNUSED std::vector<util::Coordinate>
|
||||||
|
GetCoordinatesAlongRoad(const NodeID intersection_node,
|
||||||
const EdgeID turn_edge,
|
const EdgeID turn_edge,
|
||||||
const bool traversed_in_reverse,
|
const bool traversed_in_reverse,
|
||||||
const NodeID to_node) const;
|
const NodeID to_node) const;
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
#include "util/typedefs.hpp" // EdgeID
|
#include "util/typedefs.hpp" // EdgeID
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
namespace extractor
|
namespace extractor
|
||||||
@ -53,10 +55,13 @@ struct ConnectedRoad final : public TurnOperation
|
|||||||
{
|
{
|
||||||
using Base = TurnOperation;
|
using Base = TurnOperation;
|
||||||
|
|
||||||
ConnectedRoad(const TurnOperation turn, const bool entry_allowed = false);
|
ConnectedRoad(const TurnOperation turn,
|
||||||
|
const bool entry_allowed = false,
|
||||||
|
const boost::optional<double> segment_length = {});
|
||||||
|
|
||||||
// a turn may be relevant to good instructions, even if we cannot enter the road
|
// a turn may be relevant to good instructions, even if we cannot enter the road
|
||||||
bool entry_allowed;
|
bool entry_allowed;
|
||||||
|
boost::optional<double> segment_length;
|
||||||
|
|
||||||
// used to sort the set of connected roads (we require sorting throughout turn handling)
|
// used to sort the set of connected roads (we require sorting throughout turn handling)
|
||||||
bool compareByAngle(const ConnectedRoad &other) const;
|
bool compareByAngle(const ConnectedRoad &other) const;
|
||||||
|
@ -68,6 +68,9 @@ class TurnAnalysis
|
|||||||
std::vector<TurnOperation>
|
std::vector<TurnOperation>
|
||||||
transformIntersectionIntoTurns(const Intersection &intersection) const;
|
transformIntersectionIntoTurns(const Intersection &intersection) const;
|
||||||
|
|
||||||
|
Intersection
|
||||||
|
assignTurnTypes(const NodeID from_node, const EdgeID via_eid, Intersection intersection) const;
|
||||||
|
|
||||||
const IntersectionGenerator &GetIntersectionGenerator() const;
|
const IntersectionGenerator &GetIntersectionGenerator() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -79,9 +82,6 @@ class TurnAnalysis
|
|||||||
const TurnHandler turn_handler;
|
const TurnHandler turn_handler;
|
||||||
const SliproadHandler sliproad_handler;
|
const SliproadHandler sliproad_handler;
|
||||||
|
|
||||||
Intersection
|
|
||||||
assignTurnTypes(const NodeID from_node, const EdgeID via_eid, Intersection intersection) const;
|
|
||||||
|
|
||||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||||
Intersection
|
Intersection
|
||||||
setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const;
|
setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const;
|
||||||
|
@ -22,7 +22,7 @@ namespace lanes
|
|||||||
bool findPreviousIntersection(
|
bool findPreviousIntersection(
|
||||||
const NodeID node,
|
const NodeID node,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const Intersection intersection,
|
const Intersection &intersection,
|
||||||
const IntersectionGenerator &intersection_generator,
|
const IntersectionGenerator &intersection_generator,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
|
const util::NodeBasedDynamicGraph &node_based_graph, // query edge data
|
||||||
// output parameters, will be in an arbitrary state on failure
|
// output parameters, will be in an arbitrary state on failure
|
||||||
|
@ -134,11 +134,11 @@ struct DataLayout
|
|||||||
// Interface Similar to [ptr.align] but omits space computation.
|
// Interface Similar to [ptr.align] but omits space computation.
|
||||||
// The method can be removed and changed directly to an std::align
|
// The method can be removed and changed directly to an std::align
|
||||||
// function call after dropping gcc < 5 support.
|
// function call after dropping gcc < 5 support.
|
||||||
inline void* align(std::size_t align, std::size_t , void*& ptr) const noexcept
|
inline void *align(std::size_t align, std::size_t, void *&ptr) const noexcept
|
||||||
{
|
{
|
||||||
const auto intptr = reinterpret_cast<uintptr_t>(ptr);
|
const auto intptr = reinterpret_cast<uintptr_t>(ptr);
|
||||||
const auto aligned = (intptr - 1u + align) & -align;
|
const auto aligned = (intptr - 1u + align) & -align;
|
||||||
return ptr = reinterpret_cast<void*>(aligned);
|
return ptr = reinterpret_cast<void *>(aligned);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const
|
inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
static double search_radius_for_gps_radius(double gps_radius) {
|
static double search_radius_for_gps_radius(double gps_radius)
|
||||||
|
{
|
||||||
// For a given GPS radius, determine the radius we need to search for candidate street segments
|
// For a given GPS radius, determine the radius we need to search for candidate street segments
|
||||||
// to have a 99.9% chance of finding the correct segment.
|
// to have a 99.9% chance of finding the correct segment.
|
||||||
// For more detail, see the analysis at https://github.com/Project-OSRM/osrm-backend/pull/3184
|
// For more detail, see the analysis at https://github.com/Project-OSRM/osrm-backend/pull/3184
|
||||||
|
@ -56,13 +56,29 @@ CoordinateExtractor::GetCoordinateAlongRoad(const NodeID intersection_node,
|
|||||||
const NodeID to_node,
|
const NodeID to_node,
|
||||||
const std::uint8_t intersection_lanes) const
|
const std::uint8_t intersection_lanes) const
|
||||||
{
|
{
|
||||||
const auto considered_lanes =
|
|
||||||
(intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes;
|
|
||||||
|
|
||||||
// we first extract all coordinates from the road
|
// we first extract all coordinates from the road
|
||||||
auto coordinates =
|
auto coordinates =
|
||||||
GetCoordinatesAlongRoad(intersection_node, turn_edge, traversed_in_reverse, to_node);
|
GetCoordinatesAlongRoad(intersection_node, turn_edge, traversed_in_reverse, to_node);
|
||||||
|
|
||||||
|
return ExtractRepresentativeCoordinate(intersection_node,
|
||||||
|
turn_edge,
|
||||||
|
traversed_in_reverse,
|
||||||
|
to_node,
|
||||||
|
intersection_lanes,
|
||||||
|
std::move(coordinates));
|
||||||
|
}
|
||||||
|
|
||||||
|
util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||||
|
const NodeID intersection_node,
|
||||||
|
const EdgeID turn_edge,
|
||||||
|
const bool traversed_in_reverse,
|
||||||
|
const NodeID to_node,
|
||||||
|
const std::uint8_t intersection_lanes,
|
||||||
|
std::vector<util::Coordinate> coordinates) const
|
||||||
|
{
|
||||||
|
const auto considered_lanes =
|
||||||
|
(intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes;
|
||||||
|
|
||||||
/* if we are looking at a straight line, we don't care where exactly the coordinate
|
/* if we are looking at a straight line, we don't care where exactly the coordinate
|
||||||
* is. Simply return the final coordinate. Turn angles/turn vectors are the same no matter which
|
* is. Simply return the final coordinate. Turn angles/turn vectors are the same no matter which
|
||||||
* coordinate we look at.
|
* coordinate we look at.
|
||||||
@ -406,10 +422,12 @@ CoordinateExtractor::GetCoordinatesAlongRoad(const NodeID intersection_node,
|
|||||||
geometry.rend(),
|
geometry.rend(),
|
||||||
std::back_inserter(result),
|
std::back_inserter(result),
|
||||||
compressedGeometryToCoordinate);
|
compressedGeometryToCoordinate);
|
||||||
|
BOOST_ASSERT(intersection_node < node_coordinates.size());
|
||||||
result.push_back(node_coordinates[intersection_node]);
|
result.push_back(node_coordinates[intersection_node]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(intersection_node < node_coordinates.size());
|
||||||
result.push_back(node_coordinates[intersection_node]);
|
result.push_back(node_coordinates[intersection_node]);
|
||||||
std::transform(geometry.begin(),
|
std::transform(geometry.begin(),
|
||||||
geometry.end(),
|
geometry.end(),
|
||||||
|
@ -17,8 +17,10 @@ namespace extractor
|
|||||||
namespace guidance
|
namespace guidance
|
||||||
{
|
{
|
||||||
|
|
||||||
ConnectedRoad::ConnectedRoad(const TurnOperation turn, const bool entry_allowed)
|
ConnectedRoad::ConnectedRoad(const TurnOperation turn,
|
||||||
: TurnOperation(turn), entry_allowed(entry_allowed)
|
const bool entry_allowed,
|
||||||
|
boost::optional<double> segment_length)
|
||||||
|
: TurnOperation(turn), entry_allowed(entry_allowed), segment_length(segment_length)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,19 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
from_node, via_eid, traversed_in_reverse, to_node, intersection_lanes);
|
from_node, via_eid, traversed_in_reverse, to_node, intersection_lanes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The first coordinate (the origin) can depend on the number of lanes turning onto,
|
||||||
|
// just as the target coordinate can. Here we compute the corrected coordinate for the
|
||||||
|
// incoming edge
|
||||||
|
|
||||||
|
// to compute the length along the path
|
||||||
|
const auto in_segment_length = [&]() {
|
||||||
|
const auto in_coordinates =
|
||||||
|
coordinate_extractor.GetCoordinatesAlongRoad(from_node, via_eid, INVERT, turn_node);
|
||||||
|
return util::coordinate_calculation::getLength(
|
||||||
|
in_coordinates, util::coordinate_calculation::haversineDistance);
|
||||||
|
}();
|
||||||
|
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
|
||||||
|
|
||||||
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(turn_node))
|
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(turn_node))
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(onto_edge != SPECIAL_EDGEID);
|
BOOST_ASSERT(onto_edge != SPECIAL_EDGEID);
|
||||||
@ -117,14 +130,7 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
// the turn is not restricted
|
// the turn is not restricted
|
||||||
!restriction_map.CheckIfTurnIsRestricted(from_node, turn_node, to_node);
|
!restriction_map.CheckIfTurnIsRestricted(from_node, turn_node, to_node);
|
||||||
|
|
||||||
auto angle = 0.;
|
double bearing = 0., out_segment_length = 0., angle = 0.;
|
||||||
double bearing = 0.;
|
|
||||||
|
|
||||||
// The first coordinate (the origin) can depend on the number of lanes turning onto,
|
|
||||||
// just as the target coordinate can. Here we compute the corrected coordinate for the
|
|
||||||
// incoming edge.
|
|
||||||
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
|
|
||||||
|
|
||||||
if (from_node == to_node)
|
if (from_node == to_node)
|
||||||
{
|
{
|
||||||
bearing = util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
|
bearing = util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
|
||||||
@ -150,14 +156,21 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
has_uturn_edge = true;
|
has_uturn_edge = true;
|
||||||
|
out_segment_length = in_segment_length;
|
||||||
BOOST_ASSERT(angle >= 0. && angle < std::numeric_limits<double>::epsilon());
|
BOOST_ASSERT(angle >= 0. && angle < std::numeric_limits<double>::epsilon());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// the default distance we lookahead on a road. This distance prevents small mapping
|
// the default distance we lookahead on a road. This distance prevents small mapping
|
||||||
// errors to impact the turn angles.
|
// errors to impact the turn angles.
|
||||||
const auto third_coordinate =
|
{
|
||||||
extract_coordinate(turn_node, onto_edge, !INVERT, to_node);
|
// segment of out segment
|
||||||
|
const auto out_coordinates = coordinate_extractor.GetCoordinatesAlongRoad(
|
||||||
|
turn_node, onto_edge, !INVERT, to_node);
|
||||||
|
out_segment_length = util::coordinate_calculation::getLength(
|
||||||
|
out_coordinates, util::coordinate_calculation::haversineDistance);
|
||||||
|
}
|
||||||
|
const auto third_coordinate = extract_coordinate(turn_node, onto_edge, !INVERT, to_node);
|
||||||
|
|
||||||
angle = util::coordinate_calculation::computeAngle(
|
angle = util::coordinate_calculation::computeAngle(
|
||||||
first_coordinate, turn_coordinate, third_coordinate);
|
first_coordinate, turn_coordinate, third_coordinate);
|
||||||
@ -173,7 +186,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
bearing,
|
bearing,
|
||||||
{TurnType::Invalid, DirectionModifier::UTurn},
|
{TurnType::Invalid, DirectionModifier::UTurn},
|
||||||
INVALID_LANE_DATAID},
|
INVALID_LANE_DATAID},
|
||||||
turn_is_valid));
|
turn_is_valid,
|
||||||
|
out_segment_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We hit the case of a street leading into nothing-ness. Since the code here assumes
|
// We hit the case of a street leading into nothing-ness. Since the code here assumes
|
||||||
@ -181,7 +195,6 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
// will never happen we add an artificial invalid uturn in this case.
|
// will never happen we add an artificial invalid uturn in this case.
|
||||||
if (!has_uturn_edge)
|
if (!has_uturn_edge)
|
||||||
{
|
{
|
||||||
const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node);
|
|
||||||
const double bearing =
|
const double bearing =
|
||||||
util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
|
util::coordinate_calculation::bearing(turn_coordinate, first_coordinate);
|
||||||
|
|
||||||
@ -190,7 +203,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
|||||||
bearing,
|
bearing,
|
||||||
{TurnType::Invalid, DirectionModifier::UTurn},
|
{TurnType::Invalid, DirectionModifier::UTurn},
|
||||||
INVALID_LANE_DATAID},
|
INVALID_LANE_DATAID},
|
||||||
false});
|
false,
|
||||||
|
in_segment_length});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(std::begin(intersection),
|
std::sort(std::begin(intersection),
|
||||||
@ -227,41 +241,41 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
|
|||||||
NodeID *resulting_from_node = nullptr,
|
NodeID *resulting_from_node = nullptr,
|
||||||
EdgeID *resulting_via_edge = nullptr) const
|
EdgeID *resulting_via_edge = nullptr) const
|
||||||
{
|
{
|
||||||
// This function skips over traffic lights/graph compression issues and similar to find the next
|
NodeID query_node = starting_node;
|
||||||
// actual intersection
|
EdgeID query_edge = via_edge;
|
||||||
Intersection result = GetConnectedRoads(starting_node, via_edge);
|
|
||||||
|
|
||||||
// Skip over stuff that has not been compressed due to barriers/parallel edges
|
const auto get_next_edge = [this](const NodeID from, const EdgeID via) {
|
||||||
NodeID node_at_intersection = starting_node;
|
const NodeID new_node = node_based_graph.GetTarget(via);
|
||||||
EdgeID incoming_edge = via_edge;
|
BOOST_ASSERT(node_based_graph.GetOutDegree(new_node) == 2);
|
||||||
|
const EdgeID begin_edges_new_node = node_based_graph.BeginEdges(new_node);
|
||||||
|
return (node_based_graph.GetTarget(begin_edges_new_node) == from) ? begin_edges_new_node + 1
|
||||||
|
: begin_edges_new_node;
|
||||||
|
};
|
||||||
|
|
||||||
// to prevent endless loops
|
|
||||||
const auto termination_node = node_based_graph.GetTarget(via_edge);
|
|
||||||
|
|
||||||
// using a maximum lookahead, we make sure not to end up in some form of loop
|
|
||||||
std::unordered_set<NodeID> visited_nodes;
|
std::unordered_set<NodeID> visited_nodes;
|
||||||
while (visited_nodes.count(node_at_intersection) == 0 &&
|
// skip trivial nodes without generating the intersection in between, stop at the very first
|
||||||
(result.size() == 2 &&
|
// intersection of degree > 2
|
||||||
node_based_graph.GetEdgeData(via_edge).IsCompatibleTo(
|
while (0 == visited_nodes.count(query_node) &&
|
||||||
node_based_graph.GetEdgeData(result[1].eid))))
|
2 == node_based_graph.GetOutDegree(node_based_graph.GetTarget(query_edge)))
|
||||||
{
|
{
|
||||||
visited_nodes.insert(node_at_intersection);
|
visited_nodes.insert(query_node);
|
||||||
node_at_intersection = node_based_graph.GetTarget(incoming_edge);
|
const auto next_node = node_based_graph.GetTarget(query_edge);
|
||||||
incoming_edge = result[1].eid;
|
const auto next_edge = get_next_edge(query_node, query_edge);
|
||||||
result = GetConnectedRoads(node_at_intersection, incoming_edge);
|
if (!node_based_graph.GetEdgeData(query_edge)
|
||||||
|
.IsCompatibleTo(node_based_graph.GetEdgeData(next_edge)) ||
|
||||||
// When looping back to the original node, we obviously are in a loop. Stop there.
|
node_based_graph.GetTarget(next_edge) == starting_node)
|
||||||
if (termination_node == node_based_graph.GetTarget(incoming_edge))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
query_node = next_node;
|
||||||
|
query_edge = next_edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return output if requested
|
|
||||||
if (resulting_from_node)
|
if (resulting_from_node)
|
||||||
*resulting_from_node = node_at_intersection;
|
*resulting_from_node = query_node;
|
||||||
if (resulting_via_edge)
|
if (resulting_via_edge)
|
||||||
*resulting_via_edge = incoming_edge;
|
*resulting_via_edge = query_edge;
|
||||||
|
|
||||||
return result;
|
return GetConnectedRoads(query_node, query_edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const
|
const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "extractor/guidance/constants.hpp"
|
|
||||||
#include "extractor/guidance/intersection_handler.hpp"
|
#include "extractor/guidance/intersection_handler.hpp"
|
||||||
|
#include "extractor/guidance/constants.hpp"
|
||||||
#include "extractor/guidance/toolkit.hpp"
|
#include "extractor/guidance/toolkit.hpp"
|
||||||
|
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
@ -473,8 +473,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
std::abs(best_option_deviation - straightest_data_deviation) > FUZZY_ANGLE_DIFFERENCE;
|
std::abs(best_option_deviation - straightest_data_deviation) > FUZZY_ANGLE_DIFFERENCE;
|
||||||
const auto not_ramp_class = !straightest_data.road_classification.IsRampClass();
|
const auto not_ramp_class = !straightest_data.road_classification.IsRampClass();
|
||||||
const auto not_link_class = !straightest_data.road_classification.IsLinkClass();
|
const auto not_link_class = !straightest_data.road_classification.IsLinkClass();
|
||||||
if (deviation_diff && !IsLowPriority(straightest_data) && not_ramp_class && not_link_class &&
|
if (deviation_diff && !IsLowPriority(straightest_data) && not_ramp_class &&
|
||||||
!IsContinueRoad(best_option_data))
|
not_link_class && !IsContinueRoad(best_option_data))
|
||||||
{
|
{
|
||||||
best_option = std::distance(begin(intersection), straightest);
|
best_option = std::distance(begin(intersection), straightest);
|
||||||
best_option_deviation =
|
best_option_deviation =
|
||||||
@ -489,7 +489,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
auto best_continue_it =
|
auto best_continue_it =
|
||||||
std::min_element(begin(intersection), end(intersection), RoadCompareSameName);
|
std::min_element(begin(intersection), end(intersection), RoadCompareSameName);
|
||||||
const auto best_continue_data = node_based_graph.GetEdgeData(best_continue_it->eid);
|
const auto best_continue_data = node_based_graph.GetEdgeData(best_continue_it->eid);
|
||||||
if (IsContinueRoad(best_continue_data) || (in_way_data.name_id == EMPTY_NAMEID && best_continue_data.name_id == EMPTY_NAMEID))
|
if (IsContinueRoad(best_continue_data) ||
|
||||||
|
(in_way_data.name_id == EMPTY_NAMEID && best_continue_data.name_id == EMPTY_NAMEID))
|
||||||
{
|
{
|
||||||
best_continue = std::distance(begin(intersection), best_continue_it);
|
best_continue = std::distance(begin(intersection), best_continue_it);
|
||||||
best_continue_deviation =
|
best_continue_deviation =
|
||||||
@ -754,16 +755,22 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
const util::Coordinate coordinate_at_u_turn = node_info_list[node_at_u_turn];
|
const util::Coordinate coordinate_at_u_turn = node_info_list[node_at_u_turn];
|
||||||
|
|
||||||
const double constexpr MAX_COLLAPSE_DISTANCE = 30;
|
const double constexpr MAX_COLLAPSE_DISTANCE = 30;
|
||||||
if (util::coordinate_calculation::haversineDistance(
|
const auto distance_at_u_turn = intersection[0].segment_length
|
||||||
coordinate_at_intersection, coordinate_at_u_turn) < MAX_COLLAPSE_DISTANCE)
|
? *intersection[0].segment_length
|
||||||
|
: util::coordinate_calculation::haversineDistance(
|
||||||
|
coordinate_at_intersection, coordinate_at_u_turn);
|
||||||
|
if (distance_at_u_turn < MAX_COLLAPSE_DISTANCE)
|
||||||
{
|
{
|
||||||
// this request here actually goes against the direction of the ingoing edgeid. This can
|
// this request here actually goes against the direction of the ingoing edgeid. This can
|
||||||
// even reverse the direction. Since we don't want to compute actual turns but simply
|
// even reverse the direction. Since we don't want to compute actual turns but simply
|
||||||
// try to find whether there is a turn going to the opposite direction of our obvious
|
// try to find whether there is a turn going to the opposite direction of our obvious
|
||||||
// turn, this should be alright.
|
// turn, this should be alright.
|
||||||
|
NodeID new_node;
|
||||||
const auto previous_intersection = intersection_generator.GetActualNextIntersection(
|
const auto previous_intersection = intersection_generator.GetActualNextIntersection(
|
||||||
node_at_intersection, intersection[0].eid, nullptr, nullptr);
|
node_at_intersection, intersection[0].eid, &new_node, nullptr);
|
||||||
|
|
||||||
|
if (new_node != node_at_intersection)
|
||||||
|
{
|
||||||
const auto continue_road = intersection[best_continue];
|
const auto continue_road = intersection[best_continue];
|
||||||
for (const auto &comparison_road : previous_intersection)
|
for (const auto &comparison_road : previous_intersection)
|
||||||
{
|
{
|
||||||
@ -779,6 +786,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return best_continue;
|
return best_continue;
|
||||||
}
|
}
|
||||||
|
@ -365,11 +365,17 @@ Intersection IntersectionNormalizer::AdjustForJoiningRoads(const NodeID node_at_
|
|||||||
if (intersection.size() <= 1)
|
if (intersection.size() <= 1)
|
||||||
return intersection;
|
return intersection;
|
||||||
|
|
||||||
const util::Coordinate coordinate_at_intersection = node_coordinates[node_at_intersection];
|
// we don't adjust any road that is longer than 30 meters (between centers of intersections),
|
||||||
|
// since the road is probably too long otherwise to impact perception.
|
||||||
|
const double constexpr PRUNING_DISTANCE = 30;
|
||||||
// never adjust u-turns
|
// never adjust u-turns
|
||||||
for (std::size_t index = 1; index < intersection.size(); ++index)
|
for (std::size_t index = 1; index < intersection.size(); ++index)
|
||||||
{
|
{
|
||||||
auto &road = intersection[index];
|
auto &road = intersection[index];
|
||||||
|
// only consider roads that are close
|
||||||
|
if (road.segment_length && *(road.segment_length) > PRUNING_DISTANCE)
|
||||||
|
continue;
|
||||||
|
|
||||||
// to find out about the above situation, we need to look at the next intersection (at d in
|
// to find out about the above situation, we need to look at the next intersection (at d in
|
||||||
// the example). If the initial road can be merged to the left/right, we are about to adjust
|
// the example). If the initial road can be merged to the left/right, we are about to adjust
|
||||||
// the angle.
|
// the angle.
|
||||||
@ -380,11 +386,6 @@ Intersection IntersectionNormalizer::AdjustForJoiningRoads(const NodeID node_at_
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto node_at_next_intersection = node_based_graph.GetTarget(road.eid);
|
const auto node_at_next_intersection = node_based_graph.GetTarget(road.eid);
|
||||||
const util::Coordinate coordinate_at_next_intersection =
|
|
||||||
node_coordinates[node_at_next_intersection];
|
|
||||||
if (util::coordinate_calculation::haversineDistance(coordinate_at_intersection,
|
|
||||||
coordinate_at_next_intersection) > 30)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const auto adjustAngle = [](double angle, double offset) {
|
const auto adjustAngle = [](double angle, double offset) {
|
||||||
angle += offset;
|
angle += offset;
|
||||||
|
@ -19,7 +19,7 @@ const constexpr bool USE_LOW_PRECISION_MODE = true;
|
|||||||
|
|
||||||
bool findPreviousIntersection(const NodeID node_v,
|
bool findPreviousIntersection(const NodeID node_v,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const Intersection intersection,
|
const Intersection &intersection,
|
||||||
const IntersectionGenerator &intersection_generator,
|
const IntersectionGenerator &intersection_generator,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
// output parameters
|
// output parameters
|
||||||
@ -55,6 +55,14 @@ bool findPreviousIntersection(const NodeID node_v,
|
|||||||
// (looking at the reverse direction).
|
// (looking at the reverse direction).
|
||||||
const auto node_w = node_based_graph.GetTarget(via_edge);
|
const auto node_w = node_based_graph.GetTarget(via_edge);
|
||||||
const auto u_turn_at_node_w = intersection[0].eid;
|
const auto u_turn_at_node_w = intersection[0].eid;
|
||||||
|
// make sure the ID is actually valid
|
||||||
|
BOOST_ASSERT(node_based_graph.BeginEdges(node_w) <= u_turn_at_node_w &&
|
||||||
|
u_turn_at_node_w <= node_based_graph.EndEdges(node_w));
|
||||||
|
|
||||||
|
// if we can't find the correct road, stop
|
||||||
|
if (node_based_graph.GetTarget(u_turn_at_node_w) != node_v)
|
||||||
|
return false;
|
||||||
|
|
||||||
const auto node_v_reverse_intersection =
|
const auto node_v_reverse_intersection =
|
||||||
intersection_generator.GetConnectedRoads(node_w, u_turn_at_node_w, USE_LOW_PRECISION_MODE);
|
intersection_generator.GetConnectedRoads(node_w, u_turn_at_node_w, USE_LOW_PRECISION_MODE);
|
||||||
|
|
||||||
@ -77,6 +85,8 @@ bool findPreviousIntersection(const NodeID node_v,
|
|||||||
// The u-turn at the now found intersection should, hopefully, represent the previous edge.
|
// The u-turn at the now found intersection should, hopefully, represent the previous edge.
|
||||||
result_node = node_u;
|
result_node = node_u;
|
||||||
result_via_edge = node_u_reverse_intersection[0].eid;
|
result_via_edge = node_u_reverse_intersection[0].eid;
|
||||||
|
if (node_based_graph.GetTarget(result_via_edge) != node_v)
|
||||||
|
return false;
|
||||||
|
|
||||||
// if the edge is not traversable, we obviously don't have a previous intersection or couldn't
|
// if the edge is not traversable, we obviously don't have a previous intersection or couldn't
|
||||||
// find it.
|
// find it.
|
||||||
|
@ -196,7 +196,7 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at,
|
|||||||
previous_intersection))
|
previous_intersection))
|
||||||
{
|
{
|
||||||
extractLaneData(previous_via_edge, previous_description_id, previous_lane_data);
|
extractLaneData(previous_via_edge, previous_description_id, previous_lane_data);
|
||||||
previous_intersection = turn_analysis.PostProcess(
|
previous_intersection = turn_analysis.assignTurnTypes(
|
||||||
previous_node, previous_via_edge, std::move(previous_intersection));
|
previous_node, previous_via_edge, std::move(previous_intersection));
|
||||||
for (std::size_t road_index = 0; road_index < previous_intersection.size(); ++road_index)
|
for (std::size_t road_index = 0; road_index < previous_intersection.size(); ++road_index)
|
||||||
{
|
{
|
||||||
@ -541,8 +541,9 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
|
|||||||
std::vector<bool> matched_at_second(turn_lane_data.size(), false);
|
std::vector<bool> matched_at_second(turn_lane_data.size(), false);
|
||||||
|
|
||||||
// find out about the next intersection. To check for valid matches, we also need the turn
|
// find out about the next intersection. To check for valid matches, we also need the turn
|
||||||
// types
|
// types. We can skip merging/angle adjustments, though
|
||||||
const auto next_intersection = turn_analysis(at, straightmost->eid);
|
const auto next_intersection = turn_analysis.assignTurnTypes(
|
||||||
|
at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid));
|
||||||
|
|
||||||
// check where we can match turn lanes
|
// check where we can match turn lanes
|
||||||
std::size_t straightmost_tag_index = turn_lane_data.size();
|
std::size_t straightmost_tag_index = turn_lane_data.size();
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
#include "util/json_renderer.hpp"
|
#include "util/json_renderer.hpp"
|
||||||
#include "util/simple_logger.hpp"
|
#include "util/simple_logger.hpp"
|
||||||
#include "util/string_util.hpp"
|
#include "util/string_util.hpp"
|
||||||
#include "util/typedefs.hpp"
|
|
||||||
#include "util/timing_util.hpp"
|
#include "util/timing_util.hpp"
|
||||||
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include "engine/status.hpp"
|
#include "engine/status.hpp"
|
||||||
#include "osrm/osrm.hpp"
|
#include "osrm/osrm.hpp"
|
||||||
@ -146,11 +146,11 @@ void RequestHandler::HandleRequest(const http::request ¤t_request, http::r
|
|||||||
<< 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "")
|
<< 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "")
|
||||||
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "")
|
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "")
|
||||||
<< time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "")
|
<< time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "")
|
||||||
<< time_stamp->tm_sec << " "
|
<< time_stamp->tm_sec << " " << TIMER_MSEC(request_duration) << "ms "
|
||||||
<< TIMER_MSEC(request_duration) << "ms " << current_request.endpoint.to_string() << " "
|
<< current_request.endpoint.to_string() << " " << current_request.referrer
|
||||||
<< current_request.referrer << (0 == current_request.referrer.length() ? "- " : " ")
|
<< (0 == current_request.referrer.length() ? "- " : " ") << current_request.agent
|
||||||
<< current_request.agent << (0 == current_request.agent.length() ? "- " : " ")
|
<< (0 == current_request.agent.length() ? "- " : " ") << current_reply.status
|
||||||
<< current_reply.status << " " //
|
<< " " //
|
||||||
<< request_string;
|
<< request_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user