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 是連續且不重疊的時間段落。回應會指定每個廣告插播的開始時間和持續時間。
  • 「旅遊」和「等待時間」都是「可先佔」的內容:在轉換期間,可能會多次中斷。客戶可以假設旅程「盡快」完成,而「等待」會填滿剩餘時間。

複雜的範例:

                               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」格式的時間戳記,解析度以奈秒為單位,小數點後最多 9 位。例如 "2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

vehicleEndTime

string (Timestamp format)

車輛完成路線的時間。

RFC3339 世界標準時間「Zulu」格式的時間戳記,解析度以奈秒為單位,小數點後最多 9 位。例如 "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.visits 欄位加總 AggregatedMetrics 的欄位。

routeCosts

map (key: string, value: number)

路線費用,按照費用相關要求欄位細分。鍵是相對於輸入 OptimizeToursRequest 的 proto 路徑,例如「model.shipments.pickups.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,
  "injectedSolutionLocationToken": integer
}
欄位
shipmentIndex

integer

來源 ShipmentModel 中的 shipments 欄位索引。

isPickup

boolean

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

visitRequestIndex

integer

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

startTime

string (Timestamp format)

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

RFC3339 世界標準時間「Zulu」格式的時間戳記,解析度以奈秒為單位,小數點後最多 9 位。例如 "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.

持續時間以秒為單位,最多 9 個小數位數,結尾為「s」。例如:"3.5s"

shipmentLabel

string

對應的 Shipment.label 副本 (如果在 Shipment 中指定)。

visitLabel

string

如果 VisitRequest 中指定了對應的 VisitRequest.label,則會複製該 VisitRequest.label

injectedSolutionLocationToken

integer

代表造訪位置相關資訊的不透明權杖。

如果 VisitRequest.avoid_u_turns 已為此造訪設為 true,或是 ShipmentModel.avoid_u_turns 已在要求 OptimizeToursRequest 中設為 true,則這個欄位可能會在結果路徑的造訪中填入。

轉移

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

這段轉換期間的旅遊時間。

時間長度以秒為單位,最多可有 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 時,才會填入這個欄位。

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/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」格式的時間戳記,解析度以奈秒為單位,小數點後最多 9 位。範例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

duration

string (Duration format)

休息時間長度。

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