最短或最优路径路由

简介#

duarouter 可用于导入由出发地和目的地边(即所谓的 tripsflows)给出的需求数据。此外,它还可用于修复现有的 route 文件,例如当给定的路线包含未连接的边列表时。为了实现动态用户分配,必须迭代调用 duaroutersumo。这在 需求/动态用户分配 中有描述。从版本 0.29.0 开始,duarouter 还支持 跨模式路由

Note

下面描述的 tripflow 元素也可以直接加载到 sumo 中。这会在计算路线时考虑网络内的最新交通状态,但会减慢模拟速度。

Trip 定义#

可以将放入网络中的 trip 定义通过 XML 文件提供给路由器。单个 trip 定义的语法为: <trip id="<ID>" depart="" from="<ORIGIN_EDGE_ID>" to="<DESTINATION_EDGE_ID>" [type="<VEHICLE_TYPE>"] [color="<COLOR>"]/>

属性名称 值类型 描述
id id (字符串) 将使用此 trip 定义生成的车辆的名称(如果未给出,则为运行编号)
depart int 使用此 trip 定义生成的(第一辆)车辆的出发时间
from 边 id 路线起始边的名称;该边必须是所用网络的一部分。如果使用了某个 via 属性或 trip 包含停靠点,则为可选。
to 边 id 路线结束边的名称;该边必须是所用网络的一部分。如果使用了某个 via 属性或 trip 包含停靠点,则为可选。
via 边 id 列表 应作为路线一部分的中间边 id 列表;这些边必须是所用网络的一部分
fromTaz 分区 id 路线起始的分区 名称。TAZ 边的选择旨在最小化行驶时间。
toTaz 分区 id 路线结束的分区 名称。TAZ 边的选择旨在最小化行驶时间。
type 类型 id 要生成的车辆的类型 id
color 颜色 此生成车辆的颜色
departLane int/字符串 (≥0,"random","free","departlane") 车辆应插入的车道
departPos float(米)/字符串 ("random","free","random_free","base") 车辆进入网络的位置;"free" 表示最接近出发车道起点且可以插入车辆的点。"random_free" 强制尝试查找空闲的随机位置,如果失败,则将车辆放置在下一个"free"位置。"base" 将车辆的出发位置设置为车辆长度 + eps (eps=.1m),这意味着车辆完全位于出发车道的起点。
departSpeed float(米/秒)/字符串 (≥0,"random","max") 车辆进入网络时的速度。
arrivalLane int/字符串 (≥0,"current") 车辆离开网络时的车道

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线
arrivalPos float(米)/字符串 (≥0(1),"random","max") 车辆离开网络时的位置

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线
arrivalSpeed float(米/秒)/字符串 (≥0,"current") 车辆离开网络时的速度

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线
fromJunction 路口 id 出发的路口 注意
toJunction 路口 id 到达的路口 注意
viaJunctions 路口 id 列表 途经的路口 注意
fromXY float, float 出发的网络位置 注意
toXY float, float 到达的网络位置 注意
viaXY float, float [float,float] 途经的网络位置 注意
fromLonLat float, float 出发的网络位置(地理坐标) 注意
toLonLat float, float 到达的网络位置(地理坐标) 注意
viaLonLat float, float [float,float] 途经的网络位置(地理坐标) 注意
speedFactor float > 0 设置自定义 speedFactor(道路限速的乘数)并覆盖车辆类型的 speedFactor 分布
insertionChecks 字符串列表 设置在车辆插入期间要执行的安全检查列表。可能的值为:all, none, collision, leaderGap, followerGap, junction, stop, arrivalSpeed, oncomingTrain, speedLimit, pedestrians。默认为 all
parkingBadges 字符串列表 用于访问受限停车区域的关键词列表(默认的空列表仍将允许访问无限制的停车区域)

路口间的路由#

Trip 和 flow 可以使用属性 fromJunctiontoJunctionviaJunctions 来描述起点、终点和中间位置。这是 TAZ 路由的一种特殊形式,必须通过设置 duarouter 选项 --junction-taz 或加载使用相应路口 ID 的 TAZ 定义来启用。当使用选项 --junction-taz 时,所有从路口出发的边都可以用作起点,所有进入路口的边都可以用于到达中间和最终路口。

停靠点间的路由#

  • 当定义带有停靠点元素的 <trip> 时,将为每个停靠点执行路由(从 trip 起点或前一个停靠点开始),并结束于目的地。
  • 如果至少提供了一个停靠点,则可以省略 fromto 属性之一(或 fromJunctionfromTaz 等)。
  • 如果至少提供了两个停靠点,则可以省略 fromto 属性(第一个停靠点作为起点,最后一个停靠点作为目的地)。
  • 如果给出了带有 jump 属性的停靠点,则路线的后续部分(到下一个停靠点或目的地)将断开。

地图匹配#

