638 {
639 if (segments.empty()) {
640 AERROR <<
"The input segments is empty";
641 return false;
642 }
643 CHECK_NOTNULL(truncated_segments);
645
646 if (start_s >= end_s) {
647 AERROR <<
"start_s(" << start_s <<
" >= end_s(" << end_s <<
")";
648 return false;
649 }
650 std::unordered_set<std::string> unique_lanes;
651 static constexpr double kRouteEpsilon = 1e-3;
652
653 if (start_s < 0) {
654 const auto &first_segment = *segments.begin();
655 auto lane = first_segment.lane;
656 double s = first_segment.start_s;
657 double extend_s = -start_s;
658 std::vector<hdmap::LaneSegment> extended_lane_segments;
659 while (extend_s > kRouteEpsilon) {
660 if (s <= kRouteEpsilon) {
661 lane = GetRoutePredecessor(lane);
662 if (lane == nullptr ||
663 unique_lanes.find(lane->id().id()) != unique_lanes.end()) {
664 break;
665 }
666 s = lane->total_length();
667 } else {
668 const double length = std::min(s, extend_s);
669 extended_lane_segments.emplace_back(lane, s - length, s);
670 extend_s -= length;
671 s -= length;
672 unique_lanes.insert(lane->id().id());
673 }
674 }
675 truncated_segments->insert(truncated_segments->begin(),
676 extended_lane_segments.rbegin(),
677 extended_lane_segments.rend());
678 }
679 bool found_loop = false;
680 double router_s = 0;
681 for (const auto &lane_segment : segments) {
682 const double adjusted_start_s = std::max(
683 start_s - router_s + lane_segment.start_s, lane_segment.start_s);
684 const double adjusted_end_s =
685 std::min(end_s - router_s + lane_segment.start_s, lane_segment.end_s);
686 if (adjusted_start_s < adjusted_end_s) {
687 if (!truncated_segments->empty() &&
688 truncated_segments->back().lane->id().id() ==
689 lane_segment.lane->id().id()) {
690 truncated_segments->back().end_s = adjusted_end_s;
691 } else if (unique_lanes.find(lane_segment.lane->id().id()) ==
692 unique_lanes.end()) {
693 truncated_segments->emplace_back(lane_segment.lane, adjusted_start_s,
694 adjusted_end_s);
695 unique_lanes.insert(lane_segment.lane->id().id());
696 } else {
697 found_loop = true;
698 break;
699 }
700 }
701 router_s += (lane_segment.end_s - lane_segment.start_s);
702 if (router_s > end_s) {
703 break;
704 }
705 }
706 if (found_loop) {
707 return true;
708 }
709
710 if (router_s < end_s && !truncated_segments->empty()) {
711 auto &back = truncated_segments->back();
712 if (back.lane->total_length() > back.end_s) {
713 double origin_end_s = back.end_s;
714 back.end_s =
715 std::min(back.end_s + end_s - router_s, back.lane->total_length());
716 router_s += back.end_s - origin_end_s;
717 }
718 }
719 auto last_lane = segments.back().lane;
720 while (router_s < end_s - kRouteEpsilon) {
721 last_lane = GetRouteSuccessor(last_lane);
722 if (last_lane == nullptr ||
723 unique_lanes.find(last_lane->id().id()) != unique_lanes.end()) {
724 break;
725 }
726 const double length = std::min(end_s - router_s, last_lane->total_length());
727 truncated_segments->emplace_back(last_lane, 0, length);
728 unique_lanes.insert(last_lane->id().id());
729 router_s += length;
730 }
731 return true;
732}
void SetProperties(const RouteSegments &other)
Copy the properties of other segments to current one