LaneletMap.cpp
Go to the documentation of this file.
1 #define LANELET_LAYER_DEFINITION
3 
4 #include <atomic>
5 #include <boost/geometry/algorithms/disjoint.hpp> //used but not included by rtree
6 #include <boost/geometry/algorithms/equals.hpp> //used but not included by rtree
7 #include <boost/geometry/index/rtree.hpp>
8 #include <chrono>
9 #include <random>
10 
17 
18 // boost geometry stuff
19 namespace bgi = boost::geometry::index;
20 
21 // we need this hack to cleanly remove things from the RTree
22 // because remove() internally uses equals to find the correct element to
23 // remove. However, this is not implemented for our primitives.
24 namespace boost {
25 namespace geometry {
26 template <>
27 bool equals<lanelet::LineString3d, lanelet::LineString3d>(const lanelet::LineString3d& geometry1,
28  const lanelet::LineString3d& geometry2) {
29  return geometry1 == geometry2;
30 }
31 template <>
32 bool equals<lanelet::Polygon3d, lanelet::Polygon3d>(const lanelet::Polygon3d& geometry1,
33  const lanelet::Polygon3d& geometry2) {
34  return geometry1 == geometry2;
35 }
36 } // namespace geometry
37 } // namespace boost
38 
39 // need id visitor before hash
40 namespace lanelet {
41 namespace {
42 
43 struct IdVisitor : public RuleParameterVisitor {
44  Id getId(const ConstRuleParameter& from) {
45  boost::apply_visitor(*this, from);
46  return this->id;
47  }
48  void operator()(const ConstPoint3d& p) override { id = p.id(); }
49  void operator()(const ConstLineString3d& ls) override { id = ls.id(); }
50  void operator()(const ConstPolygon3d& p) override { id = p.id(); }
51  void operator()(const ConstWeakLanelet& ll) override {
52  if (ll.expired()) {
53  return;
54  }
55  id = ll.lock().id();
56  }
57  void operator()(const ConstWeakArea& ar) override {
58  if (ar.expired()) {
59  return;
60  }
61  id = ar.lock().id();
62  }
63  Id id{InvalId};
64 };
65 
66 template <typename T>
67 inline Id getId(const T& obj) {
68  return obj.id();
69 }
70 template <>
72  return obj->id();
73 }
74 
75 template <typename T>
76 std::unordered_map<Id, T> toMap(const std::vector<T>& vec) {
77  using Map = std::unordered_map<Id, T>;
78  auto elems = utils::transform(vec, [](auto& elem) { return typename Map::value_type(getId(elem), elem); });
79  return std::unordered_map<Id, T>(std::make_move_iterator(elems.begin()), std::make_move_iterator(elems.end()));
80 }
81 
82 LineString3d uglyRemoveConst(const ConstLineString3d& ls) {
83  // this is ugly but legal, because every const data object used to be a
84  // non-const data object when the LineString was initialized.
85  auto data = std::const_pointer_cast<LineStringData>(ls.constData());
86  return LineString3d(data, ls.inverted());
87 }
88 } // namespace
89 } // namespace lanelet
90 
91 namespace std {
92 template <>
93 struct hash<lanelet::ConstRuleParameter> {
94  size_t operator()(const lanelet::ConstRuleParameter& x) const noexcept {
95  return std::hash<lanelet::Id>()(lanelet::IdVisitor().getId(x));
96  }
97 };
98 } // namespace std
99 
100 namespace lanelet {
101 using namespace traits;
102 namespace {
103 template <typename RType, typename Pair>
104 auto getSecond(const std::vector<Pair>& p) {
105  std::vector<RType> v;
106  v.reserve(p.size());
107  std::transform(p.cbegin(), p.cend(), std::back_inserter(v), [](const auto& elem) { return elem.second; });
108  return v;
109 }
110 
111 template <typename PrimT, typename LayerT>
112 void assignIdIfInvalid(PrimT&& prim, LayerT& layer) {
113  static_assert(std::is_same<typename LayerT::PrimitiveT, std::decay_t<PrimT>>::value,
114  "Primitive and layer not identical");
115  if (prim.id() == InvalId) {
116  prim.setId(layer.uniqueId());
117  }
118 }
119 
120 struct AssignIdVisitor : public boost::static_visitor<void> {
121  explicit AssignIdVisitor(LaneletMap* map) : map_(map) {}
122  void operator()(Point3d p) { assignIdIfInvalid(p, map_->pointLayer); }
123  void operator()(LineString3d l) { assignIdIfInvalid(l, map_->lineStringLayer); }
124  void operator()(Polygon3d p) { assignIdIfInvalid(p, map_->polygonLayer); }
125  void operator()(const WeakLanelet& ll) {
126  if (ll.expired()) { // NOLINT
127  return;
128  }
129  assignIdIfInvalid(ll.lock(), map_->laneletLayer);
130  }
131  void operator()(const WeakArea& ar) {
132  if (ar.expired()) {
133  return;
134  }
135  assignIdIfInvalid(ar.lock(), map_->areaLayer);
136  }
137 
138  private:
139  LaneletMap* map_;
140 };
141 
142 struct AddVisitor : public lanelet::internal::MutableParameterVisitor {
143  explicit AddVisitor(LaneletMap* map) : map_(map) {}
144 
145  void operator()(const Point3d& p) override { map_->add(p); }
146  void operator()(const LineString3d& l) override { map_->add(l); }
147  void operator()(const Polygon3d& p) override { map_->add(p); }
148  void operator()(const WeakLanelet& ll) override {
149  if (ll.expired()) { // NOLINT
150  return;
151  }
152  map_->add(ll.lock());
153  }
154  void operator()(const WeakArea& ar) override {
155  if (ar.expired()) { // NOLINT
156  return;
157  }
158  map_->add(ar.lock());
159  }
160 
161  private:
162  LaneletMap* map_;
163 };
164 
165 template <typename T, typename MapT, typename KeyT, typename Func>
166 std::vector<T> forEachMatchInMultiMap(const MapT& map, const KeyT& key, Func&& f) {
167  auto range = map.equal_range(key);
168  return utils::transform(range.first, range.second, f);
169 }
170 
171 template <typename RetT, typename TreeT, typename Func>
172 Optional<RetT> findUntilImpl(TreeT&& tree, const BoundingBox2d& area, const Func& func) {
173  if (tree.empty()) {
174  return {};
175  }
176  auto found = std::find_if(tree.qbegin(bgi::intersects(area)), tree.qend(),
177  [&func](auto& node) { return func(node.first, node.second); });
178  if (found != tree.qend()) {
179  return RetT(found->second);
180  }
181  return {};
182 }
183 
184 template <typename RetT, typename TreeT, typename Func>
185 Optional<RetT> nearestUntilImpl(TreeT&& tree, const BasicPoint2d& point, const Func& func) {
186  if (tree.empty()) {
187  return {};
188  }
189  auto found = std::find_if(tree.qbegin(bgi::nearest(point, unsigned(tree.size()))), tree.qend(),
190  [&func](auto& node) { return func(node.first, node.second); });
191  if (found != tree.qend()) {
192  return RetT(found->second);
193  }
194  return {};
195 }
196 
197 template <typename T>
198 void checkId(T& t) {
199  if (t.id() == InvalId) {
200  t.setId(utils::getId());
201  } else {
202  utils::registerId(t.id());
203  }
204 }
205 
206 template <typename ConstLaneletsT, typename ConstAreasT>
207 LaneletMapUPtr createMapFromConst(const ConstLaneletsT& fromLanelets, const ConstAreasT& fromAreas) {
208  // sorry, we temporarily have to const cast our primitives back to non-const to be able to create a const map. Its not
209  // beautiful but valid.
210  auto lanelets = utils::transform(fromLanelets, [](const ConstLanelet& llt) {
211  return Lanelet(std::const_pointer_cast<LaneletData>(llt.constData()), llt.inverted());
212  });
213  auto areas = utils::transform(
214  fromAreas, [](const ConstArea& ar) { return Area(std::const_pointer_cast<AreaData>(ar.constData())); });
215  return utils::createMap(lanelets, areas);
216 }
217 } // namespace
218 } // namespace lanelet
219 
220 namespace lanelet {
221 template <typename T>
222 struct UsageLookup {
223  void add(const T& prim) {
224  for (const auto& elem : prim) {
225  ownedLookup.insert(std::make_pair(elem, prim));
226  }
227  }
228  std::unordered_multimap<traits::ConstPrimitiveType<traits::OwnedT<T>>, T> ownedLookup;
229 };
230 
231 template <>
233  void add(const RegulatoryElementPtr& prim) {
234  for (const auto& param : prim->getParameters()) {
235  for (const auto& rule : param.second) {
236  ownedLookup.insert(std::make_pair(rule, prim));
237  }
238  }
239  }
240  std::unordered_multimap<ConstRuleParameter, RegulatoryElementPtr> ownedLookup;
241 };
242 template <>
243 struct UsageLookup<Area> {
244  void add(Area area) {
245  auto insertElement = [area, this](auto elem) { ownedLookup.insert(std::make_pair(elem, area)); };
246  utils::forEach(area.outerBound(), insertElement);
247 
248  for (const auto& innerBound : area.innerBounds()) {
249  utils::forEach(innerBound, insertElement);
250  }
251 
252  for (const auto& elem : area.regulatoryElements()) {
253  regElemLookup.insert(std::make_pair(elem, area));
254  }
255  }
256  std::unordered_multimap<ConstLineString3d, Area> ownedLookup;
257  std::unordered_multimap<RegulatoryElementConstPtr, Area> regElemLookup;
258 };
259 template <>
261  void add(Lanelet ll) {
262  ownedLookup.insert(std::make_pair(ll.leftBound(), ll));
263  ownedLookup.insert(std::make_pair(ll.rightBound(), ll));
264  for (const auto& elem : ll.regulatoryElements()) {
265  regElemLookup.insert(std::make_pair(elem, ll));
266  }
267  }
268  std::unordered_multimap<ConstLineString3d, Lanelet> ownedLookup;
269  std::unordered_multimap<RegulatoryElementConstPtr, Lanelet> regElemLookup;
270 };
271 
272 template <>
274  void add(const Point3d& /*unused*/) {}
275 };
276 
277 template <typename T>
278 struct PrimitiveLayer<T>::Tree {
279  using TreeNode = std::pair<BoundingBox2d, T>;
280  using RTree = bgi::rtree<TreeNode, bgi::quadratic<16>>;
281  static TreeNode treeNode(const T& elem) { return {geometry::boundingBox2d(to2D(elem)), elem}; }
282  explicit Tree(const PrimitiveLayer::Map& primitives) {
283  std::vector<TreeNode> nodes;
284  nodes.reserve(primitives.size());
285  for (auto& primitive : primitives) {
286  auto node = treeNode(primitive.second);
287  if (!node.first.isEmpty()) {
288  nodes.push_back(std::move(node));
289  }
290  }
291  rTree = RTree(nodes);
292  }
293 
294  void insert(const T& elem) {
295  TreeNode node = treeNode(elem);
296  if (!node.first.isEmpty()) {
297  rTree.insert(node);
298  }
299  }
300  void erase(const T& elem) {
301  TreeNode node = treeNode(elem);
302  if (!node.first.isEmpty()) {
303  rTree.remove(node);
304  }
305  }
308 };
309 
310 template <>
311 struct PrimitiveLayer<Point3d>::Tree {
312  using TreeNode = std::pair<BasicPoint2d, Point3d>;
313  using RTree = bgi::rtree<TreeNode, bgi::quadratic<16>>;
314  static TreeNode treeNode(const Point3d& p) { return {Point2d(p).basicPoint(), p}; }
315  explicit Tree(const PrimitiveLayer::Map& primitives) {
316  std::vector<TreeNode> nodes;
317  nodes.reserve(primitives.size());
318  std::transform(primitives.begin(), primitives.end(), std::back_inserter(nodes),
319  [](const auto& elem) { return treeNode(elem.second); });
320  rTree = RTree(nodes);
321  }
322  void insert(const Point3d& elem) { rTree.insert(treeNode(elem)); }
323  void erase(const Point3d& elem) { rTree.remove(treeNode(elem)); }
324  RTree rTree;
326 };
327 
328 template <typename T>
330  : elements_{primitives}, tree_{std::make_unique<Tree>(primitives)} {
331  for (const auto& prim : primitives) {
332  tree_->usage.add(prim.second);
333  }
334 }
335 
336 template <>
338  : elements_{primitives}, tree_{std::make_unique<Tree>(primitives)} {
339  for (const auto& prim : primitives) {
340  tree_->usage.add(prim.second);
341  }
342 }
343 
344 template <>
346  : elements_{primitives}, tree_{std::make_unique<Tree>(primitives)} {
347  for (const auto& prim : primitives) {
348  tree_->usage.add(prim.second);
349  utils::registerId(prim.first);
350  }
351 }
352 
353 template <typename T>
355  return id != InvalId && elements_.find(id) != elements_.end();
356 }
357 
358 template <typename T>
360  if (id == InvalId) {
361  throw NoSuchPrimitiveError("Tried to lookup an element with id InvalId!");
362  }
363  try {
364  return elements_.at(id);
365  } catch (std::out_of_range&) {
366  throw NoSuchPrimitiveError("Failed to lookup element with id " + std::to_string(id));
367  }
368 }
369 
370 template <typename T>
372  if (id == InvalId) {
373  throw NoSuchPrimitiveError("Tried to lookup an element with id InvalId!");
374  }
375  try {
376  return elements_.at(id);
377  } catch (std::out_of_range&) {
378  throw NoSuchPrimitiveError("Failed to lookup element with id " + std::to_string(id));
379  }
380 }
381 
382 template <typename T>
384  for (const auto& elem : element) {
385  tree_->usage.ownedLookup.insert(std::make_pair(elem, element));
386  }
387  elements_.insert({element.id(), element});
388  tree_->insert(element);
389 }
390 
391 template <>
392 void PrimitiveLayer<Area>::add(const Area& area) {
393  tree_->usage.add(area);
394  elements_.insert({area.id(), area});
395  tree_->insert(area);
396 }
397 
398 template <>
400  tree_->usage.add(ll);
401  elements_.insert({ll.id(), ll});
402  tree_->insert(ll);
403 }
404 
405 template <>
407  tree_->usage.add(p);
408  elements_.insert({p.id(), p});
409  tree_->insert(p);
410 }
411 
412 template <>
414  tree_->usage.add(element);
415  elements_.insert({element->id(), element});
416  tree_->insert(element);
417 }
418 
419 template <typename T>
420 std::vector<typename PrimitiveLayer<T>::ConstPrimitiveT> PrimitiveLayer<T>::findUsages(
422  return forEachMatchInMultiMap<traits::ConstPrimitiveType<typename PrimitiveLayer<T>::PrimitiveT>>(
423  tree_->usage.ownedLookup, primitive, [](const auto& elem) { return traits::toConst(elem.second); });
424 }
425 
426 template <typename T>
427 std::vector<typename PrimitiveLayer<T>::PrimitiveT> PrimitiveLayer<T>::findUsages(
429  return forEachMatchInMultiMap<typename PrimitiveLayer<T>::PrimitiveT>(tree_->usage.ownedLookup, primitive,
430  [](const auto& elem) { return elem.second; });
431 }
432 
433 template <>
434 ConstPoints3d PointLayer::findUsages(const ConstPoint3d& /*primitive*/) const {
435  return ConstPoints3d();
436 }
437 
438 template <>
439 Points3d PointLayer::findUsages(const ConstPoint3d& /*primitive*/) {
440  return Points3d();
441 }
442 
444  return forEachMatchInMultiMap<Area>(tree_->usage.regElemLookup, regElem,
445  [](const auto& elem) { return elem.second; });
446 }
447 
449  return forEachMatchInMultiMap<ConstArea>(tree_->usage.regElemLookup, regElem,
450  [](const auto& elem) { return traits::toConst(elem.second); });
451 }
452 
454  return forEachMatchInMultiMap<Lanelet>(tree_->usage.regElemLookup, regElem,
455  [](const auto& elem) { return elem.second; });
456 }
457 
459  return forEachMatchInMultiMap<ConstLanelet>(tree_->usage.regElemLookup, regElem,
460  [](const auto& elem) { return traits::toConst(elem.second); });
461 }
462 
463 template <typename T>
464 PrimitiveLayer<T>::~PrimitiveLayer() noexcept = default;
465 template <typename T>
466 PrimitiveLayer<T>::PrimitiveLayer(PrimitiveLayer&& rhs) noexcept = default;
467 template <typename T>
469 
470 template <typename T>
472  return elements_.find(id);
473 }
474 
475 template <typename T>
477  return elements_.begin();
478 }
479 
480 template <typename T>
482  return elements_.end();
483 }
484 
485 template <typename T>
487  return elements_.find(id);
488 }
489 
490 template <typename T>
492  return elements_.begin();
493 }
494 
495 template <typename T>
497  return elements_.end();
498 }
499 template <typename T>
501  std::vector<typename Tree::TreeNode> nodes;
502  tree_->rTree.query(bgi::intersects(area), std::back_inserter(nodes));
503  return getSecond<ConstPrimitiveT, typename Tree::TreeNode>(nodes);
504 }
505 
506 template <typename T>
508  std::vector<typename Tree::TreeNode> nodes;
509  tree_->rTree.query(bgi::intersects(area), std::back_inserter(nodes));
510  return getSecond<PrimitiveT, typename Tree::TreeNode>(nodes);
511 }
512 
513 template <typename T>
515  const ConstSearchFunction& func) const {
516  return findUntilImpl<ConstPrimitiveT>(tree_->rTree, area, func);
517 }
518 
519 template <typename T>
521  const PrimitiveLayer::SearchFunction& func) {
522  return findUntilImpl<PrimitiveT>(tree_->rTree, area, func);
523 }
524 
525 template <typename T>
527  std::vector<typename Tree::TreeNode> nodes;
528  tree_->rTree.query(bgi::nearest(point, n), std::back_inserter(nodes));
529  return getSecond<ConstPrimitiveT, typename Tree::TreeNode>(nodes);
530 }
531 
532 template <typename T>
534  std::vector<typename Tree::TreeNode> nodes;
535  nodes.reserve(n);
536  tree_->rTree.query(bgi::nearest(point, n), std::back_inserter(nodes));
537  return getSecond<PrimitiveT, typename Tree::TreeNode>(nodes);
538 }
539 
540 template <typename T>
542  const ConstSearchFunction& func) const {
543  return nearestUntilImpl<ConstPrimitiveT>(tree_->rTree, point, func);
544 }
545 
546 template <typename T>
548  const SearchFunction& func) {
549  return nearestUntilImpl<PrimitiveT>(tree_->rTree, point, func);
550 }
551 
552 template <typename T>
554  return utils::getId();
555 }
556 
557 LaneletMapLayers::LaneletMapLayers(const LaneletLayer::Map& lanelets, const AreaLayer::Map& areas,
558  const RegulatoryElementLayer::Map& regulatoryElements,
559  const PolygonLayer::Map& polygons, const LineStringLayer::Map& lineStrings,
560  const PointLayer::Map& points)
561  : laneletLayer(lanelets),
562  areaLayer(areas),
563  regulatoryElementLayer(regulatoryElements),
564  polygonLayer(polygons),
565  lineStringLayer(lineStrings),
566  pointLayer(points) {}
567 
569  if (lanelet.id() == InvalId) {
570  lanelet.setId(laneletLayer.uniqueId());
571  } else if (laneletLayer.exists(lanelet.id())) {
572  return;
573  } else {
574  utils::registerId(lanelet.id());
575  }
576  add(lanelet.leftBound());
577  add(lanelet.rightBound());
578  if (lanelet.hasCustomCenterline()) {
579  add(uglyRemoveConst(lanelet.centerline()));
580  }
581  // assign regelems an id so that the regelem usage lookup works
582  for (const auto& regelem : lanelet.regulatoryElements()) {
583  if (regelem->id() == InvalId) {
584  regelem->setId(regulatoryElementLayer.uniqueId());
585  }
586  }
587  // add lanelet before adding regelem to avoid cycles.
588  laneletLayer.add(lanelet);
589  for (const auto& regElem : lanelet.regulatoryElements()) {
590  add(regElem);
591  }
592 }
593 
594 void LaneletMap::add(Area area) {
595  if (area.id() == InvalId) {
596  area.setId(areaLayer.uniqueId());
597  } else if (areaLayer.exists(area.id())) {
598  return;
599  } else {
600  utils::registerId(area.id());
601  }
602  for (const auto& ls : area.outerBound()) {
603  add(ls);
604  }
605  for (const auto& lss : area.innerBounds()) {
606  for (const auto& ls : lss) {
607  add(ls);
608  }
609  }
610  // assign regelems an id so that the regelem usage lookup works
611  for (const auto& regelem : area.regulatoryElements()) {
612  if (regelem->id() == InvalId) {
613  regelem->setId(regulatoryElementLayer.uniqueId());
614  }
615  }
616  // add area before adding regelem to avoid cycles.
617  areaLayer.add(area);
618  for (const auto& regElem : area.regulatoryElements()) {
619  add(regElem);
620  }
621 }
622 
623 void LaneletMap::add(const RegulatoryElementPtr& regElem) {
624  if (!regElem) {
625  throw NullptrError("Empty regulatory element passed to add()!");
626  }
627  if (regElem->id() == InvalId) {
628  regElem->setId(regulatoryElementLayer.uniqueId());
629  } else if (regulatoryElementLayer.exists(regElem->id())) {
630  return;
631  } else {
632  utils::registerId(regElem->id());
633  }
634  AssignIdVisitor setIdVisitor(this);
635  for (const auto& elems : *regElem) {
636  for (const auto& elem : elems.second) {
637  boost::apply_visitor(setIdVisitor, elem);
638  }
639  }
640  regulatoryElementLayer.add(regElem);
641 
642  AddVisitor visitor(this);
643  regElem->applyVisitor(visitor);
644 }
645 
646 void LaneletMap::add(Polygon3d polygon) {
647  if (polygon.id() == InvalId) {
648  polygon.setId(polygonLayer.uniqueId());
649  } else if (polygonLayer.exists(polygon.id())) {
650  return;
651  } else {
652  utils::registerId(polygon.id());
653  }
654  for (const auto& p : polygon) {
655  add(p);
656  }
657  polygonLayer.add(polygon);
658 }
659 
660 void LaneletMap::add(LineString3d lineString) {
661  if (lineString.id() == InvalId) {
662  lineString.setId(lineStringLayer.uniqueId());
663  } else if (lineStringLayer.exists(lineString.id())) {
664  return;
665  } else {
666  utils::registerId(lineString.id());
667  }
668  for (const auto& p : lineString) {
669  add(p);
670  }
671  lineStringLayer.add(lineString);
672 }
673 
675  if (point.id() == InvalId) {
676  point.setId(pointLayer.uniqueId());
677  } else if (pointLayer.exists(point.id())) {
678  return;
679  } else {
680  utils::registerId(point.id());
681  }
682  pointLayer.add(point);
683 }
684 
686  checkId(lanelet);
687  utils::forEach(lanelet.regulatoryElements(), [&](auto& regElem) { this->trackParameters(*regElem); });
688  laneletLayer.add(lanelet);
689 }
690 
692  checkId(area);
693  utils::forEach(area.regulatoryElements(), [&](auto& regElem) { this->trackParameters(*regElem); });
694  areaLayer.add(area);
695 }
696 
698  checkId(*regElem);
699  trackParameters(*regElem);
700  regulatoryElementLayer.add(regElem);
701 }
702 
704  checkId(polygon);
705  polygonLayer.add(polygon);
706 }
707 
709  checkId(lineString);
710  lineStringLayer.add(lineString);
711 }
712 
714  checkId(point);
715  pointLayer.add(point);
716 }
717 
719  auto map = createMapFromConst(laneletLayer, areaLayer);
720  auto add = [&map](auto& prim) {
721  using T = std::decay_t<decltype(prim)>;
722  map->add(typename traits::PrimitiveTraits<T>::MutableType(
723  std::const_pointer_cast<typename traits::PrimitiveTraits<T>::DataType>(prim.constData())));
724  };
725  auto addLs = [&map](auto& prim) {
726  map->add(LineString3d(std::const_pointer_cast<LineStringData>(prim.constData()), prim.inverted()));
727  };
728  auto addRe = [&map](auto& prim) { map->add(std::const_pointer_cast<RegulatoryElement>(prim)); };
733  return map;
734 }
735 
737  auto map =
739  auto add = [&](auto& val) { map->add(val); };
744  return map;
745 }
746 
748  using LLorAreas = std::vector<boost::variant<ConstLanelet, ConstArea>>;
749  class AddToLLorAreaVisitor : public RuleParameterVisitor {
750  public:
751  explicit AddToLLorAreaVisitor(LLorAreas& llOrAreas) : llOrAreas_{&llOrAreas} {}
752  void operator()(const ConstWeakLanelet& wll) override {
753  if (!wll.expired()) {
754  llOrAreas_->emplace_back(wll.lock());
755  }
756  }
757  void operator()(const ConstWeakArea& wa) override {
758  if (!wa.expired()) {
759  llOrAreas_->emplace_back(wa.lock());
760  }
761  }
762 
763  private:
764  LLorAreas* llOrAreas_{};
765  };
766  AddToLLorAreaVisitor v{regelemObjects_};
767  regelem.applyVisitor(v);
768 }
769 
770 template class PrimitiveLayer<Area>;
771 template class PrimitiveLayer<Lanelet>;
772 template class PrimitiveLayer<Point3d>;
773 template class PrimitiveLayer<LineString3d>;
774 template class PrimitiveLayer<Polygon3d>;
776 
777 namespace utils {
778 template <typename PrimitiveT>
779 std::vector<ConstLayerPrimitive<PrimitiveT>> findUsages(const PrimitiveLayer<PrimitiveT>& layer, Id id) {
780  std::vector<ConstLayerPrimitive<PrimitiveT>> usages;
781  std::copy_if(layer.begin(), layer.end(), std::back_inserter(usages),
782  [&id](const auto& elem) { return utils::has(elem, id); });
783  return usages;
784 }
785 
786 template std::vector<ConstLayerPrimitive<Lanelet>> findUsages<Lanelet>(const PrimitiveLayer<Lanelet>&, Id);
787 template std::vector<ConstLayerPrimitive<LineString3d>> findUsages<LineString3d>(const PrimitiveLayer<LineString3d>&,
788  Id);
789 template std::vector<ConstLayerPrimitive<Polygon3d>> findUsages<Polygon3d>(const PrimitiveLayer<Polygon3d>&, Id);
790 template std::vector<ConstLayerPrimitive<RegulatoryElementPtr>> findUsages<RegulatoryElementPtr>(
792 
794  auto ls = map.lineStringLayer.findUsages(p);
795  auto llts = utils::concatenate(ls, [&map](const auto& ls) { return map.laneletLayer.findUsages(ls); });
796  auto lltsInv = utils::concatenate(ls, [&map](const auto& ls) { return map.laneletLayer.findUsages(ls.invert()); });
797  llts.insert(llts.end(), lltsInv.begin(), lltsInv.end());
798  auto remove = std::unique(llts.begin(), llts.end());
799  llts.erase(remove, llts.end());
800  return llts;
801 }
802 
804  auto ls = map.lineStringLayer.findUsages(p);
805  auto areas = utils::concatenate(ls, [&map](const auto& ls) { return map.areaLayer.findUsages(ls); });
806  auto areasInv = utils::concatenate(ls, [&map](const auto& ls) { return map.areaLayer.findUsages(ls.invert()); });
807  areas.insert(areas.end(), areasInv.begin(), areasInv.end());
808  auto remove = std::unique(areas.begin(), areas.end());
809  areas.erase(remove, areas.end());
810  return areas;
811 }
812 
813 LaneletMapUPtr createMap(const Points3d& fromPoints) {
814  return std::make_unique<LaneletMap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
815  PolygonLayer::Map(), LineStringLayer::Map(), toMap(fromPoints));
816 }
817 
818 LaneletMapUPtr createMap(const LineStrings3d& fromLineStrings) {
819  auto points = utils::concatenateRange(fromLineStrings, [](auto ls) { return std::make_pair(ls.begin(), ls.end()); });
820  return std::make_unique<LaneletMap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
821  PolygonLayer::Map(), toMap(fromLineStrings), toMap(points));
822 }
823 
824 LaneletMapUPtr createMap(const Lanelets& fromLanelets, const Areas& fromAreas) {
825  LineStrings3d ls;
826  ls.reserve(fromLanelets.size() * 2 + fromAreas.size() * 3);
827  for (auto ll : fromLanelets) {
828  ls.push_back(ll.leftBound());
829  ls.push_back(ll.rightBound());
830  if (ll.hasCustomCenterline()) {
831  auto center = ll.centerline();
832  ls.emplace_back(std::const_pointer_cast<LineStringData>(center.constData()), center.inverted());
833  }
834  }
835  auto appendMultiLs = [&ls](auto& lsappend) {
836  std::for_each(lsappend.begin(), lsappend.end(), [&ls](auto& l) { ls.push_back(l); });
837  };
838  for (auto area : fromAreas) {
839  appendMultiLs(area.outerBound());
840  for (auto inner : area.innerBounds()) {
841  appendMultiLs(inner);
842  }
843  }
844 
845  auto points = utils::concatenateRange(ls, [](auto ls) { return std::make_pair(ls.begin(), ls.end()); });
846  auto regelems = utils::concatenateRange(fromLanelets, [](Lanelet llt) {
847  const auto& regelems = llt.regulatoryElements();
848  return std::make_pair(regelems.begin(), regelems.end());
849  });
850  auto areaRegelems = utils::concatenateRange(fromAreas, [](Area area) {
851  const auto& regelems = area.regulatoryElements();
852  return std::make_pair(regelems.begin(), regelems.end());
853  });
854  auto map = std::make_unique<LaneletMap>(toMap(fromLanelets), toMap(fromAreas), RegulatoryElementLayer::Map(),
855  PolygonLayer::Map(), toMap(ls), toMap(points));
856  for (const auto& regelem : regelems) {
857  map->add(regelem);
858  }
859  for (const auto& regelem : areaRegelems) {
860  map->add(regelem);
861  }
862  return map;
863 }
864 
865 LaneletMapUPtr createMap(const Lanelets& fromLanelets) { return createMap(fromLanelets, {}); }
866 
867 LaneletMapUPtr createMap(const Areas& fromAreas) { return createMap({}, fromAreas); }
868 
869 LaneletMapUPtr createMap(const Polygons3d& fromPolygons) {
870  auto points = utils::concatenateRange(fromPolygons, [](auto ls) { return std::make_pair(ls.begin(), ls.end()); });
871  return std::make_unique<LaneletMap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
872  toMap(fromPolygons), LineStringLayer::Map(), toMap(points));
873 }
874 
875 LaneletMapConstUPtr createConstMap(const ConstLanelets& fromLanelets, const ConstAreas& fromAreas) {
876  return createMapFromConst(fromLanelets, fromAreas);
877 }
878 
879 namespace {
880 std::atomic<Id> currId{1000};
881 } // namespace
882 
883 Id getId() { return currId++; }
884 
885 void registerId(Id id) {
886  // this fuzz is needed because we want to be thread safe
887  Id newId = id + 1;
888  Id current = currId.load();
889  while (current < newId && !currId.compare_exchange_weak(current, newId)) {
890  }
891 }
892 
894  return std::make_unique<LaneletSubmap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
895  PolygonLayer::Map(), LineStringLayer::Map(), toMap(fromPoints));
896 }
897 
899  return std::make_unique<LaneletSubmap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
900  PolygonLayer::Map(), toMap(fromLineStrings), PointLayer::Map());
901 }
902 
904  return std::make_unique<LaneletSubmap>(LaneletLayer::Map(), AreaLayer::Map(), RegulatoryElementLayer::Map(),
905  toMap(fromPolygons), LineStringLayer::Map(), PointLayer::Map());
906 }
907 
908 LaneletSubmapUPtr createSubmap(const Lanelets& fromLanelets) { return createSubmap(fromLanelets, {}); }
909 
910 LaneletSubmapUPtr createSubmap(const Areas& fromAreas) { return createSubmap({}, fromAreas); }
911 
912 LaneletSubmapUPtr createSubmap(const Lanelets& fromLanelets, const Areas& fromAreas) {
913  auto map = std::make_unique<LaneletSubmap>(toMap(fromLanelets), toMap(fromAreas), RegulatoryElementLayer::Map(),
915  for (const auto& ll : fromLanelets) {
916  utils::forEach(ll.regulatoryElements(), [&](auto& regelem) { map->trackParameters(*regelem); });
917  }
918  for (const auto& ar : fromAreas) {
919  utils::forEach(ar.regulatoryElements(), [&](auto& regelem) { map->trackParameters(*regelem); });
920  }
921  return map;
922 }
923 
924 LaneletSubmapConstUPtr createConstSubmap(const ConstLanelets& fromLanelets, const ConstAreas& fromAreas) {
925  // sorry, we temporarily have to const cast our primitives back to non-const to be able to create a const map. Its not
926  // beautiful but valid.
927  auto lanelets = utils::transform(fromLanelets, [](const ConstLanelet& llt) {
928  return Lanelet(std::const_pointer_cast<LaneletData>(llt.constData()), llt.inverted());
929  });
930  auto areas = utils::transform(
931  fromAreas, [](const ConstArea& ar) { return Area(std::const_pointer_cast<AreaData>(ar.constData())); });
932  return utils::createSubmap(lanelets, areas);
933 }
934 
935 } // namespace utils
936 
937 namespace geometry {
938 namespace {
939 template <typename T>
940 class NSmallestElements {
941  public:
942  explicit NSmallestElements(size_t n) : n_{n} { values_.reserve(n); }
943  bool insert(double measure, T value) {
944  auto pos =
945  std::lower_bound(values_.begin(), values_.end(), measure, [](auto& v1, double v2) { return v1.first < v2; });
946  if (pos != values_.end() || values_.size() < n_) {
947  if (values_.size() >= n_) {
948  values_.pop_back();
949  }
950  values_.emplace(pos, measure, value);
951  return true;
952  }
953  return false;
954  }
955  const auto& values() const { return values_; }
956  auto moveValues() { return std::move(values_); }
957  bool full() const { return values_.size() >= n_; }
958  bool empty() const { return values_.empty(); }
959 
960  private:
961  std::vector<std::pair<double, T>> values_;
962  size_t n_;
963 };
964 
965 template <typename RetT, typename LayerT>
966 auto findNearestImpl(LayerT&& map, const BasicPoint2d& pt, unsigned count) {
967  // Idea: nearestUntil passes us elements with increasing bounding box
968  // distance.
969  // If this distance is greater than the actual distance (between primitives)
970  // of the count-th furthest current element, then we can stop, because all
971  // succeding elements will be even further away.
972  NSmallestElements<RetT> closest(count);
973  auto searchFunction = [&closest, &pt](auto& box, const RetT& prim) {
974  auto dBox = distance(box, pt);
975  if (closest.full() && dBox > closest.values().back().first) {
976  return true;
977  }
978  closest.insert(distance2d(prim, pt), prim);
979  return false;
980  };
981  map.nearestUntil(pt, searchFunction);
982  return closest.moveValues();
983 }
984 } // namespace
985 
986 template <typename PrimT>
987 std::vector<std::pair<double, PrimT>> findNearest(PrimitiveLayer<PrimT>& map, const BasicPoint2d& pt, unsigned count) {
988  return findNearestImpl<PrimT>(map, pt, count);
989 }
990 
991 template <typename PrimT>
992 std::vector<std::pair<double, traits::ConstPrimitiveType<PrimT>>> findNearest(const PrimitiveLayer<PrimT>& map,
993  const BasicPoint2d& pt, unsigned count) {
994  return findNearestImpl<traits::ConstPrimitiveType<PrimT>>(map, pt, count);
995 }
996 
997 // instanciate
998 // clang-format off
999 // NOLINTNEXTLINE
1000 #define INSTANCIATE_FIND_NEAREST(PRIM) template std::vector<std::pair<double, PRIM>> findNearest<PRIM>(PrimitiveLayer<PRIM>&, const BasicPoint2d&, unsigned)
1001 // NOLINTNEXTLINE
1002 #define INSTANCIATE_CONST_FIND_NEAREST(PRIM, CPRIM) template std::vector<std::pair<double, CPRIM>> findNearest<PRIM>(const PrimitiveLayer<PRIM>&, const BasicPoint2d&, unsigned)
1003 // clang-format on
1004 INSTANCIATE_FIND_NEAREST(Lanelet);
1006 INSTANCIATE_FIND_NEAREST(LineString3d);
1008 INSTANCIATE_FIND_NEAREST(Polygon3d);
1009 INSTANCIATE_FIND_NEAREST(Point3d);
1010 #undef INSTANCIATE_FIND_NEAREST
1011 
1012 INSTANCIATE_CONST_FIND_NEAREST(Lanelet, ConstLanelet);
1013 INSTANCIATE_CONST_FIND_NEAREST(Area, ConstArea);
1014 INSTANCIATE_CONST_FIND_NEAREST(LineString3d, ConstLineString3d);
1016 INSTANCIATE_CONST_FIND_NEAREST(Polygon3d, ConstPolygon3d);
1017 INSTANCIATE_CONST_FIND_NEAREST(Point3d, ConstPoint3d);
1018 #undef INSTANCIATE_CONST_FIND_NEAREST
1019 } // namespace geometry
1020 } // namespace lanelet
typename T::DataType DataType
Definition: Traits.h:21
const RegulatoryElementPtrs & regulatoryElements()
Return regulatoryElements that affect this lanelet.
Each primitive in lanelet2 has its own layer in the map.
Definition: LaneletMap.h:39
Id id() const noexcept
get the unique id of this primitive
Definition: Primitive.h:96
typename Owned< PrimitiveT >::Type OwnedT
Definition: Traits.h:76
std::vector< ConstLayerPrimitive< PrimitiveT > > findUsages(const PrimitiveLayer< PrimitiveT > &layer, Id id)
Definition: LaneletMap.cpp:779
BasicPoint p
Id getId()
returns a unique id by incrementing a counter each time this is called.
Definition: LaneletMap.cpp:883
void insert(const T &elem)
Definition: LaneletMap.cpp:294
const InnerBounds & innerBounds()
Get the linestrings that form the inner bound.
traits::ConstPrimitiveType< T > ConstPrimitiveT
Definition: LaneletMap.h:42
std::shared_ptr< RegulatoryElement > RegulatoryElementPtr
Definition: Forward.h:192
bool expired() const noexcept
tests whether the WeakArea is still valid
auto concatenateRange(ContainerT &&c, Func f)
Similar to concatenate but expects Func to return a pair of begin and end of the range to concatenate...
Definition: Utilities.h:295
auto basicPoint() noexcept
get a mutable reference to the 2d point data
const_iterator end() const
iterator to end of the elements
Definition: LaneletMap.cpp:481
auto find(ContainerT &&c, const ValueT &val)
Definition: Utilities.h:186
std::unordered_multimap< ConstLineString3d, Lanelet > ownedLookup
Definition: LaneletMap.cpp:268
void add(const T &prim)
Definition: LaneletMap.cpp:223
size_t n_
Definition: LaneletMap.cpp:962
ConstPrimitiveType< PrimitiveT > toConst(const PrimitiveT &primitive)
Converts a primitive to its matching const type.
Definition: Traits.h:108
std::unordered_multimap< ConstLineString3d, Area > ownedLookup
Definition: LaneletMap.cpp:256
template std::vector< ConstLayerPrimitive< LineString3d > > findUsages< LineString3d >(const PrimitiveLayer< LineString3d > &, Id)
int64_t Id
Definition: Forward.h:198
std::unordered_map< Id, T > Map
Definition: LaneletMap.h:43
Optional< ConstPrimitiveT > OptConstPrimitiveT
Definition: LaneletMap.h:46
auto transform(Iterator begin, Iterator end, const Func f)
Definition: Utilities.h:176
Tree(const PrimitiveLayer::Map &primitives)
Definition: LaneletMap.cpp:282
PointLayer pointLayer
access to the points
Definition: LaneletMap.h:358
AreaLayer areaLayer
access to areas
Definition: LaneletMap.h:354
std::vector< ConstPrimitiveT > findUsages(const traits::ConstPrimitiveType< traits::OwnedT< PrimitiveT >> &primitive) const
finds usages of an owned type within this layer
The famous (mutable) lanelet class.
Thrown when an element is not part of the map.
Definition: Exceptions.h:49
#define INSTANCIATE_CONST_FIND_NEAREST(PRIM, CPRIM)
std::vector< Lanelet > Lanelets
Definition: Forward.h:113
template std::vector< ConstLayerPrimitive< RegulatoryElementPtr > > findUsages< RegulatoryElementPtr >(const PrimitiveLayer< RegulatoryElementPtr > &, Id)
typename T::MutableType MutableType
Definition: Traits.h:23
std::vector< std::pair< double, T > > values_
Definition: LaneletMap.cpp:961
std::unordered_multimap< RegulatoryElementConstPtr, Area > regElemLookup
Definition: LaneletMap.cpp:257
std::shared_ptr< const LaneletMap > LaneletMapConstPtr
Definition: Forward.h:168
void erase(const Point3d &elem)
Definition: LaneletMap.cpp:323
LaneletSubmapConstUPtr createConstSubmap(const ConstLanelets &fromLanelets, const ConstAreas &fromAreas)
Definition: LaneletMap.cpp:924
size_t operator()(const lanelet::ConstRuleParameter &x) const noexcept
Definition: LaneletMap.cpp:94
std::function< bool(const internal::SearchBoxT< RegulatoryElementPtr > &box, const ConstPrimitiveT &prim)> ConstSearchFunction
Definition: LaneletMap.h:155
std::unordered_multimap< ConstRuleParameter, RegulatoryElementPtr > ownedLookup
Definition: LaneletMap.cpp:240
static TreeNode treeNode(const Point3d &p)
Definition: LaneletMap.cpp:314
bool has(const ConstArea &ll, Id id)
returns true if element of a regulatory element has a matching Id
Container for all layers of a lanelet map. Used by both LaneletMap and LaneletSubmap.
Definition: LaneletMap.h:313
LaneletSubmapUPtr createSubmap(const Points3d &fromPoints)
Efficiently create a LaneletSubmap from a vector of things. All elements must have a valid id! ...
Definition: LaneletMap.cpp:893
const LineStrings3d & outerBound()
Get linestrings that form the outer bound.
template std::vector< ConstLayerPrimitive< Polygon3d > > findUsages< Polygon3d >(const PrimitiveLayer< Polygon3d > &, Id)
bool expired() const noexcept
tests whether the WeakLanelet is still valid
std::vector< Point3d > Points3d
Definition: Forward.h:34
std::vector< Polygon3d > Polygons3d
Definition: Forward.h:149
std::unique_ptr< LaneletMap > LaneletMapUPtr
Definition: Forward.h:167
std::unique_ptr< const LaneletSubmap > LaneletSubmapConstUPtr
Definition: Forward.h:178
bool inverted() const
returns if this is an inverted lanelet
void forEach(Container &&c, Func &&f)
Definition: Utilities.h:226
UsageLookup< Point3d > usage
Definition: LaneletMap.cpp:325
void add(Lanelet lanelet)
adds a lanelet and all the elements it owns to the map
Definition: LaneletMap.cpp:568
A normal 3d linestring with mutable data.
Id getId< RegulatoryElementPtr >(const RegulatoryElementPtr &prim)
A mutable 3d point.
bgi::rtree< TreeNode, bgi::quadratic< 16 > > RTree
Definition: LaneletMap.cpp:280
const std::shared_ptr< const Data > & constData() const
get the internal data of this primitive
Definition: Primitive.h:178
LaneletLayer laneletLayer
access to the lanelets within this map
Definition: LaneletMap.h:353
template std::vector< ConstLayerPrimitive< Lanelet > > findUsages< Lanelet >(const PrimitiveLayer< Lanelet > &, Id)
ConstLineString3d centerline() const
get the (cached) centerline of this lanelet.
void insert(const Point3d &elem)
Definition: LaneletMap.cpp:322
std::vector< ConstPrimitiveT > ConstPrimitiveVec
Definition: LaneletMap.h:44
boost::variant< ConstPoint3d, ConstLineString3d, ConstPolygon3d, ConstWeakLanelet, ConstWeakArea > ConstRuleParameter
Const-version of the parameters.
ConstLanelets findUsagesInLanelets(const LaneletMapLayers &map, const ConstPoint3d &p)
Definition: LaneletMap.cpp:793
RegulatoryElementLayer regulatoryElementLayer
access to regElems
Definition: LaneletMap.h:355
Lanelets findUsages(const RegulatoryElementConstPtr &regElem)
Definition: LaneletMap.cpp:453
ConstAreas findUsagesInAreas(const LaneletMapLayers &map, const ConstPoint3d &p)
Definition: LaneletMap.cpp:803
std::unordered_multimap< RegulatoryElementConstPtr, Lanelet > regElemLookup
Definition: LaneletMap.cpp:269
Areas findUsages(const RegulatoryElementConstPtr &regElem)
Definition: LaneletMap.cpp:443
Optional< PrimitiveT > OptPrimitiveT
Definition: LaneletMap.h:47
SharedPtrs in lanelet2 must never point to null. If this is violated, this exception is thrown (usual...
Definition: Exceptions.h:80
LaneletMapConstPtr laneletMap() const
Converts this into a fully valid lanelet map.
Definition: LaneletMap.cpp:718
typename PrimitiveTraits< PrimitiveT >::ConstType ConstPrimitiveType
Utility for determinig the matching const type for a primitive.
Definition: Traits.h:80
void add(const RegulatoryElementPtr &prim)
Definition: LaneletMap.cpp:233
IfAr< AreaT, BoundingBox2d > boundingBox2d(const AreaT &area)
calculates an up-right 2d bounding box
std::shared_ptr< const RegulatoryElement > RegulatoryElementConstPtr
Definition: Forward.h:194
Optional< double > distance
An immutable lanelet.
void trackParameters(const RegulatoryElement &regelem)
Definition: LaneletMap.cpp:747
LineString3d leftBound()
Get the left bound.
std::function< bool(const internal::SearchBoxT< T > &box, const PrimitiveT &prim)> SearchFunction
Definition: LaneletMap.h:156
auto transform(Container &&c, Func f)
Definition: Utilities.h:120
Id uniqueId() const
returns a unique id. it is guaranteed that the id is not used within this layer
Definition: LaneletMap.cpp:553
Axis-Aligned bounding box in 2d.
LineString3d rightBound()
Get the right bound.
bool exists(Id id) const
checks whether an element exists in this layer
Definition: LaneletMap.cpp:354
auto concatenate(ContainerT &&c)
overload assuming that c is a container of containers. The return type will be the type of the inner ...
Definition: Utilities.h:260
A mutable clockwise oriented, open (ie start point != end point) polygon in 3d.
bool hasCustomCenterline() const
Returns whether the centerline has been overridden by setCenterline.
const_iterator begin() const
iterator to beginning of the elements (not ordered by id!)
Definition: LaneletMap.cpp:476
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > BasicPoint2d
a simple 2d-point
std::vector< std::pair< double, PrimT > > findNearest(PrimitiveLayer< PrimT > &map, const BasicPoint2d &pt, unsigned count)
returns the nearest n primitives to a point.
Definition: LaneletMap.cpp:987
void add(Lanelet lanelet)
adds a lanelet to the submap
Definition: LaneletMap.cpp:685
Famous Area class that represents a basic area as element of the map.
void setId(Id id) noexcept
set a new id for this primitive
Definition: Primitive.h:270
void erase(const T &elem)
Definition: LaneletMap.cpp:300
Id id
Definition: LaneletMap.cpp:63
static TreeNode treeNode(const T &elem)
Definition: LaneletMap.cpp:281
You can inherit from this visitor to perform an operation on each parameter of a regulatory element...
std::vector< Area > Areas
Definition: Forward.h:125
A general rule or limitation for a lanelet (abstract base class)
An immutable 3d point.
ConstArea lock() const
Obtains the original ConstArea.
std::unique_ptr< const LaneletMap > LaneletMapConstUPtr
Definition: Forward.h:169
PolygonLayer polygonLayer
access to the polygons
Definition: LaneletMap.h:356
const RegulatoryElementPtrs & regulatoryElements()
return regulatoryElements that affect this area.
std::vector< PrimitiveT > PrimitiveVec
Definition: LaneletMap.h:45
A const (i.e. immutable) Area.
LaneletMapUPtr createMap(const Points3d &fromPoints)
Efficiently create a LaneletMap from a vector of things. All elements must have a valid id! ...
Definition: LaneletMap.cpp:813
BoundingBox2d to2D(const BoundingBox3d &primitive)
void registerId(Id id)
Definition: LaneletMap.cpp:885
void applyVisitor(RuleParameterVisitor &visitor) const
applies a visitor to every parameter in the regulatory element
void add(const PrimitiveT &element)
Definition: LaneletMap.cpp:383
LineStringLayer lineStringLayer
access to the lineStrings
Definition: LaneletMap.h:357
#define INSTANCIATE_FIND_NEAREST(PRIM)
LaneletMap * map_
Definition: LaneletMap.cpp:139
std::unique_ptr< LaneletSubmap > LaneletSubmapUPtr
Definition: Forward.h:176
std::unordered_multimap< traits::ConstPrimitiveType< traits::OwnedT< T > >, T > ownedLookup
Definition: LaneletMap.cpp:228
std::pair< BoundingBox2d, T > TreeNode
Definition: LaneletMap.cpp:279
A mutable 2d point.
std::vector< ConstPoint3d > ConstPoints3d
Definition: Forward.h:35
void add(const Point3d &)
Definition: LaneletMap.cpp:274
ConstLanelet lock() const
Obtains the original ConstLanelet.
std::vector< LineString3d > LineStrings3d
Definition: Forward.h:57
double distance2d(const RegulatoryElement &regElem, const BasicPoint2d &p)
constexpr Id InvalId
indicates a primitive that is not part of a map
Definition: Forward.h:199
LaneletMapConstUPtr createConstMap(const ConstLanelets &fromLanelets, const ConstAreas &fromAreas)
Definition: LaneletMap.cpp:875
bool empty() const noexcept
Returns whether all layers of this object are empty.
Definition: LaneletMap.h:342
std::vector< ConstArea > ConstAreas
Definition: Forward.h:126
used internally by RegulatoryElements to avoid cyclic dependencies.
std::vector< ConstLanelet > ConstLanelets
Definition: Forward.h:114


lanelet2_core
Author(s): Fabian Poggenhans
autogenerated on Tue Jun 6 2023 02:23:32