#include "extractor/guidance/node_based_graph_walker.hpp" #include "util/coordinate_calculation.hpp" namespace osrm { namespace extractor { namespace guidance { // --------------------------------------------------------------------------------- NodeBasedGraphWalker::NodeBasedGraphWalker(const util::NodeBasedDynamicGraph &node_based_graph, const IntersectionGenerator &intersection_generator) : node_based_graph(node_based_graph), intersection_generator(intersection_generator) { } LengthLimitedCoordinateAccumulator::LengthLimitedCoordinateAccumulator( const extractor::guidance::CoordinateExtractor &coordinate_extractor, const util::NodeBasedDynamicGraph &node_based_graph, const double max_length) : coordinate_extractor(coordinate_extractor), node_based_graph(node_based_graph), max_length(max_length), accumulated_length(0) { } bool LengthLimitedCoordinateAccumulator::terminate() { return accumulated_length >= max_length; } // update the accumulator void LengthLimitedCoordinateAccumulator::update(const NodeID from_node, const EdgeID via_edge, const NodeID /*to_node*/) { const auto current_coordinates = coordinate_extractor.GetForwardCoordinatesAlongRoad(from_node, via_edge); const auto length = util::coordinate_calculation::getLength( coordinates, util::coordinate_calculation::haversineDistance); // in case we get too many coordinates, we limit them to our desired length if (length + accumulated_length > max_length) coordinate_extractor.TrimCoordinatesToLength(current_coordinates, max_length - accumulated_length); coordinates.insert(coordinates.end(), current_coordinates.begin(), current_coordinates.end()); accumulated_length += length; } // --------------------------------------------------------------------------------- SelectRoadByNameOnlyChoiceAndStraightness::SelectRoadByNameOnlyChoiceAndStraightness( const NameID desired_name_id, const bool requires_entry) : desired_name_id(desired_name_id), requires_entry(requires_entry) { } boost::optional SelectRoadByNameOnlyChoiceAndStraightness:: operator()(const NodeID /*nid*/, const EdgeID /*via_edge_id*/, const Intersection &intersection, const util::NodeBasedDynamicGraph &node_based_graph) const { BOOST_ASSERT(!intersection.empty()); const auto comparator = [this, &node_based_graph](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { // the score of an elemnt results in an ranking preferring valid entries, if required over // invalid // requested name_ids over non-requested // narrow deviations over non-narrow const auto score = [this, &node_based_graph](const ConnectedRoad &road) { double result_score = 0; // since angular deviation is limited by 0-180, we add 360 for invalid if (requires_entry && !road.entry_allowed) result_score += 360.; // 180 for undesired name-ids if (desired_name_id != node_based_graph.GetEdgeData(road.eid).name_id) result_score += 180; return result_score + angularDeviation(road.angle, STRAIGHT_ANGLE); }; return score(lhs) < score(rhs); }; const auto min_element = std::min_element(std::next(std::begin(intersection)), std::end(intersection), comparator); if (min_element == intersection.end() || (requires_entry && !min_element->entry_allowed)) return {}; else return (*min_element).eid; } } // namespace guidance } // namespace extractor } // namespace osrm