Daniel J. Hofmann 2016-09-22 16:42:38 +02:00 committed by Daniel J. H
parent f33180f092
commit c1651ccb12
9 changed files with 191 additions and 71 deletions

View File

@ -35,11 +35,11 @@ Feature: Car - Guidance - Bridges and Tunnels
| dce | primary | | Nebenstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
| e | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn right,arrive |
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,arrive |
| e | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßenbrücke,Hauptstraße | depart,turn right,arrive |
Scenario: Bridge with Immediate Turn Front and Back
Given the node map
@ -57,15 +57,15 @@ Feature: Car - Guidance - Bridges and Tunnels
| gaf | primary | | Anderestraße |
When I route I should get
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road right,arrive |
| e | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,end of road right,arrive |
| e | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,end of road left,arrive |
| d | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,end of road right,arrive |
| d | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,end of road left,arrive |
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,turn left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,turn right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,turn left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,turn right,arrive |
| e | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,turn right,arrive |
| e | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn left,turn left,arrive |
| d | f | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,turn right,arrive |
| d | g | Nebenstraße,Hauptstraßenbrücke,Anderestraße,Anderestraße | depart,turn right,turn left,arrive |
Scenario: Simple Tunnel
Given the node map
@ -98,11 +98,11 @@ Feature: Car - Guidance - Bridges and Tunnels
| dce | primary | | Nebenstraße |
When I route I should get
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,end of road right,arrive |
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
| from | to | route | turns |
| a | d | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,arrive |
| a | e | Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,arrive |
| e | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn left,arrive |
| d | a | Nebenstraße,Hauptstraßentunnel,Hauptstraße | depart,turn right,arrive |
Scenario: Tunnel with Immediate Turn Front and Back
Given the node map
@ -120,13 +120,13 @@ Feature: Car - Guidance - Bridges and Tunnels
| gaf | primary | | Anderestraße |
When I route I should get
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,end of road right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,end of road right,arrive |
| e | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,end of road right,arrive |
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,end of road left,arrive |
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,end of road right,arrive |
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,end of road left,arrive |
| from | to | route | turns |
| f | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,turn left,arrive |
| f | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn left,turn right,arrive |
| g | d | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,turn left,arrive |
| g | e | Anderestraße,Hauptstraße,Nebenstraße,Nebenstraße | depart,turn right,turn right,arrive |
| e | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,turn right,arrive |
| e | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn left,turn left,arrive |
| d | f | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn right,arrive |
| d | g | Nebenstraße,Hauptstraßentunnel,Anderestraße,Anderestraße | depart,turn right,turn left,arrive |

View File

@ -94,9 +94,9 @@ Feature: Suppress New Names on dedicated Suffices
| bd | 42 E |
When I route I should get
| waypoints | route | turns |
| a,c | 42 N,42 S | depart,arrive |
| a,d | 42 N,42 E,42 E | depart,turn right,arrive |
| waypoints | route | turns |
| a,c | 42 N,42 S | depart,arrive |
| a,d | 42 N,42 E,42 E | depart,continue right,arrive |
Scenario: Suffix To No Suffix
Given the node map

View File

@ -6,6 +6,7 @@
#include "extractor/guidance/intersection.hpp"
#include "extractor/query_node.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/suffix_table.hpp"
#include "util/attributes.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
@ -32,7 +33,9 @@ class IntersectionGenerator
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<QueryNode> &node_info_list,
const CompressedEdgeContainer &compressed_edge_container);
const CompressedEdgeContainer &compressed_edge_container,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
Intersection operator()(const NodeID nid, const EdgeID via_eid) const;
@ -64,6 +67,8 @@ class IntersectionGenerator
const std::unordered_set<NodeID> &barrier_nodes;
const std::vector<QueryNode> &node_info_list;
const CoordinateExtractor coordinate_extractor;
const util::NameTable &name_table;
const SuffixTable &street_name_suffix_table;
// check if two indices in an intersection can be seen as a single road in the perceived
// intersection representation. See below for an example. Utility function for

