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 是獨一無二的,且必須是下一次造訪 (或車輛結束) 前的連續時間。因此,只要知道延遲時間長度,就能知道延遲的開始和結束時間。
  • 中斷時間是連續且不重疊的時間範圍。回應會指定每個休息時間的開始時間和時長。
  • 「TRAVEL」和「WAIT」是「可搶占」的:在這段轉換期間,這兩者可能會多次中斷。用戶端可以假設「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)

這條路線的時長、距離和負重指標。視情況而定,AggregatedMetrics 的欄位會加總所有 ShipmentRoute.transitionsShipmentRoute.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

來源 ShipmentModelshipments 欄位的索引。

isPickup

boolean

如果為 true,表示該趟行程是為了取貨 Shipment,否則為送貨。

visitRequestIndex

integer

Shipment 的取貨或外送欄位索引 (請參閱 isPickup)。VisitRequest

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.

時間長度以秒為單位,最多可有 9 個小數位數,並應以「s」結尾,例如:"3.5s"

shipmentLabel

string

如果 Shipment 中有指定,則為對應的 Shipment.label 副本。

visitLabel

string

如果 VisitRequest 中有指定,則為對應的 VisitRequest.label 副本。

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。只有在啟用多模式最佳化時,才會使用造訪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)

這段期間的旅行時間。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「s」結尾,例如:"3.5s"

travelDistanceMeters

number

轉場期間的移動距離。

trafficInfoUnavailable

boolean

透過 OptimizeToursRequest.consider_road_traffic 要求車流量資訊時,如果無法擷取 Transition 的車流量資訊,這個布林值就會設為 true。這可能是暫時性 (即時車流量伺服器發生罕見的故障),也可能是永久性 (這個位置沒有資料)。

delayDuration

string (Duration format)

套用至這項轉換的延遲時間總和。如有延遲,會在下一個事件 (到訪或車輛結束) 發生前 delayDuration 秒開始。查看《TransitionAttributes.delay》。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「s」結尾,例如:"3.5s"

breakDuration

string (Duration format)

這段轉場期間內發生的暫停時間總和 (如有)。每個休息時間的開始時間和時長詳細資料會儲存在 ShipmentRoute.breaks 中。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「s」結尾,例如:"3.5s"

waitDuration

string (Duration format)

這段期間的等待時間。等待時間對應的是閒置時間,不包含休息時間。另請注意,這段等待時間可能會分成幾個不連續的時間間隔。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「s」結尾,例如:"3.5s"

totalDuration

string (Duration format)

轉移作業的總時間長度 (僅供參考)。這等於:

  • 下次造訪 startTime (或 vehicleEndTime,如果這是最後一次轉換) - 這次轉換的 startTime
  • 如果 ShipmentRoute.has_traffic_infeasibilities 為 false,則下列項目也會成立:`totalDuration = travelDuration + delayDuration
  • breakDuration + waitDuration`。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「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

代表折線編碼點的字串。

休息時間

代表中斷執行的資料。

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)

休息時間長度。

時間長度以秒為單位,最多可有 9 個小數位數,並應以「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)。