initial version of intersection classification

This commit is contained in:
Moritz Kobitzsch
2016-04-26 13:27:40 +02:00
committed by Patrick Niklaus
parent 6aa97048df
commit ba074b0116
33 changed files with 1065 additions and 262 deletions
+20 -8
View File
@@ -3,33 +3,35 @@
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "extractor/edge_based_edge.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/restriction_map.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "util/deallocating_vector.hpp"
#include "util/name_table.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include <algorithm>
#include <cstdint>
#include <cstddef>
#include <cstdint>
#include <iosfwd>
#include <memory>
#include <queue>
#include <string>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <string>
#include <boost/filesystem/fstream.hpp>
@@ -67,6 +69,12 @@ class EdgeBasedGraphFactory
void GetStartPointMarkers(std::vector<bool> &node_is_startpoint);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
// These access functions don't destroy the content
const std::vector<BearingClassID> &GetBearingClassIds() const;
std::vector<BearingClassID> &GetBearingClassIds();
std::vector<util::guidance::BearingClass> GetBearingClasses() const;
std::vector<util::guidance::EntryClass> GetEntryClasses() const;
unsigned GetHighestEdgeID();
// Basic analysis of a turn (u --(e1)-- v --(e2)-- w)
@@ -127,6 +135,10 @@ class EdgeBasedGraphFactory
std::size_t restricted_turns_counter;
std::size_t skipped_uturns_counter;
std::size_t skipped_barrier_turns_counter;
std::unordered_map<util::guidance::BearingClass, BearingClassID> bearing_class_hash;
std::vector<BearingClassID> bearing_class_by_node_based_node;
std::unordered_map<util::guidance::EntryClass, EntryClassID> entry_class_hash;
};
} // namespace extractor
} // namespace osrm
+16 -5
View File
@@ -29,10 +29,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define EXTRACTOR_HPP
#include "extractor/edge_based_edge.hpp"
#include "extractor/extractor_config.hpp"
#include "extractor/edge_based_graph_factory.hpp"
#include "extractor/extractor_config.hpp"
#include "extractor/graph_compressor.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/typedefs.hpp"
namespace osrm
@@ -52,14 +55,16 @@ class Extractor
ExtractorConfig config;
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
BuildEdgeExpandedGraph(lua_State *lua_state,
const ProfileProperties &profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const;
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &intersection_class_output_file);
void WriteProfileProperties(const std::string &output_path,
const ProfileProperties &properties) const;
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &edges,
@@ -76,6 +81,12 @@ class Extractor
void WriteEdgeBasedGraph(const std::string &output_file_filename,
const size_t max_edge_id,
util::DeallocatingVector<EdgeBasedEdge> const &edge_based_edge_list);
void WriteIntersectionClassificationData(
const std::string &output_file_name,
const std::vector<std::uint32_t> &node_based_intersection_classes,
const std::vector<util::guidance::BearingClass> &bearing_classes,
const std::vector<util::guidance::EntryClass> &entry_classes) const;
};
}
}
+2
View File
@@ -72,6 +72,7 @@ struct ExtractorConfig
edge_penalty_path = basepath + ".osrm.edge_penalties";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
intersection_class_data_output_path = basepath + ".osrm.icd";
}
boost::filesystem::path config_file_path;
@@ -90,6 +91,7 @@ struct ExtractorConfig
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
std::string intersection_class_data_output_path;
unsigned requested_num_threads;
unsigned small_component_size;
+4 -3
View File
@@ -41,7 +41,8 @@ const constexpr bool shiftable_ccw[] = {false, true, true, false, false, true, t
const constexpr bool shiftable_cw[] = {false, false, true, true, false, false, true, true};
const constexpr std::uint8_t modifier_bounds[detail::num_direction_modifiers] = {
0, 36, 93, 121, 136, 163, 220, 255};
const constexpr double discrete_angle_step_size = 360. / 256.;
const constexpr double discrete_angle_step_size = 360. / 24;
template <typename IteratorType>
util::Coordinate
@@ -246,12 +247,12 @@ inline bool isConflict(const TurnInstruction first, const TurnInstruction second
inline DiscreteAngle discretizeAngle(const double angle)
{
BOOST_ASSERT(angle >= 0. && angle <= 360.);
return DiscreteAngle(static_cast<std::uint8_t>(angle / detail::discrete_angle_step_size));
return DiscreteAngle(static_cast<std::uint8_t>((angle + 0.5 *detail::discrete_angle_step_size) / detail::discrete_angle_step_size));
}
inline double angleFromDiscreteAngle(const DiscreteAngle angle)
{
return static_cast<double>(angle) * detail::discrete_angle_step_size;
return static_cast<double>(angle) * detail::discrete_angle_step_size + 0.5 * detail::discrete_angle_step_size;
}
inline double getAngularPenalty(const double angle, DirectionModifier modifier)
@@ -46,6 +46,9 @@ class TurnAnalysis
// the entry into the turn analysis
std::vector<TurnOperation> getTurns(const NodeID from_node, const EdgeID via_eid) const;
// access to the intersection representation for classification purposes
Intersection getIntersection(const NodeID from_node, const EdgeID via_eid) const;
private:
const util::NodeBasedDynamicGraph &node_based_graph;
const IntersectionGenerator intersection_generator;
@@ -1,18 +1,23 @@
#ifndef OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_
#define OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/coordinate.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp"
#include <algorithm>
#include <cstddef>
#include <vector>
#include <utility>
namespace osrm
{
@@ -21,99 +26,12 @@ namespace extractor
namespace guidance
{
struct TurnPossibility
{
TurnPossibility(DiscreteAngle angle, EdgeID edge_id)
: angle(std::move(angle)), edge_id(std::move(edge_id))
{
}
TurnPossibility() : angle(0), edge_id(SPECIAL_EDGEID) {}
DiscreteAngle angle;
EdgeID edge_id;
};
struct CompareTurnPossibilities
{
bool operator()(const std::vector<TurnPossibility> &left,
const std::vector<TurnPossibility> &right) const
{
if (left.size() < right.size())
return true;
if (left.size() > right.size())
return false;
for (std::size_t i = 0; i < left.size(); ++i)
{
if ((((int)left[i].angle + 16) % 256) / 32 < (((int)right[i].angle + 16) % 256) / 32)
return true;
if ((((int)left[i].angle + 16) % 256) / 32 > (((int)right[i].angle + 16) % 256) / 32)
return false;
}
return false;
}
};
inline std::vector<TurnPossibility>
std::pair<util::guidance::EntryClass,util::guidance::BearingClass>
classifyIntersection(NodeID nid,
const util::NodeBasedDynamicGraph &graph,
const Intersection &intersection,
const util::NodeBasedDynamicGraph &node_based_graph,
const extractor::CompressedEdgeContainer &compressed_geometries,
const std::vector<extractor::QueryNode> &query_nodes)
{
std::vector<TurnPossibility> turns;
if (graph.BeginEdges(nid) == graph.EndEdges(nid))
return std::vector<TurnPossibility>();
const EdgeID base_id = graph.BeginEdges(nid);
const auto base_coordinate = getRepresentativeCoordinate(nid, graph.GetTarget(base_id), base_id,
graph.GetEdgeData(base_id).reversed,
compressed_geometries, query_nodes);
const auto node_coordinate = util::Coordinate(query_nodes[nid].lon, query_nodes[nid].lat);
// generate a list of all turn angles between a base edge, the node and a current edge
for (const EdgeID eid : graph.GetAdjacentEdgeRange(nid))
{
const auto edge_coordinate = getRepresentativeCoordinate(
nid, graph.GetTarget(eid), eid, false, compressed_geometries, query_nodes);
double angle = util::coordinate_calculation::computeAngle(base_coordinate, node_coordinate,
edge_coordinate);
turns.emplace_back(discretizeAngle(angle), eid);
}
std::sort(turns.begin(), turns.end(),
[](const TurnPossibility left, const TurnPossibility right) {
return left.angle < right.angle;
});
turns.push_back(turns.front()); // sentinel
for (std::size_t turn_nr = 0; turn_nr + 1 < turns.size(); ++turn_nr)
{
turns[turn_nr].angle = (256 + static_cast<uint32_t>(turns[turn_nr + 1].angle) -
static_cast<uint32_t>(turns[turn_nr].angle)) %
256; // calculate the difference to the right
}
turns.pop_back(); // remove sentinel again
// find largest:
std::size_t best_id = 0;
DiscreteAngle largest_turn_angle = turns.front().angle;
for (std::size_t current_turn_id = 1; current_turn_id < turns.size(); ++current_turn_id)
{
if (turns[current_turn_id].angle > largest_turn_angle)
{
largest_turn_angle = turns[current_turn_id].angle;
best_id = current_turn_id;
}
}
// rotate all angles so the largest angle comes first
std::rotate(turns.begin(), turns.begin() + best_id, turns.end());
return turns;
}
const std::vector<extractor::QueryNode> &query_nodes);
} // namespace guidance
} // namespace extractor
+6 -2
View File
@@ -1,10 +1,11 @@
#ifndef ORIGINAL_EDGE_DATA_HPP
#define ORIGINAL_EDGE_DATA_HPP
#include "extractor/travel_mode.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp"
#include <cstddef>
#include <limits>
namespace osrm
@@ -17,9 +18,10 @@ struct OriginalEdgeData
explicit OriginalEdgeData(NodeID via_node,
unsigned name_id,
guidance::TurnInstruction turn_instruction,
EntryClassID entry_classid,
TravelMode travel_mode)
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
travel_mode(travel_mode)
entry_classid(entry_classid), travel_mode(travel_mode)
{
}
@@ -27,6 +29,7 @@ struct OriginalEdgeData
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(guidance::TurnInstruction::INVALID()),
entry_classid(INVALID_ENTRY_CLASSID),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -34,6 +37,7 @@ struct OriginalEdgeData
NodeID via_node;
unsigned name_id;
guidance::TurnInstruction turn_instruction;
EntryClassID entry_classid;
TravelMode travel_mode;
};
}