Lane Handling for multiple indications per lane as in left;left|, fixes #2694
Before we asserted on unique lane indications per lane. Turns out the OSM data contains lane strings such as: left;left|right Which represents two lanes as in: << > || | The two left indications _on a single lane_ look like data issue. And we can't represent this with our enum-approach at the moment. We don't want to crash there, so silently swallow this and generate a single left|right for it.
This commit is contained in:
parent
261dbf3edd
commit
fd6bb5ec1f
@ -736,4 +736,18 @@ Feature: Turn Lane Guidance
|
|||||||
| x,d | road,road | depart,arrive | , |
|
| x,d | road,road | depart,arrive | , |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Lane Parsing Issue #2694
|
||||||
|
Given the node map
|
||||||
|
| | c |
|
||||||
|
| a | b |
|
||||||
|
| | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | turn:lanes:forward |
|
||||||
|
| ab | primary | left;left\|right |
|
||||||
|
| bc | primary | |
|
||||||
|
| bd | primary | |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | route | turns | lanes |
|
||||||
|
| a,c | ab,bc,bc | depart,turn left,arrive | ,left:true right:false, |
|
||||||
|
@ -193,7 +193,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
for (auto token_itr = inner_tokens.begin(); token_itr != inner_tokens.end();
|
for (auto token_itr = inner_tokens.begin(); token_itr != inner_tokens.end();
|
||||||
++token_itr)
|
++token_itr)
|
||||||
{
|
{
|
||||||
auto position = std::find(osm_lane_strings, osm_lane_strings + num_osm_tags, *token_itr);
|
auto position =
|
||||||
|
std::find(osm_lane_strings, osm_lane_strings + num_osm_tags, *token_itr);
|
||||||
const auto translated_mask =
|
const auto translated_mask =
|
||||||
masks_by_osm_string[std::distance(osm_lane_strings, position)];
|
masks_by_osm_string[std::distance(osm_lane_strings, position)];
|
||||||
if (translated_mask == TurnLaneType::empty)
|
if (translated_mask == TurnLaneType::empty)
|
||||||
@ -203,7 +204,10 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
<< *token_itr << "\"";
|
<< *token_itr << "\"";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
BOOST_ASSERT((lane_mask & translated_mask) == 0); // make sure the mask is valid
|
|
||||||
|
// In case of multiple times the same lane indicators withn a lane, as in
|
||||||
|
// "left;left|.." or-ing the masks generates a single "left" enum.
|
||||||
|
// Which is fine since this is data issue and we can't represent it anyway.
|
||||||
lane_mask |= translated_mask;
|
lane_mask |= translated_mask;
|
||||||
}
|
}
|
||||||
// add the lane to the description
|
// add the lane to the description
|
||||||
@ -265,8 +269,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
// name_offsets already has an offset of a new name, take the offset index as the name id
|
// name_offsets already has an offset of a new name, take the offset index as the name id
|
||||||
name_id = external_memory.name_offsets.size() - 1;
|
name_id = external_memory.name_offsets.size() - 1;
|
||||||
|
|
||||||
external_memory.name_char_data.reserve(external_memory.name_char_data.size() + name_length
|
external_memory.name_char_data.reserve(external_memory.name_char_data.size() + name_length +
|
||||||
+ destinations_length + pronunciation_length);
|
destinations_length + pronunciation_length);
|
||||||
|
|
||||||
std::copy(parsed_way.name.c_str(),
|
std::copy(parsed_way.name.c_str(),
|
||||||
parsed_way.name.c_str() + name_length,
|
parsed_way.name.c_str() + name_length,
|
||||||
@ -306,7 +310,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
std::transform(input_way.nodes().begin(),
|
std::transform(input_way.nodes().begin(),
|
||||||
input_way.nodes().end(),
|
input_way.nodes().end(),
|
||||||
std::back_inserter(external_memory.used_node_id_list),
|
std::back_inserter(external_memory.used_node_id_list),
|
||||||
[](const osmium::NodeRef &ref) { return OSMNodeID{static_cast<std::uint64_t>(ref.ref())}; });
|
[](const osmium::NodeRef &ref) {
|
||||||
|
return OSMNodeID{static_cast<std::uint64_t>(ref.ref())};
|
||||||
|
});
|
||||||
|
|
||||||
const bool is_opposite_way = TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode;
|
const bool is_opposite_way = TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode;
|
||||||
|
|
||||||
@ -338,7 +344,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
external_memory.way_start_end_id_list.push_back(
|
external_memory.way_start_end_id_list.push_back(
|
||||||
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
OSMNodeID{
|
||||||
|
static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
||||||
}
|
}
|
||||||
@ -372,8 +379,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
input_way.nodes().cbegin(),
|
input_way.nodes().cbegin(),
|
||||||
input_way.nodes().cend(),
|
input_way.nodes().cend(),
|
||||||
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
|
[&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) {
|
||||||
external_memory.all_edges_list.push_back(
|
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
||||||
InternalExtractorEdge(OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(first_node.ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
OSMNodeID{static_cast<std::uint64_t>(last_node.ref())},
|
||||||
name_id,
|
name_id,
|
||||||
backward_weight_data,
|
backward_weight_data,
|
||||||
@ -392,7 +399,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
|||||||
external_memory.way_start_end_id_list.push_back(
|
external_memory.way_start_end_id_list.push_back(
|
||||||
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
{OSMWayID{static_cast<std::uint32_t>(input_way.id())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes().back().ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
OSMNodeID{
|
||||||
|
static_cast<std::uint64_t>(input_way.nodes()[input_way.nodes().size() - 2].ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[1].ref())},
|
||||||
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
OSMNodeID{static_cast<std::uint64_t>(input_way.nodes()[0].ref())}});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user