0302:Lanelet2 地图概述

1. Lanelet2 地图概述

1.1 核心概念

Lanelet2 将道路网络表达为车道片段的组合:

  • Lanelet(车道片段):左右边界围成的可通行区域,包含方向、参与者类型、区域属性、车道类型等信息
  • Area(区域):停车区、绿化带、建筑物、交通岛等环境要素
  • RegulatoryElement(规则元素):将交通标志、信号灯、让行规则、限速等与车道关联

应用场景

  • 路径规划:在车道拓扑图上搜索可行路线
  • 规则约束:推断通行权限、变道规则、限速、路口约束
  • 定位匹配:将车辆位姿匹配到车道,获取沿程坐标

2. OSM XML 基础

核心元素

  • <node>:点(WGS84 经纬度),可带 tag 属性
  • <way>:有序点序列,表达线或面轮廓
  • <relation>:多个元素的组合,表达 lanelet、multipolygon、regulatory element
  • <tag>:键值对属性

2.1 坐标与单位

  • lat/lon:地理坐标(度),内部投影到局部平面(如 UTM)
  • ele:高程(米)
  • speed_limit:建议带单位(如 50 km/h

2.2 ID 与引用

  • node/way/relation 的 ID 分别独立编号,允许重复
  • 引用时用 type + ref 组合唯一标识
  • 解析时应使用(type, id)作为唯一键

3. 语义层映射

Lanelet2 将 OSM 元素映射为基本元素(点、线、车道、区域、规则)。

关键区别

  • 结构属性(Attributes):XML 结构定义(id、坐标、成员引用)
  • 语义标签(Tags)<tag> 定义对象含义、类型、规则

3.1 LineString ↔ OSM Way

  • Lanelet2 的 LineString(线)<way> 表达:由若干 <nd ref=.../> 连接成有序折线
  • <way> 上的 type/subtype 等标签决定它的角色(边界线、标志、信号灯、路面符号等)

3.2 Polygon ↔ OSM Way(带 area=yes

  • 多边形也可以用 <way> 表达,但需要 area=yes(仅首尾点相同并不充分也不必要;Lanelet2 使用 area=yes 判断)。

3.3 Lanelet ↔ OSM Relation(type=lanelet

Lanelet2 maps 文档定义 lanelet relation 的成员角色(role)与约束:

  • type=lanelet<relation> 必须包含:
    • role=left 的成员:type=way,表示左边界
    • role=right 的成员:type=way,表示右边界
    • (可选)role=centerline 的成员:type=way,表示中心线
    • (可选、可多)role=regulatory_element 的成员:type=relation,引用规则元素
  • 如果 lanelet relation 的成员超出上述集合,Lanelet2 会报错(这是非常重要的"格式硬约束")。

方向性:lanelet 的"行驶方向"由左右边界的点序以及 lanelet 几何关系推断;并由 one_way(及其分参与者变体)进一步约束,详见 §5。

3.4 Area ↔ OSM Relation(type=multipolygon

  • Area 使用 OSM 的 multipolygon 表达:<relation>type=multipolygon
  • role=outer:外边界(有序列表,可能由多个 way 拼接)。
  • role=inner:内孔边界(同样是有序列表)。
  • Lanelet2 会按 inner 的顺序解析,当某条 inner linestring 的末点与下一条 inner 的首点相同时,会认为这在描述同一个孔的拼接;当不连续时,开始一个新孔。

3.5 Regulatory Element ↔ OSM Relation(type=regulatory_element

  • Regulatory element 使用 relation:type=regulatory_element
  • relation 的成员(parameters)使用 role 字符串表示其语义(例如 refers/ref_line/yield/right_of_way 等)。
  • Lanelet2 maps 文档指出:没有 type 或 type 错误的 relation 会在解析 .osm 时被忽略

3.6 Lanelet2 基本元素与 OSM 元素映射详解

本节深入解释 Lanelet2 基本元素(点、线、多边形)与 OSM 元素之间的映射细节,这些细节对于正确理解地图数据至关重要。

3.6.1 Point 与 OSM Node 的映射

基本映射

  • Lanelet2 的 Point<node> 表达
  • lat/lon 是点的几何属性(WGS84 经纬度)
  • ele tag 用于表示 z 坐标(高程),单位通常为米,表示距地球椭球面的高度

Node 的语义标签

Node 可以带有 type tag 来标注特殊语义点(这些点仍然是 linestring 的组成部分,但带有额外的语义信息):

  • type=begin:标记虚线 dash 的起始点(沿 linestring 方向)
  • type=end:标记虚线 dash 的结束点
  • type=pole:标记护栏/围栏的立柱位置
  • type=dot:标记点状标线

这类语义点用于高精细度可视化或更精确的规则/感知仿真,但不影响基本的几何表达。

3.6.2 LineString 与 OSM Way 的映射

基本映射

  • Lanelet2 的 LineString (线)用 <way> 表达
  • way 由有序的 <nd ref=.../> 连接成折线

关键概念:中心线语义 (官方文档明确强调)

Linestrings are generally characterized by their centerline.

核心要点

  • Way 默认代表对象的中心线,而非边缘或轮廓
  • 车道边界线 (type=line_thin):way 为标线中心轴
  • 护栏 (type=guard_rail):way 为护栏中轴线
  • 墙体 (type=wall):way 为墙体中轴线

Width 和 Height 的语义

  • width(单位:米):描述对象在垂直于 way 方向的宽度

    • way 仍然代表中心线(不是边缘)
    • 例如:type=wall, width=0.3 表示墙体宽 30cm,way 是墙体中轴
  • height(单位:米):描述对象在垂直方向的高度

    • 特殊语义:way 代表对象的下沿/最低边(与 width 不同!)
    • 例如:type=traffic_sign, height=0.8 表示标志牌高 80cm,way 是标志底边
    • 注意:这里的 height 是对象自身高度,不是离地高度(离地高度应通过 z 坐标/ele 表达)

轮廓表达的例外情况

对于某些对象(如 traffic_sign、traffic_light),可以用以下两种方式表达:

  1. 轮廓方式:way 包含多个点围成多边形轮廓(通常用于精确建模)
  2. 两点线段方式 :way 只有两个点
    • 首点 = 对象左边缘
    • 末点 = 对象右边缘
    • 配合 height tag 表达对象尺寸

建议:用两点线段方式时,确保 way 只有两个点,避免与轮廓方式混淆。

3.6.3 Polygon 与 OSM Way 的映射

单个多边形

  • Lanelet2 的 Polygon (多边形)用 <way> + area=yes tag 表达
  • 重要 :仅凭首尾点相同不足以判定为多边形(也不是必要条件)
  • Lanelet2 使用 area=yes tag 明确判断该 way 是否为多边形

带孔的复杂多边形

  • 使用 type=multipolygon 的 relation 表达(详见 §3.4)

3.6.4 Attributes 与 Tags 的区别(重要)

理解这个区别对于正确理解 Lanelet2 数据模型至关重要:

属性类型 定义位置 示例 作用
Attributes OSM XML 结构 id, lat, lon, ref, role, type(member 的 type) 定义对象的结构关系
Tags <tag k=... v=.../> type(tag 的 type), subtype, location, speed_limit 定义对象的语义

易混淆点

  • <member type='way' ...>:这里的 typeattribute(表示成员类型)
  • <tag k='type' v='lanelet'/>:这里的 typetag(表示语义类型)
  • 两者完全不同,不要混淆

实例对比

xml 复制代码
<!-- Attribute 示例:id, lat, lon 是结构属性 -->
<node id='1001' lat='49.0' lon='8.4' />

<!-- Tag 示例:type/subtype 是语义属性 -->
<way id='2001'>
  <nd ref='1001' />
  <nd ref='1002' />
  <tag k='type' v='line_thin' />
  <tag k='subtype' v='solid' />
</way>

<!-- Member 的 type attribute vs Tag 的 type -->
<relation id='3001'>
  <member type='way' ref='2001' role='left' />  <!-- type 是 attribute -->
  <tag k='type' v='lanelet' />                  <!-- type 是 tag -->
</relation>

3.6.5 基本元素映射总结表

Lanelet2 基本元素 OSM 元素 关键标识 几何语义
Point <node> lat, lon, (ele) 点坐标
LineString <way> 有序 <nd> 序列 默认为中心线
Polygon <way> area=yes tag 闭合区域
Lanelet <relation> type=lanelet tag 左右边界围成的车道片段
Area <relation> type=multipolygon tag 外边界 + 内孔
RegulatoryElement <relation> type=regulatory_element tag 规则元素

4. "最小可用"Lanelet2-OSM

如果你只想最快把一张 Lanelet2-OSM 地图读进来并用于规划/定位,至少确保:

  1. 有 lanelet relation:<relation><tag k='type' v='lanelet'/> ...</relation>
  2. 每个 lanelet relation 至少有 left/right 两个边界 way 成员(role 必须正确)
  3. 车道边界 way 带 type(例如 line_thin/curbstone/road_border/virtual),否则 Lanelet2 很可能默认"不可变道"
  4. lanelet 上的 subtype/location/one_way/participant:* 至少能推断出:
    • 行驶方向(one_way)
    • 允许参与者(participant)
    • 限速(speed_limit 或基于 location/subtype 的默认推断,或 regulatory element)
  5. 路口规则(红绿灯/让行/停止线/限速牌)用 regulatory element 关联到 lanelet

4.1 一个"最小 lanelet"的 OSM/XML 示例

下面示例只展示 Lanelet2-OSM 的结构:两个边界 way + 一个 lanelet relation(真实地图需要更多点、更合理的几何与规则元素)。

xml 复制代码
<osm version='0.6' generator='example'>
  <node id='1' lat='49.0000000' lon='8.0000000' />
  <node id='2' lat='49.0000100' lon='8.0000000' />
  <node id='3' lat='49.0000000' lon='8.0000100' />
  <node id='4' lat='49.0000100' lon='8.0000100' />

  <way id='10'>
    <nd ref='1' /><nd ref='2' />
    <tag k='type' v='line_thin' />
    <tag k='subtype' v='solid' />
  </way>
  <way id='11'>
    <nd ref='3' /><nd ref='4' />
    <tag k='type' v='line_thin' />
    <tag k='subtype' v='dashed' />
  </way>

  <relation id='100'>
    <member type='way' ref='10' role='left' />
    <member type='way' ref='11' role='right' />
    <tag k='type' v='lanelet' />
    <tag k='subtype' v='road' />
    <tag k='location' v='urban' />
    <tag k='one_way' v='yes' />
    <tag k='region' v='de' />
  </relation>
</osm>

5. Lanelet / Area 的标签

这一部分来自 LaneletAndAreaTagging.md,强调一个核心原则

5.0 自洽性原则

核心要求:每个 Lanelet/Area 必须包含完整交通规则,无需依赖相邻元素。

必须可确定的信息

  1. 行驶方向 :通过 one_way 确定,默认单向
  2. 通行参与者 :通过 subtype + location 推断或 participant:* 指定
  3. 限速:通过标签、规则元素或默认值确定

设计目的

  • 避免推断歧义,保证数据一致性
  • 支持独立解析和分布式处理
  • 提高鲁棒性

5.1 关键标签:subtypelocation

  • subtype:描述 lanelet 的类型(road/highway/bicycle_lane/crosswalk/...)
  • location:区分 urban / nonurban(影响默认限速等)

文档给出"默认推断表"(注意:最终解释依赖所选 TrafficRules 实现):

  • subtype=road, location=urban:城市道路(车辆与自行车,城市默认限速)
  • subtype=highway:高速(通常仅车辆,不同地区默认/建议限速不同)
  • subtype=bicycle_lane:自行车道(自行车)
  • subtype=walkway/crosswalk:人行相关(行人)
  • 以及 bus_lane、play_street、shared_walkway、stairs 等

5.2 覆盖机制:participant:*speed_limit*

需显式覆盖默认推断时,使用以下标签:

交通参与者覆盖 (官方文档明确强调):

  • 使用格式:participant:<participant>=yes/no(例如 participant:vehicle:bus=yes
  • 关键约束 (官方原文用词:"ignored"):
    • 一旦使用任何一个交通参与者覆盖标签,subtype/location 的推断将被完全忽略
    • 所有未显式设置的交通参与者默认为 no(不允许通行)
    • 必须逐个显式设置允许通行的交通参与者

示例

复制代码
participant:vehicle:bus=yes
participant:vehicle:taxi=yes
participant:pedestrian=yes

含义:只允许公交车、出租车和行人通行,其他所有交通参与者(如私家车、货车、自行车)都不允许

可用的交通参与者类型(层级结构):

  • vehicle(影响所有机动车参与者)
    • vehicle:car
      • vehicle:car:electric
      • vehicle:car:combustion
    • vehicle:bus
    • vehicle:truck
    • vehicle:motorcycle
    • vehicle:taxi
    • vehicle:emergency
  • pedestrian
  • bicycle

重要规则

  • vehicle tag 不能与任何 vehicle:xxx tag 组合使用
  • 如果定义了任何一个 vehicle:xxx tag,所有其他 vehicle:xxx tag 必须单独设置

限速覆盖

  • speed_limit:值可带单位(如 50 km/h),无单位默认 km/h
  • speed_limit_mandatory:yes/no(默认 yes)
  • 也可以按参与者细分:speed_limit:<participant>speed_limit_mandatory:<participant>
  • 注意:限速也可能被 regulatory elements 覆盖(例如 speed_limit regulatory element)

官方建议

尽量避免使用覆盖机制。更清晰的方式是:

  1. 创建新的 TrafficRule 类来支持未涵盖的道路类型
  2. 使用规则元素 (RegulatoryElement) 表达特殊规则

5.3 方向性:one_wayone_way:<participant>

  • Lanelet 默认"单向"。
  • one_way=no 表示双向。
  • 可按参与者细分:one_way:bicycle=no 等。
  • one_wayone_way:xxx 不能混用。
  • 行人默认可双向(除非覆盖)。

5.4 其他可选标签

来自文档的常见建议:

  • road_name:道路名称
  • road_surface:路面类型(asphalt/concrete/dirt...)
  • region:ISO 3166-2 国家/地区代码(例如 de),TrafficRules 可能据此确认适用性

5.5 TrafficRules 机制与覆盖优先级

Lanelet2 采用"数据与解释分离"的设计:地图数据(tags)只表达"是什么"(描述性),而 TrafficRules 实现负责"如何解释"(规则引擎)。

TrafficRules 的作用

  • TrafficRules 是 Lanelet2 的规则解释引擎,位于 lanelet2_traffic_rules
  • 同一份地图数据,在不同国家/地区的 TrafficRules 实现下可能得到不同的解释
  • 例如:subtype=road, location=urban 在德国可能推断为 50 km/h 限速,在美国可能是不同值

覆盖优先级链(从高到低):

复制代码
┌─────────────────────────────────────────┐
│ 1. Regulatory Element(最高优先级)      │
│    - speed_limit regulatory element      │
│    - traffic_light regulatory element    │
│    - right_of_way regulatory element等   │
├─────────────────────────────────────────┤
│ 2. Lanelet 显式覆盖 Tags                 │
│    - speed_limit=60 km/h                 │
│    - participant:vehicle:bus=yes         │
│    - one_way:bicycle=no                  │
├─────────────────────────────────────────┤
│ 3. subtype/location 默认推断              │
│    - 依赖 TrafficRules 实现               │
│    - 不同国家/地区可能不同                │
└─────────────────────────────────────────┘

实例说明

假设某 lanelet 有以下标签:

复制代码
subtype=road
location=urban
speed_limit=60 km/h

并且被一个 speed_limit regulatory element 引用,该元素指定 sign_type=30 km/h

最终生效的限速为 30 km/h(regulatory element 优先级最高)。

region tag 的作用

  • region tag(如 region=deregion=cn)用于标识地图所属的国家/地区
  • TrafficRules 实现可以通过 region 判断是否适用(例如德国规则要求 region=de
  • 建议:同一地图内统一使用相同的 region,避免跨地区混用导致规则冲突

交通参与者覆盖的"全有或全无"原则

一旦使用任何一个 participant:xxx=yes

  • subtype/location 的交通参与者推断被完全忽略
  • 所有未设置的交通参与者默认为 no
  • 必须逐个显式设置所有允许的交通参与者

5.6 兼容性提示:布尔值写法

官方文档多使用 yes/no 表达布尔值;但在 mapping_example.osm 中,one_way 出现了 false(与 no 等价的语义)。这说明在实际数据链路中你可能会遇到 true/falseyes/no 混用:

  • 做解析器/校验器时,建议把 yes/true/1 视为真,把 no/false/0 视为假(并在导出时统一成一种写法)。
  • 做建图规范时,建议团队统一为 yes/no(更贴近 OSM 生态习惯)。

6. Linestring(OSM Way)标签:边界/符号/标志/信号灯

本节来自 LinestringTagging.md,并结合示例文件中出现的类型做解释。

6.1 车道边界(Lane Boundary)类型与变道推断

Lanelet2 用边界线的 type/subtype 来判断能否变道;若无法判断,默认不可变道

典型边界类型(文档表格):

type subtype 含义 默认变道
line_thin solid 实线
line_thin dashed 虚线
line_thin dashed_solid 左虚右实 左→右可变(从虚线侧跨越)
line_thin solid_dashed 左实右虚 右→左可变
line_thin solid_solid 双实线
line_thick 同上 粗线同理 依 subtype
curbstone high 高路沿
curbstone low 低路沿(可跨越) 否(注意:可跨越 ≠ 允许变道)
virtual - 非物理边界(多用于路口)
road_border - 道路边界(通常是可通行区域的边界)
6.1.1 强制覆盖变道(lane_change)

如果你不满意默认推断,可用:

  • lane_change=yes(双向可变)或
  • lane_change:left=<yes/no>lane_change:right=<yes/no>(必须两者都设)

这在"线型看起来不允许变道但业务想允许"的场景很常用;反之也可用来禁止虚线变道。

6.1.2 其他常见边界类型

这些类型默认都表示不可变道/不可跨越(具体可通行性仍依 TrafficRules 与几何):

guard_rail, wall, fence, keepout, jersey_barrier, gate, door, rail 等。

6.2 可选几何尺寸标签:width / height

当线表示的是"有宽度/高度"的实体(护栏、墙、标志牌等):

  • width:单位 m,linestring 表示对象中心线
  • height:单位 m,linestring 表示对象的下沿/最低边
  • temporary=yes/no:施工临时标线
  • color:标线颜色(默认 white)

6.2.1 "虚线的每一段"如何表达(Individual Dashes)

Lanelet2 文档指出:虚线在几何上通常仍用一条连续折线表达,会丢失"每一段 dash 的起止位置"。若要保留,可在 dash 的起止点打点(OSM node),并用 node 的 type 标注:

  • type=begin:某一段 dash 的开始点(沿 linestring 方向)
  • type=end:某一段 dash 的结束点
  • 也可扩展:type=pole(护栏/围栏的立柱点)、type=dot(点状标线)

这类 node 是"附加语义点",常用于高精细可视化或更精确的规则/感知仿真。

6.3 路面符号(Symbols)

文档给出常见符号表达方式:

  • 箭头:type=arrow + subtype=left/right/straight/...
  • 其他:stop_line, zig-zag, lift_gate, bump, 以及 30/50/70 等限速文字

符号既可用轮廓(多点)表示,也可用中心线(两点)表示;用中心线时建议仅两点以免与轮廓混淆。

6.4 交通标志(Traffic Signs)

  • type=traffic_sign
  • subtype=<region+编号>:ISO 3166 区域码 + 交通标志编号
    • 示例(文档):subtype=de206(德国 stop),或 subtype=usR1-1(美国 stop)

几何表示:

  • 可用多边形轮廓表示(way 多点)
  • 或用折线表示(way 的首点为标志左下边缘,末点为右下边缘),可配合 height 表示标志尺寸;注意:height 在此语境是标志自身高度,不是离地高度(离地高度应通过 z/ele 或其他约定表达)。

6.5 交通信号灯(Traffic Lights)

  • type=traffic_light
  • subtype 可描述灯型:red_yellow_green / red_yellow / red / ...
  • 同样可用轮廓或折线表达

7. RegulatoryElement(规则元素)

7.1 核心约束

双向引用(重要):

  • 规则元素与 lanelet/area 必须相互引用
  • 单向引用会导致规则失效

示例

xml 复制代码
<!-- 正确:双向引用 -->
<relation id='100'>  <!-- lanelet -->
  <member type='way' ref='10' role='left' />
  <member type='way' ref='11' role='right' />
  <member type='relation' ref='200' role='regulatory_element' />  <!-- 引用规则 -->
  <tag k='type' v='lanelet' />
</relation>

<relation id='200'>  <!-- regulatory element -->
  <member type='relation' ref='100' role='yield' />  <!-- 引用 lanelet -->
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='right_of_way' />
</relation>

<!-- 错误:仅单向引用 -->
<relation id='100'>  <!-- lanelet,缺少对规则的引用 -->
  <member type='way' ref='10' role='left' />
  <member type='way' ref='11' role='right' />
  <!-- 缺少 regulatory_element 成员! -->
  <tag k='type' v='lanelet' />
</relation>

<relation id='200'>  <!-- regulatory element -->
  <member type='relation' ref='100' role='yield' />
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='right_of_way' />
</relation>

通用标签

Regulatory element relation:

  • type=regulatory_element(缺失时 Lanelet2 写回 .osm 会补齐)
  • subtype:基本类型之一:
    • traffic_sign
    • traffic_light
    • speed_limit
    • right_of_way
    • all_way_stop

可选标签(默认值以粗体为准):

  • dynamic(yes/no):动态规则(详见 §7.1.1)
  • fallback(yes/no):低优先级规则(详见 §7.1.1)

7.1.1 Dynamic 与 Fallback 的实际应用

Dynamic 规则(dynamic=yes

定义:表示此规则元素的含义可能根据条件变化(官方原文:"might change its meaning based on a condition")。

典型应用场景

  1. 可变限速

    • 电子显示屏限速(雨天降速、雪天降速)
    • 示例:晴天 80 km/h,雨天 60 km/h
  2. 时段限制

    • 公交专用道(7-9点、17-19点限制)
    • 示例:工作日早晚高峰仅公交/出租车可用,其他时段所有车辆可用
  3. 临时封路

    • 施工期间封闭
    • 活动/赛事期间临时改道

处理建议

  • 地图数据 :标记 dynamic=yes,表达"规则会变",但不在地图中硬编码具体条件
  • 运行时:TrafficRules 需要外部输入(当前时间/天气/V2X 信息等)来解析当前有效规则
  • Lanelet2 默认行为 :默认 TrafficRules 实现会忽略 dynamic=yes 的规则(需自定义 TrafficRules 才能处理)

示例

xml 复制代码
<relation id='300'>
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='speed_limit' />
  <tag k='sign_type' v='80 km/h' />  <!-- 基准值,实际由外部系统提供 -->
  <tag k='dynamic' v='yes' />  <!-- 标记为动态规则 -->
</relation>

Fallback 规则(fallback=yes

定义:表示此规则元素的优先级低于其他规则元素(官方原文:"has a lower priority than another Regulatory Element")。

典型应用场景

  1. 路口备用规则

    • 主规则:信号灯(fallback=no
    • 备用规则:让行规则(fallback=yes),仅当信号灯故障时生效
  2. 限速备用

    • 主规则:电子限速牌(fallback=no
    • 备用规则:固定限速牌(fallback=yes),仅当电子牌故障时生效

处理逻辑

  • 同一 lanelet 可能被多个 regulatory element 引用(一个主规则 + 多个 fallback 规则)
  • TrafficRules 应优先解析 fallback=no 的规则
  • 当主规则不可用/不适用时(如信号灯状态未知、电子牌离线),启用 fallback=yes 的规则

示例

xml 复制代码
<!-- 主规则:信号灯 -->
<relation id='400'>
  <member type='way' ref='...' role='refers' />
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='traffic_light' />
  <tag k='fallback' v='no' />  <!-- 默认值,可省略 -->
</relation>

<!-- 备用规则:让行 -->
<relation id='401'>
  <member type='relation' ref='...' role='yield' />
  <member type='relation' ref='...' role='right_of_way' />
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='right_of_way' />
  <tag k='fallback' v='yes' />  <!-- 低优先级,信号灯故障时生效 -->
</relation>

<!-- 受控 lanelet 引用两个规则 -->
<relation id='500'>
  <member type='way' ref='...' role='left' />
  <member type='way' ref='...' role='right' />
  <member type='relation' ref='400' role='regulatory_element' />  <!-- 主规则 -->
  <member type='relation' ref='401' role='regulatory_element' />  <!-- 备用规则 -->
  <tag k='type' v='lanelet' />
</relation>

7.2 parameters(成员)与通用 role

Regulatory element 的成员称为 parameters,通过 <member ... role='...'/> 表达。通用 role:

  • refers:规则来源(标志/信号灯等)
  • cancels:规则结束标志(若适用)
  • ref_line:规则生效/停止线(常为 stop_line 线)
  • cancel_line:规则失效线(若适用)

7.2.1 role 是"字符串协议"

Regulatory element 的 role 本质上是字符串协议:TrafficRules/相关算法会按约定字符串查找参数。因此:

  • role 名称必须与文档/实现一致(例如 ref_line 不是 refline
  • 建图时建议复用官方文档中的 role 字符串;新增自定义 role 时需要同步实现对应的 TrafficRule/RegulatoryElement 逻辑

7.3 常见规则元素的结构

下面给出文档中的典型结构(并在 §9 对应到 mapping_example.osm 的真实片段)。

7.3.1 Traffic Light(subtype=traffic_light
  • refers:信号灯(通常是 type=traffic_light 的 way)
  • ref_line:停止线(可选;缺失时默认为 lanelet/area 末端)

官方示例:

xml 复制代码
<relation id='1'>
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='traffic_light' />
  <member type='way' ref='2' role='ref_line' />
  <member type='way' ref='3' role='refers' />
</relation>
7.3.2 Speed Limit(subtype=speed_limit

两种方式:

  1. 由限速牌构成:refers 指向 type=traffic_sign 的 way,TrafficRules 从 traffic_sign 的 subtype 解释出具体限速。
  2. 非标志来源:在 regulatory element 上用 sign_type tag 直接写速度(值带单位,如 50 km/h;无单位默认 km/h)。

官方示例(由标志构成):

xml 复制代码
<relation id='1'>
  <tag k='subtype' v='speed_limit' />
  <tag k='type' v='regulatory_element' />
  <member type='way' ref='2' role='refers' />
</relation>
7.3.3 Traffic Sign(subtype=traffic_sign

通用交通标志规则(不限于限速):

  • refers:构成规则的标志
  • cancels:结束标志(如"解除禁止超车")
  • ref_line/cancel_line:精确定义生效/失效位置

文档还强调:若 ref_line/cancel_line 与所引用 lanelet/area 有交点,则规则生效区间可按交点裁切;否则规则可能作用于整条 lanelet/area(具体实现依 TrafficRules)。

7.3.4 Right of Way(subtype=right_of_way

用于修改路口默认"先到先行"的规则。roles:

  • yield:需要让行的 lanelet(member type=relation,引用 lanelet relation)
  • right_of_way:拥有优先权的 lanelet(同上)
  • ref_line:让行 lanelet 的停车/让行线(可选;缺失则为 yield lanelet 末端)

重要一致性约束:被 right_of_way 规则引用到的 lanelet,通常也需要在 lanelet 自身通过 role=regulatory_element 引用该规则元素(形成双向关联),文档明确指出这一点。

7.3.5 All Way Stop(subtype=all_way_stop

四向停止等场景:让行顺序取决于到达顺序与路线。

roles:

  • yield:所有可能需要让行的 lanelet(通常是路口各入口 lanelet)
  • refers:构成规则的 stop 标志牌
  • ref_line:每个 yield lanelet 对应的停止线

关键约束(官方文档明确强调):

为了避免停止线与 lanelet 的匹配歧义,All Way Stop 规则元素的 ref_line 必须满足以下条件之一:

  1. 所有 yield lanelet 都没有 ref_line(停止位置默认为 lanelet 末端)
  2. 每个 yield lanelet 恰好对应一个 ref_line ,且 ref_line 的顺序与 yield lanelet 的顺序一一对应

错误示例

xml 复制代码
<!-- 错误:4个 yield lanelet 但只有2个 ref_line,无法确定对应关系 -->
<relation id='600'>
  <member type='relation' ref='701' role='yield' />
  <member type='relation' ref='702' role='yield' />
  <member type='relation' ref='703' role='yield' />
  <member type='relation' ref='704' role='yield' />
  <member type='way' ref='510' role='ref_line' />  <!-- 缺少2个 -->
  <member type='way' ref='511' role='ref_line' />
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='all_way_stop' />
</relation>

正确示例

xml 复制代码
<!-- 正确:4个 yield lanelet 对应4个 ref_line,顺序一致 -->
<relation id='600'>
  <member type='relation' ref='701' role='yield' />   <!-- 对应 ref_line 510 -->
  <member type='relation' ref='702' role='yield' />   <!-- 对应 ref_line 511 -->
  <member type='relation' ref='703' role='yield' />   <!-- 对应 ref_line 512 -->
  <member type='relation' ref='704' role='yield' />   <!-- 对应 ref_line 513 -->
  <member type='way' ref='510' role='ref_line' />
  <member type='way' ref='511' role='ref_line' />
  <member type='way' ref='512' role='ref_line' />
  <member type='way' ref='513' role='ref_line' />
  <tag k='type' v='regulatory_element' />
  <tag k='subtype' v='all_way_stop' />
</relation>

官方原文强调(RegulatoryElementTagging.md):

"To avoid confusion when matching lanelets and stop lines, an All Way Stop regelem is only valid if either no lanelet has a stop line or all lanelets have exactly one."

7.4 常见规则元素组合错误

基于官方文档和实践经验,以下是最常见的 regulatory element 使用错误:

错误类型 表现 排查方法 正确做法
错误1:单向引用 TrafficRules 未发现规则 检查 lanelet 是否包含 role=regulatory_element 成员 确保双向引用(见 §7.1)
错误2:ref_line 不相交 停止线位置推断失败 检查 ref_line 与 yield lanelet 是否有交点 ref_line 应横跨或至少触及 lanelet 几何
错误3:All Way Stop 匹配失败 解析错误或停止线对应错误 检查 yield lanelet 数量与 ref_line 数量 要么全无 ref_line,要么数量、顺序一致(见 §7.3.5)
错误4:traffic_sign subtype 无法解释 限速/禁令未生效 检查 TrafficRules 是否支持该 subtype 使用 sign_type tag 作为兜底(见 §7.3.2)
错误5:多个规则冲突 规则优先级不明确 检查是否有多个非 fallback 规则作用于同一 lanelet 使用 fallback=yes 明确优先级(见 §7.1.1)
错误6:dynamic 规则被忽略 动态限速未生效 检查 TrafficRules 是否实现了 dynamic 规则处理 默认 TrafficRules 会忽略 dynamic,需自定义实现

错误诊断示例

场景:限速规则未生效

排查步骤

  1. 检查 regulatory element 是否被 lanelet 引用

    bash 复制代码
    # 在 .osm 文件中搜索 lanelet relation,查看是否包含该 regulatory element
    grep -A 20 "relation id='<lanelet_id>'" map.osm | grep "regulatory_element"
  2. 检查 traffic_sign subtype 是否可解释

    bash 复制代码
    # 查看 traffic_sign 的 subtype
    grep -A 5 "way id='<sign_id>'" map.osm | grep "subtype"
    # 确认 TrafficRules 是否支持该 subtype,或使用 sign_type 兜底
  3. 检查是否有多个限速规则冲突

    bash 复制代码
    # 查找所有引用该 lanelet 的 speed_limit 规则
    grep -B 5 "ref='<lanelet_id>'" map.osm | grep "speed_limit"

8. 格式硬约束

  1. lanelet 成员仅限:left/right/centerline(way)和 regulatory_element(relation)
  2. Area 使用 type=multipolygon,按点连接顺序解析孔洞
  3. relation 必须有正确的 type,否则被忽略
  4. Tag key 使用小写

8.1 共享边界与车道拓扑

核心机制 :相邻车道共享边界 way,一个车道的 right 同时是另一个的 left

影响

  • 变道图建立(左右邻接关系)
  • 边界连续性保证
  • 变道规则推断(根据共享边界的线型)

9. 官方示例解读

样例文件

  • mapping_example.osm:完整示例(lanelet/multipolygon/regulatory_element等)
  • mapping_example-debug.osm:调试输出(routing_cost、拓扑关系)

官方路径

9.1 全局统计(快速建立直觉)

mapping_example.osm

  • 元素数量:node=2258, way=1141, relation=456
  • 地理范围(WGS84):lat 约 49.0018~49.0111,lon 约 8.4119~8.4588
  • 出现的 tag keys(按 node/way/relation 汇总):type/subtype/location/region/one_way/participant:*,以及 elefallback

mapping_example-debug.osm

  • 元素数量:node=328, way=436
  • 主要 tag keys:relation, relation_reverse, routing_cost, routing_cost_reverse(用于表达路由图边/代价)

9.2 这个样例里有哪些 lanelet / area / rules?

relation(按 type/subtype)的主要分布:

  • lanelet:
    • subtype=road(最多)
    • subtype=bicycle_lane/crosswalk/highway/rail/walkway
  • multipolygon:
    • vegetation/walkway/parking/traffic_island/building/exit/keepout
  • regulatory_element:
    • traffic_light
    • right_of_way
    • speed_limit

9.3 lanelet relation 的成员形态(与 lanelet2_maps 规则一致)

mapping_example.osm 中,lanelet 的成员 role 统计(可见其结构非常"规整"):

  • left:371 次
  • right:371 次
  • regulatory_element:26 次
  • centerline:未出现(说明本样例不依赖 centerline;Lanelet2 可在需要时生成/推导)

示例片段(节选,实际见文件):

xml 复制代码
<relation id='45216'>
  <member type='way' ref='43978' role='left' />
  <member type='way' ref='43974' role='right' />
  <tag k='location' v='urban' />
  <tag k='one_way' v='yes' />
  <tag k='region' v='de' />
  <tag k='subtype' v='road' />
  <tag k='type' v='lanelet' />
</relation>

9.4 线要素(ways)的类型

本样例中 <way>type/subtype 组合:

  • 边界/道路结构:road_border, curbstone(low/high), wall, fence, guard_rail, virtual
  • 车道线:line_thin(solid/dashed), line_thick(solid/dashed),以及 dashed_solid/solid_dashed
  • 停止线:stop_line
  • 行人/自行车标线:pedestrian_marking, zebra_marking, bike_marking
  • 交通标志:traffic_sign(subtype=de205/de301/de274_1/...)
  • 信号灯:traffic_light(subtype=red_yellow_green/...)
  • 路面符号:symbol(subtype=30)(例如道路上画的"30"限速字样)

它们决定了可行驶走廊边界、是否允许变道、路口停止位置与信号灯约束来源。

9.5 regulatory element 的真实结构

9.5.1 traffic_light regulatory element

样例中可见:

  • ref_line 指向某条 way(停止线)
  • refers 指向 1~N 条信号灯 way(type=traffic_light

例如(节选):

xml 复制代码
<relation id='45218'>
  <member type='way' ref='43606' role='ref_line' />
  <member type='way' ref='49639' role='refers' />
  <member type='way' ref='44960' role='refers' />
  <tag k='subtype' v='traffic_light' />
  <tag k='type' v='regulatory_element' />
</relation>
9.5.2 right_of_way regulatory element

样例中可见:

  • ref_line:停止/让行线
  • refers:让行/优先标志牌(type=traffic_sign 的 way)
  • yield / right_of_way:直接引用 lanelet relation(member type=relation)
  • fallback=yes:低优先级(例如"信号灯坏了才用")

(节选):

xml 复制代码
<relation id='45230'>
  <member type='way' ref='43584' role='ref_line' />
  <member type='way' ref='85773' role='refers' />
  <member type='relation' ref='44968' role='right_of_way' />
  <member type='relation' ref='45014' role='yield' />
  <tag k='fallback' v='yes' />
  <tag k='subtype' v='right_of_way' />
  <tag k='type' v='regulatory_element' />
</relation>
9.5.3 speed_limit regulatory element

样例中 speed_limit 规则元素非常精简:只用 refers 指向一个限速牌:

xml 复制代码
<relation id='45390'>
  <member type='way' ref='44952' role='refers' />
  <tag k='subtype' v='speed_limit' />
  <tag k='type' v='regulatory_element' />
</relation>

对应的限速牌 way(节选):

xml 复制代码
<way id='44952'>
  <tag k='subtype' v='de274_1' />
  <tag k='type' v='traffic_sign' />
</way>

TrafficRules 会根据 traffic_sign.subtype(地区+编号)解释出具体限速(或你也可以用 sign_type 在规则元素上直接写速度值,见 §7.3.2)。


10. 自动驾驶应用

10.1 几何层

  • 边界:定义可通行空间和变道约束
  • 线型:决定横向可达性(实线不可变道,虚线可变道)
  • 环境要素:标识不可通行区域

规划器用途:参考线、横向边界、代价地图

10.2 拓扑层

路由图构建

  • Successor:前后继关系
  • Left/Right:左右邻接(变道)
  • Merging/Splitting:汇入分流

10.3 规则层

关键规则

  • participant:*:通行参与者
  • one_way*:行驶方向
  • speed_limit:速度约束
  • traffic_light:信号灯与停止线
  • right_of_way:让行/先行规则

规划器用途:停止线约束、通行权判断、速度上限


11. 制作地图实践建议

11.1 标签一致性

  • Tag key 使用小写
  • region 与 traffic sign subtype 匹配
  • 严格遵守 lanelet 成员角色规范
  • 保持规则元素与 lanelet 双向引用

11.2 变道语义

  • 默认按边界线型推断
  • 使用 lane_change 显式覆盖

11.3 限速表达优先级

  1. speed_limit regulatory element(推荐)
  2. lanelet 的 speed_limit 属性
  3. 默认推断(不推荐)

免责声明

本文档仅供技术学习和交流使用,内容基于作者对Lanelet2地图格式和OpenStreetMap规范的个人理解和分析整理。

重要提示

  • 本文档不代表Lanelet2官方文档或OpenStreetMap官方规范
  • 文档内容为个人学习整理,仅供参考
  • Lanelet2是开源项目,遵循BSD 3-Clause许可证,版权归原作者所有
  • OpenStreetMap数据遵循ODbL许可协议
  • 实际使用Lanelet2时应参考官方文档:
  • 文档内容可能存在理解偏差或过时信息,欢迎指正
  • 不同版本的Lanelet2和TrafficRules实现可能存在差异,请以实际使用版本为准
  • 因使用本文档产生的任何后果由使用者自行承担

参考来源

  • Lanelet2 官方文档(LaneletAndAreaTagging、LinestringTagging、RegulatoryElementTagging)
  • Lanelet2 maps 映射规则
  • OpenStreetMap Wiki
相关推荐
爱看书的小沐3 个月前
【小沐学GIS】基于C++瓦片地图下载工具(高德/天地图/谷歌/必应/OSM/MapBox/ArcGIS)第十三期
c++·webgl·谷歌地图·earth·osm·瓦片地图下载·mapdowloader
爱看书的小沐1 年前
【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut、QT)第三期
c++·qt·opengl·earth·osm·三维地球·数字地球
爱看书的小沐1 年前
【小沐学GIS】blender导入OpenStreetMap城市建筑(blender-osm、blosm)
python·gis·blender·openstreetmap·osm·blosm·blender-osm