Detect possible uturns in the data.
To make them work, we have to disable PhantomNode splitting for this coordinates.
This commit is contained in:
parent
a5db3ea25b
commit
b5228dcda0
@ -69,7 +69,7 @@ file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp util/co
|
|||||||
set(PrepareSources prepare.cpp ${PrepareGlob})
|
set(PrepareSources prepare.cpp ${PrepareGlob})
|
||||||
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
||||||
|
|
||||||
file(GLOB ServerGlob server/*.cpp)
|
file(GLOB ServerGlob server/*.cpp util/compute_angle.cpp)
|
||||||
file(GLOB DescriptorGlob descriptors/*.cpp)
|
file(GLOB DescriptorGlob descriptors/*.cpp)
|
||||||
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
|
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
|
||||||
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
|
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
|
||||||
|
@ -27,6 +27,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "../util/integer_range.hpp"
|
#include "../util/integer_range.hpp"
|
||||||
#include "../data_structures/search_engine.hpp"
|
#include "../data_structures/search_engine.hpp"
|
||||||
#include "../routing_algorithms/map_matching.hpp"
|
#include "../routing_algorithms/map_matching.hpp"
|
||||||
|
#include "../util/compute_angle.hpp"
|
||||||
#include "../util/simple_logger.hpp"
|
#include "../util/simple_logger.hpp"
|
||||||
#include "../util/string_util.hpp"
|
#include "../util/string_util.hpp"
|
||||||
#include "../descriptors/descriptor_base.hpp"
|
#include "../descriptors/descriptor_base.hpp"
|
||||||
@ -68,22 +69,39 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
|||||||
return 400;
|
return 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalRouteResult raw_route;
|
const auto& input_coords = route_parameters.coordinates;
|
||||||
Matching::CandidateLists candidate_lists;
|
Matching::CandidateLists candidate_lists;
|
||||||
|
std::vector<bool> uturn_indicators(false, input_coords.size());
|
||||||
|
|
||||||
double last_distance = coordinate_calculation::great_circle_distance(
|
double last_distance = coordinate_calculation::great_circle_distance(
|
||||||
route_parameters.coordinates[0],
|
input_coords[0],
|
||||||
route_parameters.coordinates[1]);
|
input_coords[1]);
|
||||||
for (const auto current_coordinate : osrm::irange<std::size_t>(0, route_parameters.coordinates.size()))
|
for (const auto current_coordinate : osrm::irange<std::size_t>(0, input_coords.size()))
|
||||||
{
|
{
|
||||||
if (0 < current_coordinate)
|
if (0 < current_coordinate)
|
||||||
|
{
|
||||||
last_distance = coordinate_calculation::great_circle_distance(
|
last_distance = coordinate_calculation::great_circle_distance(
|
||||||
route_parameters.coordinates[current_coordinate - 1],
|
input_coords[current_coordinate - 1],
|
||||||
route_parameters.coordinates[current_coordinate]);
|
input_coords[current_coordinate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_coords.size()-1 > current_coordinate && 0 < current_coordinate)
|
||||||
|
{
|
||||||
|
double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(
|
||||||
|
input_coords[current_coordinate-1],
|
||||||
|
input_coords[current_coordinate],
|
||||||
|
input_coords[current_coordinate+1]);
|
||||||
|
|
||||||
|
// sharp turns indicate a possible uturn
|
||||||
|
if (turn_angle < 100.0 || turn_angle > 260.0)
|
||||||
|
{
|
||||||
|
uturn_indicators[current_coordinate] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::pair<PhantomNode, double>> candidates;
|
std::vector<std::pair<PhantomNode, double>> candidates;
|
||||||
if (!facade->IncrementalFindPhantomNodeForCoordinateWithMaxDistance(
|
if (!facade->IncrementalFindPhantomNodeForCoordinateWithMaxDistance(
|
||||||
route_parameters.coordinates[current_coordinate],
|
input_coords[current_coordinate],
|
||||||
candidates,
|
candidates,
|
||||||
last_distance/2.0,
|
last_distance/2.0,
|
||||||
5,
|
5,
|
||||||
@ -98,8 +116,10 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
|||||||
// call the actual map matching
|
// call the actual map matching
|
||||||
std::vector<PhantomNode> matched_nodes;
|
std::vector<PhantomNode> matched_nodes;
|
||||||
JSON::Object debug_info;
|
JSON::Object debug_info;
|
||||||
search_engine_ptr->map_matching(candidate_lists, route_parameters.coordinates, matched_nodes, debug_info);
|
search_engine_ptr->map_matching(candidate_lists, input_coords, uturn_indicators, matched_nodes, debug_info);
|
||||||
|
|
||||||
|
|
||||||
|
InternalRouteResult raw_route;
|
||||||
PhantomNodes current_phantom_node_pair;
|
PhantomNodes current_phantom_node_pair;
|
||||||
for (unsigned i = 0; i < matched_nodes.size() - 1; ++i)
|
for (unsigned i = 0; i < matched_nodes.size() - 1; ++i)
|
||||||
{
|
{
|
||||||
@ -110,8 +130,7 @@ template <class DataFacadeT> class MapMatchingPlugin : public BasePlugin
|
|||||||
|
|
||||||
if (2 > matched_nodes.size())
|
if (2 > matched_nodes.size())
|
||||||
{
|
{
|
||||||
reply = http::Reply::StockReply(http::Reply::badRequest);
|
return 400;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
search_engine_ptr->shortest_path(
|
search_engine_ptr->shortest_path(
|
||||||
|
@ -276,7 +276,8 @@ template <class DataFacadeT> class MapMatching final
|
|||||||
|
|
||||||
// TODO optimize: a lot of copying that could probably be avoided
|
// TODO optimize: a lot of copying that could probably be avoided
|
||||||
void expandCandidates(const Matching::CandidateLists &candidates_lists,
|
void expandCandidates(const Matching::CandidateLists &candidates_lists,
|
||||||
Matching::CandidateLists &expanded_lists) const
|
Matching::CandidateLists &expanded_lists,
|
||||||
|
const std::vector<bool>& uturn_indicators) const
|
||||||
{
|
{
|
||||||
// expand list of PhantomNodes to be single-directional
|
// expand list of PhantomNodes to be single-directional
|
||||||
expanded_lists.resize(candidates_lists.size());
|
expanded_lists.resize(candidates_lists.size());
|
||||||
@ -284,8 +285,8 @@ template <class DataFacadeT> class MapMatching final
|
|||||||
{
|
{
|
||||||
for (const auto& candidate : candidates_lists[i])
|
for (const auto& candidate : candidates_lists[i])
|
||||||
{
|
{
|
||||||
// bi-directional edge, split phantom node
|
// bi-directional edge, split phantom node if we don't expect a uturn
|
||||||
if (candidate.first.forward_node_id != SPECIAL_NODEID && candidate.first.reverse_node_id != SPECIAL_NODEID)
|
if (!uturn_indicators[i] && candidate.first.forward_node_id != SPECIAL_NODEID && candidate.first.reverse_node_id != SPECIAL_NODEID)
|
||||||
{
|
{
|
||||||
PhantomNode forward_node(candidate.first);
|
PhantomNode forward_node(candidate.first);
|
||||||
PhantomNode reverse_node(candidate.first);
|
PhantomNode reverse_node(candidate.first);
|
||||||
@ -304,13 +305,15 @@ template <class DataFacadeT> class MapMatching final
|
|||||||
|
|
||||||
void operator()(const Matching::CandidateLists &candidates_lists,
|
void operator()(const Matching::CandidateLists &candidates_lists,
|
||||||
const std::vector<FixedPointCoordinate> coordinate_list,
|
const std::vector<FixedPointCoordinate> coordinate_list,
|
||||||
|
const std::vector<bool>& uturn_indicators,
|
||||||
std::vector<PhantomNode>& matched_nodes,
|
std::vector<PhantomNode>& matched_nodes,
|
||||||
JSON::Object& _debug_info) const
|
JSON::Object& _debug_info) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(candidates_lists.size() == coordinate_list.size());
|
BOOST_ASSERT(candidates_lists.size() == coordinate_list.size());
|
||||||
|
BOOST_ASSERT(candidates_lists.size() == uturn_indicators.size());
|
||||||
|
|
||||||
Matching::CandidateLists timestamp_list;
|
Matching::CandidateLists timestamp_list;
|
||||||
expandCandidates(candidates_lists, timestamp_list);
|
expandCandidates(candidates_lists, timestamp_list, uturn_indicators);
|
||||||
|
|
||||||
std::vector<bool> breakage(timestamp_list.size(), true);
|
std::vector<bool> breakage(timestamp_list.size(), true);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user