Skip to content

Commit

Permalink
Merge IntersectionShapeData and IntersectionEdgeGeometry
Browse files Browse the repository at this point in the history
  • Loading branch information
oxidase committed Mar 2, 2018
1 parent 023f6dc commit 38c567b
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 103 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
- Bugfixes:
- fix deduplication of route steps when waypoints are used [#4909](https://github.com/Project-OSRM/osrm-backend/issues/4909)
- FIXED #4920: Use smaller range for U-turn angles in map-matching [#4920](https://github.com/Project-OSRM/osrm-backend/pull/4920)
- Profile:
- CHANGED #4929: Handle oneways in get_forward_backward_by_key [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- Guidance:
- CHANGED #4929: Don't use obviousness for links bifurcations [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- FIXED #4929: Adjust Straight direction modifiers of side roads in driveway handler [#4929](https://github.com/Project-OSRM/osrm-backend/pull/4929)
- Tools:
- `osrm-routed` accepts a new property `--memory_file` to store memory in a file on disk.
- NodeJS:
Expand Down
11 changes: 8 additions & 3 deletions include/extractor/intersection/intersection_edge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,19 @@ struct IntersectionEdge

using IntersectionEdges = std::vector<IntersectionEdge>;

// The extracted geometry of an intersection edge only knows about edge IDs and bearings
// Bearing is the direction in clockwise angle from true north after taking the turn:
// 0 = heading north, 90 = east, 180 = south, 270 = west
// `initial_bearing` is the original OSM edge bearing
// `perceived_bearing` is the edge bearing after line fitting and edges merging
struct IntersectionEdgeGeometry
{
EdgeID edge;
EdgeID eid;
double initial_bearing;
double perceived_bearing;
double length;
double segment_length;

bool operator<(const IntersectionEdgeGeometry &other) const { return edge < other.edge; }
bool operator<(const IntersectionEdgeGeometry &other) const { return eid < other.eid; }
};

using IntersectionEdgeGeometries = std::vector<IntersectionEdgeGeometry>;
Expand Down
57 changes: 22 additions & 35 deletions include/extractor/intersection/intersection_view.hpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,33 @@
#ifndef OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_
#define OSRM_EXTRACTOR_INTERSECTION_INTERSECTION_VIEW_HPP_

#include <algorithm>
#include <functional>
#include <limits>
#include <string>
#include <type_traits>
#include <vector>
#include "extractor/intersection/intersection_edge.hpp"

#include "guidance/turn_instruction.hpp"

#include "util/bearing.hpp"
#include "util/log.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // EdgeID

#include "guidance/turn_instruction.hpp"

#include <boost/range/algorithm/count_if.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/min_element.hpp>

#include <algorithm>
#include <functional>
#include <limits>
#include <string>
#include <type_traits>
#include <vector>

namespace osrm
{
namespace extractor
{
namespace intersection
{

// the shape of an intersection only knows about edge IDs and bearings
// `bearing` is the direction in clockwise angle from true north after taking the turn:
// 0 = heading north, 90 = east, 180 = south, 270 = west
struct IntersectionShapeData
{
EdgeID eid;
double bearing;
double segment_length;
};

inline auto makeCompareShapeDataByBearing(const double base_bearing)
{
return [base_bearing](const auto &lhs, const auto &rhs) {
return util::angularDeviation(lhs.bearing, base_bearing) <
util::angularDeviation(rhs.bearing, base_bearing);
};
}

inline auto makeCompareAngularDeviation(const double angle)
{
return [angle](const auto &lhs, const auto &rhs) {
Expand All @@ -60,12 +44,12 @@ inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_base

// When viewing an intersection from an incoming edge, we can transform a shape into a view which
// gives additional information on angles and whether a turn is allowed
struct IntersectionViewData : IntersectionShapeData
struct IntersectionViewData : IntersectionEdgeGeometry
{
IntersectionViewData(const IntersectionShapeData &shape,
IntersectionViewData(const IntersectionEdgeGeometry &geometry,
const bool entry_allowed,
const double angle)
: IntersectionShapeData(shape), entry_allowed(entry_allowed), angle(angle)
: IntersectionEdgeGeometry(geometry), entry_allowed(entry_allowed), angle(angle)
{
}

Expand All @@ -80,10 +64,13 @@ struct IntersectionViewData : IntersectionShapeData
template <typename Self> struct EnableShapeOps
{
// same as closest turn, but for bearings
auto FindClosestBearing(double bearing) const
auto FindClosestBearing(double base_bearing) const
{
auto comp = makeCompareShapeDataByBearing(bearing);
return std::min_element(self()->begin(), self()->end(), comp);
return std::min_element(
self()->begin(), self()->end(), [base_bearing](const auto &lhs, const auto &rhs) {
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
util::angularDeviation(rhs.perceived_bearing, base_bearing);
});
}

// search a given eid in the intersection
Expand Down Expand Up @@ -119,10 +106,10 @@ template <typename Self> struct EnableShapeOps
auto self() const { return static_cast<const Self *>(this); }
};

struct IntersectionShape final : std::vector<IntersectionShapeData>, //
EnableShapeOps<IntersectionShape> //
struct IntersectionShape final : std::vector<IntersectionEdgeGeometry>, //
EnableShapeOps<IntersectionShape> //
{
using Base = std::vector<IntersectionShapeData>;
using Base = std::vector<IntersectionEdgeGeometry>;
};

// Common operations shared among IntersectionView and Intersections.
Expand Down
2 changes: 1 addition & 1 deletion include/extractor/intersection/mergable_road_detector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MergableRoadDetector
{
public:
// in case we have to change the mode we are operating on
using MergableRoadData = IntersectionShapeData;
using MergableRoadData = IntersectionEdgeGeometry;

MergableRoadDetector(const util::NodeBasedDynamicGraph &node_based_graph,
const EdgeBasedNodeDataContainer &node_data_container,
Expand Down
2 changes: 1 addition & 1 deletion include/guidance/intersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ inline std::string toString(const ConnectedRoad &road)
result += " angle: ";
result += std::to_string(road.angle);
result += " bearing: ";
result += std::to_string(road.bearing);
result += std::to_string(road.perceived_bearing);
result += " instruction: ";
result += std::to_string(static_cast<std::int32_t>(road.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.instruction.direction_modifier)) + " " +
Expand Down
2 changes: 1 addition & 1 deletion include/guidance/intersection_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
const auto turns_onto_through_street = [&](const auto &road) {
// find edge opposite to the one we are checking (in-road)
const auto in_through_candidate =
intersection.FindClosestBearing(util::bearing::reverse(road.bearing));
intersection.FindClosestBearing(util::bearing::reverse(road.perceived_bearing));

const auto &in_edge = node_based_graph.GetEdgeData(in_through_candidate->eid);
const auto &out_edge = node_based_graph.GetEdgeData(road.eid);
Expand Down
9 changes: 5 additions & 4 deletions include/util/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace guidance
inline std::ostream &operator<<(std::ostream &out, const ConnectedRoad &road)
{
out << "ConnectedRoad {" << road.eid << " allows entry: " << road.entry_allowed
<< " angle: " << road.angle << " bearing: " << road.bearing
<< " angle: " << road.angle << " bearing: " << road.perceived_bearing
<< " instruction: " << static_cast<std::int32_t>(road.instruction.type) << " "
<< static_cast<std::int32_t>(road.instruction.direction_modifier) << " "
<< static_cast<std::int32_t>(road.lane_data_id) << "}";
Expand All @@ -80,16 +80,17 @@ namespace extractor
{
namespace intersection
{
inline std::ostream &operator<<(std::ostream &out, const IntersectionShapeData &shape)
inline std::ostream &operator<<(std::ostream &out, const IntersectionEdgeGeometry &shape)
{
out << "IntersectionShapeData { " << shape.eid << " bearing: " << shape.bearing << "}";
out << "IntersectionEdgeGeometry { " << shape.eid << " bearing: " << shape.perceived_bearing
<< "}";
return out;
}

inline std::ostream &operator<<(std::ostream &out, const IntersectionViewData &view)
{
out << "IntersectionViewData {" << view.eid << " allows entry: " << view.entry_allowed
<< " angle: " << view.angle << " bearing: " << view.bearing << "}";
<< " angle: " << view.angle << " bearing: " << view.perceived_bearing << "}";
return out;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/extractor/intersection/intersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ bool IntersectionViewData::CompareByAngle(const IntersectionViewData &other) con
return angle < other.angle;
}

std::string toString(const IntersectionShapeData &shape)
std::string toString(const IntersectionEdgeGeometry &shape)
{
std::string result =
"[shape] " + std::to_string(shape.eid) + " bearing: " + std::to_string(shape.bearing);
std::string result = "[shape] " + std::to_string(shape.eid) + " bearing: " +
std::to_string(shape.perceived_bearing);
return result;
}

Expand All @@ -35,7 +35,7 @@ std::string toString(const IntersectionViewData &view)
result += " angle: ";
result += std::to_string(view.angle);
result += " bearing: ";
result += std::to_string(view.bearing);
result += std::to_string(view.perceived_bearing);
return result;
}

Expand Down
45 changes: 19 additions & 26 deletions src/extractor/intersection/intersection_analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ std::pair<bool, double> findMergedBearing(const util::NodeBasedDynamicGraph &gra

const auto &lhs = edge_geometries[lhs_index];
const auto &rhs = edge_geometries[rhs_index];
BOOST_ASSERT(graph.GetEdgeData(lhs.edge).reversed != graph.GetEdgeData(rhs.edge).reversed);
BOOST_ASSERT(graph.GetEdgeData(lhs.eid).reversed != graph.GetEdgeData(rhs.eid).reversed);

const auto &entry = graph.GetEdgeData(lhs.edge).reversed ? rhs : lhs;
const auto &entry = graph.GetEdgeData(lhs.eid).reversed ? rhs : lhs;
const auto opposite_bearing =
findClosestOppositeBearing(edge_geometries, entry.perceived_bearing);
const auto merged_bearing = findAngleBisector(rhs.perceived_bearing, lhs.perceived_bearing);
Expand Down Expand Up @@ -178,13 +178,8 @@ bool isRoadsPairMergeable(const MergableRoadDetector &detector,

// TODO: check IsDistinctFrom - it is an angle and name-only check
// also check CanMergeRoad for all merging scenarios
return detector.IsDistinctFrom({llhs.edge, llhs.perceived_bearing, llhs.length},
{lhs.edge, lhs.perceived_bearing, lhs.length}) &&
detector.CanMergeRoad(intersection_node,
{lhs.edge, lhs.perceived_bearing, lhs.length},
{rhs.edge, rhs.perceived_bearing, rhs.length}) &&
detector.IsDistinctFrom({rhs.edge, rhs.perceived_bearing, rhs.length},
{rrhs.edge, rrhs.perceived_bearing, rrhs.length});
return detector.IsDistinctFrom(llhs, lhs) &&
detector.CanMergeRoad(intersection_node, lhs, rhs) && detector.IsDistinctFrom(rhs, rrhs);
}

auto getIntersectionLanes(const util::NodeBasedDynamicGraph &graph, const NodeID intersection_node)
Expand Down Expand Up @@ -293,9 +288,9 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,

// Only one of the edges must be reversed, mark it as merged to remove from
// intersection view
BOOST_ASSERT(graph.GetEdgeData(lhs.edge).reversed ^
graph.GetEdgeData(rhs.edge).reversed);
merged_edge_ids.insert(graph.GetEdgeData(lhs.edge).reversed ? lhs.edge : rhs.edge);
BOOST_ASSERT(graph.GetEdgeData(lhs.eid).reversed ^
graph.GetEdgeData(rhs.eid).reversed);
merged_edge_ids.insert(graph.GetEdgeData(lhs.eid).reversed ? lhs.eid : rhs.eid);
}
}
}
Expand All @@ -310,10 +305,10 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,

// Don't adjust bearings of roads that were merged at the current intersection
// or have neighbor intersection farer than the pruning distance
if (merged_edges[index] || edge_geometry.length > PRUNING_DISTANCE)
if (merged_edges[index] || edge_geometry.segment_length > PRUNING_DISTANCE)
continue;

const auto neighbor_intersection_node = graph.GetTarget(edge_geometry.edge);
const auto neighbor_intersection_node = graph.GetTarget(edge_geometry.eid);

const auto neighbor_geometries = getIntersectionOutgoingGeometries<false>(
graph, compressed_geometries, node_coordinates, neighbor_intersection_node);
Expand All @@ -327,7 +322,7 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
std::find_if(neighbor_geometries.begin(),
neighbor_geometries.end(),
[&graph, &intersection_node](const auto &road) {
return graph.GetTarget(road.edge) == intersection_node;
return graph.GetTarget(road.eid) == intersection_node;
}));
BOOST_ASSERT(static_cast<std::size_t>(neighbor_curr) != neighbor_geometries.size());
const auto neighbor_prev = (neighbor_curr + neighbor_edges - 1) % neighbor_edges;
Expand Down Expand Up @@ -396,12 +391,12 @@ getIntersectionGeometries(const util::NodeBasedDynamicGraph &graph,
for (std::size_t index = 0; index < edges_number; ++index)
{
const auto &geometry = edge_geometries[index];
const auto remote_node = graph.GetTarget(geometry.edge);
const auto remote_node = graph.GetTarget(geometry.eid);
const auto incoming_edge = graph.FindEdge(remote_node, intersection_node);
edge_geometries[edges_number + index] = {incoming_edge,
util::bearing::reverse(geometry.initial_bearing),
util::bearing::reverse(geometry.perceived_bearing),
geometry.length};
geometry.segment_length};
}

// Enforce ordering of edges by IDs
Expand All @@ -414,9 +409,9 @@ inline auto findEdge(const IntersectionEdgeGeometries &geometries, const EdgeID
{
const auto it = std::lower_bound(
geometries.begin(), geometries.end(), edge, [](const auto &geometry, const auto edge) {
return geometry.edge < edge;
return geometry.eid < edge;
});
BOOST_ASSERT(it != geometries.end() && it->edge == edge);
BOOST_ASSERT(it != geometries.end() && it->eid == edge);
return it;
}

Expand All @@ -427,7 +422,7 @@ double findEdgeBearing(const IntersectionEdgeGeometries &geometries, const EdgeI

double findEdgeLength(const IntersectionEdgeGeometries &geometries, const EdgeID &edge)
{
return findEdge(geometries, edge)->length;
return findEdge(geometries, edge)->segment_length;
}

template <typename RestrictionsRange>
Expand Down Expand Up @@ -634,7 +629,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr

using IntersectionViewDataWithAngle = std::pair<IntersectionViewData, double>;
std::vector<IntersectionViewDataWithAngle> pre_intersection_view;
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0.}, false, 0.};
IntersectionViewData uturn{{SPECIAL_EDGEID, 0., 0., 0.}, false, 0.};
std::size_t allowed_uturns_number = 0;
for (const auto &outgoing_edge : outgoing_edges)
{
Expand All @@ -643,7 +638,6 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
};

const auto edge_it = findEdge(edge_geometries, outgoing_edge.edge);
const auto segment_length = edge_it->length;
const auto is_merged = merged_edges.count(outgoing_edge.edge) != 0;
const auto is_turn_allowed = intersection::isTurnAllowed(graph,
node_data_container,
Expand Down Expand Up @@ -673,8 +667,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr

const auto is_uturn_angle = is_uturn(turn_angle);

IntersectionViewData road{
{outgoing_edge.edge, outgoing_bearing, segment_length}, is_turn_allowed, turn_angle};
IntersectionViewData road{*edge_it, is_turn_allowed, turn_angle};

if (graph.GetTarget(outgoing_edge.edge) == incoming_edge.node)
{ // Save the true U-turn road to add later if no allowed U-turns will be added
Expand Down Expand Up @@ -772,12 +765,12 @@ IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
for (std::size_t index = 0; index < edges_number; ++index)
{
const auto &geometry = edge_geometries[index];
const auto remote_node = graph.GetTarget(geometry.edge);
const auto remote_node = graph.GetTarget(geometry.eid);
const auto incoming_edge = graph.FindEdge(remote_node, intersection_node);
edge_geometries[edges_number + index] = {incoming_edge,
util::bearing::reverse(geometry.initial_bearing),
util::bearing::reverse(geometry.perceived_bearing),
geometry.length};
geometry.segment_length};
}

// Enforce ordering of edges by IDs
Expand Down
Loading

0 comments on commit 38c567b

Please # to comment.