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 之前。

放大来看,在 Transition 和 Visit 期间会发生以下情况:

---+-------------------------------------+-----------------------------+-->
   |           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)
  },
  "vehicleFullness": {
    object (VehicleFullness)
  },
  "routeCosts": {
    string: number,
    ...
  },
  "routeTotalCost": number
}
字段
vehicleIndex

integer

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

vehicleLabel

string

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

vehicleStartTime

string (Timestamp format)

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

采用 RFC 3339 标准,生成的输出将始终进行 Z 规范化(即转换为 UTC 零时区格式并在末尾附加 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 规范化(即转换为 UTC 零时区格式并在末尾附加 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)

相应路线的时长、距离和负荷指标。AggregatedMetrics 的字段会针对所有 ShipmentRoute.transitions 或 ShipmentRoute.visits 求和,具体取决于上下文。

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,
  "visitType": enum (VisitType),
  "injectedSolutionLocationToken": integer
}
字段
shipmentIndex

integer

来源 ShipmentModel 中 shipments 字段的索引。

isPickup

boolean

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

visitRequestIndex

integer

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

startTime

string (Timestamp format)

相应访问的开始时间。请注意,车辆可能会比此时间更早到达访问地点。时间与 ShipmentModel 保持一致。

采用 RFC 3339 标准,生成的输出将始终进行 Z 规范化(即转换为 UTC 零时区格式并在末尾附加 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.
shipmentLabel

string

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

visitLabel

string

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

visitType

enum (VisitType)

可选。指定访问类型。替换 Visit.is_pickup 字段。

injectedSolutionLocationToken

integer

表示访问位置相关信息的不透明令牌。

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

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

VisitType

指明相应访问是取货、送货还是访问 Stop。仅当启用多模态优化时,系统才会使用对停靠点的访问。

枚举
VISIT_TYPE_UNSPECIFIED 未指定访问类型。
PICKUP_SHIPMENT 访问对应于取件。
DELIVER_SHIPMENT 访问对应于配送。

过渡

在路线上的两个活动之间切换。请参阅 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)

此过渡期间的出行时长。

travelDistanceMeters

number

过渡期间的行驶距离。

trafficInfoUnavailable

boolean

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

delayDuration

string (Duration format)

应用于相应过渡的延迟时长的总和。如果有延迟,则延迟会在下一个事件(访问或车辆结束)开始前 delayDuration 秒开始。请参阅TransitionAttributes.delay。

breakDuration

string (Duration format)

相应过渡期间发生的插播广告的时长总和(如有)。有关每个中断的开始时间和时长的详细信息存储在 ShipmentRoute.breaks 中。

waitDuration

string (Duration format)

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

totalDuration

string (Duration format)

为方便起见,系统会提供过渡的总时长。它等于:

  • 下一次访问 startTime(或 vehicleEndTime,如果这是最后一次转变)- 相应转变的 startTime;
  • 如果 ShipmentRoute.has_traffic_infeasibilities 为 false,则以下等式也成立:`totalDuration = travelDuration + delayDuration
  • breakDuration + waitDuration”。
startTime

string (Timestamp format)

相应过渡的开始时间。

采用 RFC 3339 标准,生成的输出将始终进行 Z 规范化(即转换为 UTC 零时区格式并在末尾附加 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

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

休息时间

表示中断执行的数据。

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

string (Timestamp format)

休息的开始时间。

采用 RFC 3339 标准,生成的输出将始终进行 Z 规范化(即转换为 UTC 零时区格式并在末尾附加 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)

休息时长。

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_meters 与 Vehicle.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) 代替。