从版本 1.2 开始,duarouter 支持使用以 'XY' 或 'LonLat' 结尾的属性将位置映射到道路。后者仅在地理参考的网络中有效。地图匹配的最大距离可以使用选项 --mapmatch.distance(自版本 1.5 起)进行配置。

通过设置选项 --mapmatch.junctions,位置将映射到路口而不是边。然后路线将在路口之间计算。 虽然可以通过使用属性 viaXYviaLonLat 来匹配详细的路线,但这需要相当精确的坐标才能工作。为了处理数据中的模糊性/噪声,最好使用在匹配单个位置时考虑整个路线的匹配算法

Note

地图匹配在坐标位于边的中心线而不是道路的中线上时效果最佳。

Caution

选项 --map-match-junctions 可能会缩短路线,如果 from 坐标位于起始边的中点之后,并且 to 坐标位于目的地边的中点之前。

车辆类型#

如果任何 trip 使用了 type 属性,则必须将引用的 vType 元素放入包含 trip/flow 的输入文件中,或放入额外加载的 rou.xml 文件中,或放入 additional-file 中。

Note

默认情况下,duarouter 会在输出路线文件中,在使用该类型的第一个车辆之前写入 vType 定义。通过使用选项 --vtype-output,可以将这些定义放入另一个文件中。

Flow 定义#

Flow 数量与 trip 定义共享大部分参数。语法为: <flow id="<ID>" from="<ORIGIN_EDGE_ID>" to="<DESTINATION_EDGE_ID>" begin="<INTERVAL_BEGIN>" end="<INTERVAL_END>" number="<VEHICLES_TO_INSERT>" [type="<VEHICLE_TYPE>"] [color="<COLOR>"]/>。注意以下区别:车辆不采用特定的出发时间,因为此参数描述的不是一辆车,而是一组车辆,由属性 "number" 给出。出发时间在 <INTERVAL_BEGIN> 和 <INTERVAL_END> 描述的时间间隔内均匀分布。这三个属性都必须是整数值。Flow 定义也可以嵌入到 interval 标签中。在这种情况下,可以(但不必)省略标签 beginend。因此,以下两个代码片段的含义相同:

<routes>
    <flow id="0" from="edge0" to="edge1" begin="0" end="3600" number="100"/>
</routes>

<routes>
    <interval begin="0" end="3600">
        <flow id="0" from="edge0" to="edge1" number="100"/>
    </interval>
</routes>

Note

输入文件始终需要一个根级元素来包裹 trip/flow 元素,并且该元素应命名为 <routes>

让我们回顾一下 flow 参数:

