turn lane handler moved to scenario based handling

This commit is contained in:
Moritz Kobitzsch
2016-06-30 09:31:08 +02:00
parent 802b93fa9a
commit 3b81b39998
21 changed files with 955 additions and 292 deletions
@@ -92,8 +92,9 @@ class EdgeBasedGraphFactory
const std::vector<QueryNode> &node_info_list,
ProfileProperties profile_properties,
const util::NameTable &name_table,
const std::vector<std::uint32_t> &turn_lane_offsets,
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks);
std::vector<std::uint32_t> &turn_lane_offsets,
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks,
guidance::LaneDescriptionMap &lane_description_map);
void Run(ScriptingEnvironment &scripting_environment,
const std::string &original_edge_data_filename,
@@ -154,8 +155,9 @@ class EdgeBasedGraphFactory
ProfileProperties profile_properties;
const util::NameTable &name_table;
const std::vector<std::uint32_t> &turn_lane_offsets;
const std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
std::vector<std::uint32_t> &turn_lane_offsets;
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
guidance::LaneDescriptionMap &lane_description_map;
void CompressGeometry();
unsigned RenumberEdges();
+2 -5
View File
@@ -39,11 +39,11 @@ class ExtractionContainers
void WriteNodes(std::ofstream &file_out_stream) const;
void WriteRestrictions(const std::string &restrictions_file_name) const;
void WriteEdges(std::ofstream &file_out_stream) const;
void WriteCharData(const std::string &file_name);
void
WriteTurnLaneMasks(const std::string &file_name,
const stxxl::vector<std::uint32_t> &turn_lane_offsets,
const stxxl::vector<guidance::TurnLaneType::Mask> &turn_lane_masks) const;
void WriteCharData(const std::string &file_name);
public:
using STXXLNodeIDVector = stxxl::vector<OSMNodeID>;
@@ -60,8 +60,6 @@ class ExtractionContainers
STXXLNameCharData name_char_data;
STXXLNameOffsets name_offsets;
// an adjacency array containing all turn lane masks
stxxl::vector<std::uint32_t> turn_lane_offsets;
stxxl::vector<guidance::TurnLaneType::Mask> turn_lane_masks;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
std::unordered_map<OSMNodeID, NodeID> external_to_internal_node_id_map;
@@ -72,8 +70,7 @@ class ExtractionContainers
void PrepareData(ScriptingEnvironment &scripting_environment,
const std::string &output_file_name,
const std::string &restrictions_file_name,
const std::string &names_file_name,
const std::string &turn_lane_file_name);
const std::string &names_file_name);
};
}
}
+11
View File
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
@@ -87,6 +88,16 @@ class Extractor
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;
void WriteTurnLaneData(const std::string &turn_lane_file) const;
// globals persisting during the extraction process and the graph generation process
// during turn lane analysis, we might have to combine lanes for roads that are modelled as two
// but are more or less experienced as one. This can be due to solid lines in between lanes, for
// example, that genereate a small separation between them. As a result, we might have to
// augment the turn lane map during processing, further adding more types.
guidance::LaneDescriptionMap turn_lane_map;
};
}
}
+3 -5
View File
@@ -40,14 +40,12 @@ class ExtractorCallbacks
using MapKey = std::pair<std::string, std::string>;
using MapVal = unsigned;
std::unordered_map<MapKey, MapVal, boost::hash<MapKey>> string_map;
std::unordered_map<guidance::TurnLaneDescription,
LaneDescriptionID,
guidance::TurnLaneDescription_hash>
lane_description_map;
guidance::LaneDescriptionMap &lane_description_map;
ExtractionContainers &external_memory;
public:
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers);
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
guidance::LaneDescriptionMap &lane_description_map);
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
ExtractorCallbacks &operator=(const ExtractorCallbacks &) = delete;
@@ -28,7 +28,7 @@ typedef std::vector<TurnLaneData> LaneDataVector;
// convertes a string given in the OSM format into a TurnLaneData vector
OSRM_ATTR_WARN_UNUSED
LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_description);
LaneDataVector laneDataFromDescription(TurnLaneDescription turn_lane_description);
// Locate A Tag in a lane data vector (if multiple tags are set, the first one found is returned)
LaneDataVector::const_iterator findTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
@@ -37,6 +37,9 @@ LaneDataVector::iterator findTag(const TurnLaneType::Mask tag, LaneDataVector &d
// Returns true if any of the queried tags is contained
bool hasTag(const TurnLaneType::Mask tag, const LaneDataVector &data);
// Check if a set of lanes is a subset of a different set of lanes
bool isSubsetOf(const LaneDataVector &subset_candidate, const LaneDataVector &superset_candidate);
} // namespace lane_data_generation
} // namespace guidance
@@ -33,27 +33,75 @@ namespace lanes
{
class TurnLaneHandler
{
typedef enum TurnLaneScenario {
SIMPLE, // a straightforward assignment
PARTITION_LOCAL, // an assignment that requires partitioning, using local turns
SIMPLE_PREVIOUS, // an assignemtnn using the turns specified at the previous road (e.g.
// traffic light, lanes not drawn up to the intersection)
PARTITION_PREVIOUS, // a set of lanes on a turn with a traffic island. The lanes for the
// turn end at the previous turn (parts of it remain valid without being
// shown again)
SLIPROAD, // Sliproads are simple assignments that, for better visual representation should
// include turns from other roads in their listings
MERGE, // Merging Lanes
NONE, // not a turn lane scenario at all
INVALID, // some error might have occurred
UNKNOWN, // UNKNOWN describes all cases that we are currently not able to handle
NUM_SCENARIOS
} TurnLaneScenario;
const constexpr static char *scenario_names[TurnLaneScenario::NUM_SCENARIOS] = {
"Simple",
"Partition Local",
"Simple Previous",
"Partition Previous",
"Sliproad",
"Merge",
"None",
"Invalid",
"Unknown"};
public:
typedef std::vector<TurnLaneData> LaneDataVector;
TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<std::uint32_t> &turn_lane_offsets,
const std::vector<TurnLaneType::Mask> &turn_lane_masks,
const TurnAnalysis &turn_analysis);
std::vector<std::uint32_t> &turn_lane_offsets,
std::vector<TurnLaneType::Mask> &turn_lane_masks,
LaneDescriptionMap &lane_description_map,
const std::vector<QueryNode> &node_info_list,
const TurnAnalysis &turn_analysis,
LaneDataIdMap &id_map);
~TurnLaneHandler();
OSRM_ATTR_WARN_UNUSED
Intersection assignTurnLanes(const NodeID at,
const EdgeID via_edge,
Intersection intersection,
LaneDataIdMap &id_map) const;
Intersection assignTurnLanes(const NodeID at, const EdgeID via_edge, Intersection intersection);
private:
unsigned *count_handled;
unsigned *count_called;
// we need to be able to look at previous intersections to, in some cases, find the correct turn
// lanes for a turn
const util::NodeBasedDynamicGraph &node_based_graph;
const std::vector<std::uint32_t> &turn_lane_offsets;
const std::vector<TurnLaneType::Mask> &turn_lane_masks;
std::vector<std::uint32_t> &turn_lane_offsets;
std::vector<TurnLaneType::Mask> &turn_lane_masks;
LaneDescriptionMap &lane_description_map;
const std::vector<QueryNode> &node_info_list;
const TurnAnalysis &turn_analysis;
LaneDataIdMap &id_map;
// Find out which scenario we have to handle
TurnLaneScenario deduceScenario(const NodeID at,
const EdgeID via_edge,
const Intersection &intersection,
// Output Parameters to reduce repeated creation
LaneDescriptionID &lane_description_id,
LaneDataVector &lane_data,
NodeID &previous_node,
EdgeID &previous_id,
Intersection &previous_intersection,
LaneDataVector &previous_lane_data,
LaneDescriptionID &previous_description_id);
// check whether we can handle an intersection
bool isSimpleIntersection(const LaneDataVector &turn_lane_data,
@@ -63,21 +111,28 @@ class TurnLaneHandler
OSRM_ATTR_WARN_UNUSED
Intersection simpleMatchTuplesToTurns(Intersection intersection,
const LaneDataVector &lane_data,
const LaneDescriptionID lane_string_id,
LaneDataIdMap &id_map) const;
const LaneDescriptionID lane_string_id);
// partition lane data into lane data relevant at current turn and at next turn
OSRM_ATTR_WARN_UNUSED
std::pair<TurnLaneHandler::LaneDataVector, TurnLaneHandler::LaneDataVector> partitionLaneData(
const NodeID at, LaneDataVector turn_lane_data, const Intersection &intersection) const;
// if the current intersections turn string is empty, we check whether there is an incoming
// intersection whose turns might be related to this current intersection
// Sliproad turns have a separated lane to the right/left of other depicted lanes. These lanes
// are not necessarily separated clearly from the rest of the way. As a result, we combine both
// lane entries for our output, while performing the matching with the separated lanes only.
OSRM_ATTR_WARN_UNUSED
Intersection handleTurnAtPreviousIntersection(const NodeID at,
const EdgeID via_edge,
Intersection intersection,
LaneDataIdMap &id_map) const;
Intersection handleSliproadTurn(Intersection intersection,
const LaneDescriptionID lane_description_id,
LaneDataVector lane_data,
const Intersection &previous_intersection,
const LaneDescriptionID &previous_lane_description_id,
const LaneDataVector &previous_lane_data);
// get the lane data for an intersection
void extractLaneData(const EdgeID via_edge,
LaneDescriptionID &lane_description_id,
LaneDataVector &lane_data) const;
};
} // namespace lanes
@@ -22,16 +22,20 @@ namespace lanes
{
// Translate Turn Lane Tags into a matching modifier
DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask &tag);
DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask tag);
// check whether a match of a given tag and a turn instruction can be seen as valid
bool isValidMatch(const TurnLaneType::Mask &tag, const TurnInstruction instruction);
bool isValidMatch(const TurnLaneType::Mask tag, const TurnInstruction instruction);
// localisation of the best possible match for a tag
typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask &tag,
typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask tag,
const Intersection &intersection);
// the quality of a matching to decide between first/second possibility on segregated intersections
double getMatchingQuality( const TurnLaneType::Mask tag, const ConnectedRoad &road );
typename Intersection::const_iterator
findBestMatchForReverse(const TurnLaneType::Mask &leftmost_tag, const Intersection &intersection);
findBestMatchForReverse(const TurnLaneType::Mask leftmost_tag, const Intersection &intersection);
// a match is trivial if all turns can be associated with their best match in a valid way and the
// matches occur in order
@@ -5,6 +5,7 @@
#include <cstddef>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/assert.hpp>
@@ -95,6 +96,11 @@ struct TurnLaneDescription_hash
}
};
typedef std::unordered_map<guidance::TurnLaneDescription,
LaneDescriptionID,
guidance::TurnLaneDescription_hash>
LaneDescriptionMap;
} // guidance
} // extractor
} // osrm
+4 -5
View File
@@ -25,8 +25,7 @@ inline void print(const engine::guidance::RouteStep &step)
<< static_cast<int>(step.maneuver.waypoint_type) << " "
<< " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " exit: " << step.maneuver.exit << " Intersections: " << step.intersections.size()
<< " [";
<< "\n\tIntersections: " << step.intersections.size() << " [";
for (const auto &intersection : step.intersections)
{
@@ -36,9 +35,9 @@ inline void print(const engine::guidance::RouteStep &step)
std::cout << ", entry: ";
for (auto entry : intersection.entry)
std::cout << " " << (entry ? "true" : "false");
std::cout << " Lanes: (" << static_cast<int>(intersection.lanes.lanes_in_turn) << ", "
<< static_cast<int>(intersection.lanes.first_lane_from_the_right) << ")";
std::cout << ")";
const auto lanes = intersection.lanes;
std::cout<< " Lanes: (" << static_cast<int>(lanes.lanes_in_turn) << ", "
<< static_cast<int>(lanes.first_lane_from_the_right) << "))";
}
std::cout << "] name[" << step.name_id << "]: " << step.name;
}