geometry/impl/LineString.h
Go to the documentation of this file.
1 #pragma once
2 #include <boost/geometry/algorithms/equals.hpp>
3 #include <boost/geometry/algorithms/intersection.hpp>
4 
9 
10 namespace lanelet {
11 namespace geometry {
12 namespace internal {
13 
15  size_t idx;
16  double s; // coordinate along linestring
17 };
18 
23 };
24 using SelfIntersections2d = std::vector<SelfIntersection2d>;
25 
29 };
30 
31 template <typename T>
32 struct GetGeometry<T, IfLS<T, void>> {
33  static inline auto twoD(const T& geometry) { return traits::toHybrid(traits::to2D(geometry)); }
34  static inline auto threeD(const T& geometry) { return traits::toHybrid(traits::to3D(geometry)); }
35 };
36 
37 inline auto crossProd(const BasicPoint3d& p1, const BasicPoint3d& p2) { return p1.cross(p2).eval(); }
38 inline auto crossProd(const BasicPoint2d& p1, const BasicPoint2d& p2) {
39  return BasicPoint3d(p1.x(), p1.y(), 0.).cross(BasicPoint3d(p2.x(), p2.y(), 0.)).eval();
40 }
41 // required for Polygon triangulation
42 inline auto crossProd(const Eigen::Matrix<double, 2, 1>& p1, const Eigen::Matrix<double, 2, 1>& p2) {
43  return BasicPoint3d(p1.x(), p1.y(), 0.).cross(BasicPoint3d(p2.x(), p2.y(), 0.)).eval();
44 }
45 
46 template <typename LineStringT, typename BasicPointT>
47 auto findPoint(const LineStringT& ls, const BasicPointT& p) {
48  return std::find_if(ls.begin(), ls.end(), [&p](const auto& elem) { return boost::geometry::equals(elem, p); });
49 }
50 
51 template <typename PointT>
52 bool pointIsLeftOf(const PointT& pSeg1, const PointT& pSeg2, const PointT& p) {
53  return crossProd(PointT(pSeg2 - pSeg1), PointT(p - pSeg1)).z() > 0;
54 }
55 
56 template <typename LineStringT>
57 LineStringT invert(const LineStringT& ls) {
58  return ls.invert();
59 }
60 
61 template <>
63  return BasicLineString2d{ls.rbegin(), ls.rend()};
64 }
65 
66 template <>
68  return BasicLineString3d{ls.rbegin(), ls.rend()};
69 }
70 
71 template <typename PointT>
75 };
76 
77 template <typename LineStringT, typename BasicPointT>
78 bool isLeftOf(const LineStringT& ls, const BasicPointT& p, const ProjectedPointInfo<BasicPointT>& ppInfo) {
79  BasicPointT pSeg1 = ppInfo.closestSegment.first;
80  BasicPointT pSeg2 = ppInfo.closestSegment.second;
81  bool isLeft = pointIsLeftOf(pSeg1, pSeg2, p);
82  if (pSeg2 == ppInfo.projectedPoint) {
83  auto nextSegPointIt = std::next(findPoint(ls, pSeg2));
84  if (nextSegPointIt != ls.end()) {
85  // see stackoverflow.com/questions/10583212
86  BasicPointT nextSegPoint;
87  boost::geometry::convert(*nextSegPointIt, nextSegPoint);
88  if (isLeft != pointIsLeftOf(pSeg2, nextSegPoint, p) && isLeft == pointIsLeftOf(pSeg1, pSeg2, nextSegPoint)) {
89  return !isLeft;
90  }
91  }
92  }
93  return isLeft;
94 }
95 
96 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const ConstHybridLineString2d& l1,
97  const ConstHybridLineString2d& l2);
98 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const CompoundHybridLineString2d& l1,
99  const CompoundHybridLineString2d& l2);
100 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const ConstHybridLineString2d& l1,
101  const CompoundHybridLineString2d& l2);
102 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const CompoundHybridLineString2d& l1,
103  const ConstHybridLineString2d& l2);
104 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const ConstHybridLineString2d& l1, const BasicLineString2d& l2);
105 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const BasicLineString2d& l1, const ConstHybridLineString2d& l2);
106 std::pair<BasicPoint2d, BasicPoint2d> projectedPoint2d(const BasicLineString2d& l1, const BasicLineString2d& l2);
107 
108 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const ConstHybridLineString3d& l1,
109  const ConstHybridLineString3d& l2);
110 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const CompoundHybridLineString3d& l1,
111  const CompoundHybridLineString3d& l2);
112 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const ConstHybridLineString3d& l1,
113  const CompoundHybridLineString3d& l2);
114 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const CompoundHybridLineString3d& l1,
115  const ConstHybridLineString3d& l2);
116 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const ConstHybridLineString3d& l1, const BasicLineString3d& l2);
117 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const BasicLineString3d& l1, const ConstHybridLineString3d& l2);
118 std::pair<BasicPoint3d, BasicPoint3d> projectedPoint3d(const BasicLineString3d& l1, const BasicLineString3d& l2);
119 
120 BasicPoint2d project(const BasicLineString2d& lineString, const BasicPoint2d& pointToProject);
121 BasicPoint3d project(const BasicLineString3d& lineString, const BasicPoint3d& pointToProject);
122 BasicPoint2d project(const ConstHybridLineString2d& lineString, const BasicPoint2d& pointToProject);
123 BasicPoint3d project(const ConstHybridLineString3d& lineString, const BasicPoint3d& pointToProject);
124 BasicPoint2d project(const CompoundHybridLineString2d& lineString, const BasicPoint2d& pointToProject);
125 BasicPoint3d project(const CompoundHybridLineString3d& lineString, const BasicPoint3d& pointToProject);
126 
127 template <typename LineStringT, typename PointT>
128 std::pair<double, ProjectedPointInfo<traits::BasicPointT<PointT>>> signedDistanceImpl(const LineStringT lineString,
129  const PointT& p) {
130  const auto basicP = utils::toBasicPoint(p);
131  const auto nextSegment = closestSegment(lineString, basicP);
132  const auto projPoint = lanelet::geometry::project(utils::toBasicSegment(nextSegment), basicP);
133  const auto d = distance(projPoint, p);
134  ProjectedPointInfo<traits::BasicPointT<PointT>> ppInfo{nextSegment, projPoint};
135  const auto isLeft = isLeftOf(lineString, p, ppInfo);
136  return {isLeft ? d : -d, ppInfo};
137 }
138 
139 template <typename HybridLineStringT>
140 BasicPoint2d fromArcCoords(const HybridLineStringT& hLineString, const BasicPoint2d& projStart,
141  const size_t startIdx, // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
142  const size_t endIdx, const double distance) {
143  if (hLineString.size() < startIdx) {
144  throw InvalidInputError(std::string("Linestring point out of bounds. Linestring size ") +
145  std::to_string(hLineString.size()) + ", startIdx " + std::to_string(startIdx));
146  }
147  if (hLineString.size() < endIdx) {
148  throw InvalidInputError(std::string("Linestring point out of bounds. Linestring size ") +
149  std::to_string(hLineString.size()) + ", endIdx " + std::to_string(endIdx));
150  }
151  if (startIdx == endIdx) {
152  throw InvalidInputError(
153  std::string("Can't determine shift direction from two identical points on linestring. Point index ") +
154  std::to_string(startIdx));
155  }
156  const auto dx(hLineString[endIdx](0) - hLineString[startIdx](0));
157  const auto dy(hLineString[endIdx](1) - hLineString[startIdx](1));
158 
159  return projStart + Eigen::Vector2d(-dy, dx).normalized() * distance;
160 }
161 
168 template <typename LineString2dT>
169 PointVincinity makeVincinity(const LineString2dT& lineString, const size_t idx) {
170  if (idx == 0) {
171  return PointVincinity{BasicPoint2d::Zero(),
172  utils::toBasicPoint(lineString[idx + 1]) - utils::toBasicPoint(lineString[idx])};
173  }
174  if (idx + 1 == lineString.size()) {
175  return PointVincinity{utils::toBasicPoint(lineString[idx]) - utils::toBasicPoint(lineString[idx - 1]),
176  BasicPoint2d::Zero()};
177  }
178  return PointVincinity{utils::toBasicPoint(lineString[idx]) - utils::toBasicPoint(lineString[idx - 1]),
179  utils::toBasicPoint(lineString[idx + 1]) - utils::toBasicPoint(lineString[idx])};
180 }
181 
190 template <typename LineString2dT>
191 BasicPoint2d shiftLateral(const LineString2dT& lineString, const size_t idx, const double offset,
192  const PointVincinity& pv) {
193  Eigen::Vector2d perpendicular;
194  double realOffset = offset;
195  const auto epsilon{1.e-5};
196  if (idx == 0) {
197  perpendicular = pv.following;
198  } else if (idx + 1 == lineString.size()) {
199  perpendicular = pv.preceding;
200  } else {
201  perpendicular = pv.following.normalized() + pv.preceding.normalized();
202  auto minussin2 = perpendicular.norm() / 2;
203  realOffset = (minussin2 > epsilon) ? offset / minussin2 : 0;
204  }
205 
206  Eigen::Vector2d direction(-perpendicular(1), perpendicular(0));
207  return utils::toBasicPoint(lineString[idx]) + direction.normalized() * realOffset;
208 }
209 
213 template <typename LineString2dT>
214 bool isConvex(const LineString2dT& lineString, const size_t idx, const bool offsetPositive) {
215  if (idx != 0 && idx + 1 != lineString.size()) {
216  auto isLeft = pointIsLeftOf<BasicPoint2d>(lineString[idx - 1], lineString[idx], lineString[idx + 1]);
217  return offsetPositive ? !isLeft : isLeft;
218  }
219  return true;
220 }
221 
223 
224 template <typename LineString2dT>
225 Convexity getConvexity(const LineString2dT& lineString, const size_t idx, const PointVincinity& pv,
226  const bool offsetPositive) {
227  if (!isConvex(lineString, idx, offsetPositive)) {
228  return Convexity::Concave;
229  }
230  if (pv.following.dot(pv.preceding) < 0) {
231  return Convexity::ConvexSharp;
232  }
233  return Convexity::Convex;
234 }
235 
236 template <typename LineStringT>
237 BasicPoints2d sortAlongS(const LineStringT& ls, const BasicPoints2d& points) {
238  auto idxs = sortAlongSIdxs(ls, points);
239  BasicPoints2d ret;
240  ret.reserve(idxs.size());
241  for (const auto& i : idxs) {
242  ret.emplace_back(points.at(i));
243  }
244  return ret;
245 }
246 
254 template <typename LineString2dT>
255 BasicPoint2d lateralShiftPointAtIndex(const LineString2dT& lineString, const int idx, const double distance) {
256  if (std::abs(idx) + 1 > lineString.size()) {
257  throw InvalidInputError("Index out of bounds");
258  }
259  int startIdx = (idx >= 0) ? std::max(0, idx - 1) : std::max(0, static_cast<int>(lineString.size()) + idx - 1);
260  int endIdx = (idx >= 0)
261  ? std::min(idx + 1, static_cast<int>(lineString.size()) - 1)
262  : std::min(static_cast<int>(lineString.size()) + idx + 1, static_cast<int>(lineString.size()) - 1);
263  int pIdx = (idx >= 0) ? idx : static_cast<int>(lineString.size()) + idx;
264  auto hLineString = utils::toHybrid(lineString);
265  return internal::fromArcCoords(hLineString, hLineString[pIdx], startIdx, endIdx, distance);
266 }
267 
268 namespace bgi = boost::geometry::index;
269 using IndexedSegment2d = std::pair<BasicSegment2d, size_t>;
270 using IndexedSegmentTree = bgi::rtree<IndexedSegment2d, bgi::linear<4>>;
271 using SegmentTree = bgi::rtree<BasicSegment2d, bgi::linear<4>>;
272 
274  const size_t lineStringIdx;
275  const size_t segmentIdx;
276 };
277 
284 template <typename LineString2dT>
285 inline SegmentTree makeSegmentTree(const LineString2dT& lineString) {
286  if (lineString.size() < 2) {
287  throw InvalidInputError("Need line string size of at least 2 to make tree");
288  }
289  SegmentTree tree;
290  std::vector<BasicSegment2d> segContainer;
291  segContainer.reserve(lineString.size() - 1);
292  for (size_t i = 0; i < lineString.size() - 1; ++i) {
293  segContainer.emplace_back(
294  BasicSegment2d{utils::toBasicPoint(lineString[i]), utils::toBasicPoint(lineString[i + 1])});
295  }
296  tree.insert(segContainer);
297 
298  return tree;
299 }
300 
308  if (lineString.size() < 2) {
309  throw InvalidInputError("Need line string size of at least 2 to make tree");
310  }
311  IndexedSegmentTree tree;
312  std::vector<std::pair<BasicSegment2d, size_t>> segContainer;
313  segContainer.reserve(lineString.size() - 1);
314  for (size_t i = 0; i < lineString.size() - 1; ++i) {
315  segContainer.emplace_back(std::make_pair(BasicSegment2d{lineString.at(i), lineString.at(i + 1)}, i));
316  }
317  tree.insert(segContainer);
318  return tree;
319 }
320 
327 inline Optional<size_t> getLowestSAbove(const SelfIntersections2d& selfIntersections, const double minS) {
328  double curMinS = std::numeric_limits<double>::max();
329  Optional<size_t> res;
330  for (size_t i = 0; i < selfIntersections.size(); ++i) {
331  const auto& ci = selfIntersections.at(i);
332  if (ci.firstSegment.s > minS && ci.firstSegment.s < curMinS) {
333  res = i;
334  curMinS = ci.firstSegment.s;
335  }
336  }
337  return res;
338 }
339 
347 inline SelfIntersections2d getSelfIntersectionsAt(const IndexedSegmentTree& tree, const size_t segToCheck,
348  const BasicSegment2d& seg) {
349  SelfIntersections2d curSegIntersections;
350  for (auto it = tree.qbegin(bgi::intersects(seg)); it != tree.qend(); ++it) {
351  const auto& otherSegIdx = it->second;
352  const auto& otherSeg = it->first;
353  if (otherSeg.first != seg.second && otherSeg.second != seg.first && otherSeg.first != seg.first &&
354  otherSegIdx > segToCheck) {
355  BasicPoints2d intersectionPoints;
356  boost::geometry::intersection(seg, otherSeg, intersectionPoints);
357  const auto intersectionPoint = intersectionPoints.front();
358  auto firstS = (intersectionPoint - seg.first).norm();
359  auto lastS = (intersectionPoint - otherSeg.first).norm();
360  curSegIntersections.emplace_back(SelfIntersection2d{SelfIntersectionLong{segToCheck, firstS},
361  SelfIntersectionLong{otherSegIdx, lastS}, intersectionPoint});
362  }
363  }
364 
365  return curSegIntersections;
366 }
367 
370  const size_t nextSegIdx;
371  const double lastS;
372 };
373 
382 inline PointSearchResult findNextPoint(const SelfIntersections2d& curSegIntersections, const BasicSegment2d& seg,
383  const double lastS, const size_t i) {
384  if (!curSegIntersections.empty()) {
385  auto possibeNextIntersection = getLowestSAbove(curSegIntersections, lastS);
386  if (possibeNextIntersection) {
387  const auto& ni = curSegIntersections.at(*possibeNextIntersection);
388  return PointSearchResult{ni.intersectionPoint, ni.lastSegment.idx, ni.lastSegment.s};
389  }
390  }
391  return PointSearchResult{seg.second, i + 1, 0.};
392 }
393 
395  if (lineString.size() <= 3) {
396  return lineString;
397  }
398  auto tree = makeIndexedSegmenTree(lineString);
399  double lastS{0.};
400  BasicLineString2d newLS{lineString.front()};
401  size_t i = 0;
402  while (i < lineString.size() - 2) {
403  BasicSegment2d curSeg{lineString.at(i), lineString.at(i + 1)};
404  auto curSegIntersections = getSelfIntersectionsAt(tree, i, curSeg);
405  auto np = findNextPoint(curSegIntersections, curSeg, lastS, i);
406  newLS.emplace_back(np.nextPoint);
407  i = np.nextSegIdx;
408  lastS = np.lastS;
409  }
410  newLS.push_back(lineString.back());
411  return newLS;
412 }
413 
422 template <typename LineString2dT>
423 inline void checkForInversion(const LineString2dT& oldLS, const BasicLineString2d& offsetLS, const double distance,
424  const double epsilon = 1.e-7) {
425  auto tree = internal::makeSegmentTree(oldLS);
426  for (const auto& p : offsetLS) {
427  auto it = tree.qbegin(internal::bgi::nearest(p, 1));
428  auto pd = geometry::distance2d(BasicLineString2d{it->first, it->second}, p);
429  if (pd + epsilon < distance) {
430  throw GeometryError("Possible Lanelet Inversion");
431  }
432  }
433 }
434 
444 template <typename LineString2dT>
445 inline BasicPoint2d shiftPerpendicular(const LineString2dT& lineString, const size_t idx, const double distance,
446  const bool asLast, const PointVincinity& pv) {
447  if (idx == 0 && asLast) {
448  throw GeometryError("Can't shift first point of line string as endpoint of segment");
449  }
450  if (idx + 1 == lineString.size() && !asLast) {
451  throw GeometryError("Can't shift last point of line string as start point of segment");
452  }
453  Eigen::Vector2d perpendicular = asLast ? pv.preceding.normalized() : pv.following.normalized();
454  Eigen::Vector2d norm(-perpendicular(1), perpendicular(0));
455  return utils::toBasicPoint(lineString[idx]) + norm * distance;
456 }
457 
467 template <typename LineString2dT>
468 inline BasicLineString2d shiftConvexSharp(const LineString2dT& lineString, const size_t idx, const double distance,
469  const PointVincinity& pv) {
470  if (idx == 0) {
471  throw GeometryError("Can't shift first point of line string as sharp convex");
472  }
473  if (idx + 1 == lineString.size()) {
474  throw GeometryError("Can't shift last point of line string as sharp convex");
475  }
476  BasicPoint2d firstP = shiftPerpendicular(lineString, idx, distance, true, pv);
477  BasicPoint2d lastP = shiftPerpendicular(lineString, idx, distance, false, pv);
478  auto alpha = M_PI - std::acos(pv.following.dot(pv.preceding) / (pv.preceding.norm() * pv.following.norm()));
479  auto overshoot = distance * std::tan(M_PI_4 - alpha / 4);
480  return {firstP + pv.preceding.normalized() * overshoot, lastP - pv.following.normalized() * overshoot};
481 }
482 
491 template <typename LineString2dT>
492 inline std::pair<BasicLineString2d, bool> shiftPoint(const LineString2dT& lineString, const double distance,
493  const size_t idx, const PointVincinity& pv) {
494  auto convexity = internal::getConvexity(lineString, idx, pv, distance > 0);
495  if (convexity == Convexity::Concave) {
496  return std::make_pair(BasicLineString2d{shiftPerpendicular(lineString, idx, distance, true, pv)}, false);
497  }
498  if (convexity == Convexity::Convex) {
499  return std::make_pair(BasicLineString2d{shiftLateral(lineString, idx, distance, pv)}, true);
500  }
501  if (convexity == Convexity::ConvexSharp) {
502  return std::make_pair(shiftConvexSharp(lineString, idx, distance, pv), true);
503  }
504  throw InvalidInputError("Unknown Convexity status");
505 }
506 
513 template <typename LineString2dT>
514 inline std::vector<BasicLineString2d> extractConvex(const LineString2dT& lineString, const double distance) {
515  std::vector<BasicLineString2d> offsets;
516  size_t curIdx{0};
517  while (curIdx + 1 < lineString.size()) {
518  auto pv = internal::makeVincinity(lineString, curIdx);
519  BasicLineString2d ls{shiftPerpendicular(lineString, curIdx, distance, false, pv)};
520  for (size_t i = curIdx + 1; i < lineString.size(); ++i) {
521  curIdx = i;
522  auto ipv = internal::makeVincinity(lineString, i);
523  auto shiftResult = shiftPoint(lineString, distance, i, ipv);
524  ls.insert(ls.end(), shiftResult.first.begin(), shiftResult.first.end());
525  if (!shiftResult.second) {
526  break;
527  }
528  }
529  offsets.push_back(ls);
530  }
531  return offsets;
532 }
533 
534 using SegmentMap = std::map<size_t, LineStringsCoordinate>;
535 
539 };
540 
547 inline SegmentSearch makeTree(const std::vector<BasicLineString2d>& convexSubStrings) {
548  IndexedSegmentTree tree;
549  SegmentMap segMap;
550  size_t idx{0};
551  for (size_t i = 0; i < convexSubStrings.size(); ++i) {
552  const auto& ss = convexSubStrings.at(i);
553  for (size_t j = 0; j + 1 < ss.size(); ++j) {
554  BasicSegment2d seg{utils::toBasicPoint(ss.at(j)), utils::toBasicPoint(ss.at(j + 1))};
555  tree.insert(std::make_pair(seg, idx));
556  segMap.emplace(idx, LineStringsCoordinate{i, j});
557  ++idx;
558  }
559  }
560  return SegmentSearch{tree, segMap};
561 }
562 
572 inline BasicLineString2d joinSubStrings(const std::vector<BasicLineString2d>& convexSubStrings,
573  const IndexedSegmentTree& tree, const SegmentMap& segMap) {
574  if (convexSubStrings.empty()) {
575  return BasicLineString2d();
576  }
577  if (convexSubStrings.size() == 1) {
578  return convexSubStrings.front();
579  }
580  double lastS{0.};
581  BasicLineString2d newLS{convexSubStrings.front().front()};
582  size_t i = 0;
583  size_t idx = 0;
584  while (i < convexSubStrings.size()) {
585  const auto& ls = convexSubStrings.at(i);
586  for (size_t j = 0; j + 1 < ls.size(); ++j) {
587  BasicSegment2d curSeg{ls.at(j), ls.at(j + 1)};
588  auto curSegIntersections = getSelfIntersectionsAt(tree, idx, curSeg);
589  auto np = findNextPoint(curSegIntersections, curSeg, lastS, idx);
590  newLS.emplace_back(np.nextPoint);
591  idx = np.nextSegIdx;
592  if (idx >= segMap.size()) {
593  i = convexSubStrings.size();
594  break;
595  }
596  lastS = np.lastS;
597  if (segMap.at(idx).lineStringIdx != i) {
598  i = segMap.at(idx).lineStringIdx;
599  break;
600  }
601  }
602  }
603  newLS.push_back(convexSubStrings.back().back());
604  return newLS;
605 }
606 
607 } // namespace internal
608 
609 template <typename LineStringIterator>
610 double rangedLength(LineStringIterator start, LineStringIterator end) {
611  double l = 0.;
612  helper::forEachPair(start, end, [&l](const auto& seg1, const auto& seg2) { l += distance(seg1, seg2); });
613  return l;
614 }
615 
616 template <typename LineStringT>
617 std::vector<double> lengthRatios(const LineStringT& lineString) {
618  std::vector<double> lengths;
619  if (lineString.size() <= 1) {
620  return lengths;
621  }
622  if (lineString.size() == 2) {
623  return {1.};
624  }
625  const auto totalLength = length(lineString);
626  lengths.reserve(lineString.size() - 1);
627  helper::forEachPair(lineString.begin(), lineString.end(), [&lengths, &totalLength](const auto& p1, const auto& p2) {
628  lengths.push_back(distance(p1, p2) / totalLength);
629  });
630  return lengths;
631 }
632 
633 template <typename LineStringT>
634 std::vector<double> accumulatedLengthRatios(const LineStringT& lineString) {
635  auto lengths = lengthRatios(lineString);
636  helper::forEachPair(lengths.begin(), lengths.end(), [](const auto& l1, auto& l2) { l2 += l1; });
637  return lengths;
638 }
639 
640 template <typename LineStringT>
642  assert(!lineString.empty());
643  if (dist < 0) {
644  lineString = internal::invert(lineString);
645  dist = -dist;
646  }
647 
648  double currentCumulativeLength = 0.0;
649  for (auto first = lineString.begin(), second = std::next(lineString.begin()); second != lineString.end();
650  ++first, ++second) {
651  auto p1 = traits::toBasicPoint(*first);
652  auto p2 = traits::toBasicPoint(*second);
653  double currentLength = distance(p1, p2);
654  currentCumulativeLength += currentLength;
655  if (currentCumulativeLength >= dist) {
656  double remainingDistance = dist - (currentCumulativeLength - currentLength);
657  if (remainingDistance < 1.e-8) {
658  return p1;
659  }
660  return p1 + remainingDistance / currentLength * (p2 - p1);
661  }
662  }
663  return traits::toBasicPoint(lineString.back());
664 }
665 
666 template <typename LineStringT>
667 traits::PointType<LineStringT> nearestPointAtDistance(LineStringT lineString, double dist) {
668  using traits::toBasicPoint;
669  assert(!lineString.empty());
670  if (dist < 0) {
671  lineString = internal::invert(lineString);
672  dist = -dist;
673  }
674  double currentCumulativeLength = 0.0;
675  for (auto first = lineString.begin(), second = std::next(lineString.begin()); second != lineString.end();
676  ++first, ++second) {
677  const auto& p1 = *first;
678  const auto& p2 = *second;
679  double currentLength = distance(p1, p2);
680  currentCumulativeLength += currentLength;
681  if (currentCumulativeLength >= dist) {
682  double remainingDistance = dist - (currentCumulativeLength - currentLength);
683  if (remainingDistance > currentLength / 2.0) {
684  return p2;
685  }
686  return p1;
687  }
688  }
689  return lineString.back();
690 }
691 
692 template <typename LineString3dT>
693 double signedDistance(const LineString3dT& lineString, const BasicPoint3d& p) {
694  static_assert(traits::is3D<LineString3dT>(), "Please call this function with a 3D type!");
695  return internal::signedDistanceImpl(lineString, p).first;
696 }
697 
698 template <typename LineString2dT>
699 double signedDistance(const LineString2dT& lineString, const BasicPoint2d& p) {
700  static_assert(traits::is2D<LineString2dT>(), "Please call this function with a 2D type!");
701  return internal::signedDistanceImpl(lineString, p).first;
702 }
703 
704 template <typename Point2dT>
705 double curvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3) {
706  return std::fabs(signedCurvature2d(p1, p2, p3));
707 }
708 
709 template <typename Point2dT>
710 double signedCurvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3) {
711  // see https://en.wikipedia.org/wiki/Menger_curvature#Definition
712  const double area = 0.5 * ((p2.x() - p1.x()) * (p3.y() - p1.y()) - (p2.y() - p1.y()) * (p3.x() - p1.x()));
713  const double side1 = distance(p1, p2);
714  const double side2 = distance(p1, p3);
715  const double side3 = distance(p2, p3);
716  const double product = side1 * side2 * side3;
717  if (product < 1e-20) {
718  return std::numeric_limits<double>::infinity();
719  }
720  return 4 * area / product;
721 }
722 
723 template <typename LineString2dT>
724 ArcCoordinates toArcCoordinates(const LineString2dT& lineString, const BasicPoint2d& point) {
725  auto res = internal::signedDistanceImpl(lineString, point);
726  auto dist = res.first;
727  const auto& projectedPoint = res.second;
728  // find first point in segment in linestring
729  double length = 0.;
730  auto accumulateLength = [&](const auto& first, const auto& second) {
731  if (boost::geometry::equals(first, projectedPoint.closestSegment.first)) {
732  return true;
733  }
734  length += distance(first, second);
735  return false;
736  };
737  helper::forEachPairUntil(lineString.begin(), lineString.end(), accumulateLength);
738  length += distance(projectedPoint.closestSegment.first, projectedPoint.projectedPoint);
739  return {length, dist};
740 }
741 
742 template <typename LineString3dT>
743 IfLS<LineString3dT, BoundingBox3d> boundingBox3d(const LineString3dT& lineString) {
744  static_assert(traits::is3D<LineString3dT>(), "Please call this function with a 3D type!");
745  BoundingBox3d bb;
746  for (const auto& p : lineString) {
747  bb.extend(traits::toBasicPoint(p));
748  }
749  return bb;
750 }
751 
752 template <typename LineString2dT>
753 IfLS<LineString2dT, BoundingBox2d> boundingBox2d(const LineString2dT& lineString) {
754  BoundingBox2d bb;
755  for (const auto& p : traits::to2D(lineString)) {
757  }
758  return bb;
759 }
760 
761 template <typename LineString3dT, typename>
762 BasicPoint3d project(const LineString3dT& lineString, const BasicPoint3d& pointToProject) {
763  static_assert(traits::is3D<LineString3dT>(), "Please call this function with a 3D type!");
764  return internal::project(utils::toHybrid(lineString), pointToProject);
765 }
766 
767 template <typename LineString2dT, typename>
768 BasicPoint2d project(const LineString2dT& lineString, const BasicPoint2d& pointToProject) {
769  static_assert(traits::is2D<LineString2dT>(), "Please call this function with a 2D type!");
770  return internal::project(utils::toHybrid(lineString), pointToProject);
771 }
772 
773 template <typename LineString3dT>
774 IfLS<LineString3dT, bool> intersects3d(const LineString3dT& linestring, const LineString3dT& otherLinestring,
775  double heightTolerance) {
776  auto ls2d(traits::toHybrid(traits::to2D(linestring)));
777  auto ols2d(traits::toHybrid(traits::to2D(otherLinestring)));
778  BasicPoints2d intersections;
779  boost::geometry::intersection(ls2d, ols2d, intersections);
780  auto distanceSmallerTolerance = [heightTolerance, &linestring, &otherLinestring](const auto& point) {
781  auto pProj1 = project(linestring, BasicPoint3d(point.x(), point.y(), 0));
782  auto pProj2 = project(otherLinestring, BasicPoint3d(point.x(), point.y(), 0));
783  return distance(pProj1, pProj2) < heightTolerance;
784  };
785  return std::any_of(intersections.begin(), intersections.end(), distanceSmallerTolerance);
786 }
787 
788 template <typename LineString2dT>
790  const LineString2dT& l2) {
791  static_assert(traits::is2D<LineString2dT>(), "Please call this function with a 2D type!");
793 }
794 
795 template <typename LineString3dT>
797  const LineString3dT& l2) {
798  static_assert(traits::is3D<LineString3dT>(), "Please call this function with a 3D type!");
800 }
801 
802 template <typename LineString3d1T, typename LineString3d2T>
803 IfLS2<LineString3d1T, LineString3d2T, double> distance3d(const LineString3d1T& l1, const LineString3d2T& l2) {
805  return (projPoint.first - projPoint.second).norm();
806 }
807 
808 template <typename LineString1T, typename LineString2T>
809 std::pair<LineString1T, LineString2T> align(LineString1T left, LineString2T right) {
810  using traits::toBasicPoint;
811  // degenerated case
812  if ((left.size() <= 1 && right.size() <= 1) || right.empty() || left.empty()) {
813  return {left, right};
814  }
815  auto getMiddlePoint = [](auto& ls) {
816  return ls.size() > 2 ? toBasicPoint(ls[ls.size() / 2]) : (toBasicPoint(ls.front()) + toBasicPoint(ls.back())) * 0.5;
817  };
819  bool rightOfLeft = signedDistance(left, getMiddlePoint(right)) < 0;
820  if (!rightOfLeft && left.size() > 1) {
821  left = left.invert();
822  }
823 
824  bool leftOfRight = signedDistance(right, getMiddlePoint(left)) > 0;
825  if (!leftOfRight && right.size() > 1) {
826  right = right.invert();
827  }
828  return {left, right};
829 }
830 
831 template <typename LineString2dT>
832 BasicPoint2d fromArcCoordinates(const LineString2dT& lineString, const ArcCoordinates& arcCoords) {
833  if (lineString.size() < 2) {
834  throw InvalidInputError("Can't use arc coordinates on degenerated line string");
835  }
836  auto hLineString = utils::toHybrid(lineString);
837  auto ratios = accumulatedLengthRatios(lineString);
838  const auto llength = length(lineString);
839  size_t startIdx{};
840  size_t endIdx{};
841  for (size_t i = 0; i < ratios.size(); ++i) {
842  if (ratios.at(i) * llength > arcCoords.length) {
843  startIdx = i;
844  endIdx = i + 1;
845  break;
846  }
847  }
848  if (endIdx == 0) {
849  endIdx = lineString.size() - 1;
850  startIdx = endIdx - 1;
851  }
852  return internal::fromArcCoords(hLineString, interpolatedPointAtDistance(utils::to2D(lineString), arcCoords.length),
853  startIdx, endIdx, arcCoords.distance);
854 }
855 
856 template <typename LineString2dT>
857 BasicLineString2d offsetNoThrow(const LineString2dT& lineString, const double distance) {
858  auto convexSubStrings = internal::extractConvex(lineString, distance);
859  auto segSearch = internal::makeTree(convexSubStrings);
860  auto newLS = internal::joinSubStrings(convexSubStrings, segSearch.tree, segSearch.map);
861  return newLS;
862 }
863 
864 template <typename LineString2dT>
865 BasicLineString2d offset(const LineString2dT& lineString, const double distance) {
866  auto newLS = offsetNoThrow(lineString, distance);
867  internal::checkForInversion(lineString, newLS, distance);
868  return newLS;
869 }
870 } // namespace geometry
871 } // namespace lanelet
lanelet::ArcCoordinates::length
double length
length along linestring
Definition: primitives/Point.h:99
lanelet::geometry::boundingBox3d
IfAr< AreaT, BoundingBox3d > boundingBox3d(const AreaT &area)
calculates 3d bounding box
Definition: geometry/impl/Area.h:30
lanelet::IfLS2
std::enable_if_t< traits::isLinestringT< T1 >() &&traits::isLinestringT< T2 >(), RetT > IfLS2
Definition: primitives/LineString.h:774
lanelet::geometry::internal::getLowestSAbove
Optional< size_t > getLowestSAbove(const SelfIntersections2d &selfIntersections, const double minS)
getLowestSAbove find self-intersection nearest to the given start point along a segment
Definition: geometry/impl/LineString.h:327
lanelet::geometry::internal::GetGeometry< T, IfLS< T, void > >::twoD
static auto twoD(const T &geometry)
Definition: geometry/impl/LineString.h:33
lanelet::geometry::internal::getSelfIntersectionsAt
SelfIntersections2d getSelfIntersectionsAt(const IndexedSegmentTree &tree, const size_t segToCheck, const BasicSegment2d &seg)
getSelfIntersectionsAt find list of intersections based on a segment search tree
Definition: geometry/impl/LineString.h:347
lanelet::CompoundHybridLineString2d
A hybrid compound linestring in 2d (returns BasicPoint2d)
Definition: CompoundLineString.h:306
lanelet::traits::toBasicSegment
auto toBasicSegment(const Segment< PointT > &s)
Definition: primitives/LineString.h:75
lanelet::geometry::fromArcCoordinates
BasicPoint2d fromArcCoordinates(const LineString2dT &lineString, const ArcCoordinates &arcCoords)
create a point by moving laterally arcCoords.distance from the linestring point at arcCoords....
Definition: geometry/impl/LineString.h:832
lanelet::GeometryError
Thrown when a geometric operation is not valid.
Definition: Exceptions.h:63
lanelet::geometry::internal::ProjectedPointInfo
Definition: geometry/impl/LineString.h:72
lanelet::geometry::interpolatedPointAtDistance
traits::BasicPointT< traits::PointType< LineStringT > > interpolatedPointAtDistance(LineStringT lineString, double dist)
Definition: geometry/impl/LineString.h:641
lanelet::helper::forEachPair
void forEachPair(FwIter first, FwIter end, Func f)
apply a function for each pair of adjacent elements in a range
Definition: GeometryHelper.h:15
lanelet::geometry::internal::IndexedSegment2d
std::pair< BasicSegment2d, size_t > IndexedSegment2d
Definition: geometry/impl/LineString.h:269
lanelet::traits::to2D
BoundingBox2d to2D(const BoundingBox3d &primitive)
Definition: primitives/BoundingBox.h:304
lanelet::geometry::align
std::pair< LineString1T, LineString2T > align(LineString1T left, LineString2T right)
inverts the two linestrings such that they are parallel
Definition: geometry/impl/LineString.h:809
lanelet
Definition: Attribute.h:13
lanelet::geometry::internal::LineStringsCoordinate::segmentIdx
const size_t segmentIdx
Definition: geometry/impl/LineString.h:275
lanelet::geometry::internal::crossProd
auto crossProd(const BasicPoint3d &p1, const BasicPoint3d &p2)
Definition: geometry/impl/LineString.h:37
lanelet::BasicPoint3d
Eigen::Vector3d BasicPoint3d
a simple 3d-point
Definition: primitives/Point.h:19
GeometryHelper.h
lanelet::geometry::internal::PointSearchResult::nextPoint
const BasicPoint2d nextPoint
Definition: geometry/impl/LineString.h:369
lanelet::geometry::internal::fromArcCoords
BasicPoint2d fromArcCoords(const HybridLineStringT &hLineString, const BasicPoint2d &projStart, const size_t startIdx, const size_t endIdx, const double distance)
Definition: geometry/impl/LineString.h:140
lanelet::geometry::internal::makeVincinity
PointVincinity makeVincinity(const LineString2dT &lineString, const size_t idx)
makeVincinity create pair of preceding and following point on a line string
Definition: geometry/impl/LineString.h:169
lanelet::geometry::lengthRatios
std::vector< double > lengthRatios(const LineStringT &lineString)
Definition: geometry/impl/LineString.h:617
lanelet::IfLS
std::enable_if_t< traits::isLinestringT< T >(), RetT > IfLS
Definition: primitives/LineString.h:771
lanelet::traits::toHybrid
constexpr auto toHybrid(const LineStringT ls)
Definition: primitives/LineString.h:765
lanelet::geometry::project
BasicPoint3d project(const LineString3dT &lineString, const BasicPoint3d &pointToProject)
Projects the given point in 3d to the LineString.
Definition: geometry/impl/LineString.h:762
p2
BasicPoint p2
Definition: LineStringGeometry.cpp:167
p
BasicPoint p
Definition: LineStringGeometry.cpp:196
lanelet::geometry::internal::checkForInversion
void checkForInversion(const LineString2dT &oldLS, const BasicLineString2d &offsetLS, const double distance, const double epsilon=1.e-7)
checkForInversion asserts that a shifted line string is not inverted relative to the original line st...
Definition: geometry/impl/LineString.h:423
lanelet::geometry::internal::Convexity::Convex
@ Convex
lanelet::geometry::intersects3d
IfLL< Lanelet1T, bool > intersects3d(const Lanelet1T &lanelet, const Lanelet2T &otherLanelet, double heightTolerance)
test whether two lanelets intersect in 2d.
Definition: geometry/impl/Lanelet.h:111
lanelet::geometry::internal::isLeftOf
bool isLeftOf(const LineStringT &ls, const BasicPointT &p, const ProjectedPointInfo< BasicPointT > &ppInfo)
Definition: geometry/impl/LineString.h:78
lanelet::traits::toBasicPoint
auto toBasicPoint(const PointT &point) -> std::enable_if_t< PointTraits< PointT >::IsPrimitive, BasicPointT< PointT >>
Definition: Traits.h:165
lanelet::geometry::internal::Convexity::ConvexSharp
@ ConvexSharp
lanelet::geometry::internal::LineStringsCoordinate::lineStringIdx
const size_t lineStringIdx
Definition: geometry/impl/LineString.h:274
lanelet::geometry::internal::SelfIntersection2d::intersectionPoint
BasicPoint2d intersectionPoint
Definition: geometry/impl/LineString.h:22
lanelet::geometry::internal::findPoint
auto findPoint(const LineStringT &ls, const BasicPointT &p)
Definition: geometry/impl/LineString.h:47
lanelet::geometry::internal::extractConvex
std::vector< BasicLineString2d > extractConvex(const LineString2dT &lineString, const double distance)
extractConvex get convex parts of line string offset by distance.
Definition: geometry/impl/LineString.h:514
lanelet::geometry::internal::sortAlongS
BasicPoints2d sortAlongS(const LineStringT &ls, const BasicPoints2d &points)
Definition: geometry/impl/LineString.h:237
lanelet::Segment
std::pair< PointT, PointT > Segment
Definition: primitives/LineString.h:18
lanelet::geometry::offsetNoThrow
BasicLineString2d offsetNoThrow(const LineString2dT &lineString, const double distance)
create a linestring that is offset to the original one. the result.
Definition: geometry/impl/LineString.h:857
lanelet::geometry::internal::SelfIntersection2d::lastSegment
SelfIntersectionLong lastSegment
Definition: geometry/impl/LineString.h:21
lanelet::geometry::internal::signedDistanceImpl
std::pair< double, ProjectedPointInfo< traits::BasicPointT< PointT > > > signedDistanceImpl(const LineStringT lineString, const PointT &p)
Definition: geometry/impl/LineString.h:128
lanelet::geometry::internal::joinSubStrings
BasicLineString2d joinSubStrings(const std::vector< BasicLineString2d > &convexSubStrings, const IndexedSegmentTree &tree, const SegmentMap &segMap)
joinSubStrings create one line string of several ones by walking along them and joining them at the f...
Definition: geometry/impl/LineString.h:572
lanelet::geometry::internal::SegmentSearch
Definition: geometry/impl/LineString.h:536
lanelet::geometry::internal::SelfIntersection2d::firstSegment
SelfIntersectionLong firstSegment
Definition: geometry/impl/LineString.h:20
lanelet::geometry::internal::shiftPoint
std::pair< BasicLineString2d, bool > shiftPoint(const LineString2dT &lineString, const double distance, const size_t idx, const PointVincinity &pv)
shiftPoint in lateral direction
Definition: geometry/impl/LineString.h:492
lanelet::ArcCoordinates::distance
double distance
signed distance to linestring (left=positive)
Definition: primitives/Point.h:100
lanelet::geometry::internal::IndexedSegmentTree
bgi::rtree< IndexedSegment2d, bgi::linear< 4 > > IndexedSegmentTree
Definition: geometry/impl/LineString.h:270
lanelet::ArcCoordinates
Describes a position in linestring coordinates.
Definition: primitives/Point.h:98
lanelet::ConstHybridLineString2d
A Linestring that returns BasicPoint2d instead of Point2d.
Definition: primitives/LineString.h:636
lanelet::geometry::internal::PointSearchResult
Definition: geometry/impl/LineString.h:368
Point.h
lanelet::geometry::internal::GetGeometry< T, IfLS< T, void > >::threeD
static auto threeD(const T &geometry)
Definition: geometry/impl/LineString.h:34
lanelet::BoundingBox2d
Axis-Aligned bounding box in 2d.
Definition: primitives/BoundingBox.h:23
lanelet::BoundingBox2d::extend
BoundingBox2d & extend(const Eigen::MatrixBase< Derived > &p)
Definition: primitives/BoundingBox.h:178
lanelet::geometry::internal::shiftLateral
BasicPoint2d shiftLateral(const LineString2dT &lineString, const size_t idx, const double offset, const PointVincinity &pv)
shiftLateral shift point along the bisectrix
Definition: geometry/impl/LineString.h:191
lanelet::traits::PointType
typename LineStringTraits< LineStringT >::PointType PointType
Definition: Traits.h:191
lanelet::geometry::internal::projectedPoint3d
std::pair< BasicPoint3d, BasicPoint3d > projectedPoint3d(const ConstHybridLineString3d &l1, const ConstHybridLineString3d &l2)
Definition: LineStringGeometry.cpp:390
lanelet::Optional
boost::optional< T > Optional
Definition: Optional.h:7
lanelet::geometry::internal::Convexity::Concave
@ Concave
lanelet::geometry::internal::PointVincinity
Definition: geometry/impl/LineString.h:26
lanelet::geometry::internal::shiftPerpendicular
BasicPoint2d shiftPerpendicular(const LineString2dT &lineString, const size_t idx, const double distance, const bool asLast, const PointVincinity &pv)
shiftPerpendicular shift point perpendicular to either the preceding or following segment
Definition: geometry/impl/LineString.h:445
lanelet::BoundingBox3d
Eigen::AlignedBox3d BoundingBox3d
Convenience type for an axis aligned bounding box in 3d.
Definition: primitives/BoundingBox.h:283
lanelet::geometry::internal::ProjectedPointInfo::projectedPoint
PointT projectedPoint
Definition: geometry/impl/LineString.h:74
lanelet::geometry::internal::PointSearchResult::lastS
const double lastS
Definition: geometry/impl/LineString.h:371
lanelet::CompoundHybridLineString3d
A hybrid compound linestring in 3d (returns BasicPoint3d)
Definition: CompoundLineString.h:327
lanelet::geometry::internal::findNextPoint
PointSearchResult findNextPoint(const SelfIntersections2d &curSegIntersections, const BasicSegment2d &seg, const double lastS, const size_t i)
findNextPoint find next point to walk on a line strings join operation
Definition: geometry/impl/LineString.h:382
lanelet::BasicLineString2d
BasicPoints2d BasicLineString2d
Definition: primitives/LineString.h:14
lanelet::geometry::nearestPointAtDistance
traits::PointType< LineStringT > nearestPointAtDistance(LineStringT lineString, double dist)
returns the cosest point to a position on the linestring
Definition: geometry/impl/LineString.h:667
lanelet::geometry::internal::pointIsLeftOf
bool pointIsLeftOf(const PointT &pSeg1, const PointT &pSeg2, const PointT &p)
Definition: geometry/impl/LineString.h:52
lanelet::geometry::projectedPoint2d
IfLS< LineString2dT, std::pair< BasicPoint2d, BasicPoint2d > > projectedPoint2d(const LineString2dT &l1, const LineString2dT &l2)
Computes the projected points on the two linestrings for the shortest distance.
Definition: geometry/impl/LineString.h:789
p1
BasicPoint p1
Definition: LineStringGeometry.cpp:166
lanelet::geometry::accumulatedLengthRatios
std::vector< double > accumulatedLengthRatios(const LineStringT &lineString)
Definition: geometry/impl/LineString.h:634
lanelet::geometry::internal::PointVincinity::preceding
const BasicPoint2d preceding
Definition: geometry/impl/LineString.h:27
lanelet::geometry::internal::PointSearchResult::nextSegIdx
const size_t nextSegIdx
Definition: geometry/impl/LineString.h:370
lanelet::geometry::internal::PointVincinity::following
const BasicPoint2d following
Definition: geometry/impl/LineString.h:28
lanelet::geometry::signedDistance
double signedDistance(const LineString3dT &lineString, const BasicPoint3d &p)
Definition: geometry/impl/LineString.h:693
lanelet::geometry::curvature2d
double curvature2d(const Point2dT &p1, const Point2dT &p2, const Point2dT &p3)
Definition: geometry/impl/LineString.h:705
lanelet::BasicPoint2d
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > BasicPoint2d
a simple 2d-point
Definition: primitives/Point.h:20
lanelet::geometry::internal::SelfIntersections2d
std::vector< SelfIntersection2d > SelfIntersections2d
Definition: geometry/impl/LineString.h:24
lanelet::geometry::closestSegment
Segment< BasicPoint2d > closestSegment(const BasicLineString2d &lineString, const BasicPoint2d &pointToProject)
find the segment on a 2d line string that is closest to a given point, determined by boost::geometry:...
Definition: LineStringGeometry.cpp:442
lanelet::geometry::internal::lateralShiftPointAtIndex
BasicPoint2d lateralShiftPointAtIndex(const LineString2dT &lineString, const int idx, const double distance)
create a point by moving distance laterally from the linestring at the point idx. The direction is th...
Definition: geometry/impl/LineString.h:255
lanelet::geometry::internal::Convexity
Convexity
Definition: geometry/impl/LineString.h:222
lanelet::geometry::internal::isConvex
bool isConvex(const LineString2dT &lineString, const size_t idx, const bool offsetPositive)
Definition: geometry/impl/LineString.h:214
Traits.h
lanelet::geometry::internal::project
BasicPoint2d project(const BasicLineString2d &lineString, const BasicPoint2d &pointToProject)
Definition: LineStringGeometry.cpp:418
lanelet::geometry::boundingBox2d
IfAr< AreaT, BoundingBox2d > boundingBox2d(const AreaT &area)
calculates an up-right 2d bounding box
Definition: geometry/impl/Area.h:25
lanelet::geometry::internal::shiftConvexSharp
BasicLineString2d shiftConvexSharp(const LineString2dT &lineString, const size_t idx, const double distance, const PointVincinity &pv)
shiftConvexSharp shift corner that is convex at a more than 90 degree angle. Inserts a new point to l...
Definition: geometry/impl/LineString.h:468
lanelet::geometry::internal::invert
LineStringT invert(const LineStringT &ls)
Definition: geometry/impl/LineString.h:57
lanelet::geometry::internal::SegmentSearch::map
SegmentMap map
Definition: geometry/impl/LineString.h:538
lanelet::geometry::internal::LineStringsCoordinate
Definition: geometry/impl/LineString.h:273
lanelet::geometry::toArcCoordinates
ArcCoordinates toArcCoordinates(const LineString2dT &lineString, const BasicPoint2d &point)
Transform a point to the coordinates of the linestring.
Definition: geometry/impl/LineString.h:724
lanelet::geometry::internal::SelfIntersectionLong
Definition: geometry/impl/LineString.h:14
lanelet::geometry::internal::makeIndexedSegmenTree
IndexedSegmentTree makeIndexedSegmenTree(const BasicLineString2d &lineString)
makeIndexedSegmenTree create search tree of segments with indices
Definition: geometry/impl/LineString.h:307
lanelet::geometry::distance3d
IfLS2< LineString3d1T, LineString3d2T, double > distance3d(const LineString3d1T &l1, const LineString3d2T &l2)
Definition: geometry/impl/LineString.h:803
lanelet::geometry::internal::ProjectedPointInfo::closestSegment
Segment< PointT > closestSegment
Definition: geometry/impl/LineString.h:73
LineString.h
distance
Optional< double > distance
Definition: LineStringGeometry.cpp:168
lanelet::ConstHybridLineString3d
A Linestring that returns BasicPoint3d instead of Point3d.
Definition: primitives/LineString.h:585
d
double d
Definition: RegulatoryElementGeometry.cpp:69
lanelet::geometry::internal::SegmentMap
std::map< size_t, LineStringsCoordinate > SegmentMap
Definition: geometry/impl/LineString.h:534
lanelet::geometry::internal::removeSelfIntersections
BasicLineString2d removeSelfIntersections(const BasicLineString2d &lineString)
Definition: geometry/impl/LineString.h:394
lanelet::traits::BasicPointT
typename PointTraits< PointT >::BasicPoint BasicPointT
Definition: Traits.h:156
lanelet::geometry::signedCurvature2d
double signedCurvature2d(const Point2dT &p1, const Point2dT &p2, const Point2dT &p3)
Definition: geometry/impl/LineString.h:710
lanelet::geometry::distance2d
double distance2d(const RegulatoryElement &regElem, const BasicPoint2d &p)
Definition: RegulatoryElementGeometry.cpp:85
lanelet::geometry::internal::SelfIntersectionLong::s
double s
Definition: geometry/impl/LineString.h:16
lanelet::geometry::internal::SelfIntersection2d
Definition: geometry/impl/LineString.h:19
lanelet::geometry::internal::SelfIntersectionLong::idx
size_t idx
Definition: geometry/impl/LineString.h:15
lanelet::helper::forEachPairUntil
FwIter forEachPairUntil(FwIter first, FwIter end, Func f)
Apply a function of all pairs in a sequenc in sorted order until a predicate returns true.
Definition: GeometryHelper.h:38
lanelet::geometry::internal::getConvexity
Convexity getConvexity(const LineString2dT &lineString, const size_t idx, const PointVincinity &pv, const bool offsetPositive)
Definition: geometry/impl/LineString.h:225
lanelet::geometry::internal::projectedPoint2d
std::pair< BasicPoint2d, BasicPoint2d > projectedPoint2d(const ConstHybridLineString2d &l1, const ConstHybridLineString2d &l2)
Definition: LineStringGeometry.cpp:347
lanelet::geometry::internal::makeSegmentTree
SegmentTree makeSegmentTree(const LineString2dT &lineString)
makeIndexedSegmenTree create search tree of segments
Definition: geometry/impl/LineString.h:285
lanelet::BasicSegment2d
Segment< BasicPoint2d > BasicSegment2d
Definition: primitives/LineString.h:24
lanelet::BasicPoints2d
std::vector< Eigen::Vector2d, Eigen::aligned_allocator< Eigen::Vector2d > > BasicPoints2d
multiple simple 2d-points
Definition: primitives/Point.h:22
lanelet::geometry::internal::makeTree
SegmentSearch makeTree(const std::vector< BasicLineString2d > &convexSubStrings)
makeTree create search tree of segments from line strings
Definition: geometry/impl/LineString.h:547
lanelet::geometry::internal::SegmentTree
bgi::rtree< BasicSegment2d, bgi::linear< 4 > > SegmentTree
Definition: geometry/impl/LineString.h:271
lanelet::traits::to3D
BoundingBox3d to3D(const BoundingBox2d &primitive)
Definition: primitives/BoundingBox.h:303
lanelet::geometry::rangedLength
double rangedLength(LineStringIterator start, LineStringIterator end)
Definition: geometry/impl/LineString.h:610
lanelet::geometry::projectedPoint3d
IfLS< LineString3dT, std::pair< BasicPoint3d, BasicPoint3d > > projectedPoint3d(const LineString3dT &l1, const LineString3dT &l2)
Computes the projected points on the two linestrings for the shortest distance.
Definition: geometry/impl/LineString.h:796
lanelet::geometry::offset
BasicLineString2d offset(const LineString2dT &lineString, const double distance)
create a linestring that is offset to the original one. Guarantees no self-intersections and no inver...
Definition: geometry/impl/LineString.h:865
lanelet::geometry::internal::SegmentSearch::tree
IndexedSegmentTree tree
Definition: geometry/impl/LineString.h:537
lanelet::InvalidInputError
Thrown when a function was called with invalid input arguments.
Definition: Exceptions.h:56
lanelet::BasicLineString3d
BasicPoints3d BasicLineString3d
Definition: primitives/LineString.h:15


lanelet2_core
Author(s): Fabian Poggenhans
autogenerated on Thu Mar 6 2025 03:25:52