属性名称 值类型 描述
id id (字符串) 将使用此 trip 定义生成的车辆的名称;车辆和路线将被命名为 "<id>_<RUNNING>",其中 <RUNNING> 是一个从 0 开始并为每辆车递增的数字。
from 边 id 路线起始边的名称;该边必须是所用网络的一部分
to(1) 边 id 路线结束边的名称;该边必须是所用网络的一部分
via 边 id 列表 应作为路线一部分的中间边 id 列表;这些边必须是所用网络的一部分
type 类型 id 要生成的车辆的类型 id
begin int 所述间隔的开始时间
end int 间隔的结束时间;必须大于 <begin>;车辆将在 <begin> 和 <end>-1 之间插入
vehsPerHour float(#/h) 每小时的车辆数,等间距(不与 period 或 probability 一起使用)
period float(秒) 以该周期等间距插入车辆(不与 vehsPerHour 或 probability 一起使用)
probability float([0,1]) 每秒发射一辆车的概率(不与 vehsPerHour 或 period 一起使用),另见 模拟/随机性
number int 应在此间隔期间插入的车辆数
color 颜色 定义车辆及其路线的颜色
departLane int/字符串 (≥0,"random","free","departlane") 车辆应插入的车道
departPos float(米)/字符串 ("random","free","random_free","base") 车辆进入网络的位置;"free" 表示最接近出发车道起点且可以插入车辆的点。"random_free" 强制尝试查找空闲的随机位置,如果失败,则将车辆放置在下一个"free"位置。"base" 将车辆的出发位置设置为车辆长度 + eps (eps=.1m),这意味着车辆完全位于出发车道的起点。
departSpeed float(米/秒)/字符串 (≥0,"random","max") 车辆进入网络时的速度。
arrivalLane int/字符串 (≥0,"current") 车辆离开网络时的车道

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线
arrivalPos float(米)/字符串 (≥0(1),"random","max") 车辆离开网络时的位置

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线
arrivalSpeed float(米/秒)/字符串 (≥0,"current") 车辆离开网络时的速度

注意: 参见 车辆、车辆类型和路线的定义#车辆和路线

(1) jtrrouter 不需要此参数,duarouter 需要它。

自定义边权重#

选项 --weight-files <FILE> 可用于影响路由期间使用的权重。输入格式符合基于边的交通量度的输出格式。默认情况下,这使用边的 traveltime 属性。选项 --weight-attribute <STRING> 可用于使用其他属性进行路由。仅包含部分网络边的权重文件是允许的。如果未定义,边的行驶时间默认为自由流行驶时间。此外,仅必须定义 weight-attribute

<meandata>
    <interval begin="0" end="3600" id="whatever">
        <edge id="edgeID1" traveltime="23"/>
        <edge id="edgeID2" traveltime="1000"/>
    </interval>
</meandata>

访问限制#

对网络边的访问通常受车辆类型中定义的车辆等级限制,但也可以使用数值限制进行自定义。

修复路线#

--repair 选项旨在修复存在连接性问题的路线。 根据路线的定义方式,duarouter 将尝试以不同的方式修复它:

  • 如果路线是用 "edges" 属性定义的,duarouter 将首先尝试通过修复边之间的连接性来修复路线。如果这不可能,那么 duarouter 将在存在连接性问题的边之间搜索另一条有效的路线。这可能导致原始路线中的某些边不再出现在新路线上。换句话说,在路线修复期间,用 "edges" 属性定义的边不被视为强制性的。
  • 如果路线是用 "edges" 属性定义的,但也有 "stops",duarouter 将把停靠点的边视为强制性的。它将首先尝试像上一个示例那样修复路线,但如果 duarouter 无法找到一条经过给定停靠点边的有效路线,那么该路线就无法修复。
  • 如果路线是用 "via" 边属性定义的,所有边都将被视为强制性的。如果 duarouter 无法修复指定边之间的连接性问题,则会出现警告并且路线无法修复。

Duarouter 还有 --repair.from--repair.to 选项,它们允许使用路线的第一个或最后一个可用边来修复无效的起始边或结束边。

转换输入样式#

SUMO 支持各种样式的需求定义(车辆、trips、flows),并且 duarouter 可用于在它们之间进行转换。

  • 默认情况下,duarouter 会将所有输入转换为带有嵌入式路线的车辆(路线作为车辆的子元素)。
  • 使用选项 --write-trips,所有输入都将转换为 trips
    • 与选项 --write-trips.geo 结合使用,trips 将使用地理坐标(fromLonLat, toLonLat)而不是边(from, to)写入
    • 与选项 --write-trips.junctions 结合使用,trips 将在路口之间(fromJunction, toJunction)写入

使用示例#

duarouter --trip-files trips.xml --net-file road.net.xml --output-file result.rou.xml

下面给出的文件 ''trips.xml '' 必须包含网络文件 ''road.net.xml '' 中包含的边。

<routes>
    <trip id="1625993_25" depart="25" from="-15229224#3" to="4474184"/>
    <trip id="1542480_35" depart="35" from="-46771582"   to="-24038909#1"/>
    <trip id="1544282_35" depart="35" from="20554351#2"  to="-4876083#5"/>
    <trip id="1565407_35" depart="35" from="-25771472#1" to="-25160470#0"/>
    <trip id="1620115_45" depart="45" from="11279351#3"  to="5198584#1"/>
    <trip id="1647560_45" depart="45" from="54048879#0"  to="-52105434#0"/>
    <trip id="3761248_45" depart="45" from="-31928311"   to="23792451#7"/>
</routes>

Trips 可以包含源和目的地分区以及边。如果要使用分区进行路由,则必须使用选项 "--with-taz" 进行指定。此外(如果网络不包含分区)则需要提供分区文件:

duarouter --trip-files=<TRIP_DEFS> --net-file=<SUMO_NET> \
  --output-file=MySUMORoutes.rou.xml --taz-files=<DISTRICTS> --with-taz

Caution

当以这种方式使用 TAZ 时,边权重将被忽略。相反,TAZ 边的选择旨在最小化行驶时间。

由于我们必须将 flow 定义完全读入内存——而 trip 不一定需要这样做,因此使用一个额外的参数 (-f 或 --flows) 来让路由器知道它们:

duarouter --flows=<FLOW_DEFS> --net=<SUMO_NET> \
  --output-file=MySUMORoutes.rou.xml -b <UINT> -e <UINT>

请记住,不能将 flow 描述插入到 trip 定义文件中。反之(在 flow 描述文件中包含一些 trip 定义)是可能的。您也可以在输入文件中同时提供两个文件,例如:

duarouter --flows=<FLOW_DEFS> --trip-files=<TRIP_DEFS> --net=<SUMO_NET> \
  --output-file=MySUMORoutes.rou.xml -b <UINT> -e <UINT>

处理路由过程中的错误#

运行 duarouter 时,您可能会遇到以下类型的错误:

Error: No connection between 'edge1' and 'edge2' found

这是由未连接的网络引起的。如果您的网络具有车辆等级限制,则可能仅对特定的车辆等级缺乏连接性,这从 GUI 中不太明显。您可以使用选项 --ignore-errors 忽略这些路线。但是,如果您的大部分路线都导致此错误,您绝对应该检查您的网络文件是否存在问 题。工具 Tools/Net#netcheckpy 可用于锁定网络中的连接间隙。