Skip to content

Commit

Permalink
Refactor isThroughStreet/Intersection options (#4751)
Browse files Browse the repository at this point in the history
* refactor isThroughStreet 
* refactor HaveIdenticalName
* fix a typo in the unit tests
  • Loading branch information
ghoshkaj committed Jan 19, 2018
1 parent 341a534 commit 155772f
Show file tree
Hide file tree
Showing 18 changed files with 229 additions and 107 deletions.
27 changes: 27 additions & 0 deletions include/extractor/guidance/have_identical_names.hpp
@@ -0,0 +1,27 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
#define OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_

#include "extractor/guidance/constants.hpp"
#include "extractor/suffix_table.hpp"
#include "util/name_table.hpp"

namespace osrm
{
namespace extractor
{
namespace guidance
{

// check if two name ids can be seen as identical (in presence of refs/others)
// in our case this translates into no name announcement in either direction (lhs->rhs and
// rhs->lhs)
bool HaveIdenticalNames(const NameID lhs,
const NameID rhs,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);

} // namespace guidance
} // namespace extractor
} // namespace osrm

#endif /*OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_*/
5 changes: 3 additions & 2 deletions include/extractor/guidance/intersection.hpp
Expand Up @@ -293,10 +293,11 @@ struct IntersectionView final : std::vector<IntersectionViewData>, //
};

// `Intersection` is a relative view of an intersection by an incoming edge.
// `Intersection` are streets at an intersection ordered from from sharp right counter-clockwise to
// `Intersection` are streets at an intersection stored as an ordered list of connected roads
// ordered from sharp right counter-clockwise to
// sharp left where `intersection[0]` is _always_ a u-turn

// An intersection is an ordered list of connected roads ordered from from sharp right
// An intersection is an ordered list of connected roads ordered from sharp right
// counter-clockwise to sharp left where `intersection[0]` is always a u-turn
//
// |
Expand Down
3 changes: 0 additions & 3 deletions include/extractor/guidance/intersection_handler.hpp
Expand Up @@ -96,9 +96,6 @@ class IntersectionHandler
const std::size_t begin,
const std::size_t end) const;

// Checks the intersection for a through street connected to `intersection[index]`
bool isThroughStreet(const std::size_t index, const Intersection &intersection) const;

// See `getNextIntersection`
struct IntersectionViewAndNode final
{
Expand Down
63 changes: 63 additions & 0 deletions include/extractor/guidance/is_through_street.hpp
@@ -0,0 +1,63 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_
#define OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_

#include "extractor/guidance/constants.hpp"
#include "extractor/suffix_table.hpp"
#include "util/guidance/name_announcements.hpp"

using osrm::util::angularDeviation;

namespace osrm
{
namespace extractor
{
namespace guidance
{

template <typename IntersectionType>
inline bool isThroughStreet(const std::size_t index,
const IntersectionType &intersection,
const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
{

const auto &data_at_index = node_data_container.GetAnnotation(
node_based_graph.GetEdgeData(intersection[index].eid).annotation_data);

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)
{
if (road_index == index)
continue;

const auto &road = intersection[road_index];
const auto &road_data = node_data_container.GetAnnotation(
node_based_graph.GetEdgeData(road.eid).annotation_data);

// roads have a near straight angle (180 degree)
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);

const bool have_same_name = HaveIdenticalNames(
data_at_index.name_id, road_data.name_id, name_table, street_name_suffix_table);

const bool have_same_category =
node_based_graph.GetEdgeData(intersection[index].eid).flags.road_classification ==
node_based_graph.GetEdgeData(road.eid).flags.road_classification;

if (is_nearly_straight && have_same_name && have_same_category)
return true;
}
return false;
}

} // namespace guidance
} // namespace extractor
} // namespace osrm

#endif /*OSRM_EXTRACTOR_GUIDANCE_IS_THROUGH_STREET_HPP_*/
6 changes: 1 addition & 5 deletions include/extractor/guidance/mergable_road_detector.hpp
Expand Up @@ -3,6 +3,7 @@

