ShipmentRoute

车辆的路线可以沿时间轴分解,如下所示(假设有 n 次访问):

  |            |            |          |       |  T[2], |        |      |
  | Transition |  Visit #0  |          |       |  V[2], |        |      |
  |     #0     |    aka     |   T[1]   |  V[1] |  ...   | V[n-1] | T[n] |
  |  aka T[0]  |    V[0]    |          |       | V[n-2],|        |      |
  |            |            |          |       | T[n-1] |        |      |
  ^            ^            ^          ^       ^        ^        ^      ^
vehicle    V[0].start   V[0].end     V[1].   V[1].    V[n].    V[n]. vehicle
 start     (arrival)   (departure)   start   end      start    end     end

请注意,我们会区分以下两种情况:

  • “准时事件”,例如车辆启动和停止以及每次访问的开始和结束(也称为到达和离开)。它们会在指定的秒数发生。
  • “时间间隔”,例如访问本身以及访问之间的转换。虽然时间间隔有时可能为零时长(即开始和结束时间相同),但通常为正时长。

不变量:

  • 如果有 n 次访问,则有 n+1 次转化。
  • 每次访问始终由前面的转换(相同的索引)和后面的转换(索引 + 1)包围。
  • 车辆启动始终会跟随转换 #0。
  • 车辆结束始终位于转换 #n 之前。

下面详细介绍了 TransitionVisit 期间会发生的情况:

---+-------------------------------------+-----------------------------+-->
   |           TRANSITION[i]             |           VISIT[i]          |
   |                                     |                             |
   |  * TRAVEL: the vehicle moves from   |      PERFORM the visit:     |
   |    VISIT[i-1].departure_location to |                             |
   |    VISIT[i].arrival_location, which |  * Spend some time:         |
   |    takes a given travel duration    |    the "visit duration".    |
   |    and distance                     |                             |
   |                                     |  * Load or unload           |
   |  * BREAKS: the driver may have      |    some quantities from the |
   |    breaks (e.g. lunch break).       |    vehicle: the "demand".   |
   |                                     |                             |
   |  * WAIT: the driver/vehicle does    |                             |
   |    nothing. This can happen for     |                             |
   |    many reasons, for example when   |                             |
   |    the vehicle reaches the next     |                             |
   |    event's destination before the   |                             |
   |    start of its time window         |                             |
   |                                     |                             |
   |  * DELAY: *right before* the next   |                             |
   |    arrival. E.g. the vehicle and/or |                             |
   |    driver spends time unloading.    |                             |
   |                                     |                             |
---+-------------------------------------+-----------------------------+-->
   ^                                     ^                             ^
V[i-1].end                           V[i].start                    V[i].end

最后,下面介绍了如何在转场期间安排 TRAVEL、BREAKS、DELAY 和 WAIT。

  • 不会重叠。
  • DELAY 是唯一的,必须是紧接着下次访问(或车辆结束)之前的一个连续时间段。因此,只需知道延迟时长即可知道其开始时间和结束时间。
  • BREAKS 是相邻且不重叠的时间段。该响应会指定每个休息时间的开始时间和时长。
  • TRAVEL 和 WAIT 是“可抢占”状态:在此过渡期间,它们可能会被中断多次。客户可以假定行程会“尽快”完成,并使用“等待”填充剩余时间。

一个(复杂的)示例:

                               TRANSITION[i]
--++-----+-----------------------------------------------------------++-->
  ||     |       |           |       |           |         |         ||
  ||  T  |   B   |     T     |       |     B     |         |    D    ||
  ||  r  |   r   |     r     |   W   |     r     |    W    |    e    ||
  ||  a  |   e   |     a     |   a   |     e     |    a    |    l    ||
  ||  v  |   a   |     v     |   i   |     a     |    i    |    a    ||
  ||  e  |   k   |     e     |   t   |     k     |    t    |    y    ||
  ||  l  |       |     l     |       |           |         |         ||
  ||     |       |           |       |           |         |         ||