View File

@ -2,6 +2,8 @@
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp"
#include <algorithm>
#include <functional>
#include <iomanip>
@ -24,10 +26,13 @@ IntersectionGenerator::IntersectionGenerator(
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<QueryNode> &node_info_list,
const CompressedEdgeContainer &compressed_edge_container)
const CompressedEdgeContainer &compressed_edge_container,
const util::NameTable &name_table_,
const SuffixTable &street_name_suffix_table_)
: node_based_graph(node_based_graph), restriction_map(restriction_map),
barrier_nodes(barrier_nodes), node_info_list(node_info_list),
coordinate_extractor(node_based_graph, compressed_edge_container, node_info_list)
coordinate_extractor(node_based_graph, compressed_edge_container, node_info_list),
name_table(name_table_), street_name_suffix_table(street_name_suffix_table_)
{
}
@ -223,7 +228,12 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
return false;
// need to be same name
if (first_data.name_id != second_data.name_id)
if (second_data.name_id != EMPTY_NAMEID &&
util::guidance::requiresNameAnnounced(name_table.GetNameForID(first_data.name_id),
name_table.GetRefForID(first_data.name_id),
name_table.GetNameForID(second_data.name_id),
name_table.GetRefForID(second_data.name_id),
street_name_suffix_table))
return false;
// compatibility is required
@ -328,7 +338,14 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection,
}();
// needs to be same road coming in
if (node_based_graph.GetEdgeData(intersection[third_index].eid).name_id != first_data.name_id)
const auto &third_data = node_based_graph.GetEdgeData(intersection[third_index].eid);
if (third_data.name_id != EMPTY_NAMEID &&
util::guidance::requiresNameAnnounced(name_table.GetNameForID(third_data.name_id),
name_table.GetRefForID(third_data.name_id),
name_table.GetNameForID(first_data.name_id),
name_table.GetRefForID(first_data.name_id),
street_name_suffix_table))
return false;
// we only allow collapsing of a Y like fork. So the angle to the third index has to be
@ -491,7 +508,7 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti
intersection[0].entry_allowed = false;
}
// a merge including the first u-turn requres an adjustment of the turn angles
// a merge including the first u-turn requires an adjustment of the turn angles
// therefore these are handled prior to this step
for (std::size_t index = 2; index < intersection.size(); ++index)
{

View File

@ -59,7 +59,14 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
if (!on_ramp && onto_ramp)
return TurnType::OnRamp;
if (in_data.name_id == out_data.name_id && in_data.name_id != EMPTY_NAMEID)
const auto same_name =
!util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(out_data.name_id),
name_table.GetRefForID(out_data.name_id),
street_name_suffix_table);
if (in_data.name_id != EMPTY_NAMEID && out_data.name_id != EMPTY_NAMEID && same_name)
{
return TurnType::Continue;
}
@ -89,8 +96,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
if (in_data.name_id != out_data.name_id &&
util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
if (util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(out_data.name_id),
name_table.GetRefForID(out_data.name_id),
@ -340,11 +347,11 @@ void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid,
bool IntersectionHandler::isThroughStreet(const std::size_t index,
const Intersection &intersection) const
{
if (node_based_graph.GetEdgeData(intersection[index].eid).name_id == EMPTY_NAMEID)
return false;
const auto &data_at_index = node_based_graph.GetEdgeData(intersection[index].eid);
if (data_at_index.name_id == EMPTY_NAMEID)
return false;
// a through street cannot start at our own position -> index 1
for (std::size_t road_index = 1; road_index < intersection.size(); ++road_index)
{
@ -358,7 +365,14 @@ bool IntersectionHandler::isThroughStreet(const std::size_t index,
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);
const bool have_same_name = data_at_index.name_id == road_data.name_id;
const bool have_same_name =
road_data.name_id != EMPTY_NAMEID &&
!util::guidance::requiresNameAnnounced(name_table.GetNameForID(data_at_index.name_id),
name_table.GetRefForID(data_at_index.name_id),
name_table.GetNameForID(road_data.name_id),
name_table.GetRefForID(road_data.name_id),
street_name_suffix_table);
const bool have_same_category =
data_at_index.road_classification == road_data.road_classification;
@ -399,14 +413,20 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
const auto continue_class =
node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification;
if (out_data.name_id == in_data.name_id &&
(best_continue == 0 ||
(continue_class.GetPriority() > out_data.road_classification.GetPriority() &&
in_classification != continue_class) ||
(deviation < best_continue_deviation &&
out_data.road_classification == continue_class) ||
(continue_class != in_classification &&
out_data.road_classification == continue_class)))
const auto same_name =
!util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(out_data.name_id),
name_table.GetRefForID(out_data.name_id),
street_name_suffix_table);
if (same_name && (best_continue == 0 || (continue_class.GetPriority() >
out_data.road_classification.GetPriority() &&
in_classification != continue_class) ||
(deviation < best_continue_deviation &&
out_data.road_classification == continue_class) ||
(continue_class != in_classification &&
out_data.road_classification == continue_class)))
{
best_continue_deviation = deviation;
best_continue = i;
@ -453,7 +473,16 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
for (std::size_t i = 1; i < intersection.size(); ++i)
{
const auto &road = intersection[i];
if ((in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id))
const auto &road_data = node_based_graph.GetEdgeData(road.eid);
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(road_data.name_id),
name_table.GetRefForID(road_data.name_id),
street_name_suffix_table);
if (same_name)
{
++count;
if (road.entry_allowed)
@ -481,7 +510,15 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
return std::count_if(
intersection.begin() + 1, intersection.end(), [&](const ConnectedRoad &road) {
return (in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id) &&
const auto &road_data = node_based_graph.GetEdgeData(road.eid);
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(road_data.name_id),
name_table.GetRefForID(road_data.name_id),
street_name_suffix_table);
return same_name &&
angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE;
}) == num_continue_names.first;
}();
@ -687,8 +724,14 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
c
*/
if (turn_data.name_id == continue_data.name_id &&
deviation_ratio < 1.5 * DISTINCTION_RATIO)
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(turn_data.name_id),
name_table.GetRefForID(turn_data.name_id),
name_table.GetNameForID(continue_data.name_id),
name_table.GetRefForID(continue_data.name_id),
street_name_suffix_table);
if (same_name && deviation_ratio < 1.5 * DISTINCTION_RATIO)
return 0;
}

View File

@ -120,8 +120,17 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (const auto &road : intersection)
{
const auto &out_data = node_based_graph.GetEdgeData(road.eid);
if (road.angle != 0 && in_data.name_id == out_data.name_id &&
in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.eid, node_based_graph))
const auto same_name =
!util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(out_data.name_id),
name_table.GetRefForID(out_data.name_id),
street_name_suffix_table);
if (road.angle != 0 && in_data.name_id != EMPTY_NAMEID &&
out_data.name_id != EMPTY_NAMEID && same_name &&
isMotorwayClass(road.eid, node_based_graph))
return road.angle;
}
return intersection[0].angle;
@ -352,6 +361,17 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
}
else if (intersection.size() == 3)
{
const auto &second_intersection_data =
node_based_graph.GetEdgeData(intersection[2].eid);
const auto &first_intersection_data =
node_based_graph.GetEdgeData(intersection[1].eid);
const auto first_second_same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(second_intersection_data.name_id),
name_table.GetRefForID(second_intersection_data.name_id),
name_table.GetNameForID(first_intersection_data.name_id),
name_table.GetRefForID(first_intersection_data.name_id),
street_name_suffix_table);
// merging onto a passing highway / or two ramps merging onto the same highway
if (num_valid_turns == 1)
{
@ -367,9 +387,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
if (intersection[1].entry_allowed)
{
if (isMotorwayClass(intersection[1].eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id != EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].eid).name_id)
second_intersection_data.name_id != EMPTY_NAMEID &&
first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name)
{
// circular order indicates a merge to the left (0-3 onto 4
if (angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) <
@ -393,9 +412,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
{
BOOST_ASSERT(intersection[2].entry_allowed);
if (isMotorwayClass(intersection[2].eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[1].eid).name_id != EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].eid).name_id ==
node_based_graph.GetEdgeData(intersection[1].eid).name_id)
second_intersection_data.name_id != EMPTY_NAMEID &&
first_intersection_data.name_id != EMPTY_NAMEID && first_second_same_name)
{
// circular order (5-0) onto 4
if (angularDeviation(intersection[2].angle, STRAIGHT_ANGLE) <

View File

@ -152,9 +152,17 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto check_valid = [this, source_edge_data](const ConnectedRoad &road) {
const auto road_edge_data = node_based_graph.GetEdgeData(road.eid);
// Test to see if the source edge and the one we're looking at are the same road
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(road_edge_data.name_id),
name_table.GetRefForID(road_edge_data.name_id),
name_table.GetNameForID(source_edge_data.name_id),
name_table.GetRefForID(source_edge_data.name_id),
street_name_suffix_table);
return road_edge_data.road_classification == source_edge_data.road_classification &&
road_edge_data.name_id != EMPTY_NAMEID &&
road_edge_data.name_id == source_edge_data.name_id && road.entry_allowed;
road_edge_data.name_id != EMPTY_NAMEID && source_edge_data.name_id != EMPTY_NAMEID &&
same_name && road.entry_allowed;
};
if (!check_valid(next_road))
@ -215,8 +223,17 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
std::find_if(target_intersection.begin() + 1,
target_intersection.end(),
[this, &link_data](const ConnectedRoad &road) {
return node_based_graph.GetEdgeData(road.eid).name_id ==
link_data.name_id;
const auto &road_edge_data =
node_based_graph.GetEdgeData(road.eid);
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(road_edge_data.name_id),
name_table.GetRefForID(road_edge_data.name_id),
name_table.GetNameForID(link_data.name_id),
name_table.GetRefForID(link_data.name_id),
street_name_suffix_table);
return same_name;
});
// if the sliproad candidate is a through street, we cannot handle it as a sliproad
@ -254,7 +271,15 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
if (next_road.instruction.type == TurnType::Fork)
{
const auto &next_data = node_based_graph.GetEdgeData(next_road.eid);
if (next_data.name_id == source_edge_data.name_id)
const auto same_name = !util::guidance::requiresNameAnnounced(
name_table.GetNameForID(next_data.name_id),
name_table.GetRefForID(next_data.name_id),
name_table.GetNameForID(source_edge_data.name_id),
name_table.GetRefForID(source_edge_data.name_id),
street_name_suffix_table);
if (same_name)
{
if (angularDeviation(next_road.angle, STRAIGHT_ANGLE) < 5)
intersection[obvious_turn_index].instruction.type = TurnType::Suppressed;

View File

@ -43,7 +43,9 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
restriction_map,
barrier_nodes,
node_info_list,
compressed_edge_container),
compressed_edge_container,
name_table,
street_name_suffix_table),
roundabout_handler(node_based_graph,
node_info_list,
compressed_edge_container,

View File

@ -5,6 +5,7 @@
#include "util/guidance/toolkit.hpp"
#include <algorithm>
#include <limits>
#include <utility>
@ -109,8 +110,17 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
const bool turn_is_perfectly_straight =
angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon();
const auto &road_data = node_based_graph.GetEdgeData(road.eid);
const auto same_name =
!util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
name_table.GetRefForID(in_data.name_id),
name_table.GetNameForID(road_data.name_id),
name_table.GetRefForID(road_data.name_id),
street_name_suffix_table);
if (turn_is_perfectly_straight && in_data.name_id != EMPTY_NAMEID &&
in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id)
road_data.name_id != EMPTY_NAMEID && same_name)
return true;
const bool is_much_narrower_than_other =