#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/have_identical_names.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/restriction_index.hpp"
Expand Down Expand Up @@ -78,11 +79,6 @@ class MergableRoadDetector
bool IsDistinctFrom(const MergableRoadData &lhs, const MergableRoadData &rhs) const;

private:
// check if two name ids can be seen as identical (in presence of refs/others)
// in our case this translates into no name announcement in either direction (lhs->rhs and
// rhs->lhs)
bool HaveIdenticalNames(const NameID lhs, const NameID rhs) const;

// When it comes to merging roads, we need to find out if two ways actually represent the
// same road. This check tries to identify roads which are the same road in opposite directions
bool EdgeDataSupportsMerge(const NodeBasedEdgeClassification &lhs_flags,
Expand Down
1 change: 1 addition & 0 deletions include/extractor/guidance/motorway_handler.hpp
Expand Up @@ -3,6 +3,7 @@

#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/is_through_street.hpp"
#include "extractor/query_node.hpp"

#include "util/attributes.hpp"
Expand Down
1 change: 1 addition & 0 deletions include/extractor/guidance/roundabout_handler.hpp
Expand Up @@ -5,6 +5,7 @@
#include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/is_through_street.hpp"
#include "extractor/guidance/roundabout_type.hpp"
#include "extractor/query_node.hpp"

Expand Down
4 changes: 1 addition & 3 deletions include/extractor/guidance/sliproad_handler.hpp
Expand Up @@ -3,6 +3,7 @@

#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/is_through_street.hpp"
#include "extractor/query_node.hpp"

#include "util/name_table.hpp"
Expand Down Expand Up @@ -53,9 +54,6 @@ class SliproadHandler final : public IntersectionHandler
// Next intersection from `start` onto `onto` is too far away for a Siproad scenario
bool nextIntersectionIsTooFarAway(const NodeID start, const EdgeID onto) const;

// Through street: does a road continue with from's name at the intersection
bool isThroughStreet(const EdgeID from, const IntersectionView &intersection) const;

// Does the road from `current` to `next` continue
bool roadContinues(const EdgeID current, const EdgeID next) const;

Expand Down
1 change: 1 addition & 0 deletions include/extractor/guidance/turn_handler.hpp
Expand Up @@ -3,6 +3,7 @@

#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/is_through_street.hpp"
#include "extractor/query_node.hpp"

#include "util/attributes.hpp"
Expand Down
33 changes: 33 additions & 0 deletions src/extractor/guidance/have_identical_names.cpp
@@ -0,0 +1,33 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_
#define OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_

#include "util/guidance/name_announcements.hpp"

namespace osrm
{
namespace extractor
{
namespace guidance
{

// check if two name ids can be seen as identical (in presence of refs/others)
// in our case this translates into no name announcement in either direction (lhs->rhs and
// rhs->lhs)
bool HaveIdenticalNames(const NameID lhs,
const NameID rhs,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
{
const auto non_empty = (lhs != EMPTY_NAMEID) && (rhs != EMPTY_NAMEID);

// symmetrical check for announcements
return non_empty &&
!util::guidance::requiresNameAnnounced(lhs, rhs, name_table, street_name_suffix_table) &&
!util::guidance::requiresNameAnnounced(rhs, lhs, name_table, street_name_suffix_table);
}

} // namespace guidance
} // namespace extractor
} // namespace osrm

#endif /*OSRM_EXTRACTOR_GUIDANCE_HAVE_IDENTICAL_NAMES_HPP_*/
38 changes: 0 additions & 38 deletions src/extractor/guidance/intersection_handler.cpp
Expand Up @@ -418,44 +418,6 @@ void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid,
}
}

bool IntersectionHandler::isThroughStreet(const std::size_t index,
const Intersection &intersection) const
{
const auto &data_at_index = node_data_container.GetAnnotation(
node_based_graph.GetEdgeData(intersection[index].eid).annotation_data);

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)
{
if (road_index == index)
continue;

const auto &road = intersection[road_index];
const auto &road_data = node_data_container.GetAnnotation(
node_based_graph.GetEdgeData(road.eid).annotation_data);

// roads have a near straight angle (180 degree)
const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) >
(STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE);