--++-----------------------------------------------------------------++-->
JSON 表示法
{
  "vehicleIndex": integer,
  "vehicleLabel": string,
  "vehicleStartTime": string,
  "vehicleEndTime": string,
  "visits": [
    {
      object (Visit)
    }
  ],
  "transitions": [
    {
      object (Transition)
    }
  ],
  "hasTrafficInfeasibilities": boolean,
  "routePolyline": {
    object (EncodedPolyline)
  },
  "breaks": [
    {
      object (Break)
    }
  ],
  "metrics": {
    object (AggregatedMetrics)
  },
  "vehicleFullness": {
    object (VehicleFullness)
  },
  "routeCosts": {
    string: number,
    ...
  },
  "routeTotalCost": number
}
字段
vehicleIndex

integer

执行路线的车辆,由其在来源 ShipmentModel 中的索引标识。

vehicleLabel

string

执行此路线的车辆的标签,等于 ShipmentModel.vehicles(vehicleIndex).label(如果已指定)。

vehicleStartTime

string (Timestamp format)

车辆开始行驶路线的时间。

采用 RFC 3339 标准,生成的输出将始终在末尾带 Z,并使用 0、3、6 或 9 个小数位。不带“Z”的偏差时间也是可以接受的。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z""2014-10-02T15:01:23+05:30"

vehicleEndTime

string (Timestamp format)

车辆完成行程的时间。

采用 RFC 3339 标准,生成的输出将始终在末尾带 Z,并使用 0、3、6 或 9 个小数位。不带“Z”的偏差时间也是可以接受的。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z""2014-10-02T15:01:23+05:30"

visits[]

object (Visit)

表示路线的访问有序序列。visits[i] 是路线中的第 i 次访问。如果此字段为空,则车辆会被视为未使用。

transitions[]

object (Transition)

相应路线的有序转换列表。

hasTrafficInfeasibilities

boolean

如果 OptimizeToursRequest.consider_road_traffic 设置为 true,则此字段表示系统会使用基于交通状况的预计行程时长来预测路线时间不一致的情况。在首次访问前、最后一次访问后或访问之间,可能没有足够的时间来完成考虑交通状况的旅行、延迟和休息时间,同时仍能满足访问和车辆时间范围。例如,

  startTime(previous_visit) + duration(previous_visit) +
  travelDuration(previous_visit, next_visit) > startTime(next_visit)

由于交通拥堵导致预计的旅行时间 travelDuration(previous_visit, next_visit) 增加,因此 next_visit 的到达时间可能会晚于其当前时间范围。此外,由于预计的旅行时间增加以及访问或休息时间窗口限制,休息时间可能会与访问时间重叠。

routePolyline

object (EncodedPolyline)

路线的编码多段线表示法。只有当 OptimizeToursRequest.populate_polylines 设置为 true 时,系统才会填充此字段。

breaks[]

object (Break)

为执行此路线的车辆安排的休息时间。breaks 序列表示时间间隔,每个间隔从相应的 startTime 开始,持续 duration 秒。

metrics

object (AggregatedMetrics)

此路线的时长、距离和载荷指标。系统会对所有 ShipmentRoute.transitionsShipmentRoute.visits 求和,以获取 AggregatedMetrics 的字段值(具体取决于上下文)。

vehicleFullness

object (VehicleFullness)

VehicleFullness 字段,用于计算已设上限的指标与其各自的车辆限值之间的接近程度。其字段是上限型指标字段(例如 AggregatedMetrics.travel_distance_meters)与相关车辆数上限(例如 Vehicle.route_distance_limit)之间的比率。

实验性:此字段的行为或存在性未来可能会发生变化。

routeCosts

map (key: string, value: number)

路线费用,按费用相关的请求字段细分。键是相对于输入 OptimizeToursRequest 的 proto 路径,例如“model.shipments.pickups.cost”,值是相应费用字段生成的总费用,涵盖整个路线。换句话说,costs["model.shipments.pickups.cost"] 是整个路线上的所有上门取件费用的总和。此处会详细报告模型中定义的所有费用,但与 TransitionAttributes 相关的费用除外,自 2022 年 1 月起,这些费用仅以汇总方式报告。

routeTotalCost

number

路线的总费用。费用图中所有费用的总和。

访问

在路线中执行的访问。此访问对应于 Shipment 的取件或送货。

JSON 表示法
{
  "shipmentIndex": integer,
  "isPickup": boolean,
  "visitRequestIndex": integer,
  "startTime": string,
  "loadDemands": {
    string: {
      object (Load)
    },
    ...
  },
  "detour": string,
  "shipmentLabel": string,
  "visitLabel": string,
  "injectedSolutionLocationToken": integer
}
字段
shipmentIndex

