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 世界標準時間「Zulu」格式的時間戳記,精確度達奈秒單位,最多九個小數位數。例如 "2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

vehicleEndTime

string (Timestamp format)

車輛完成路線的時間。

RFC3339 世界標準時間「Zulu」格式的時間戳記,精確度達奈秒單位,最多九個小數位數。例如 "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)

此路線的時間長度、距離和載入指標。AggregatedMetrics 的欄位會根據上下文,對所有 ShipmentRoute.transitionsShipmentRoute.visits 加總。

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
}
欄位
shipmentIndex

integer

來源 ShipmentModelshipments 欄位的索引。

isPickup

boolean

如果為 true,則表示該造訪對應至 Shipment 的接送。否則,則對應至提交內容。

visitRequestIndex

integer

Shipment 的「pickup」或「delivery」欄位中 VisitRequest 的索引 (請參閱 isPickup)。

startTime

string (Timestamp format)

訪客開始造訪的時間。請注意,車輛可能會提早抵達造訪地點。時間與 ShipmentModel 一致。

RFC3339 世界標準時間「Zulu」格式的時間戳記,精確度達奈秒單位,最多九個小數位數。例如 "2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

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,則為該 Shipment.label 的副本。

visitLabel

string

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

轉移

在路徑上,兩個事件之間的轉換。請參閱 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)

此轉場效果的開始時間。

RFC3339 世界標準時間「Zulu」格式的時間戳記,精確度達奈秒單位,最多九個小數位數。例如 "2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

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)

廣告插播的開始時間。

RFC3339 世界標準時間「Zulu」格式的時間戳記,精確度達奈秒單位,最多九個小數位數。例如 "2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

duration

string (Duration format)

休息時間長度。

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