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