integer

来源 ShipmentModel 中的 shipments 字段的索引。

isPickup

boolean

如果为 true,则表示相应到访与 Shipment 的接人服务相对应。否则,它对应于传送。

visitRequestIndex

integer

Shipment 的“自提”或“送达”字段中的 VisitRequest 的索引(请参阅 isPickup)。

startTime

string (Timestamp format)

访问的开始时间。请注意,车辆可能会提前到达上门服务地点。时间与 ShipmentModel 一致。

采用 RFC 3339 标准,生成的输出将始终在末尾带 Z,并使用 0、3、6 或 9 个小数位。不带“Z”的偏差时间也是可以接受的。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z""2014-10-02T15:01:23+05:30"

loadDemands

map (key: string, value: object (Load))

总光顾负载需求为发货量和光顾请求 loadDemands 的总和。如果是送货,则值为负数。需求的类型与 Transition.loads 相同(请参阅此字段)。

detour

string (Duration format)

由于在到达之前在路线上拜访的运输服务而产生的额外绕道时间,以及由于时间范围而产生的潜在等待时间。如果是送货服务,则绕路距离是根据相应的上门取件服务计算得出的,等于:

startTime(delivery) - startTime(pickup)
- (duration(pickup) + travel duration from the pickup location
to the delivery location).

否则,系统会根据车辆 startLocation 计算此值,其等于:

startTime - vehicleStartTime - travel duration from
the vehicle's `startLocation` to the visit.

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

shipmentLabel

string

相应 Shipment.label 的副本(如果在 Shipment 中指定)。

visitLabel

string

相应 VisitRequest.label 的副本(如果在 VisitRequest 中指定)。

injectedSolutionLocationToken

integer

一个不透明令牌,表示与访问地点相关的信息。

如果为此访问设置了 VisitRequest.avoid_u_turns,或者在请求 OptimizeToursRequest 中将 ShipmentModel.avoid_u_turns 设置为 true,则系统可能会在结果路线的访问中填充此字段。

实验性功能:如需了解详情,请访问 https://developers.google.com/maps/tt/route-optimization/experimental/u-turn-avoidance/make-request

过渡

路线上两个事件之间的转换。请参阅 ShipmentRoute 的说明。

如果车辆没有 startLocation 和/或 endLocation,则相应的行程指标为 0。

JSON 表示法
{
  "travelDuration": string,
  "travelDistanceMeters": number,
  "trafficInfoUnavailable": boolean,
  "delayDuration": string,
  "breakDuration": string,
  "waitDuration": string,
  "totalDuration": string,
  "startTime": string,
  "routePolyline": {
    object (EncodedPolyline)
  },
  "routeToken": string,
  "vehicleLoads": {
    string: {
      object (VehicleLoad)
    },
    ...
  }
}
字段
travelDuration

string (Duration format)

在此过渡期间的旅行时长。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

travelDistanceMeters

number

过渡期间行驶的距离。

trafficInfoUnavailable

boolean

通过 OptimizeToursRequest.consider_road_traffic 请求流量时,如果无法为 Transition 检索到流量信息,此布尔值会设为 true。这可能是暂时性的(实时交通服务器中出现罕见的故障),也可能是永久性的(没有此位置的数据)。

delayDuration

string (Duration format)

应用于此转换的延迟时长的总和。延迟时间(如果有)会在下一个事件(光顾或车辆结束)开始前恰好 delayDuration 秒开始。请参阅TransitionAttributes.delay

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

breakDuration

string (Duration format)

在此转换期间发生的休息时长(如果有)的总和。有关每个休息时间的开始时间和时长的详细信息存储在 ShipmentRoute.breaks 中。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

waitDuration

string (Duration format)

在此过渡期间的等待时间。等待时长对应于空闲时间,不包括休息时间。另请注意,此等待时间可能会拆分为多个不连续的间隔时间。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

totalDuration

string (Duration format)

转换的总时长,提供以供参考。等于:

  • 下次访问 startTime(如果这是最后一次转化,则为 vehicleEndTime)- 此转化的 startTime
  • 如果 ShipmentRoute.has_traffic_infeasibilities 为 false,则还成立以下关系:`totalDuration = travelDuration + delayDuration
  • breakDuration + waitDuration`。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

