- Here is more information on the basic primitives that make up a Lanelet2 map.
- Read here for a primer on the software architecture of lanelet2.
- There is also some documentation on the geometry calculations you can do with lanelet2 primitives.
- If you are interested in Lanelet2's projections, you will find more here.
- To get more information on how to create valid maps, see here.
1.
https://github.com/changhexingchen/Lanelet2/blob/master/lanelet2_core/doc/RegulatoryElementTagging.md
Lanelet2/lanelet2_core/doc/RegulatoryElementTagging.md
Tagging Regulatory Elements
Regulatory Elements are divided into categories. The most common ones are TrafficLight
, TrafficSign
, SpeedLimit
and RightOfWay
, which are already included in the core library, but there are many more ways to model restrictions on lanelets and areas. More might be added in the future and also users are able to add own regulatory elements by inheriting from the generic RegulatoryElement
class and registering the new type using the RegisterRegulatoryElement
class.
This document describes the generic layout of a Regulatory Element and shows how the common Regulatory Elements are structured.
本文件描述了交通規則元素的一般布局,並展示了那些普通的交通規則元素(如:交通燈,交通標志,限速標志)是如何被結構化的。
Tags
Regulatory Elements always have type=regulatory_element
. If this tag is not present, Lanelet2 will add it when writing to an .osm file.
交通規則元素總是有這個鍵值對:type=regulatory_element。如果這個標簽不存在,Lanelet2將在寫入.osm格式的文件時添加它。
Subtype
The subtype
tag helps Lanelet2 to distinguish between the different regulatory elements. For the basic Regulatory Elements this would be:
- traffic_light
- traffic_sign
- speed_limit
- right_of_way
子類型標記幫助Lanelet2區分不同的交通規則。對於基本的交通規則來說,這將是:
- 紅綠燈
- 指示牌
- 車速限制
- 路權
Other, Optional Tags
The following tags can be used to add more information to a Regulatory Element (of course you can add you own to enhance your map and implement a new TrafficRule
object that implements them). The default values for the tag are highlighted.
- dynamic (yes/no): Indicates that this Regulatory Element might change its meaning based on a condition. Examples would be a road that is closed on weekends. Or a speed limit that is only in action if the road is wet. By default, Lanelet2 cannot handle dynamic Regulatory Elements and will ignore them. Specialized traffic rule classes could be implemented that use background information (such as the current time) to resolve dynamic Regulatory Elements.
- fallback (yes/no): Indicates that this Regulatory Element has a lower priority than another Regulatory Element. Examples are right of way regulations that become valid if the traffic lights of an intersection are out of order.
其他的可選標簽
以下標簽被用來向交通規則添加更多信息(當然,您可以添加自己的標簽來增強你的地圖並新建TrafficRule對象實施與你的地圖)。標簽的默認值被突出顯示(高亮顯示)。
- 動態(的)(yes/no):指示此交通規則可能根據某種情況更改其含義。例如,一條道路在周末關閉。或者只有在路面潮濕的情況下才會起作用的限速。默認情況下,Lanelet2無法處理動態交通規則,所以將忽略它們。可以實現專門化的交通規則類,這些類使用背景信息(例如當前時間)來解析動態交通規則。
- 后退(yes/no):指示此交通規則的優先級低於另一個交通規則。例如,當交叉路口的交通燈出現故障時,通行(權)規則就會生效。
Basic Regulatory Elements
一些基本的交通規則
Traffic Sign
A traffic sign generically expresses a restriction that is expressed by a traffic sign. The refers part refers to traffic signs that form the rule. The cancels parameter then refers to traffic signs that mark the end of the restriction expressed by the sign (e.g. the end of no-overtaking section). The ref_line and cancel_line parameters can then be used to define the exact start and end points of the rule. The LineStrings referenced by that must not have an intersection with the referencing lanelet or Area. If they do, the rule is valid from/to this intersection point. If not, the rule is valid for the whole lanelet/area.
交通標志
一般情況下,一種交通標志表達一種限制。參考部分是指構成規則的交通標志。cancels參數則是指解除限制(如禁止超車路段結束)。用ref_line和cancel_line參數定義規則的確切起點和終點。它引用的線串不能與引用的小lanelet或Area有交叉。如果他們這樣做了,規則從/到這個交點是有效的。如果不是,則該規則適用於整個lanelet/area。
Speed Limit
Speed limits work very similar to traffic signs. If they are put up by a traffic sign, they simply reference this traffic sign. Similar for the ref_line and the cancels role. The TrafficRules
class then takes care of interpreting the speed limit from the subtype
of the referenced traffic sign.
Alternatively, if the speed limit does not originate from a traffic sign, a sign_type
tag can be used to define the speed limit. The value should contain the unit, eg "50 km/h". mph or mps or similar units are possible as well. If no unit is given, km/h is assumed.
限速
限速工作原理與交通標志非常相似。如果他們被一個交通標志提供,他們只是簡單地引用這個交通標志。類似於ref_line和cancels角色。然后,traffic rules類負責從引用的交通標志的子類型(subtype)解釋速度限制。
或者,如果速度限制不是來自交通標志,可以使用sign_type標記來定義速度限制。數值應包含單位,如“50km /h”。英里每小時或mps或類似的單位也是可能的。如果沒有給出單位,則默認是km/h。
Traffic Light
Traffic lights are also similar to traffic signs. Instead of a sign, the light itself is referenced as refers parameter. The cancels and cancels_line role have no meaning for traffic lights. The ref_line can reference the respective stop line. If they are not present, the stop line is implicitly at the end of the lanelet or Area.
交通燈
交通燈也類似於其他交通標志。並不是一個符號,燈本身被引用作為參數。cancels和cancels_line角色對於交通燈沒有意義。ref_line可以引用各自的停止線。如果它們不存在,則停止線隱含地位於lanelet或Area的末尾。
Right of Way
By default, intersecting lanelets are treated as a "first come first served" situation, meaning that the vehicle that arrives first at the intersection point has right of way. The RightOfWay
Regulatory Element changes this. It has three roles:
- yield: References the lanelets that have to yield
- right_of_way: the lanelets that have the right of way over the yielding ones
- ref_line: The lines where vehicles that are crossing a yield lanelet have to stop at. If not set, this is the end of the yieldlanelet.
Only one lanelet of a chain of lanelets that belong to the same lane have to be referenced. Generally this is the last lanelet that can be undoubtedly assigned to one specific intersection arm (i.e. the last lanelet before the intersection begins). All lanelets that are mentioned by the right of way Regulatory Element also have to reference the regulatory element.
路權
默認情況下,相交的lanelets被視為“先到先得”的情況,這意味着首先到達交叉點(或者翻譯成沖突點)的車輛擁有優先通行權。路權的概念改變了這一點。它承擔三個角色:
- 屈服/讓步:引用具有路權的Lanelets
- 路權:具有先行權的lanelets
- ref_line:車輛需要停在那里的停止線。如果不設置,就相當於具有路權並且不需要讓行。
只需引用屬於同一lane的一個lanelets鏈中的一個lanelet。一般來說,這是最后一個可以毫無疑問地分配給一個特定交臂的lanelet(即交點開始前的最后一個lanelet)。所有被指定路權的lanelets也要引用基本的交通規則。
2.
https://github.com/changhexingchen/Lanelet2/blob/master/lanelet2_core/doc/Architecture.md
Lanelet2/lanelet2_core/doc/Architecture.md
Architecture
This file describes the technical architectural architecture of Lanelet2. For information on the representation of lanelet and its primitives, please read first here.
架構
這個文件描述了Lanelet2的技術架構。有關lanelet及其基本組成的信息,請先在這里閱讀。
Principles
原則
Data sharing
數據分享
In lanelet two, everything that has an id is unique across the whole map. Because multiple primitives can reference the same element, it is therefore not possible to duplicate/copy the information of a lanelet primitive. If that was possible, modifying the information would leave the map in an invalid state, because other elements that reference it would not be notified of the change.
在lanelet 2中,所有事物都擁有唯一的id。由於許多的地圖基本組成可以引用同一個元素,因此不可能復制/復制一個lanelet的基本組成之信息。如果可能的話,修改信息將使地圖處於無效狀態,因為引用它的其他元素不會被通知那個更改。
To solve this issue, Lanelet2's primitive do not actually store data. Instead, they hold a pointer to the real, uncopyable data object. This means they only provide a view on the underlying map data. This means that Lanelet2 primitives can be copied without regret, because all copies still point to the same underlying data object. If the data is modified through one of the primtives, all other copies can observe the change.
為了解決這個問題,Lanelet2的基本組成元素實際上不存儲數據。相反,它們持有一個指向真實的、不可復制的數據對象的指針。這意味着它們只提供底層地圖數據的視圖。這意味着可以毫無遺憾地復制Lanelet2基本組成元素,因為所有副本仍然指向相同的底層數據對象。如果通過其中一個基本組成元素修改了數據,則所有其他副本可以觀察到這個更改。
This gives some interesting properties. Firstly, primitives can be copied extremely fast, because only the pointer is copied, not the data. Secondly, this means that we can provide different views on the data. One example is that we can give you a 2D view and a 3D view on the data, e.g. a Point2d that returns x and y coordinates but not the z coordinate. You can convert this point back to Point3d without losing information, because in the underlying data, the z-coordinate was always there. Linestrings behave similar. A LineString3d
returns Point3d
, a LineString2d
gives you Point2d
.
這給出了一些有趣的性質。首先,基本組成元素的復制速度非常快,因為只復制指針,而不復制數據。其次,這意味着我們可以對數據提供不同的觀測視角。例如,我們可以在數據上提供2D視圖和3D視圖,例如返回x和y坐標但不返回z坐標的Point2d。您可以在不丟失信息的情況下將這個點轉換回Point3d,因為在底層數據中,z坐標始終存在。線串具有相似的表現。LineString3d返回Point3d, LineString2d返回Point2d。
We can also easily invert Linestrings and Lanelets with this technique. An inverted Linestring simply returns the underlying data in reversed order. You will not even notice it is inverted, because it still behaves in the same way as a non-inverted one. The effort of creating the inverted Linestring is - you guessed it - just the effort of copying a pointer!
我們還可以使用這種技術輕松地反轉線串和Lanelets。一個翻轉的線串以相反的順序返回底層數據。你甚至不會注意到它是倒置的,因為它的行為方式和非倒置的是一樣的。創建反向Linestring的工作—您猜對了—就是復制一個指針的工作!
Like this we can make sure that modifying the map is alwas consistent. All primitives will observe the change. However there are two exceptions to this, and they are related to caching: The centerline of a lanelet is calculated based on the left and right bound at the time it was first requested. If the points of a left or right bounds were modified, the Lanelet can not notice the change and still returns the now wrong centerline. You have to reset the centerline of the lanelet yourself. The second issue is within the laneletMap itself. It holds some precalculated Tree structures to efficiently query closest points or usages of a point. If one of the points is modified, the query will still run on the old tree structure. So the general message is: When you plan to modify the map, know what you are doing!
這樣我們就可以確保地圖的修改始終是一致和連貫的。所有地圖的基本組成元素都能觀察到這種改變。但是有兩個例外,它們與緩存有關:一個lanelet的中心線是根據第一次請求時的左右邊界計算的。如果修改了左邊界或右邊界的點,則Lanelet無法注意到更改,仍然返回錯誤的中心線。你必須自己重新設置lanelet的中心線。第二個問題是laneletMap本身。它包含一些預先計算的樹結構,以有效地查詢最近點或點的使用。如果修改了其中一個點,查詢仍將在舊的樹結構上運行。因此,總的信息是:當您計划修改地圖時,要知道您在做什么!
Composability
可組合性
Since Lanelet2's primitives, especially Lanelets represent an atomic section of the map, it is often important to compose these atomic parts together to create compound objects. These compound primitives behave in the same way as the primitives they are composed of, but internally access their data. This is also driven by the pointer-based concept introduced above: The compound objects simply hold a list of pointers instead of a single one. As an example, you can compose multiple Linestring3d
to one CompoundLineString3d
. It behaves like a single linestring, gives you its size()
in points acces to the individual points while still internally accessing the data of the actual linestrings. You can also compose Polygons from Linestrings, LaneletSet from Lanelets, and so on.
由於Lanelet2的基本組成元素,尤其是Lanelets表示地圖的微小的不可分割的部分,因此將這些微小部分組合在一起以創建復合對象通常非常重要。這些復合對象的行為方式與組成它們的那些基本元素的行為方式相同,但在內部訪問它們的數據。這也是由上面介紹的基於指針的概念驅動:復合對象只包含一個指針列表,而不是單個指針。例如,您可以將多個Linestring3d組合為一個CompoundLineString3d。它的行為類似於一個linestring線串,它的大小()以點表示,在訪問各個點的同時仍然在內部訪問實際linestring的數據。您還可以從linestrings組合多邊形,從Lanelets組合Lanelet集,等等。
Const correctness
常量正確性
Since modifying the map can make cached data invalid, and since modification affects the whole map, Lanelet2 offers some protection against unwanted modification. This is related to const correctness: If an object is passed to a function as const
, not only the data of the object itself is immutable, but also the data derived from it and all the copies that you make.
E.g. if a function accepts a Linestring as const Linestring3d
, its data is immutable. If you access a point of the linestring, you get a ConstPoint3d
, that allows you to access its data, but not modify it. It is not possible to convert a ConstPoint3d
back to a Point3d
. This means, if you call a function that accepts a const LineString3d
or even a ConstLineString3d
, you can be 100% sure that you map data will not be modified.
由於修改地圖會使緩存的數據無效,而且修改會影響整個地圖,所以Lanelet2提供了一些保護,防止不必要的修改。這與常量正確性有關:如果一個對象以常量的形式傳遞給一個函數,那么不僅對象本身的數據是不可變的,它派生的數據以及您創建的所有副本也是不可變的。
例如,如果一個函數接受一個Linestring作為const Linestring3d,那么它的數據是不可變的。如果您訪問linestring的一個點,您將得到ConstPoint3d,它允許您訪問它的數據,但不修改它。將ConstPoint3d轉換回Point3d是不可能的。這意味着,如果調用一個接受const LineString3d甚至ConstLineString3d的函數,您可以100%確定映地圖數據不會被修改。
Modularity
模塊化
We are aware of the fact that roads can be very different in different countries and different places. Some things can be hard to squeeze into the typical map format. Also, the requirements on the map can be very different. To account for this, we tried to make Lanelet2 as flexible as possible by adding customization points where you can plugin your customized solution. Also the modularity of Lanelet2 aims to make it as simple as possible to add new functionality in the future.
Part of the flexibility concept is that the tags that are used on objects can be extended without any limits. This way you can easily add more specific information to your maps that you are missing. New, custom Regulatory Elements can be added to accout for difficult traffic situations. Also Lanelet2 can be extended for different countries and different road participants by adding new TrafficRules
objects which are used by Lanelet2 to interpret the map data. New parsers and writers for new map formats can be added and registered while still using the same good old load
/write
function.
我們意識到,在不同的國家和不同的地方,道路可能是非常不同的。有些東西很難硬塞進典型的地圖格式中。此外,地圖上的需求可能非常不同。為了解決這個問題,我們試圖通過添加定制點,使Lanelet2盡可能靈活,您可以在定制的解決方案中插入定制點。此外,Lanelet2的模塊化的目標是使它在未來盡可能簡單地添加新功能。
Geometry calculations
幾何計算
Lanelet2's objects meant to be directly usable for geometry calculations. They are all registered with boost::geometry, meaning the follwing is easily possible: double d = boost::geometry::distance(laneletPoint1, laneletPoint2)
. If laneletPoint1/2 is a 2D point, you will get the result in 2D, else in 3D.
However, there are limitations to this that originate from the fact that the ConstCorrectness concept and boost::geometry do not play well with each other, because boost::geometry gets confused by the different point types used when things are used in a const and a non-const context. If you want to know more how to solve this problem and avoid pages and pages of compiler errors from boost's feared template code, read our Geometry Primer on this.
Lanelet2的對象意味着可以直接用於幾何計算。它們都注冊了boost::geometry,這意味着下面的操作很容易實現:double d = boost::geometry::distance(laneletPoint1, laneletPoint2)。如果laneletPoint1/2是一個二維點,你將得到二維的結果,否則是三維的。
然而,由於const和非const環境中使用的內容使用的點類型不同(?),因此const常量正確性概念和boost::geometry不能很好地相互配合,因此存在一些限制。如果您想知道更多如何解決這個問題,並避免boost的模板代碼中編譯器的錯誤,請閱讀我們的幾何入門教程。
Overview and Interaction
概述和交互
If you don't know Lanelet2's basic primitives yet, better read here first!
如果你還不知道Lanelet2的基本的組成部分,你最好先閱讀 一下這里!
Here, we want to introduce the basic terms and object that you will be confronted with when using Lanelet2 and how they interact:
這里,我們想介紹你使用Llanelet2的時候將遇到的基本術語和對象,以及它們是如何相互作用的。
- Primitive any Lanelet2 primitive and their derivates (
Lanelet
,ConstLanelet
,LineString2d
, etc) - 一切Lanelet2組成和它們的衍生品(
Lanelet
,ConstLanelet
,LineString2d
, 等) - LaneletMap a laneletMap is the basic storage container for primitives. It is separated in layers, one for each primitive type and offers different ways to access its data (by a BoundingBox, by id, by nearest point, etc). It does not provide routing functionality.
- LaneletMap laneMap是lanelet的基本組件的最基本的存儲容器。它是分層的,每一層存儲一個基本類型,並提供了不同的方法來訪問它的數據(通過一個BoundingBox,通過id,通過最近的點,等等)。它不提供路線規划功能。
- TrafficRules a traffic rules object interprets the map. E.g. it reports if a lanelet
isPassable
, or if lane changes are possible between two lanelets. A traffic rule object interprets the map from the perspective of one road participant type. A vehicle TrafficRule object will therefore give completely different results on a specific lanelet than a pedestrian TrafficRule object. - 交通規則:一個交通規則對象解釋地圖。例如,它報告一個lanelet是否是可通行的,或者兩個lanelets之間是否可變道。交通規則對象從道路參與者類型的角度解釋地圖。因此,車輛交通規則對象在特定的lanelet上給出的結果與行人交通規則對象完全不同。
- RoutingCost these classes are used by the routing graph to determine costs when driving from one Lanelet/Area to another one. It could be by travelled distance, by travel time but there are no limits for more advanced routing cost functions. You can also choose the cost of lane changes so that routes with few, preferably long lane changes are preferred.
- 路線成本:這些類被用來確定從一個Lanelet/Area到另一個Lanelet/Area的最小成本。它可以通過旅行距離,旅行時間來實現,但是對於更高級的路線成本函數沒有限制。您還可以選擇車道更改的成本,以便選擇較少、最好是較長的車道更改的路線。
- RoutingGraph a routing graph is built from a LaneletMap, TrafficRules and RoutingCost objects. One routing graph is only for one single participant: The one that the TrafficRules belong to. With the routing graph, you can make all kinds of queries to determine where you or someone else can go/drive.
- 路線圖:路線圖是根據LaneletMap、交通規則和路線成本對象構建的。一個路由圖只針對一個交通參與者:即交通規則所屬的參與者。使用路線圖,您可以進行各種查詢來確定您或其他人可以去/駕駛的位置。
- Route a route is something returned by the graph when you query a route from A to B. It contains a structure of all the lanelets that you can use on the way with the lowest routing cost, including all possible lane changes.
- 路線:一條路線是在查詢從a到b的路路線時由路線圖返回的內容。它包含一個你在路上所使用的所有lanelets,您可以在路線成本最低的情況下使用這些lanelets,包括所有可能的變道。
- LaneletPath or Path in general is a sequence of lanelets returned by the RoutingGraph that are directly adjacent and have the lowest routing cost to the destination. "Adjacent" means that they can also be connected by a lane change, not only by following the lanelet in a straight direction.
- 路徑:LaneletPath或Path通常是由路線圖返回的直接相鄰且到目的地路線成本最低的lanelets序列。“相鄰”意味着它們也可以通過變道連接,而不僅僅在直線方向上沿着lanelet行駛。
- LaneletSequence a list of directly succeeding lanelets that can be reached without lane changes. A LaneletSequence is the special case of a LaneletPath where no lane change is necessary.
- Lanelet序列:無需更改車道即可到達的連續的lanelets的列表。一個Lanelet序列是不需要改變車道的Lanelet路徑的特殊情況。
- Projector projectors are used by the IO module to convert between maps that store date in the WGS84 (lat/lon) format and the local coordinates used by Lanelet2. There are many different projections that all have different properties, so you should choose the one that fits best to you. If in doubt, use UTM.
- 投影:IO模塊使用投影在存儲數據格式為WGS84 (lat/lon)格式的地圖和Lanelet2使用的本地坐標之間進行轉換。有很多不同的投影都有不同的性質,所以你應該選擇最適合你的投影。如果有疑問,請使用UTM。
3.
https://github.com/changhexingchen/Lanelet2/blob/master/lanelet2_core/doc/GeometryPrimer.md
Geometry Calculations With Lanelet2
用Lanelet2進行幾何計算
Lanelet2 primitives interface with Boost.Geometry. Boost.Geometry offers almost all common geometry calculations and is very fast. One downside is that not all algorithms work well with normal Lanelet2 primitives (see below). Another downside is that Boost.Geometry is compile-time heavy and is thus not included in the normal lanelet2 headers. To use geometry calculations, include the respective geometry header, e.g. geometry/LineString.h
.
Lanelet2基本組件與Boost.Geometry接口。Boost.Geometry提供了幾乎所有常見的幾何計算,而且非常快。一個缺點是,並不是所有的算法都能很好地與普通的Lanelet2組件一起工作(見下文)。另一個不利因素是Boost.Geometry編譯時費時和繁重的,因此不包括在普通的lanelet2頭文件中。若要使用幾何計算,請包含相應的頭文件,例如:geometry/LineString.h。
Thanks to boost, all common geometry algorithms are available out of the box. E.g. you can compute distances between points, linestrings, polygons, etc in all combinations in (mostly) all dimensions.
多虧了boost,所有常見的幾何算法都是開箱即用的。例如,你可以計算點與點之間的距離,線串,多邊形等,在幾乎所有的維度上所有的組合。
There are usually two different kinds of algorithms: The one that Boost implements (like distance
) and the one that Lanelet2 implements (mostly on top of Boost), like boundingBox2d
. When using the first kind, you should read the lines below, while the second kind can be used without further reading.
通常有兩種不同的算法:一種是Boost實現的(比如距離),另一種是Lanelet2實現的(主要建立在Boost之上),比如boundingBox2d。在使用第一種方法時,您應該閱讀下面的代碼行,而第二種方法無需進一步閱讀就可以使用。
For a list of algorithms that are available, please refer too Boost's documentation or look through lanelet's geometry headers (or doxygen). All algorithms there have a small description.
有關可用算法的列表,請參考Boost的文檔或查看lanelet的幾何頭文件(或doxygen)。所有的算法都有一個小的描述。
Using Lanelet Primitives in Boost.Geometry
在Boost.Geometry中使用Lanelet基本組件
Lanelet2 offers every geometrical primitive in three flavors, each for 2D and 3D. Because they are just pointers to the actual data, they can be converted without actually copying data:
Lanelet2提供了三種形式的幾何元素,分別用於2D和3D。因為它們只是指向實際數據的指針,可以在不復制數據的情況下進行轉換:
- Mutable (e.g.
LineString2d
): Are mutable, returned members are mutable (unless the object is const, then they are also immutable) - Const (e.g.
ConstLineString2d
): These are immutable, returned members (e.g. points of linestring) are also immutable - Hybrid (e.g.
ConstHybridLineString2d
): Also immutable, returned members are not lanelet primitives (e.g.BasicPoint2d
). If in doubt, use this one.
Let us consider these types one by one. The first one (mutable) has the property that it behaves differently (i.e. returns different types) when used const
or non-const
. This is an issue for some of Boost.Geometry algorithms, because they sometimes accept const and sometimes non-const objects and therefore get the type wrong. Even if they get the type right, Boost is not fully compatible with the concept that copied primitives still refer to the same data and might therefore accidentally modify the wrong data. Therefore algorithms that modify the input (e.g. correct
) are possible, but there is no 100% guarantee they work as expected (across all versions of Boost).
讓我們逐一考慮這些類型。第一個變量(可變)的屬性是,當使用const或non-const時,它的行為是不同的(即返回不同的類型)。這是Boost.Geometry算法的問題,因為它們有時接受const對象,有時接受非const對象,因此得到錯誤的類型。即使類型正確,Boost也不完全兼容,復制的元素仍然引用相同數據的概念,因此可能會意外修改錯誤的數據。因此,修改輸入(例如,正確)的算法是可能的,但是不能100%保證它們能正常工作(在Boost的所有版本中)。
The const version does not have the risk of accidentally modifying the wrong data (because they are always immutable), however some algorithms that should not modify the data still try to instanciate templates in which the data can be modified. This results in longish compiler errors (and this might change from Boost version to Boost version). Algorithms that modify the input data (such as correct
) can not be used because of the constness.
const版本沒有意外修改錯誤數據的風險(因為它們總是不可變的),但是一些不應該修改數據的算法仍然試圖實例化可以修改數據的模板。這會導致較長時間的編譯器錯誤(這可能會在不同的Boost版本之間發生變化)。不能使用修改輸入數據(如correct)的算法,由於常量。
The hybrid version returns non-lanelet objects (BasicPoint2d/3d), which are fully compatible with Boost. This is the best solution for almost all geometry calculations. However, algorithms that mutate the primitive itself (such as correct
) are not possible because the hybrid versions themselves are immutable (no points can be deleted or added).
混合版本返回與Boost完全兼容的非lanelet對象(BasicPoint2d/3d)。這是幾乎所有幾何計算的最佳解決方案。然而,改變基本元素本身(如correct)的算法是不可能的,因為混合版本本身是不可變的(不能刪除或添加任何點)。
In summary:
Type | For example | Use for Boost.Geometry |
---|---|---|
Mutable | LineString2d | Only for mutating algorithms, but use with care |
Const | ConstLineString2d | No |
Hybrid | ConstHybridLineString2d | Yes, safe to use if they compile |
Understanding Boost Geometry's Errors
Boost geometry is known for outputting endless lines of compiler errors when used in the wrong way. Here are some hints to find out what you did wrong (sometimes you have to look closely for the actual error in many lines of instanciated templates). They are related to GCC's error messages, but other compilers will output similar stuff:
- Something about "no member named 'set' in boost::geometry::traits::access [...]: You used a const primitive (or you used a mutable primitive and Boost converted it into a const by a mistake). Try using the hybrid version.
- Some error including "NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE" together with some *no matching function for call to assertion failed": This is a very generic error and the error message may be misleading. One reason could be that you forgot to include some
lanelet2_core/geometry
headers. Other reasons could be that you used the function on a primitive it was not implemented for (refer to Boosts documentation for that) or that it was not implemented for this particular dimension. Especially 3D operations are often not implemented in boost::geometry. - Something with "You mixed matrices of different sizes". This is actually an error from
Eigen
. It means you passed aBasicPoint3d
where aBasicPoint2d
was expected (or vice versa). - Something with "no matching member function for call to '_init1'", also from
Eigen
: You passed a wrong type where a BasicPoint2d/3d was expected. - Some error in
boost::assert_dimension_equal
: You passed a 2d primitive to Boost where a 3d primitive was expected (or vice versa).