20#include <unordered_set>
35 if (junction_info_ptr_ !=
nullptr &&
36 junction_info_ptr_->id().id() == junction_id) {
41 SetAllJunctionExits();
46 junction_info_ptr_ =
nullptr;
47 junction_exits_.clear();
48 junction_features_.clear();
51void JunctionAnalyzer::SetAllJunctionExits() {
52 CHECK_NOTNULL(junction_info_ptr_);
54 for (
const auto& overlap_id : junction_info_ptr_->junction().overlap_id()) {
56 if (overlap_info_ptr ==
nullptr) {
61 for (
const auto&
object : overlap_info_ptr->overlap().object()) {
62 if (
object.has_lane_overlap_info()) {
63 const std::string& lane_id =
object.id().id();
65 double s =
object.lane_overlap_info().end_s();
66 if (s + FLAGS_junction_exit_lane_threshold <
67 lane_info_ptr->total_length()) {
68 JunctionExit junction_exit;
69 PointENU position = lane_info_ptr->GetSmoothPoint(s);
70 junction_exit.set_exit_lane_id(lane_id);
71 junction_exit.mutable_exit_position()->set_x(position.x());
72 junction_exit.mutable_exit_position()->set_y(position.y());
73 junction_exit.set_exit_heading(lane_info_ptr->Heading(s));
74 junction_exit.set_exit_width(lane_info_ptr->GetWidth(s));
76 junction_exits_[lane_id] = junction_exit;
83std::vector<JunctionExit> JunctionAnalyzer::GetJunctionExits(
84 const std::string& start_lane_id) {
86 int max_search_level = 6;
88 std::vector<JunctionExit> junction_exits;
89 std::queue<std::pair<ConstLaneInfoPtr, int>> lane_info_queue;
91 std::unordered_set<std::string> visited_exit_lanes;
94 while (!lane_info_queue.empty()) {
96 int level = lane_info_queue.front().second;
97 lane_info_queue.pop();
98 const std::string& curr_lane_id = curr_lane->id().id();
100 if (IsExitLane(curr_lane_id) &&
101 visited_exit_lanes.find(curr_lane_id) == visited_exit_lanes.end()) {
102 junction_exits.push_back(junction_exits_[curr_lane_id]);
103 visited_exit_lanes.insert(curr_lane_id);
107 if (level >= max_search_level) {
110 for (
const auto& succ_lane_id : curr_lane->lane().successor_id()) {
113 lane_info_queue.emplace(succ_lane_ptr, level + 1);
116 return junction_exits;
120 const std::string& start_lane_id) {
121 if (junction_features_.find(start_lane_id) != junction_features_.end()) {
122 return junction_features_[start_lane_id];
128 std::vector<JunctionExit> junction_exits = GetJunctionExits(start_lane_id);
130 for (
const auto& junction_exit : junction_exits) {
131 junction_feature.add_junction_exit()->CopyFrom(junction_exit);
133 junction_feature.mutable_enter_lane()->set_lane_id(start_lane_id);
134 junction_feature.add_start_lane_id(start_lane_id);
135 junction_features_[start_lane_id] = junction_feature;
136 return junction_features_[start_lane_id];
140 const std::vector<std::string>& start_lane_ids) {
142 bool initialized =
false;
143 std::unordered_map<std::string, JunctionExit> junction_exits_map;
144 for (
const std::string& start_lane_id : start_lane_ids) {
147 merged_junction_feature.set_junction_id(junction_feature.
junction_id());
148 merged_junction_feature.set_junction_range(
153 if (junction_exits_map.find(junction_exit.exit_lane_id()) ==
154 junction_exits_map.end()) {
155 junction_exits_map[junction_exit.exit_lane_id()] = junction_exit;
159 for (
const auto& exit : junction_exits_map) {
160 merged_junction_feature.add_start_lane_id(exit.first);
161 merged_junction_feature.add_junction_exit()->CopyFrom(exit.second);
163 return merged_junction_feature;
166bool JunctionAnalyzer::IsExitLane(
const std::string& lane_id) {
167 return junction_exits_.find(lane_id) != junction_exits_.end();
171 CHECK_NOTNULL(junction_info_ptr_);
172 return junction_info_ptr_->id().id();
176 CHECK_NOTNULL(junction_info_ptr_);
177 if (!junction_info_ptr_->junction().has_polygon() ||
178 junction_info_ptr_->junction().polygon().point_size() < 3) {
180 <<
"] has not enough polygon points to compute range";
181 return FLAGS_defualt_junction_range;
183 double x_min = std::numeric_limits<double>::infinity();
184 double x_max = -std::numeric_limits<double>::infinity();
185 double y_min = std::numeric_limits<double>::infinity();
186 double y_max = -std::numeric_limits<double>::infinity();
187 for (
const auto& point : junction_info_ptr_->junction().polygon().point()) {
188 x_min = std::min(x_min, point.x());
189 x_max = std::max(x_max, point.x());
190 y_min = std::min(y_min, point.y());
191 y_max = std::max(y_max, point.y());
193 double dx = std::abs(x_max - x_min);
194 double dy = std::abs(y_max - y_min);
195 double range = std::sqrt(dx * dx + dy * dy);
const std::string & GetJunctionId()
Get junction ID
double ComputeJunctionRange()
Compute junction range
void Clear()
Clear all stored data
const JunctionFeature & GetJunctionFeature(const std::string &start_lane_id)
Get junction feature starting from start_lane_id
void Init(const std::string &junction_id)
Initialize by junction ID, if junction id differs from prev cycle
static std::shared_ptr< const hdmap::JunctionInfo > JunctionById(const std::string &id)
Get a shared pointer to a junction by junction ID.
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
static std::shared_ptr< const hdmap::OverlapInfo > OverlapById(const std::string &id)
Get a shared pointer to an overlap by overlap ID.
std::shared_ptr< const LaneInfo > ConstLaneInfoPtr
optional double junction_range
repeated JunctionExit junction_exit
optional string junction_id