const bool have_same_name =
road_data.name_id != EMPTY_NAMEID &&
!util::guidance::requiresNameAnnounced(
data_at_index.name_id, road_data.name_id, name_table, street_name_suffix_table);

const bool have_same_category =
node_based_graph.GetEdgeData(intersection[index].eid).flags.road_classification ==
node_based_graph.GetEdgeData(road.eid).flags.road_classification;

if (is_nearly_straight && have_same_name && have_same_category)
return true;
}
return false;
}

boost::optional<IntersectionHandler::IntersectionViewAndNode>
IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) const
{
Expand Down
17 changes: 5 additions & 12 deletions src/extractor/guidance/mergable_road_detector.cpp
Expand Up @@ -122,16 +122,6 @@ bool MergableRoadDetector::CanMergeRoad(const NodeID intersection_node,
!IsCircularShape(intersection_node, lhs, rhs);
}

bool MergableRoadDetector::HaveIdenticalNames(const NameID lhs, const NameID rhs) const
{
const auto non_empty = (lhs != EMPTY_NAMEID) && (rhs != EMPTY_NAMEID);

// symmetrical check for announcements
return non_empty &&
!util::guidance::requiresNameAnnounced(lhs, rhs, name_table, street_name_suffix_table) &&
!util::guidance::requiresNameAnnounced(rhs, lhs, name_table, street_name_suffix_table);
}

bool MergableRoadDetector::IsDistinctFrom(const MergableRoadData &lhs,
const MergableRoadData &rhs) const
{
Expand All @@ -143,7 +133,9 @@ bool MergableRoadDetector::IsDistinctFrom(const MergableRoadData &lhs,
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(lhs.eid).annotation_data)
.name_id,
node_data_container.GetAnnotation(node_based_graph.GetEdgeData(rhs.eid).annotation_data)
.name_id);
.name_id,
name_table,
street_name_suffix_table);
}

bool MergableRoadDetector::EdgeDataSupportsMerge(
Expand All @@ -165,7 +157,8 @@ bool MergableRoadDetector::EdgeDataSupportsMerge(
return false;

// we require valid names
if (!HaveIdenticalNames(lhs_annotation.name_id, rhs_annotation.name_id))
if (!HaveIdenticalNames(
lhs_annotation.name_id, rhs_annotation.name_id, name_table, street_name_suffix_table))
return false;

return lhs_flags.road_classification == rhs_flags.road_classification;
Expand Down
45 changes: 38 additions & 7 deletions src/extractor/guidance/motorway_handler.cpp
Expand Up @@ -239,7 +239,12 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1, intersection),
isThroughStreet(1,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
intersection[1]);
}
else
Expand All @@ -253,8 +258,16 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in

if (road.angle == continue_angle)
{
road.instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(1, intersection), road);
road.instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
road);
}
else if (road.angle < continue_angle)
{
Expand Down Expand Up @@ -353,8 +366,16 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
BOOST_ASSERT(!intersection[0].entry_allowed);
BOOST_ASSERT(isMotorwayClass(intersection[1].eid, node_based_graph));

intersection[1].instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
intersection[1]);
}
else if (intersection.size() == 3)
{
Expand Down Expand Up @@ -404,7 +425,12 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
intersection[1].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(1, intersection),
isThroughStreet(1,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
intersection[1]);
}
}
Expand All @@ -429,7 +455,12 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
intersection[2].instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(2, intersection),
isThroughStreet(2,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
intersection[2]);
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/extractor/guidance/roundabout_handler.cpp
Expand Up @@ -478,8 +478,16 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
if (util::angularDeviation(turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE &&
crossing_roundabout)
{
turn.instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(idx, intersection), turn);
turn.instruction =
getInstructionForObvious(intersection.size(),
via_eid,
isThroughStreet(idx,
intersection,
node_based_graph,
node_data_container,
name_table,
street_name_suffix_table),
turn);
}
else
{
Expand Down

0 comments on commit 155772f

Please sign in to comment.