startTime

string (Timestamp format)

此转换的开始时间。

采用 RFC 3339 标准,生成的输出将始终在末尾带 Z,并使用 0、3、6 或 9 个小数位。不带“Z”的偏差时间也是可以接受的。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z""2014-10-02T15:01:23+05:30"

routePolyline

object (EncodedPolyline)

转换期间所遵循路线的编码多段线表示法。只有当 populateTransitionPolylines 设置为 true 时,系统才会填充此字段。

routeToken

string

仅限输出。一个不透明令牌,可传递给 Navigation SDK 以在导航期间重构路线,并在重新路线时遵循创建路线时的原始意图。将此令牌视为不透明 blob。请勿比较不同请求的此值,因为即使服务返回完全相同的路线,此值也可能会发生变化。只有当 populateTransitionPolylines 设置为 true 时,系统才会填充此字段。

vehicleLoads

map (key: string, value: object (VehicleLoad))

在此过渡期间的车辆载荷,对于此车辆的 Vehicle.load_limits 中显示的每种类型,或者在此路线上执行的某些运输的 Shipment.load_demands 不为零的每种类型。

第一次转换期间的载荷是车辆路线的起始载荷。然后,在每次访问后,系统都会根据相应访问是上门取件还是送货,来添加或减去相应访问的 loadDemands,以获取下一次转换的载荷。

EncodedPolyline

多段线的编码表示法。如需详细了解多段线编码,请参阅:https://developers.google.com/maps/documentation/utilities/polylinealgorithm https://developers.google.com/maps/documentation/javascript/reference/geometry#encoding

JSON 表示法
{
  "points": string
}
字段
points

string

表示多段线编码点的字符串。

休息时间

表示执行 break 的数据。

JSON 表示法
{
  "startTime": string,
  "duration": string
}
字段
startTime

string (Timestamp format)

休息时间的开始时间。

采用 RFC 3339 标准,生成的输出将始终在末尾带 Z,并使用 0、3、6 或 9 个小数位。不带“Z”的偏差时间也是可以接受的。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z""2014-10-02T15:01:23+05:30"

duration

string (Duration format)

休息时长的时长。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

VehicleFullness

VehicleFullness 是一个用于计算车辆载客率的指标。每个 VehicleFullness 字段的值介于 0 和 1 之间,计算方式为上限型指标字段(例如 AggregatedMetrics.travel_distance_meters)与其相关的车辆载客量上限(例如 Vehicle.route_distance_limit,如果存在)的比率。否则,饱满度比率将保持未设置状态。如果上限为 0,则将该字段设置为 1。注意:当某条路线因交通原因而不可行时,某些原始载客率可能会超过 1.0,例如车辆可能会超出距离限制。在这些情况下,我们将饱满度值上限设为 1.0。

JSON 表示法
{
  "maxFullness": number,
  "distance": number,
  "travelDuration": number,
  "activeDuration": number,
  "maxLoad": number,
  "activeSpan": number
}
字段
maxFullness

number

此消息中所有其他字段的最大值。

distance

number

介于 AggregatedMetrics.travel_distance_metersVehicle.route_distance_limit 之间的比率。如果 Vehicle.route_distance_limit 未设置,则此字段将未设置。

travelDuration

number

[AggregatedMetrics.travel_duration_seconds][] 与 Vehicle.travel_duration_limit 的比率。如果 Vehicle.travel_duration_limit 未设置,则此字段将未设置。

activeDuration

number

[AggregatedMetrics.total_duration_seconds][] 与 Vehicle.route_duration_limit 的比率。如果 Vehicle.route_duration_limit 未设置,则此字段将未设置。

maxLoad

number

所有类型的 [AggregatedMetrics.max_load][] 与其各自 Vehicle.load_limits 之间的最大比率。如果所有 Vehicle.load_limits 字段均未设置,则此字段将未设置。

activeSpan

number

给定车辆的 (vehicleEndTime - vehicleStartTime) / (latestVehicleEndTime - earliestVehicleStartTime) 比率。如果分母不存在,则改用 (ShipmentModel.global_end_time - ShipmentModel.global_start_time)。