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。

  • 它们不会重叠。
  • 延迟是唯一的,必须是下次访问(或车辆结束)之前的连续时间段。因此,知道延迟时长即可知道其开始时间和结束时间。
  • 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)
  },
  "routeCosts": {
    string: number,
    ...
  },
  "routeTotalCost": number
}
字段
vehicleIndex

integer

执行路线的车辆,通过来源 ShipmentModel 中的索引进行标识。

vehicleLabel

string

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

vehicleStartTime

string (Timestamp format)

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

采用 RFC3339 世界协调时间 (UTC)(即“祖鲁时”)格式的时间戳,采用纳秒级精度,最多包含九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

vehicleEndTime

string (Timestamp format)

车辆完成路线的时间。

采用 RFC3339 世界协调时间 (UTC)(即“祖鲁时”)格式的时间戳,采用纳秒级精度,最多包含九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

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.visitsAggregatedMetrics 的字段进行求和。

routeCosts

map (key: string, value: number)

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

包含一系列 "key": value 对的对象。示例:{ "name": "wrench", "mass": "1.3kg", "count": "3" }

routeTotalCost

number

路线的总费用。费用映射中所有费用的总和。

访问

在路线中执行的访问。此次访问对应于自提或送餐 Shipment

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

integer

来源 ShipmentModelshipments 字段的索引。

isPickup

boolean

如果为 true,则表示访问对应于 Shipment 的取货。否则,它对应于交付。

visitRequestIndex

integer

Shipment 的提货或送货字段中的 VisitRequest 索引(请参阅 isPickup)。

startTime

string (Timestamp format)

访问的开始时间。请注意,车辆可能会早于此时间到达游览地点。时间与 ShipmentModel 一致。

采用 RFC3339 世界协调时间 (UTC)(即“祖鲁时”)格式的时间戳,采用纳秒级精度,最多包含九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

loadDemands

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

总访问加载需求量为运单和访问请求 loadDemands 的总和。如果访问为交付,则这些值为负。系统会针对与 Transition.loads 相同的类型报告需求(请参阅此字段)。

包含一系列 "key": value 对的对象。示例:{ "name": "wrench", "mass": "1.3kg", "count": "3" }

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 中指定)。

转场

在路线上两个事件之间的过渡。请参阅 ShipmentRoute 的说明。

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

JSON 表示法
{
  "travelDuration": string,
  "travelDistanceMeters": number,
  "trafficInfoUnavailable": boolean,
  "delayDuration": string,
  "breakDuration": string,
  "waitDuration": string,
  "totalDuration": string,
  "startTime": string,
  "routePolyline": {
    object (EncodedPolyline)
  },
  "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)

此转换的开始时间。

采用 RFC3339 世界协调时间 (UTC)(即“祖鲁时”)格式的时间戳,采用纳秒级精度,最多包含九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

routePolyline

object (EncodedPolyline)

过渡期间遵循的路线的编码多段线表示法。仅当 populateTransitionPolylines 设置为 true 时,系统才会填充此字段。

vehicleLoads

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

车辆在此过渡期间的加载,适用于出现在此车辆的 Vehicle.load_limits 中的每种类型,或在此路线上执行的某些运单的 Shipment.load_demands 为非零类型。

第一次转换期间的负载是车辆路线的起始负载。然后,在每次访问之后,系统会根据访问是取货还是送餐,将增加或减去访问的 loadDemands,以获取下一次转场的加载次数。

包含一系列 "key": value 对的对象。示例:{ "name": "wrench", "mass": "1.3kg", "count": "3" }

EncodedPolyline

多段线的编码表示形式。如需详细了解多段线编码,请访问以下网页:https://developers.google.com/maps/documentation/utilities/polylinealgorithmhttps://developers.google.com/maps/documentation/javascript/reference/geometry#encoding

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

string

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

休息时间

表示广告插播执行的数据。

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

string (Timestamp format)

休息开始时间。

采用 RFC3339 世界协调时间 (UTC)(即“祖鲁时”)格式的时间戳,采用纳秒级精度,最多包含九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

duration

string (Duration format)

休息持续时间。

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