handle stronger merge cases as well
This commit is contained in:
parent
7886d06839
commit
6a2518c0df
@ -136,6 +136,12 @@ Feature: Collapse
|
||||
|
||||
Scenario: Partly Segregated Intersection, Two Segregated Roads
|
||||
Given the node map
|
||||
| | n | | m | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | g | | h | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
@ -144,6 +150,12 @@ Feature: Collapse
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | j | | i | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | k | | l | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
@ -152,8 +164,8 @@ Feature: Collapse
|
||||
| de | primary | first | yes |
|
||||
| ef | primary | first | yes |
|
||||
| be | primary | first | no |
|
||||
| gbh | primary | second | yes |
|
||||
| iej | primary | second | yes |
|
||||
| ngbhm | primary | second | yes |
|
||||
| liejk | primary | second | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@ -176,6 +188,10 @@ Feature: Collapse
|
||||
|
||||
Scenario: Partly Segregated Intersection, Two Segregated Roads, Intersection belongs to Second
|
||||
Given the node map
|
||||
| | n | | m | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | g | | h | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
@ -184,6 +200,10 @@ Feature: Collapse
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | j | | i | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| | k | | l | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
@ -192,8 +212,8 @@ Feature: Collapse
|
||||
| de | primary | first | yes |
|
||||
| ef | primary | first | yes |
|
||||
| be | primary | second | no |
|
||||
| gbh | primary | second | yes |
|
||||
| iej | primary | second | yes |
|
||||
| ngbhm | primary | second | yes |
|
||||
| liejk | primary | second | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@ -382,13 +402,13 @@ Feature: Collapse
|
||||
|
||||
Scenario: Pankenbruecke
|
||||
Given the node map
|
||||
| h | | | | | | i | | | | | | |
|
||||
| | | b | c | d | e | f | | | | | | g |
|
||||
| a | | | | | | | | | | | | |
|
||||
| j | | | | h | | | | | | i | | | | | | |
|
||||
| | | | | | | b | c | d | e | f | | | | | | g |
|
||||
| k | | | | a | | | | | | | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abh | primary | inroad | yes |
|
||||
| kabhj | primary | inroad | yes |
|
||||
| bc | primary | inroad | no |
|
||||
| cd | primary | bridge | no |
|
||||
| defg | primary | outroad | no |
|
||||
@ -686,3 +706,43 @@ Feature: Collapse
|
||||
| a,c | main,main | depart,arrive |
|
||||
| a,e | main,straight,straight | depart,turn straight,arrive |
|
||||
| a,f | main,straight,right,right | depart,turn straight,turn right,arrive |
|
||||
|
||||
Scenario: Entering a segregated road
|
||||
Given the node map
|
||||
| | a | f | | |
|
||||
| | | | | g |
|
||||
| | b | e | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| c | d | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abc | primary | first | yes |
|
||||
| def | primary | first | yes |
|
||||
| be | primary | first | no |
|
||||
| ge | primary | second | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| d,c | first,first,first | depart,continue uturn,arrive |
|
||||
|
||||
Scenario: Entering a segregated road slight turn
|
||||
Given the node map
|
||||
| | | a | f | |
|
||||
| | | | | g |
|
||||
| | b | e | | |
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
| c | d | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | name | oneway |
|
||||
| abc | primary | first | yes |
|
||||
| def | primary | first | yes |
|
||||
| be | primary | first | no |
|
||||
| ge | primary | second | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| d,c | first,first,first | depart,continue uturn,arrive |
|
||||
|
149
features/guidance/perception.feature
Normal file
149
features/guidance/perception.feature
Normal file
@ -0,0 +1,149 @@
|
||||
@routing @guidance @perceived-angles
|
||||
Feature: Simple Turns
|
||||
|
||||
Background:
|
||||
Given the profile "car"
|
||||
Given a grid size of 5 meters
|
||||
|
||||
Scenario: Turning into splitting road
|
||||
Given the node map
|
||||
| | a | | |
|
||||
| | b | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| c | | d | |
|
||||
| | | | |
|
||||
| | | | e |
|
||||
| | | | |
|
||||
| | | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | road | primary | no |
|
||||
| bc | road | primary | yes |
|
||||
| fdb | road | primary | yes |
|
||||
| de | turn | primary | no |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| e,a | depart,turn slight right,arrive | turn,road,road |
|
||||
|
||||
Scenario: Middle Island
|
||||
Given the node map
|
||||
| | a | |
|
||||
| | | |
|
||||
| | b | |
|
||||
| c | | h |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| d | | g |
|
||||
| | e | |
|
||||
| | | |
|
||||
| | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | road | no |
|
||||
| ef | road | no |
|
||||
| bcde | road | yes |
|
||||
| eghb | road | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,f | depart,arrive | road,road |
|
||||
| c,f | depart,arrive | road,road |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| g,a | depart,arrive | road,road |
|
||||
|
||||
Scenario: Middle Island Over Bridge
|
||||
Given the node map
|
||||
| | a | |
|
||||
| | | |
|
||||
| | b | |
|
||||
| c | | h |
|
||||
| | | |
|
||||
| | | |
|
||||
| 1 | | 2 |
|
||||
| | | |
|
||||
| d | | g |
|
||||
| | e | |
|
||||
| | | |
|
||||
| | f | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | road | no |
|
||||
| ef | road | no |
|
||||
| bc | road | yes |
|
||||
| cd | bridge | yes |
|
||||
| de | road | yes |
|
||||
| eg | road | yes |
|
||||
| gh | bridge | yes |
|
||||
| hb | road | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,f | depart,arrive | road,road |
|
||||
| c,f | depart,new name straight,arrive | bridge,road,road |
|
||||
| 1,f | depart,new name straight,arrive | bridge,road,road |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| g,a | depart,new name straight,arrive | bridge,road,road |
|
||||
| 2,a | depart,new name straight,arrive | bridge,road,road |
|
||||
|
||||
@negative
|
||||
Scenario: Don't Collapse Places:
|
||||
Given the node map
|
||||
| | | | | | | h | | | | | | |
|
||||
| | | | | | | g | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| a | b | | | | | | | | | | e | f |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | c | | | | | | |
|
||||
| | | | | | | d | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ab | place | no |
|
||||
| cd | bottom | no |
|
||||
| ef | place | no |
|
||||
| gh | top | no |
|
||||
| bcegb | place | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| a,d | depart,continue right,turn right,arrive | place,place,bottom,bottom |
|
||||
| a,f | depart,continue right,continue left,continue right,arrive | place,place,place,place,place |
|
||||
| d,f | depart,turn right,continue right,arrive | bottom,place,place,place |
|
||||
| d,h | depart,turn right,continue left,turn right,arrive | bottom,place,place,top,top |
|
||||
|
||||
Scenario: Don't Collapse Places:
|
||||
Given the node map
|
||||
| | | | | | | g | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | e | f |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | | | | | | | |
|
||||
| | | | | | | c | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway |
|
||||
| ef | place | no |
|
||||
| ceg | place | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| c,f | depart,turn right,continue right,arrive | bottom,place,place,place |
|
@ -246,22 +246,28 @@ Feature: Simple Turns
|
||||
|
||||
Scenario: Four Way Intersection Double Through Street Segregated
|
||||
Given the node map
|
||||
| | b | | c | |
|
||||
| i | | | | d |
|
||||
| | | a | | |
|
||||
| h | | | | e |
|
||||
| | g | | f | |
|
||||
| | | | | q | | p | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | b | | c | | | | |
|
||||
| j | | | i | | | | d | | | o |
|
||||
| | | | | | a | | | | | |
|
||||
| k | | | h | | | | e | | | n |
|
||||
| | | | | g | | f | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | l | | m | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | oneway | name |
|
||||
| ha | primary | yes | first |
|
||||
| ai | primary | yes | first |
|
||||
| ae | primary | yes | first |
|
||||
| da | primary | yes | first |
|
||||
| ba | primary | yes | second |
|
||||
| ac | primary | yes | second |
|
||||
| fa | primary | yes | second |
|
||||
| ag | primary | yes | second |
|
||||
| khaij | primary | yes | first |
|
||||
| odaen | primary | yes | first |
|
||||
| qbacp | primary | yes | second |
|
||||
| mfagl | primary | yes | second |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
@ -969,13 +975,14 @@ Feature: Simple Turns
|
||||
| a,d | depart,new name straight,arrive | Molkenmarkt,Stralauer Str,Stralauer Str |
|
||||
| e,d | depart,new name slight left,arrive | Molkenmarkt,Stralauer Str,Stralauer Str |
|
||||
|
||||
Scenario: Collapse Turn Instruction, Issue #2725
|
||||
# https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q
|
||||
# http://www.openstreetmap.org/#map=19/52.46750/13.43171
|
||||
Scenario: Collapse Turn Instruction, Issue #2725
|
||||
Given the node map
|
||||
| | f | |
|
||||
| | e | |
|
||||
| | | |
|
||||
| | | |
|
||||
| g | | d |
|
||||
| | | |
|
||||
| | | |
|
||||
@ -1014,26 +1021,46 @@ Feature: Simple Turns
|
||||
| y,f | depart,arrive | Hermannstr,Hermannstr |
|
||||
| f,y | depart,arrive | Hermannstr,Hermannstr |
|
||||
|
||||
Scenario: Turning into splitting road
|
||||
Scenario: Collapse Turn Instruction, Issue #2725 - not trivially mergable at e
|
||||
# https://www.mapillary.com/app/?lat=52.466483333333336&lng=13.431908333333332&z=17&focus=photo&pKey=LWXnKqoGqUNLnG0lofiO0Q
|
||||
# http://www.openstreetmap.org/#map=19/52.46750/13.43171
|
||||
Given the node map
|
||||
| | a | | |
|
||||
| | b | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| c | | d | |
|
||||
| | | | |
|
||||
| | | | e |
|
||||
| | | | |
|
||||
| | | f | |
|
||||
| | f | |
|
||||
| | e | |
|
||||
| g | | d |
|
||||
| | | |
|
||||
| | | |
|
||||
| h | | c |
|
||||
| | | |
|
||||
| | | |
|
||||
| | b | |
|
||||
| | a | |
|
||||
| | | |
|
||||
| | | |
|
||||
| r | x | s |
|
||||
| | y | |
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | road | primary | no |
|
||||
| bc | road | primary | yes |
|
||||
| fdb | road | primary | yes |
|
||||
| de | turn | primary | no |
|
||||
| nodes | name | highway | oneway |
|
||||
| ab | Hermannstr | secondary | |
|
||||
| bc | Hermannstr | secondary | yes |
|
||||
| cd | Hermannbruecke | secondary | yes |
|
||||
| de | Hermannstr | secondary | yes |
|
||||
| ef | Hermannstr | secondary | |
|
||||
| eg | Hermannstr | secondary | yes |
|
||||
| gh | Hermannbruecke | secondary | yes |
|
||||
| hb | Hermannstr | secondary | yes |
|
||||
| xa | Hermannstr | secondary | |
|
||||
| yx | Hermannstr | secondary | |
|
||||
| rxs | Silbersteinstr | tertiary | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| x | traffic_signals |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | turns | route |
|
||||
| f,a | depart,arrive | road,road |
|
||||
| e,a | depart,turn slight right,arrive | turn,road,road |
|
||||
| waypoints | turns | route |
|
||||
| a,f | depart,arrive | Hermannstr,Hermannstr |
|
||||
| f,a | depart,arrive | Hermannstr,Hermannstr |
|
||||
| y,f | depart,arrive | Hermannstr,Hermannstr |
|
||||
| f,y | depart,arrive | Hermannstr,Hermannstr |
|
||||
|
@ -48,11 +48,12 @@ class IntersectionGenerator
|
||||
// from `from_node` via `via_eid`
|
||||
// The resulting candidates have to be analysed for their actual instructions later on.
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
Intersection getConnectedRoads(const NodeID from_node, const EdgeID via_eid) const;
|
||||
Intersection GetConnectedRoads(const NodeID from_node, const EdgeID via_eid) const;
|
||||
|
||||
// check if two indices in an intersection can be seen as a single road in the perceived
|
||||
// intersection representation
|
||||
bool canMerge(const Intersection &intersection,
|
||||
bool CanMerge(const NodeID intersection_node,
|
||||
const Intersection &intersection,
|
||||
std::size_t first_index,
|
||||
std::size_t second_index) const;
|
||||
|
||||
@ -68,7 +69,8 @@ class IntersectionGenerator
|
||||
// The treatment results in a straight turn angle of 180º rather than a turn angle of approx
|
||||
// 160
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
Intersection mergeSegregatedRoads(Intersection intersection) const;
|
||||
Intersection MergeSegregatedRoads(const NodeID intersection_node,
|
||||
Intersection intersection) const;
|
||||
|
||||
// The counterpiece to mergeSegregatedRoads. While we can adjust roads that split up at the
|
||||
// intersection itself, it can also happen that intersections are connected to joining roads.
|
||||
@ -81,8 +83,20 @@ class IntersectionGenerator
|
||||
// b
|
||||
//
|
||||
// for the local view of b at a.
|
||||
Intersection adjustForJoiningRoads(const NodeID node_at_intersection,
|
||||
OSRM_ATTR_WARN_UNUSED
|
||||
Intersection AdjustForJoiningRoads(const NodeID node_at_intersection,
|
||||
Intersection intersection) const;
|
||||
|
||||
// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
|
||||
// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an
|
||||
// intermediate intersection, if there is a traffic light in between. If we want to look farther
|
||||
// down a road, finding the next actual decision requires the look at multiple intersections.
|
||||
// Here we follow the road until we either reach a dead end or find the next intersection with
|
||||
// more than a single next road.
|
||||
inline Intersection GetActualNextIntersection(const NodeID starting_node,
|
||||
const EdgeID via_edge,
|
||||
NodeID *resulting_from_node,
|
||||
EdgeID *resulting_via_edge) const;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
@ -20,8 +20,6 @@ namespace guidance
|
||||
{
|
||||
inline void print(const engine::guidance::RouteStep &step)
|
||||
{
|
||||
const auto lanes = step.intersections.front().lanes;
|
||||
|
||||
std::cout << static_cast<int>(step.maneuver.instruction.type) << " "
|
||||
<< static_cast<int>(step.maneuver.instruction.direction_modifier) << " "
|
||||
<< static_cast<int>(step.maneuver.waypoint_type) << " "
|
||||
|
@ -51,14 +51,19 @@ struct NodeBasedEdgeData
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassification road_classification;
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
bool IsCompatibleToExceptForName(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (name_id == other.name_id) && (reversed == other.reversed) &&
|
||||
return (reversed == other.reversed) &&
|
||||
(roundabout == other.roundabout) && (startpoint == other.startpoint) &&
|
||||
(access_restricted == other.access_restricted) &&
|
||||
(travel_mode == other.travel_mode) &&
|
||||
(road_classification == other.road_classification);
|
||||
}
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (name_id == other.name_id) && IsCompatibleToExceptForName(other);
|
||||
}
|
||||
};
|
||||
|
||||
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "util/debug.hpp"
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
@ -584,6 +586,7 @@ std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps)
|
||||
// that we come across.
|
||||
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
{
|
||||
util::guidance::print(steps);
|
||||
// the steps should always include the first/last step in form of a location
|
||||
BOOST_ASSERT(steps.size() >= 2);
|
||||
if (steps.size() == 2)
|
||||
|
@ -59,7 +59,6 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
// forward_e1
|
||||
//
|
||||
// If the edges are compatible.
|
||||
|
||||
const bool reverse_edge_order = graph.GetEdgeData(graph.BeginEdges(node_v)).reversed;
|
||||
const EdgeID forward_e2 = graph.BeginEdges(node_v) + reverse_edge_order;
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
@ -30,9 +31,13 @@ IntersectionGenerator::IntersectionGenerator(
|
||||
|
||||
Intersection IntersectionGenerator::operator()(const NodeID from_node, const EdgeID via_eid) const
|
||||
{
|
||||
auto intersection = getConnectedRoads(from_node, via_eid);
|
||||
return adjustForJoiningRoads(node_based_graph.GetTarget(via_eid),
|
||||
mergeSegregatedRoads(std::move(intersection)));
|
||||
auto intersection = GetConnectedRoads(from_node, via_eid);
|
||||
const auto node_at_intersection = node_based_graph.GetTarget(via_eid);
|
||||
std::cout << "Creating Intersection: " << from_node << " ("
|
||||
<< util::Coordinate(node_info_list[from_node]) << ") " << node_at_intersection << " ("
|
||||
<< util::Coordinate(node_info_list[node_at_intersection]) << ")" << std::endl;
|
||||
return AdjustForJoiningRoads(
|
||||
node_at_intersection, MergeSegregatedRoads(node_at_intersection, std::move(intersection)));
|
||||
}
|
||||
|
||||
// a
|
||||
@ -48,7 +53,7 @@ Intersection IntersectionGenerator::operator()(const NodeID from_node, const Edg
|
||||
// That means we not only get (from_node, turn_node, c) in the above example
|
||||
// but also (from_node, turn_node, a), (from_node, turn_node, b). These turns are
|
||||
// marked as invalid and only needed for intersection classification.
|
||||
Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
||||
Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node,
|
||||
const EdgeID via_eid) const
|
||||
{
|
||||
Intersection intersection;
|
||||
@ -163,7 +168,8 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
||||
return intersection;
|
||||
}
|
||||
|
||||
bool IntersectionGenerator::canMerge(const Intersection &intersection,
|
||||
bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
|
||||
const Intersection &intersection,
|
||||
std::size_t first_index,
|
||||
std::size_t second_index) const
|
||||
{
|
||||
@ -192,9 +198,108 @@ bool IntersectionGenerator::canMerge(const Intersection &intersection,
|
||||
if (first_data.reversed == second_data.reversed)
|
||||
return false;
|
||||
|
||||
// one of them needs to be invalid
|
||||
if (intersection[first_index].entry_allowed && intersection[second_index].entry_allowed)
|
||||
return false;
|
||||
|
||||
// mergeable if the angle is not too big
|
||||
return angularDeviation(intersection[first_index].turn.angle,
|
||||
intersection[second_index].turn.angle) < 60;
|
||||
const auto angle_between = angularDeviation(intersection[first_index].turn.angle,
|
||||
intersection[second_index].turn.angle);
|
||||
|
||||
const auto coordinate_at_in_edge =
|
||||
getRepresentativeCoordinate(node_at_intersection,
|
||||
node_based_graph.GetTarget(intersection[0].turn.eid),
|
||||
intersection[0].turn.eid,
|
||||
false,
|
||||
compressed_edge_container,
|
||||
node_info_list);
|
||||
const auto coordinate_at_intersection = node_info_list[node_at_intersection];
|
||||
|
||||
const auto isValidYArm = [this,
|
||||
intersection,
|
||||
coordinate_at_in_edge,
|
||||
coordinate_at_intersection,
|
||||
node_at_intersection](const std::size_t index,
|
||||
const std::size_t other_index) {
|
||||
const auto target_id = [&]() {
|
||||
EdgeID last_in_edge_id;
|
||||
GetActualNextIntersection(
|
||||
node_at_intersection, intersection[index].turn.eid, nullptr, &last_in_edge_id);
|
||||
return node_based_graph.GetTarget(last_in_edge_id);
|
||||
}();
|
||||
|
||||
const auto coordinate_at_target = node_info_list[target_id];
|
||||
|
||||
const auto turn_angle = util::coordinate_calculation::computeAngle(
|
||||
coordinate_at_in_edge, coordinate_at_intersection, coordinate_at_target);
|
||||
const double distance_to_target = util::coordinate_calculation::haversineDistance(
|
||||
coordinate_at_intersection, coordinate_at_target);
|
||||
|
||||
const auto other_angle = intersection[other_index].turn.angle;
|
||||
const bool becomes_narrower =
|
||||
angularDeviation(turn_angle, other_angle) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(turn_angle, other_angle) <
|
||||
angularDeviation(intersection[index].turn.angle, other_angle);
|
||||
|
||||
return becomes_narrower;
|
||||
};
|
||||
|
||||
// Only merge valid y-arms
|
||||
if (!isValidYArm(first_index, second_index) || !isValidYArm(second_index, first_index))
|
||||
{
|
||||
if (angle_between < 60)
|
||||
{
|
||||
std::cout << "Cannot Merge here, due two y-arms." << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (angle_between < 60)
|
||||
{
|
||||
std::cout << "Merging success at (" << first_index << "." << second_index << "):\n";
|
||||
for (auto road : intersection)
|
||||
std::cout << "\t" << toString(road) << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// return false;
|
||||
// Finally, we also allow merging if all streets offer the same name, it is only three roads and
|
||||
// the angle is not fully extreme:
|
||||
if (intersection.size() != 3)
|
||||
return false;
|
||||
|
||||
const std::size_t missing_index = [first_index, second_index]() {
|
||||
if (first_index == 0)
|
||||
return second_index == 2 ? 1 : 2;
|
||||
else if (first_index == 1)
|
||||
return second_index == 2 ? 0 : 2;
|
||||
else
|
||||
return second_index == 1 ? 0 : 1;
|
||||
}();
|
||||
|
||||
// needs to be same road coming in
|
||||
if (node_based_graph.GetEdgeData(intersection[missing_index].turn.eid).name_id !=
|
||||
first_data.name_id)
|
||||
return false;
|
||||
|
||||
// we only allow collapsing of a Y like fork. So the angle to the missing index has to be
|
||||
// roughly equal:
|
||||
const auto y_angle_difference =
|
||||
angularDeviation(angularDeviation(intersection[missing_index].turn.angle,
|
||||
intersection[first_index].turn.angle),
|
||||
angularDeviation(intersection[missing_index].turn.angle,
|
||||
intersection[second_index].turn.angle));
|
||||
|
||||
// Allow larger angles if its three roads only of the same name
|
||||
const bool could_be_valid_y_intersection =
|
||||
angle_between < 100 && y_angle_difference < FUZZY_ANGLE_DIFFERENCE;
|
||||
if (could_be_valid_y_intersection)
|
||||
{
|
||||
std::cout << "Merging success (y) at (" << first_index << "." << second_index << "):\n";
|
||||
for (auto road : intersection)
|
||||
std::cout << "\t" << toString(road) << std::endl;
|
||||
}
|
||||
return could_be_valid_y_intersection;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -220,7 +325,8 @@ bool IntersectionGenerator::canMerge(const Intersection &intersection,
|
||||
* Anything containing the first u-turn in a merge affects all other angles
|
||||
* and is handled separately from all others.
|
||||
*/
|
||||
Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersection) const
|
||||
Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersection_node,
|
||||
Intersection intersection) const
|
||||
{
|
||||
const auto getRight = [&](std::size_t index) {
|
||||
return (index + intersection.size() - 1) % intersection.size();
|
||||
@ -298,7 +404,7 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
// the difference to all angles. Otherwise we subtract it.
|
||||
bool merged_first = false;
|
||||
// these result in an adjustment of all other angles
|
||||
if (canMerge(intersection, 0, intersection.size() - 1))
|
||||
if (CanMerge(intersection_node, intersection, 0, intersection.size() - 1))
|
||||
{
|
||||
merged_first = true;
|
||||
// moving `a` to the left
|
||||
@ -313,7 +419,7 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
|
||||
intersection.pop_back();
|
||||
}
|
||||
else if (canMerge(intersection, 0, 1))
|
||||
else if (CanMerge(intersection_node, intersection, 0, 1))
|
||||
{
|
||||
merged_first = true;
|
||||
// moving `a` to the right
|
||||
@ -344,7 +450,7 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
// therefore these are handled prior to this step
|
||||
for (std::size_t index = 2; index < intersection.size(); ++index)
|
||||
{
|
||||
if (canMerge(intersection, index, getRight(index)))
|
||||
if (CanMerge(intersection_node, intersection, index, getRight(index)))
|
||||
{
|
||||
intersection[getRight(index)] =
|
||||
merge(intersection[getRight(index)], intersection[index]);
|
||||
@ -378,11 +484,13 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
// Where we see the turn to `d` as a right turn, rather than going straight.
|
||||
// We do this by adjusting the local turn angle at `x` to turn onto `d` to be reflective of this
|
||||
// situation.
|
||||
Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_intersection,
|
||||
Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_intersection,
|
||||
Intersection intersection) const
|
||||
{
|
||||
// FIXME remove
|
||||
return intersection;
|
||||
// nothing to do for dead ends
|
||||
if ( intersection.size() <= 1)
|
||||
if (intersection.size() <= 1)
|
||||
return intersection;
|
||||
|
||||
for (auto &road : intersection)
|
||||
@ -391,7 +499,7 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i
|
||||
// the example). If the initial road can be merged to the left/right, we are about to adjust
|
||||
// the angle.
|
||||
const auto next_intersection_along_road =
|
||||
getConnectedRoads(node_at_intersection, road.turn.eid);
|
||||
GetConnectedRoads(node_at_intersection, road.turn.eid);
|
||||
if (next_intersection_along_road.size() <= 1)
|
||||
continue;
|
||||
|
||||
@ -404,7 +512,7 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i
|
||||
return angle;
|
||||
};
|
||||
|
||||
if (canMerge(next_intersection_along_road, 0, 1))
|
||||
if (CanMerge(node_based_graph.GetTarget(road.turn.eid), next_intersection_along_road, 0, 1))
|
||||
{
|
||||
const auto offset = 0.5 * angularDeviation(next_intersection_along_road[0].turn.angle,
|
||||
next_intersection_along_road[1].turn.angle);
|
||||
@ -412,7 +520,10 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i
|
||||
// angle to the left
|
||||
road.turn.angle = adjustAngle(road.turn.angle, offset);
|
||||
}
|
||||
else if (canMerge(next_intersection_along_road, 0, next_intersection_along_road.size() - 1))
|
||||
else if (CanMerge(node_based_graph.GetTarget(road.turn.eid),
|
||||
next_intersection_along_road,
|
||||
0,
|
||||
next_intersection_along_road.size() - 1))
|
||||
{
|
||||
const auto offset =
|
||||
0.5 * angularDeviation(
|
||||
@ -428,6 +539,43 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i
|
||||
return intersection;
|
||||
}
|
||||
|
||||
inline Intersection
|
||||
IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
|
||||
const EdgeID via_edge,
|
||||
NodeID *resulting_from_node = nullptr,
|
||||
EdgeID *resulting_via_edge = nullptr) const
|
||||
{
|
||||
// This function skips over traffic lights/graph compression issues and similar to find the next
|
||||
// actual intersection
|
||||
Intersection potential_result = GetConnectedRoads(starting_node, via_edge);
|
||||
|
||||
// Skip over stuff that has not been compressed due to barriers/parallel edges
|
||||
NodeID node_at_intersection = starting_node;
|
||||
EdgeID incoming_edge = via_edge;
|
||||
|
||||
// if we only have the u-turn and the node could have been compressed
|
||||
while (potential_result.size() == 2 &&
|
||||
node_based_graph.GetEdgeData(via_edge).IsCompatibleToExceptForName(
|
||||
node_based_graph.GetEdgeData(potential_result[1].turn.eid)))
|
||||
{
|
||||
if (!node_based_graph.GetEdgeData(via_edge).IsCompatibleTo(
|
||||
node_based_graph.GetEdgeData(potential_result[1].turn.eid)))
|
||||
std::cout << "Got Further Down the road." << std::endl;
|
||||
|
||||
node_at_intersection = node_based_graph.GetTarget(incoming_edge);
|
||||
incoming_edge = potential_result[1].turn.eid;
|
||||
potential_result = GetConnectedRoads(node_at_intersection, incoming_edge);
|
||||
}
|
||||
|
||||
// return output if requested
|
||||
if (resulting_from_node)
|
||||
*resulting_from_node = node_at_intersection;
|
||||
if (resulting_via_edge)
|
||||
*resulting_via_edge = incoming_edge;
|
||||
|
||||
return potential_result;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
Loading…
Reference in New Issue
Block a user