Skip to content

Commit

Permalink
revert #4443, use initial_bearing to sort intersection ways
Browse files Browse the repository at this point in the history
  • Loading branch information
karenzshea committed Nov 29, 2017
1 parent 02a2d25 commit f566f8a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 75 deletions.
6 changes: 5 additions & 1 deletion include/extractor/guidance/intersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct IntersectionShapeData
EdgeID eid;
double bearing;
double segment_length;
double initial_bearing;
};

inline auto makeCompareShapeDataByBearing(const double base_bearing)
Expand Down Expand Up @@ -81,6 +82,7 @@ struct IntersectionViewData : IntersectionShapeData
double angle;

bool CompareByAngle(const IntersectionViewData &other) const;
bool CompareByInitBearing(const IntersectionViewData &other) const;
};

// A Connected Road is the internal representation of a potential turn. Internally, we require
Expand Down Expand Up @@ -117,6 +119,7 @@ struct ConnectedRoad final : IntersectionViewData

// used to sort the set of connected roads (we require sorting throughout turn handling)
bool compareByAngle(const ConnectedRoad &other) const;
bool CompareByInitBearing(const ConnectedRoad &other) const;

// make a left turn into an equivalent right turn and vice versa
void mirror();
Expand Down Expand Up @@ -204,10 +207,11 @@ template <typename Self> struct EnableIntersectionOps
*/
auto valid() const
{
return true;
if (self()->empty())
return false;

auto comp = [](const auto &lhs, const auto &rhs) { return lhs.CompareByAngle(rhs); };
auto comp = [](const auto &lhs, const auto &rhs) { return lhs.CompareByInitBearing(rhs); };

const auto ordered = std::is_sorted(self()->begin(), self()->end(), comp);

Expand Down
10 changes: 10 additions & 0 deletions src/extractor/guidance/intersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ namespace extractor
namespace guidance
{

bool IntersectionViewData::CompareByInitBearing(const IntersectionViewData &other) const
{
return initial_bearing > other.initial_bearing;
}

bool ConnectedRoad::CompareByInitBearing(const ConnectedRoad &other) const
{
return initial_bearing > other.initial_bearing;
}

bool IntersectionViewData::CompareByAngle(const IntersectionViewData &other) const
{
return angle < other.angle;
Expand Down
93 changes: 19 additions & 74 deletions src/extractor/guidance/intersection_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,12 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
const boost::optional<NodeID> sorting_base,
const bool use_low_precision_angles) const
{
IntersectionShape intersection;
// reserve enough items (+ the possibly missing u-turn edge)
const auto intersection_degree = node_based_graph.GetOutDegree(node_at_center_of_intersection);
intersection.reserve(intersection_degree);
const util::Coordinate turn_coordinate = coordinates[node_at_center_of_intersection];

// compute bearings in a relatively small circle to prevent wrong roads order with true bearings
struct RoadWithInitialBearing
{
double bearing;
IntersectionShapeData road;
};
std::vector<RoadWithInitialBearing> initial_roads_ordering;
// reserve enough items (+ the possibly missing u-turn edge)
initial_roads_ordering.reserve(intersection_degree);

// number of lanes at the intersection changes how far we look down the road
const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection);
const auto max_lanes_intersection =
Expand Down Expand Up @@ -136,79 +129,31 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
BOOST_ASSERT(std::abs(bearing) <= 0.1);
}

initial_roads_ordering.push_back(
{initial_bearing, {edge_connected_to_intersection, bearing, segment_length}});
intersection.push_back({edge_connected_to_intersection, bearing, segment_length, initial_bearing});
}

if (!initial_roads_ordering.empty())
if (!intersection.empty())
{
const auto base_initial_bearing = [&]() {
const auto base_bearing = [&]() {
if (sorting_base)
{
const auto itr = std::find_if(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
[&](const auto &data) {
return node_based_graph.GetTarget(
data.road.eid) == *sorting_base;
});
if (itr != initial_roads_ordering.end())
const auto itr =
std::find_if(intersection.begin(),
intersection.end(),
[&](const IntersectionShapeData &data) {
return node_based_graph.GetTarget(data.eid) == *sorting_base;
});
if (itr != intersection.end())
return util::bearing::reverse(itr->bearing);
}
return util::bearing::reverse(initial_roads_ordering.begin()->bearing);
return util::bearing::reverse(intersection.begin()->bearing);
}();

// sort roads with respect to the initial bearings, a tie-breaker for equal initial bearings
// is to order roads via final bearings to have roads in clockwise order
//
// rhs <---. lhs <----.
// / /
// lhs / rhs /
//
// lhs road is before rhs one rhs road is before lhs one
// bearing::angleBetween < 180 bearing::angleBetween > 180
const auto initial_bearing_order = makeCompareShapeDataAngleToBearing(base_initial_bearing);
std::sort(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
[&initial_bearing_order](const auto &lhs, const auto &rhs) {
return initial_bearing_order(lhs, rhs) ||
(lhs.bearing == rhs.bearing &&
util::bearing::angleBetween(lhs.road.bearing, rhs.road.bearing) <
180);
});

// copy intersection data in the initial order
IntersectionShape intersection;
intersection.reserve(initial_roads_ordering.size());
std::transform(initial_roads_ordering.begin(),
initial_roads_ordering.end(),
std::back_inserter(intersection),
[](const auto &entry) { return entry.road; });

if (intersection.size() > 2)
{ // Check bearings ordering with respect to true bearings
const auto base_bearing = intersection.front().bearing;
const auto bearings_order =
makeCompareShapeDataAngleToBearing(util::bearing::reverse(base_bearing));
for (auto curr = intersection.begin(), next = std::next(curr);
next != intersection.end();
++curr, ++next)
{
if (bearings_order(*next, *curr))
{ // If the true bearing is out of the initial order (next before current) then
// adjust the next bearing to keep the order. The adjustment angle is at most
// 0.5° or a half-angle between the current bearing and the base bearing.
// to prevent overlapping over base bearing + 360°.
const auto angle_adjustment = std::min(
.5, util::restrictAngleToValidRange(base_bearing - curr->bearing) / 2.);
next->bearing =
util::restrictAngleToValidRange(curr->bearing + angle_adjustment);
}
}
}
return intersection;
std::sort(intersection.begin(),
intersection.end(),
makeCompareShapeDataAngleToBearing(base_bearing));
}

return IntersectionShape{};
return intersection;
}

// a
Expand Down Expand Up @@ -456,7 +401,7 @@ IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
}
std::sort(std::begin(intersection_view),
std::end(intersection_view),
std::mem_fn(&IntersectionViewData::CompareByAngle));
std::mem_fn(&IntersectionViewData::CompareByInitBearing));

// Move entering_via_edge to intersection front and place all roads prior entering_via_edge
// at the end of the intersection view with 360° angle
Expand Down
1 change: 1 addition & 0 deletions src/extractor/guidance/turn_analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection,
return intersection;
}

// Unused?
const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const
{
return intersection_generator;
Expand Down

0 comments on commit f566f8a

Please # to comment.