Package google.maps.routeoptimization.v1

索引

RouteOptimization

用於最佳化車輛導覽的服務。

特定類型的欄位有效性:

  • google.protobuf.Timestamp
    • 時間以 Unix 時間表示:自 1970-01-01T00:00:00+00:00 起算的秒數。
    • 秒數必須介於 [0, 253402300799] 之間,也就是 [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00]。
    • nanos 必須設為未設定或設為 0。
  • google.protobuf.Duration
    • 秒數必須介於 [0, 253402300799] 之間,也就是 [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00]。
    • nanos 必須設為未設定或設為 0。
  • google.type.LatLng
    • 緯度必須介於 [-90.0, 90.0] 之間。
    • 經度必須介於 [-180.0, 180.0] 的範圍之間。
    • 經緯度至少須有一個非零值。
BatchOptimizeTours

rpc BatchOptimizeTours(BatchOptimizeToursRequest) returns (Operation)

針對一或多個 OptimizeToursRequest 訊息,批次最佳化車輛導覽。

這個方法是長時間執行作業 (LRO)。系統會以使用者指定的格式,讀取/寫入/寫出最佳化輸入內容 (OptimizeToursRequest 訊息) 和輸出內容 (OptimizeToursResponse 訊息)。與 OptimizeTours 方法一樣,每個 OptimizeToursRequest 都包含 ShipmentModel,並傳回包含 ShipmentRouteOptimizeToursResponse,這些 ShipmentRoute 是車輛執行的一系列路線,可盡量降低整體成本。

使用者可以輪詢 operations.get 來查看 LRO 的狀態:

如果 LRO 的 done 欄位為 false,表示至少有一項要求仍在處理中。其他要求可能已順利完成,且結果可在 GCS 中取得。

如果 LRO 的 done 欄位為 true,表示已處理所有要求。所有成功處理的要求,結果都會顯示在 GCS 中。任何失敗的要求都不會在 GCS 中顯示結果。如果設定了 LRO 的 error 欄位,則該欄位會包含其中一個失敗要求的錯誤。

授權範圍

需要下列 OAuth 範圍:

  • https://www.googleapis.com/auth/cloud-platform
身分與存取權管理權限

需要在 parent 資源上具備下列 IAM 權限:

  • routeoptimization.operations.create

詳情請參閱 身分與存取權管理說明文件

OptimizeTours

rpc OptimizeTours(OptimizeToursRequest) returns (OptimizeToursResponse)

傳送包含 ShipmentModelOptimizeToursRequest,並傳回包含 ShipmentRouteOptimizeToursResponse,這些是車輛執行的一系列路線,可盡量降低整體成本。

ShipmentModel 模型主要由需要執行的 Shipment 和可用於傳輸 ShipmentVehicle 組成。ShipmentRoute 會將 Shipment 指派給 Vehicle。具體來說,系統會為每輛車輛指派一系列 Visit,其中 Visit 對應至 VisitRequest,也就是 Shipment 的接送或送達地點。

目標是將 ShipmentRoute 指派給 Vehicle,以盡可能降低總成本,其中成本包含 ShipmentModel 中定義的多個元件。

授權範圍

需要下列 OAuth 範圍:

  • https://www.googleapis.com/auth/cloud-platform
身分與存取權管理權限

需要在 parent 資源上具備下列 IAM 權限:

  • routeoptimization.locations.use

詳情請參閱 身分與存取權管理說明文件

AggregatedMetrics

ShipmentRoute (resp. for OptimizeToursResponse over all Transition and/or Visit (resp. over all ShipmentRoute) 元素的匯總指標。

欄位
performed_shipment_count

int32

已完成的出貨數量。請注意,每組接送和送達作業只會計入一次。

travel_duration

Duration

路線或解決方案的總行程時間。

wait_duration

Duration

路線或解決方案的總等待時間長度。

delay_duration

Duration

路線或解決方案的總延遲時間長度。

break_duration

Duration

路線或解決方案的總休息時間長度。

visit_duration

Duration

路線或解決方案的總造訪時間長度。

total_duration

Duration

總時間應等於上述所有時間的總和。對於路線,也對應到:

[ShipmentRoute.vehicle_end_time][google.maps.routeoptimization.v1.ShipmentRoute.vehicle_end_time] - [ShipmentRoute.vehicle_start_time][google.maps.routeoptimization.v1.ShipmentRoute.vehicle_start_time]
travel_distance_meters

double

路線或解決方案的總行程距離。

max_loads

map<string, VehicleLoad>

在整個路徑 (或解決方案) 中,針對路徑 (或解決方案) 上的每個數量,達成的最大負載量,計算方式為所有 Transition.vehicle_loads (或 ShipmentRoute.metrics.max_loads

BatchOptimizeToursMetadata

這個類型沒有任何欄位。

BatchOptimizeToursRequest 呼叫的作業中繼資料。

BatchOptimizeToursRequest

要求以非同步作業的形式批次最佳化行程。每個輸入檔案都應包含一個 OptimizeToursRequest,每個輸出檔案則會包含一個 OptimizeToursResponse。這項要求包含讀取/寫入及剖析檔案的資訊。所有輸入和輸出檔案都必須位於同一個專案中。

欄位
parent

string

必要欄位。要呼叫的目標專案和位置。

格式:* projects/{project-id} * projects/{project-id}/locations/{location-id}

如果未指定位置,系統會自動選擇區域。

model_configs[]

AsyncModelConfig

必要欄位。每個購買模型的輸入/輸出資訊,例如檔案路徑和資料格式。

AsyncModelConfig

非同步解決單一最佳化模型的資訊。

欄位
display_name

string

選用設定。使用者定義的模型名稱,可做為使用者追蹤模型的別名。

input_config

InputConfig

必要欄位。輸入模型的相關資訊。

output_config

OutputConfig

必要欄位。所需的輸出位置資訊。

BatchOptimizeToursResponse

這個類型沒有任何欄位。

回覆 BatchOptimizeToursRequest。在作業完成後,會在長時間執行作業中傳回此值。

BreakRule

產生車輛休息時間的規則 (例如午餐休息時間)。休息時間是指車輛在目前位置處於閒置狀態,無法執行任何拜訪的連續時間。可能會發生中斷的情況如下:

  • 在兩次造訪之間的轉換時間 (包括造訪前或造訪後的時間,但不包括造訪期間),在這種情況下,系統會延長兩次造訪之間的對應轉換時間,
  • 或在車輛發動前 (車輛可能不會在休息期間發動),這不會影響車輛發動時間。
  • 或在車輛結束後 (同樣地,請提供車輛結束時間)。
欄位
break_requests[]

BreakRequest

中斷序列。請參閱 BreakRequest 訊息。

frequency_constraints[]

FrequencyConstraint

可能會套用多個 FrequencyConstraint。這些值都必須符合這個 BreakRuleBreakRequest。請參閱 FrequencyConstraint

BreakRequest

您必須事先知道適用於每輛車的休息時間序列 (即數量和順序)。重複的 BreakRequest 會定義該序列,並按照必須發生的順序排列。兩者的時間範圍 (earliest_start_time / latest_start_time) 可能會重疊,但必須與訂單相容 (系統會檢查這項條件)。

欄位
earliest_start_time

Timestamp

必要欄位。休息時間開始時間的下限 (包含在內)。

latest_start_time

Timestamp

必要欄位。休息時間開始的上限 (包含在內)。

min_duration

Duration

必要欄位。插播時間長度下限。必須為正數。

FrequencyConstraint

您可以進一步限制上述指定的插播廣告頻率和時間長度,例如強制設下最小插播廣告頻率,例如「每 12 小時至少要插播 1 次廣告」。假設這可解讀為「在任何 12 小時的滑動時間窗格內,至少須有一次至少 1 小時的休息時間」,那麼這個範例會轉譯為以下 FrequencyConstraint

{
   min_break_duration { seconds: 3600 }         # 1 hour.
   max_inter_break_duration { seconds: 39600 }  # 11 hours (12 - 1 = 11).
}

除了 BreakRequest 中已指定的時間區間和最短時間長度外,解決方案中的中斷時間和時間長度都會遵循所有這類限制。

FrequencyConstraint 實際上可能會套用於非連續的廣告插播。舉例來說,以下時程會遵循「每 12 小時 1 小時」的範例:

  04:00 vehicle start
   .. performing travel and visits ..
  09:00 1 hour break
  10:00 end of the break
   .. performing travel and visits ..
  12:00 20-min lunch break
  12:20 end of the break
   .. performing travel and visits ..
  21:00 1 hour break
  22:00 end of the break
   .. performing travel and visits ..
  23:59 vehicle end
欄位
min_break_duration

Duration

必要欄位。此限制的插播時間長度下限。非負值。請參閱 FrequencyConstraint 的說明。

max_inter_break_duration

Duration

必要欄位。路徑中不含 duration >= min_break_duration 中斷的部分時段,允許的時間間隔上限。必須為正數。

DataFormat

輸入和輸出檔案的資料格式。

列舉
DATA_FORMAT_UNSPECIFIED 值無效,格式不得為 UNSPECIFIED。
JSON JavaScript 物件標記法。
PROTO_TEXT 通訊協定緩衝區文字格式。請參閱 https://protobuf.dev/reference/protobuf/textformat-spec/

DistanceLimit

定義可行駛的最大距離。可以是硬式或軟式。

如果定義軟性限制,soft_max_meterscost_per_kilometer_above_soft_max 都必須定義且為非負值。

欄位
max_meters

int64

硬性限制,限制距離不得超過 max_meters。限制值不得為負數。

soft_max_meters

int64

軟性限制不會強制執行最大距離限制,但如果違反限制,會產生費用,並與模型中定義的其他費用相加,使用相同的單位。

如果已定義,則 soft_max_meters 必須小於 max_meters,且不得為負數。

cost_per_kilometer_above_soft_max

double

如果距離超過 soft_max_meters 上限,則會產生每公里費用。如果距離低於限制,額外費用為 0,否則計算費用的公式如下:

  (distance_meters - soft_max_meters) / 1000.0 *
  cost_per_kilometer_above_soft_max.

費用必須為非負值。

GcsDestination

輸出檔案的寫入位置(Google Cloud Storage)。

欄位
uri

string

必要欄位。Google Cloud Storage URI。

GcsSource

系統會從這裡讀取輸入檔案的 Google Cloud Storage 位置。

欄位
uri

string

必要欄位。Google Cloud Storage 物件的 URI,格式為 gs://bucket/path/to/object

InjectedSolutionConstraint

在要求中插入的解決方案,其中包含哪些造訪必須受到限制,以及如何限制的資訊。

欄位
routes[]

ShipmentRoute

要插入的解決方案路徑。原始解決方案可能會省略部分路線。路線和略過的運送作業必須符合 injected_first_solution_routes 列出的基本有效性假設。

skipped_shipments[]

SkippedShipment

略過要插入的解決方案出貨作業。部分內容可能會從原始解決方案中省略。請參閱 routes 欄位。

constraint_relaxations[]

ConstraintRelaxation

針對零或多個車輛群組,指定放寬限制的時機和程度。如果這個欄位為空白,則所有非空白的車輛路線都會受到完全限制。

ConstraintRelaxation

針對一組車輛,指定訪客限制的門檻和鬆綁程度。skipped_shipment 欄位中列出的運送作業會遭到略過,也就是無法執行。

欄位
relaxations[]

Relaxation

所有造訪限制放寬項目,會套用至 vehicle_indices 中含有車輛的路線造訪。

vehicle_indices[]

int32

指定要套用造訪限制 relaxations 的車輛索引。如果留空,系統會將其視為預設值,並將 relaxations 套用至其他 constraint_relaxations 未指定的所有車輛。最多只能有一個預設值,也就是最多只能有一個限制放寬欄位可為空白 vehicle_indices。車輛索引只能列出一次,即使在多個 constraint_relaxations 中也是如此。

如果 interpret_injected_solutions_using_labels 為 true (請參閱 fields 註解),車輛索引會與 ShipmentRoute.vehicle_index 進行相同的對應。

休閒場所

如果 relaxations 為空白,routes 上所有造訪記錄的開始時間和順序都會受到完全限制,且無法在這些路徑中插入或新增新的造訪記錄。此外,除非車輛為空 (即在模型中沒有造訪,且 used_if_route_is_empty 設為 false),否則 routes 中的車輛開始和結束時間會受到完全限制。

relaxations(i).level 會指定套用至符合下列條件的 #j 次訪問的限制放寬程度:

  • route.visits(j).start_time >= relaxations(i).threshold_time
  • j + 1 >= relaxations(i).threshold_visit_count

同樣地,如果車輛啟動符合下列條件,系統會將啟動時間延後至 relaxations(i).level

  • vehicle_start_time >= relaxations(i).threshold_time
  • relaxations(i).threshold_visit_count == 0 和車輛端會在滿足下列條件時放寬至 relaxations(i).level
  • vehicle_end_time >= relaxations(i).threshold_time
  • route.visits_size() + 1 >= relaxations(i).threshold_visit_count

如要針對符合 threshold_visit_countthreshold_time 的造訪次數套用放寬程度,請新增兩個具有相同 levelrelaxations:一個只設定 threshold_visit_count,另一個只設定 threshold_time。如果造訪符合多個 relaxations 的條件,系統會套用最寬鬆的層級。因此,從車輛開始行駛到依序造訪路線,再到車輛行程結束,放鬆程度會越來越高,也就是說,放鬆程度不會隨著路線的進行而降低。

路線造訪的時間和順序若不符合任何 relaxations 的門檻條件,就會受到完全限制,且無法在這些序列中插入造訪。此外,如果車輛的起點或終點不符合任何放寬條件,則會固定時間,除非車輛為空車。

欄位
level

Level

threshold_time 之後或之後,且至少滿足 threshold_visit_count 的條件時,套用的限制放寬程度。

threshold_time

Timestamp

可套用放寬 level 的時間點或之後。

threshold_visit_count

int32

系統可在多少次造訪後套用放寬 level 的數量。如果 threshold_visit_count 為 0 (或未設定),level 可能會在車輛啟動時直接套用。

如果是 route.visits_size() + 1level 可能只會套用至車輛端。如果超過 route.visits_size() + 1,則該路徑將完全不套用 level

層級

表示不同的限制放寬層級,這些層級會套用至符合門檻條件的單一造訪,以及後續的造訪。

下列列舉的順序是依放鬆程度排序。

列舉
LEVEL_UNSPECIFIED

隱含的預設放寬程度:不放寬任何限制,也就是所有造訪皆受到完全限制。

此值不得在 level 中明確使用。

RELAX_VISIT_TIMES_AFTER_THRESHOLD 系統會放寬造訪開始時間和車輛開始/結束時間,但每個造訪仍會綁定至同一輛車輛,且必須遵循造訪順序:在兩次造訪之間或之前,不得插入其他造訪。
RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD RELAX_VISIT_TIMES_AFTER_THRESHOLD 相同,但訪問序列也已放寬:訪問只能由此車輛執行,但可能不會執行。
RELAX_ALL_AFTER_THRESHOLD RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD 相同,但車輛也放寬限制:在門檻時間點或之後,訪客可完全免費,且可能不會執行。

InputConfig

指定 [BatchOptimizeTours][google.maps.routeoptimization.v1.RouteOptimizationService.BatchOptimizeTours] 的輸入內容。

欄位
data_format

DataFormat

必要欄位。輸入資料格式。

聯集欄位 source。必要欄位。source 只能是下列其中一項:
gcs_source

GcsSource

Google Cloud Storage 位置。這必須是單一物件 (檔案)。

位置

封裝位置 (地理點和選用的標頭)。

欄位
lat_lng

LatLng

航點的地理座標。

heading

int32

與流量方向相關的指南針方位。這個值用來指定接送和下車地點的道路兩側。方向值的範圍為 0 到 360,其中 0 指定正北方向,90 指定正東方向,以此類推。

OptimizeToursRequest

要求交給導覽最佳化解決方案,該解決方案會定義要解決的運送模型,以及最佳化參數。

欄位
parent

string

必要欄位。要呼叫的目標專案或位置。

格式:* projects/{project-id} * projects/{project-id}/locations/{location-id}

如果未指定位置,系統會自動選擇區域。

timeout

Duration

如果設定了這個逾時時間,伺服器會在逾時時間到期前或同步要求的伺服器期限到期前 (以先到者為準) 傳回回應。

對於非同步要求,伺服器會在逾時前產生解決方案 (如果可行)。

model

ShipmentModel

解決運送模型。

solving_mode

SolvingMode

根據預設,解題模式為 DEFAULT_SOLVE (0)。

search_mode

SearchMode

用於解決要求的搜尋模式。

injected_first_solution_routes[]

ShipmentRoute

引導最佳化演算法,找出與先前解決方案相似的第一個解決方案。

建立第一個解決方案時,模型會受到限制。在第一個解決方案中,系統會隱含略過任何未在路線上執行的運送作業,但可能會在後續解決方案中執行。

解決方案必須滿足一些基本有效性假設:

  • 對於所有路線,vehicle_index 必須在範圍內,且不得重複。
  • 對於所有造訪,shipment_indexvisit_request_index 都必須在範圍內。
  • 一筆出貨只能參照一條路徑。
  • 取貨/送貨運送服務的取貨作業必須在送貨前完成。
  • 每筆訂單只能使用一種取貨或送貨替代方案。
  • 對於所有路線,時間都會增加 (也就是vehicle_start_time <= visits[0].start_time <= visits[1].start_time ... <= vehicle_end_time)。
  • 運送作業只能在允許的車輛上執行。如果 Shipment.allowed_vehicle_indices 為空白,或其 vehicle_index 包含在 Shipment.allowed_vehicle_indices 中,系統就會允許該車輛。
  • 如果將 avoid_u_turns 設為 true,則必須為相關造訪設定 injected_solution_location_token

如果注入的解決方案不可行,系統不一定會傳回驗證錯誤,而是可能傳回表示不可行性的錯誤。

injected_solution_constraint

InjectedSolutionConstraint

限制最佳化演算法,找出與先前解決方案相似的最終解決方案。舉例來說,您可以使用此方法,將已完成或即將完成但不得修改的路線部分凍結。

如果注入的解決方案不可行,系統不一定會傳回驗證錯誤,而是可能傳回表示不可行性的錯誤。

refresh_details_routes[]

ShipmentRoute

如果不為空白,系統會重新整理指定路線,但不會修改其基礎的造訪序列或行程時間:只會更新其他詳細資料。這並無法解決模型問題。

截至 2020 年 11 月,這個方法只會填入非空路線的多邊形,且需要 populate_polylines 為 true。

傳入路徑的 route_polyline 欄位可能與路徑 transitions 不一致。

這個欄位不得與 injected_first_solution_routesinjected_solution_constraint 搭配使用。

Shipment.ignoreVehicle.ignore 不會對行為造成任何影響。無論是否忽略相關的運送或車輛,系統仍會在所有非空白路線的所有造訪之間填入折線。

interpret_injected_solutions_using_labels

bool

如果為 true:

這項解釋適用於 injected_first_solution_routesinjected_solution_constraintrefresh_details_routes 欄位。當建立解決方案後,要求中的運送或車輛索引發生變化時,即可使用這項方法。這可能是因為運送或車輛已從要求中移除或新增。

如果為 true,則下列類別中的標籤在該類別中最多只能出現一次:

如果插入的解決方案中的 vehicle_label 不對應至要求車輛,系統會從解決方案中移除對應的路線,並一併移除其造訪次數。如果插入的解決方案中的 shipment_label 與要求傳送作業不符,系統會從解決方案中移除對應的造訪。如果注入的解決方案中的 SkippedShipment.label 與要求的傳送作業不符,系統會從解決方案中移除 SkippedShipment

從已插入的解決方案中移除路徑造訪或整個路徑,可能會影響隱含限制,進而導致解決方案變更、驗證錯誤或無法執行。

注意:呼叫端必須確保每個 Vehicle.label (resp. Shipment.label) 會在兩個相關要求中,明確指出所使用的車輛 (或相應的出貨) 實體:產生在注入解決方案中使用的 OptimizeToursResponse 的過去要求,以及包含注入解決方案的目前要求。上述的唯一性檢查無法保證符合這項規定。

consider_road_traffic

bool

在計算 ShipmentRoute 欄位 Transition.travel_durationVisit.start_timevehicle_end_time、設定 ShipmentRoute.has_traffic_infeasibilities 欄位,以及計算 OptimizeToursResponse.total_cost 欄位時,請考慮使用流量估算值。

populate_polylines

bool

如果為 true,回應 ShipmentRoute 會填入多邊形。

populate_transition_polylines

bool

如果為 true,回應 ShipmentRoute.transitions 中就會填入多邊形。

allow_large_deadline_despite_interruption_risk

bool

如果設定了這個值,要求的期限 (請參閱 https://grpc.io/blog/deadlines) 最多可達 60 分鐘。否則,最長期限僅為 30 分鐘。請注意,長時間存在的要求有較高 (但仍很低) 的中斷風險。

use_geodesic_distances

bool

如果為 true,系統會使用大地測量距離 (而非 Google 地圖距離) 計算行程距離,並使用大地測量距離和 geodesic_meters_per_second 定義的速度計算行程時間。

label

string

可能用於識別此要求的標籤,會回報至 OptimizeToursResponse.request_label

geodesic_meters_per_second

double

如果 use_geodesic_distances 為 true,則必須設定這個欄位,並定義用於計算行程時間的速度。這個值必須至少為 1.0 公尺/秒。

max_validation_errors

int32

截斷傳回的驗證錯誤數量。除非 solving_mode=VALIDATE_ONLY: 請參閱 OptimizeToursResponse.validation_errors 欄位,否則這些錯誤通常會附加至 INVALID_ARGUMENT 錯誤酬載,做為 BadRequest 錯誤詳細資料 (https://cloud.google.com/apis/design/errors#error_details)。預設值為 100,上限為 10,000。

SearchMode

定義搜尋行為的模式,取捨延遲時間與解決方案品質。在所有模式中,系統都會強制執行全域要求期限。

列舉
SEARCH_MODE_UNSPECIFIED 未指定搜尋模式,等同於 RETURN_FAST
RETURN_FAST 找到第一個可行解決方案後,請停止搜尋。
CONSUME_ALL_AVAILABLE_TIME 盡可能尋找更合適的解決方案。

SolvingMode

定義解算器應如何處理要求。在 VALIDATE_ONLY 以外的所有模式中,如果要求無效,您會收到 INVALID_REQUEST 錯誤。請參閱 max_validation_errors,瞭解如何限制傳回的錯誤數量。

列舉
DEFAULT_SOLVE 解決模型。警告可能會顯示在 [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors] 中。
VALIDATE_ONLY 只驗證模型,但不解決模型:盡可能填入 OptimizeToursResponse.validation_errors
DETECT_SOME_INFEASIBLE_SHIPMENTS

只會填入 OptimizeToursResponse.validation_errorsOptimizeToursResponse.skipped_shipments,實際上並未解決要求的其餘部分 (statusroutes 在回應中未設定)。如果偵測到 injected_solution_constraint 路線上有不可行性,系統會在 OptimizeToursResponse.validation_errors 欄位中填入這些不可行性,而 OptimizeToursResponse.skipped_shipments 則會留空。

重要事項:系統只會傳回在預處理期間偵測為不切實際的出貨,而非所有不切實際的出貨。

OptimizeToursResponse

解決巡迴路線最佳化問題後的回應,其中包含每輛車輛所遵循的路線、已略過的貨件,以及解決方案的總費用。

欄位
routes[]

ShipmentRoute

為每輛車輛計算的路線;第 i 條路線對應至模型中的第 i 輛車輛。

request_label

string

如果要求中指定了標籤,則為 OptimizeToursRequest.label 的副本。

skipped_shipments[]

SkippedShipment

略過所有出貨的清單。

validation_errors[]

OptimizeToursValidationError

我們獨立偵測到的所有驗證錯誤清單。請參閱「MULTIPLE ERRORS」一節,瞭解 OptimizeToursValidationError 訊息的說明。在 solving_modeDEFAULT_SOLVE 的情況下,這會加入警告,而非錯誤。

metrics

Metrics

這項解決方案的時間長度、距離和用量指標。

指標

匯總所有路徑的整體指標。

欄位
aggregated_route_metrics

AggregatedMetrics

匯總路線。每個指標都是所有同名 ShipmentRoute.metrics 欄位的總和 (或負載的最大值)。

skipped_mandatory_shipment_count

int32

略過的強制貨件數量。

used_vehicle_count

int32

使用的車輛數量。注意:如果車輛路線為空白,且 Vehicle.used_if_route_is_empty 為 true,系統會將車輛視為已使用。

earliest_vehicle_start_time

Timestamp

二手車最早的開始時間,計算方式為所有二手車 ShipmentRoute.vehicle_start_time 的最小值。

latest_vehicle_end_time

Timestamp

二手車輛的最新結束時間,計算方式為所有二手車輛的 ShipmentRoute.vehicle_end_time 最大值。

costs

map<string, double>

解決方案的費用,依費用相關要求欄位細分。鍵是相對於輸入 OptimizeToursRequest 的 proto 路徑,例如「model.shipments.pickups.cost」,而值則是相應費用欄位產生的總費用,並在整個解決方案中匯總。換句話說,costs["model.shipments.pickups.cost"] 是解決方案中所有提貨費用的總和。這裡會詳細列出模型中定義的所有費用,但 TransitionAttributes 相關費用除外,因為這類費用自 2022 年 1 月起只會以匯總方式呈報。

total_cost

double

解決方案的總費用。成本對應項目中的所有值總和。

OptimizeToursValidationError

說明驗證 OptimizeToursRequest 時發生的錯誤或警告。

欄位
code

int32

驗證錯誤是由一組一律存在的值 (codedisplay_name) 定義。

其他欄位 (如下方所示) 會提供更多錯誤相關資訊。

MULTIPLE ERRORS:如果發生多項錯誤,驗證程序會嘗試輸出其中幾項。這項程序與編譯器相似,並非完美無瑕。部分驗證錯誤會導致「致命」錯誤,也就是會停止整個驗證程序。display_name="UNSPECIFIED" 錯誤就是這種情況。有些錯誤可能會導致驗證程序略過其他錯誤。

穩定性codedisplay_name 應非常穩定。但隨著時間過去,可能會出現新的代碼和顯示名稱,導致特定 (無效) 要求產生不同的 (codedisplay_name) 組合,因為新錯誤會隱藏舊錯誤 (請參閱「多個錯誤」)。

參考資料:所有 (代碼、名稱) 組合的清單:

  • UNSPECIFIED = 0;
  • VALIDATION_TIMEOUT_ERROR = 10;驗證無法在期限內完成。
  • REQUEST_OPTIONS_ERROR = 12;

    • REQUEST_OPTIONS_INVALID_SOLVING_MODE = 1201;
    • REQUEST_OPTIONS_INVALID_MAX_VALIDATION_ERRORS = 1203;
    • REQUEST_OPTIONS_INVALID_GEODESIC_METERS_PER_SECOND = 1204;
    • REQUEST_OPTIONS_GEODESIC_METERS_PER_SECOND_TOO_SMALL = 1205;
    • REQUEST_OPTIONS_MISSING_GEODESIC_METERS_PER_SECOND = 1206;
    • REQUEST_OPTIONS_POPULATE_PATHFINDER_TRIPS_AND_GEODESIC_DISTANCE = 1207;
    • REQUEST_OPTIONS_COST_MODEL_OPTIONS_AND_GEODESIC_DISTANCE = 1208;
    • REQUEST_OPTIONS_TRAVEL_MODE_INCOMPATIBLE_WITH_TRAFFIC = 1211;
    • REQUEST_OPTIONS_MULTIPLE_TRAFFIC_FLAVORS = 1212;
    • REQUEST_OPTIONS_INVALID_TRAFFIC_FLAVOR = 1213;
    • REQUEST_OPTIONS_TRAFFIC_ENABLED_WITHOUT_GLOBAL_START_TIME = 1214;
    • REQUEST_OPTIONS_TRAFFIC_ENABLED_WITH_PRECEDENCES = 1215;
    • REQUEST_OPTIONS_TRAFFIC_PREFILL_MODE_INVALID = 1216;
    • REQUEST_OPTIONS_TRAFFIC_PREFILL_ENABLED_WITHOUT_TRAFFIC = 1217;
  • INJECTED_SOLUTION_ERROR = 20;
    • INJECTED_SOLUTION_MISSING_LABEL = 2000;
    • INJECTED_SOLUTION_DUPLICATE_LABEL = 2001;
    • INJECTED_SOLUTION_AMBIGUOUS_INDEX = 2002;
    • INJECTED_SOLUTION_INFEASIBLE_AFTER_GETTING_TRAVEL_TIMES = 2003;
    • INJECTED_SOLUTION_TRANSITION_INCONSISTENT_WITH_ACTUAL_TRAVEL = 2004;
    • INJECTED_SOLUTION_CONCURRENT_SOLUTION_TYPES = 2005;
    • INJECTED_SOLUTION_MORE_THAN_ONE_PER_TYPE = 2006;
    • INJECTED_SOLUTION_REFRESH_WITHOUT_POPULATE = 2008;
    • INJECTED_SOLUTION_CONSTRAINED_ROUTE_PORTION_INFEASIBLE = 2010;
  • SHIPMENT_MODEL_ERROR = 22;
    • SHIPMENT_MODEL_TOO_LARGE = 2200;
    • SHIPMENT_MODEL_TOO_MANY_CAPACITY_TYPES = 2201;
    • SHIPMENT_MODEL_GLOBAL_START_TIME_NEGATIVE_OR_NAN = 2202;
    • SHIPMENT_MODEL_GLOBAL_END_TIME_TOO_LARGE_OR_NAN = 2203;
    • SHIPMENT_MODEL_GLOBAL_START_TIME_AFTER_GLOBAL_END_TIME = 2204;
    • SHIPMENT_MODEL_GLOBAL_DURATION_TOO_LONG = 2205;
    • SHIPMENT_MODEL_MAX_ACTIVE_VEHICLES_NOT_POSITIVE = 2206;
    • SHIPMENT_MODEL_DURATION_MATRIX_TOO_LARGE = 2207;
  • INDEX_ERROR = 24;
  • TAG_ERROR = 26;
  • TIME_WINDOW_ERROR = 28;
    • TIME_WINDOW_INVALID_START_TIME = 2800;
    • TIME_WINDOW_INVALID_END_TIME = 2801;
    • TIME_WINDOW_INVALID_SOFT_START_TIME = 2802;
    • TIME_WINDOW_INVALID_SOFT_END_TIME = 2803;
    • TIME_WINDOW_OUTSIDE_GLOBAL_TIME_WINDOW = 2804;
    • TIME_WINDOW_START_TIME_AFTER_END_TIME = 2805;
    • TIME_WINDOW_INVALID_COST_PER_HOUR_BEFORE_SOFT_START_TIME = 2806;
    • TIME_WINDOW_INVALID_COST_PER_HOUR_AFTER_SOFT_END_TIME = 2807;
    • TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_WITHOUT_SOFT_START_TIME = 2808;
    • TIME_WINDOW_COST_AFTER_SOFT_END_TIME_WITHOUT_SOFT_END_TIME = 2809;
    • TIME_WINDOW_SOFT_START_TIME_WITHOUT_COST_BEFORE_SOFT_START_TIME = 2810;
    • TIME_WINDOW_SOFT_END_TIME_WITHOUT_COST_AFTER_SOFT_END_TIME = 2811;
    • TIME_WINDOW_OVERLAPPING_ADJACENT_OR_EARLIER_THAN_PREVIOUS = 2812;
    • TIME_WINDOW_START_TIME_AFTER_SOFT_START_TIME = 2813;
    • TIME_WINDOW_SOFT_START_TIME_OUTSIDE_GLOBAL_TIME_WINDOW = 2819;
    • TIME_WINDOW_SOFT_END_TIME_OUTSIDE_GLOBAL_TIME_WINDOW = 2820;
    • TIME_WINDOW_SOFT_END_TIME_AFTER_END_TIME = 2816;
    • TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_SET_AND_MULTIPLE_WINDOWS = 2817;
    • TIME_WINDOW_COST_AFTER_SOFT_END_TIME_SET_AND_MULTIPLE_WINDOWS = 2818;
    • TRANSITION_ATTRIBUTES_ERROR = 30;
    • TRANSITION_ATTRIBUTES_INVALID_COST = 3000;
    • TRANSITION_ATTRIBUTES_INVALID_COST_PER_KILOMETER = 3001;
    • TRANSITION_ATTRIBUTES_DUPLICATE_TAG_PAIR = 3002;
    • TRANSITION_ATTRIBUTES_DISTANCE_LIMIT_MAX_METERS_UNSUPPORTED = 3003;
    • TRANSITION_ATTRIBUTES_UNSPECIFIED_SOURCE_TAGS = 3004;
    • TRANSITION_ATTRIBUTES_CONFLICTING_SOURCE_TAGS_FIELDS = 3005;
    • TRANSITION_ATTRIBUTES_UNSPECIFIED_DESTINATION_TAGS = 3006;
    • TRANSITION_ATTRIBUTES_CONFLICTING_DESTINATION_TAGS_FIELDS = 3007;
    • TRANSITION_ATTRIBUTES_DELAY_DURATION_NEGATIVE_OR_NAN = 3008;
    • TRANSITION_ATTRIBUTES_DELAY_DURATION_EXCEEDS_GLOBAL_DURATION = 3009;
  • AMOUNT_ERROR = 31;
    • AMOUNT_NEGATIVE_VALUE = 3100;
  • LOAD_LIMIT_ERROR = 33;
    • LOAD_LIMIT_INVALID_COST_ABOVE_SOFT_MAX = 3303;
    • LOAD_LIMIT_SOFT_MAX_WITHOUT_COST_ABOVE_SOFT_MAX = 3304;
    • LOAD_LIMIT_COST_ABOVE_SOFT_MAX_WITHOUT_SOFT_MAX = 3305;
    • LOAD_LIMIT_NEGATIVE_SOFT_MAX = 3306;
    • LOAD_LIMIT_MIXED_DEMAND_TYPE = 3307;
    • LOAD_LIMIT_MAX_LOAD_NEGATIVE_VALUE = 3308;
    • LOAD_LIMIT_SOFT_MAX_ABOVE_MAX = 3309;
  • INTERVAL_ERROR = 34;
    • INTERVAL_MIN_EXCEEDS_MAX = 3401;
    • INTERVAL_NEGATIVE_MIN = 3402;
    • INTERVAL_NEGATIVE_MAX = 3403;
    • INTERVAL_MIN_EXCEEDS_CAPACITY = 3404;
    • INTERVAL_MAX_EXCEEDS_CAPACITY = 3405;
  • DISTANCE_LIMIT_ERROR = 36;
    • DISTANCE_LIMIT_INVALID_COST_AFTER_SOFT_MAX = 3601;
    • DISTANCE_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3602;
    • DISTANCE_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3603;
    • DISTANCE_LIMIT_NEGATIVE_MAX = 3604;
    • DISTANCE_LIMIT_NEGATIVE_SOFT_MAX = 3605;
    • DISTANCE_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3606;
  • DURATION_LIMIT_ERROR = 38;
    • DURATION_LIMIT_MAX_DURATION_NEGATIVE_OR_NAN = 3800;
    • DURATION_LIMIT_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3801;
    • DURATION_LIMIT_INVALID_COST_PER_HOUR_AFTER_SOFT_MAX = 3802;
    • DURATION_LIMIT_SOFT_MAX_WITHOUT_COST_AFTER_SOFT_MAX = 3803;
    • DURATION_LIMIT_COST_AFTER_SOFT_MAX_WITHOUT_SOFT_MAX = 3804;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3805;
    • DURATION_LIMIT_INVALID_COST_AFTER_QUADRATIC_SOFT_MAX = 3806;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_COST_PER_SQUARE_HOUR = 3807;
    • DURATION_LIMIT_COST_PER_SQUARE_HOUR_WITHOUT_QUADRATIC_SOFT_MAX = 3808;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_MAX = 3809;
    • DURATION_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3810;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_LARGER_THAN_MAX = 3811;
    • DURATION_LIMIT_DIFF_BETWEEN_MAX_AND_QUADRATIC_SOFT_MAX_TOO_LARGE = 3812;
    • DURATION_LIMIT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3813;
    • DURATION_LIMIT_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3814;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3815;
  • SHIPMENT_ERROR = 40;
    • SHIPMENT_PD_LIMIT_WITHOUT_PICKUP_AND_DELIVERY = 4014;
    • SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_NEGATIVE_OR_NAN = 4000;
    • SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4001;
    • SHIPMENT_PD_RELATIVE_DETOUR_LIMIT_INVALID = 4015;
    • SHIPMENT_PD_DETOUR_LIMIT_AND_EXTRA_VISIT_DURATION = 4016;
    • SHIPMENT_PD_TIME_LIMIT_DURATION_NEGATIVE_OR_NAN = 4002;
    • SHIPMENT_PD_TIME_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4003;
    • SHIPMENT_EMPTY_SHIPMENT_TYPE = 4004;
    • SHIPMENT_NO_PICKUP_NO_DELIVERY = 4005;
    • SHIPMENT_INVALID_PENALTY_COST = 4006;
    • SHIPMENT_ALLOWED_VEHICLE_INDEX_OUT_OF_BOUNDS = 4007;
    • SHIPMENT_DUPLICATE_ALLOWED_VEHICLE_INDEX = 4008;
    • SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITHOUT_INDEX = 4009;
    • SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITH_INDEX = 4010;
    • SHIPMENT_INVALID_COST_FOR_VEHICLE = 4011;
    • SHIPMENT_COST_FOR_VEHICLE_INDEX_OUT_OF_BOUNDS = 4012;
    • SHIPMENT_DUPLICATE_COST_FOR_VEHICLE_INDEX = 4013;
  • VEHICLE_ERROR = 42;
    • VEHICLE_EMPTY_REQUIRED_OPERATOR_TYPE = 4200;
    • VEHICLE_DUPLICATE_REQUIRED_OPERATOR_TYPE = 4201;
    • VEHICLE_NO_OPERATOR_WITH_REQUIRED_OPERATOR_TYPE = 4202;
    • VEHICLE_EMPTY_START_TAG = 4203;
    • VEHICLE_DUPLICATE_START_TAG = 4204;
    • VEHICLE_EMPTY_END_TAG = 4205;
    • VEHICLE_DUPLICATE_END_TAG = 4206;
    • VEHICLE_EXTRA_VISIT_DURATION_NEGATIVE_OR_NAN = 4207;
    • VEHICLE_EXTRA_VISIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4208;
    • VEHICLE_EXTRA_VISIT_DURATION_EMPTY_KEY = 4209;
    • VEHICLE_FIRST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4210;
    • VEHICLE_FIRST_SHIPMENT_IGNORED = 4211;
    • VEHICLE_FIRST_SHIPMENT_NOT_BOUND = 4212;
    • VEHICLE_LAST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4213;
    • VEHICLE_LAST_SHIPMENT_IGNORED = 4214;
    • VEHICLE_LAST_SHIPMENT_NOT_BOUND = 4215;
    • VEHICLE_IGNORED_WITH_USED_IF_ROUTE_IS_EMPTY = 4216;
    • VEHICLE_INVALID_COST_PER_KILOMETER = 4217;
    • VEHICLE_INVALID_COST_PER_HOUR = 4218;
    • VEHICLE_INVALID_COST_PER_TRAVELED_HOUR = 4219;
    • VEHICLE_INVALID_FIXED_COST = 4220;
    • VEHICLE_INVALID_TRAVEL_DURATION_MULTIPLE = 4221;
    • VEHICLE_TRAVEL_DURATION_MULTIPLE_WITH_SHIPMENT_PD_DETOUR_LIMITS = 4223;
    • VEHICLE_MATRIX_INDEX_WITH_SHIPMENT_PD_DETOUR_LIMITS = 4224;
    • VEHICLE_MINIMUM_DURATION_LONGER_THAN_DURATION_LIMIT = 4222;
  • VISIT_REQUEST_ERROR = 44;
    • VISIT_REQUEST_EMPTY_TAG = 4400;
    • VISIT_REQUEST_DUPLICATE_TAG = 4401;
    • VISIT_REQUEST_DURATION_NEGATIVE_OR_NAN = 4404;
    • VISIT_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4405;
  • PRECEDENCE_ERROR = 46;
    • PRECEDENCE_RULE_MISSING_FIRST_INDEX = 4600;
    • PRECEDENCE_RULE_MISSING_SECOND_INDEX = 4601;
    • PRECEDENCE_RULE_FIRST_INDEX_OUT_OF_BOUNDS = 4602;
    • PRECEDENCE_RULE_SECOND_INDEX_OUT_OF_BOUNDS = 4603;
    • PRECEDENCE_RULE_DUPLICATE_INDEX = 4604;
    • PRECEDENCE_RULE_INEXISTENT_FIRST_VISIT_REQUEST = 4605;
    • PRECEDENCE_RULE_INEXISTENT_SECOND_VISIT_REQUEST = 4606;
  • BREAK_ERROR = 48;
    • BREAK_RULE_EMPTY = 4800;
    • BREAK_REQUEST_UNSPECIFIED_DURATION = 4801;
    • BREAK_REQUEST_UNSPECIFIED_EARLIEST_START_TIME = 4802;
    • BREAK_REQUEST_UNSPECIFIED_LATEST_START_TIME = 4803;
    • BREAK_REQUEST_DURATION_NEGATIVE_OR_NAN = 4804; = 4804;
    • BREAK_REQUEST_LATEST_START_TIME_BEFORE_EARLIEST_START_TIME = 4805;
    • BREAK_REQUEST_EARLIEST_START_TIME_BEFORE_GLOBAL_START_TIME = 4806;
    • BREAK_REQUEST_LATEST_END_TIME_AFTER_GLOBAL_END_TIME = 4807;
    • BREAK_REQUEST_NON_SCHEDULABLE = 4808;
    • BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_NEGATIVE_OR_NAN = 4809;
    • BREAK_FREQUENCY_MIN_BREAK_DURATION_NEGATIVE_OR_NAN = 4810;
    • BREAK_FREQUENCY_MIN_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4811;
    • BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4812;
    • BREAK_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4813;
    • BREAK_FREQUENCY_MISSING_MAX_INTER_BREAK_DURATION = 4814;
    • BREAK_FREQUENCY_MISSING_MIN_BREAK_DURATION = 4815;
  • SHIPMENT_TYPE_INCOMPATIBILITY_ERROR = 50;
    • SHIPMENT_TYPE_INCOMPATIBILITY_EMPTY_TYPE = 5001;
    • SHIPMENT_TYPE_INCOMPATIBILITY_LESS_THAN_TWO_TYPES = 5002;
    • SHIPMENT_TYPE_INCOMPATIBILITY_DUPLICATE_TYPE = 5003;
    • SHIPMENT_TYPE_INCOMPATIBILITY_INVALID_INCOMPATIBILITY_MODE = 5004;
    • SHIPMENT_TYPE_INCOMPATIBILITY_TOO_MANY_INCOMPATIBILITIES = 5005;
  • SHIPMENT_TYPE_REQUIREMENT_ERROR = 52;
    • SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE = 52001;
    • SHIPMENT_TYPE_REQUIREMENT_NO_DEPENDENT_TYPE = 52002;
    • SHIPMENT_TYPE_REQUIREMENT_INVALID_REQUIREMENT_MODE = 52003;
    • SHIPMENT_TYPE_REQUIREMENT_TOO_MANY_REQUIREMENTS = 52004;
    • SHIPMENT_TYPE_REQUIREMENT_EMPTY_REQUIRED_TYPE = 52005;
    • SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_REQUIRED_TYPE = 52006;
    • SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE_FOUND = 52007;
    • SHIPMENT_TYPE_REQUIREMENT_EMPTY_DEPENDENT_TYPE = 52008;
    • SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_DEPENDENT_TYPE = 52009;
    • SHIPMENT_TYPE_REQUIREMENT_SELF_DEPENDENT_TYPE = 52010;
    • SHIPMENT_TYPE_REQUIREMENT_GRAPH_HAS_CYCLES = 52011;
  • VEHICLE_OPERATOR_ERROR = 54;
    • VEHICLE_OPERATOR_EMPTY_TYPE = 5400;
    • VEHICLE_OPERATOR_MULTIPLE_START_TIME_WINDOWS = 5401;
    • VEHICLE_OPERATOR_SOFT_START_TIME_WINDOW = 5402;
    • VEHICLE_OPERATOR_MULTIPLE_END_TIME_WINDOWS = 5403;
    • VEHICLE_OPERATOR_SOFT_END_TIME_WINDOW = 5404;
  • DURATION_SECONDS_MATRIX_ERROR = 56;
    • DURATION_SECONDS_MATRIX_DURATION_NEGATIVE_OR_NAN = 5600;
    • DURATION_SECONDS_MATRIX_DURATION_EXCEEDS_GLOBAL_DURATION = 5601;
  • WARNING = 9;
    • WARNING_INJECTED_FIRST_SOLUTION = 90;
      • WARNING_INJECTED_FIRST_SOLUTION_INFEASIBLE_SHIPMENTS_REMOVED = 9000;
      • WARNING_INJECTED_FIRST_SOLUTION_INFEASIBLE_AFTER_GETTING_TRAVEL_TIMES = 9001;
display_name

string

錯誤的顯示名稱。

fields[]

FieldReference

錯誤內容可能涉及 0 個、1 個 (大多數情況下) 或更多欄位。舉例來說,如要參照車輛 #4 和貨件 #2 的首次取件,可以執行以下操作:

fields { name: "vehicles" index: 4}
fields { name: "shipments" index: 2 sub_field {name: "pickups" index: 0} }

不過,請注意,fields 的基數不應因特定錯誤代碼而變更。

error_message

string

使用者容易理解的錯誤說明字串。codeerror_message 之間的對應關係為 1:1 (當代碼 !=「UNSPECIFIED」時)。

穩定性:不穩定:與特定 code 相關聯的錯誤訊息可能會隨時間變更 (希望能更清楚說明)。請改用 display_namecode

offending_values

string

可能包含欄位的值。但不一定適用於所有情況。請務必不要依賴這項功能,並且只用於手動模型偵錯。

FieldReference

指定驗證錯誤的內容。FieldReference 一律會參照此檔案中的特定欄位,並遵循相同的階層結構。舉例來說,我們可以使用以下方式指定車輛 #5 的 start_time_windows 元素 #2:

name: "vehicles" index: 5 sub_field { name: "end_time_windows" index: 2 }

不過,我們會省略 OptimizeToursRequestShipmentModel 等頂層實體,以免訊息過於擁擠。

欄位
name

string

欄位名稱,例如「vehicles」。

sub_field

FieldReference

必要時,可遞迴巢狀子欄位。

聯集欄位 index_or_key

index_or_key 只能是下列其中一項:

index

int32

如果是重複欄位,則為該欄位的索引。

key

string

若欄位為對應項,則為索引鍵。

OutputConfig

指定 [BatchOptimizeTours][google.maps.routeoptimization.v1.RouteOptimizationService.BatchOptimizeTours] 結果的目的地。

欄位
data_format

DataFormat

必要欄位。輸出資料格式。

聯集欄位 destination。必要欄位。destination 只能是下列其中一項:
gcs_destination

GcsDestination

要寫入輸出內容的 Google Cloud Storage 位置。

運送地址

單一商品的運送作業,從其中一個提貨地點到其中一個送達地點。運送作業才會視為完成,車輛必須先前往其中一個取貨地點 (並相應減少其備用容量),然後再前往其中一個送貨地點 (並相應增加其備用容量)。

欄位
display_name

string

使用者定義的運送貨物顯示名稱。長度上限為 63 個半形字元,可以使用 UTF-8 字元。

pickups[]

VisitRequest

與運送作業相關的取貨替代方案集合。如果未指定,車輛只需前往與送貨地點相對應的位置即可。

deliveries[]

VisitRequest

與運送作業相關的替代運送選項集合。如果未指定,車輛只需前往與接送地點相對應的位置即可。

load_demands

map<string, Load>

裝載貨物的負載需求 (例如重量、體積、貨架數量等)。對應檔中的鍵應為描述對應負載類型的 ID,最好也包含單位。例如:"weight_kg"、"volume_gallons"、"pallet_count" 等。如果指定的鍵未顯示在對應的載入中,系統會將該載入視為空值。

allowed_vehicle_indices[]

int32

可能執行這項運送作業的車輛組合。如果留空,則所有車輛都可能執行該動作。車輛會依據 ShipmentModelvehicles 清單中的索引指定。

costs_per_vehicle[]

double

指定透過每輛車輛運送這項貨物時產生的費用。如果已指定,則必須具備下列任一條件:

  • costs_per_vehicle_indices 相同的元素數量。costs_per_vehicle[i] 對應至車款的 costs_per_vehicle_indices[i] 車輛。
  • 元素數量必須與模型中的車輛數量相同。第 i 個元素對應至模型的車輛 #i。

這些費用必須與 penalty_cost 使用相同的單位,且不得為負值。如果沒有此類費用,請將這個欄位留空。

costs_per_vehicle_indices[]

int32

costs_per_vehicle 適用的車輛索引。如果不為空白,則必須與 costs_per_vehicle 具有相同數量的元素。車輛索引只能指定一次。如果車輛從 costs_per_vehicle_indices 中排除,其費用為零。

pickup_to_delivery_absolute_detour_limit

Duration

指定相較於從上車地點到送達地點的最短路徑,最大絕對繞路時間。如果指定了這個值,則必須為非負值,且運送作業至少必須包含一個取件和一個送達作業。

舉例來說,假設 t 是從所選取的取貨替代方案直接前往所選取的送貨替代方案所需的最短時間。接著,設定 pickup_to_delivery_absolute_detour_limit 會強制執行以下操作:

start_time(delivery) - start_time(pickup) <=
t + pickup_to_delivery_absolute_detour_limit

如果在同一筆訂單上同時指定相對和絕對限制,系統會針對每個可能的接送/取件組合,採用較嚴格的限制。自 2017 年 10 月起,系統只會在行程時間不受車輛影響時支援繞道。

pickup_to_delivery_time_limit

Duration

指定從商品開始取件到開始送達的時間長度上限。如果指定了這項屬性,則該值必須為非負值,且運送作業至少必須包含一個取件和一個送達作業。這不取決於你選取的取貨和送貨替代方案,也不取決於車輛速度。您可以同時指定這項限制和最大繞行限制:解決方案會遵循這兩項規範。

shipment_type

string

非空白字串,指定此出貨的「類型」。這項功能可用於定義 shipment_types 之間的不相容性或需求 (請參閱 ShipmentModel 中的 shipment_type_incompatibilitiesshipment_type_requirements)。

visit_types 不同,後者是針對單一造訪指定:屬於同一筆訂單的所有取貨/送貨都會共用相同的 shipment_type

label

string

指定此運送單的標籤。這個標籤會在對應 ShipmentRoute.Visitshipment_label 回應中回報。

ignore

bool

如果為 True,則略過這項出貨作業,但不會套用 penalty_cost

如果模型中含有任何 shipment_type_requirements,忽略出貨作業就會導致驗證錯誤。

系統允許忽略在 injected_first_solution_routesinjected_solution_constraint 中執行的運送作業;解決程序會從執行路線中移除相關的取貨/送貨拜訪。precedence_rules 參照的忽略出貨項目也會遭到忽略。

penalty_cost

double

如果無法完成運送,這筆罰款會加到路線的整體費用中。如果運送員前往其中一個提貨和送貨地點,系統就會將該筆訂單視為完成。費用可以使用模型中所有其他費用相關欄位使用的單位來表示,且必須為正值。

重要事項:如果未指定這項處罰,系統會視為無限,也就是必須完成出貨。

pickup_to_delivery_relative_detour_limit

double

指定相對於從上車地點到送達地點的最短路徑,相對繞路時間的上限。如果指定了這個值,則必須為非負值,且運送作業至少必須包含一個取件和一個送達作業。

舉例來說,假設 t 是從所選取的取貨替代方案直接前往所選取的送貨替代方案所需的最短時間。接著,設定 pickup_to_delivery_relative_detour_limit 會強制執行以下操作:

start_time(delivery) - start_time(pickup) <=
std::ceil(t * (1.0 + pickup_to_delivery_relative_detour_limit))

如果在同一筆訂單上同時指定相對和絕對限制,系統會針對每個可能的接送/取件組合,採用較嚴格的限制。自 2017 年 10 月起,系統只會在行程時間不受車輛影響時支援繞道。

載入

執行訪問時,如果是接送,系統可能會將預先定義的金額加到車輛負載量;如果是送貨,則會從車輛負載量中扣除該金額。這則訊息會定義這筆金額。詳情請參閱《load_demands》。

欄位
amount

int64

執行相應造訪的車輛載重量會有所不同。由於這是整數,建議使用者選擇適當的單位,以免精確度降低。必須大於或等於 0。

VisitRequest

可透過車輛完成的訪問要求:包含一個或兩個地理位置 (請參閱下方說明)、以時間窗口表示的開始和結束時間,以及服務時間長度 (車輛抵達取貨或送貨地點所需的時間)。

欄位
arrival_location

LatLng

車輛執行此 VisitRequest 時抵達的地理位置。如果運送模型含有時間距離矩陣,請勿指定 arrival_location

arrival_waypoint

Waypoint

車輛執行這項 VisitRequest 時抵達的路線點。如果運送模型含有時間距離矩陣,請勿指定 arrival_waypoint

departure_location

LatLng

車輛完成這個 VisitRequest 後的出發地點。如果與 arrival_location 相同,可以省略。如果運送模型含有時間距離矩陣,請勿指定 departure_location

departure_waypoint

Waypoint

車輛完成這個 VisitRequest 後的出發路徑點。如果與 arrival_waypoint 相同,可以省略。如果運送模型含有時間距離矩陣,請勿指定 departure_waypoint

tags[]

string

指定附加至造訪要求的標記。不得使用空字串或重複的字串。

time_windows[]

TimeWindow

限制造訪時間的時間區間。請注意,車輛可能會在到達時間回溯期過後離開,也就是說,到達時間 + 車程時間不一定會在回溯期內。如果車輛在 TimeWindow.start_time 之前抵達,乘客可能會等待一段時間。

如果沒有 TimeWindow,表示車輛可隨時執行這項拜訪。

時段必須不重疊,也就是說,每個時段都不能與其他時段重疊或相鄰,且必須依遞增順序排列。

只有在單一時間範圍內,才能設定 cost_per_hour_after_soft_end_timesoft_end_time

duration

Duration

行程時間,也就是車輛從抵達到離開所需的時間 (會加入可能的等候時間;請參閱 time_windows)。

cost

double

在車輛路線上為這項拜訪要求提供服務的費用。你可以使用這項功能,為每項替代取貨或運送服務支付不同的費用。這個成本必須與 Shipment.penalty_cost 使用相同的單位,且不得為負數。

load_demands

map<string, Load>

載入此造訪要求的需求。這與 Shipment.load_demands 欄位相同,但只會套用至這個 VisitRequest,而非整個 Shipment。這裡列出的請求會加入 Shipment.load_demands 中列出的請求。

visit_types[]

string

指定造訪類型。這項資訊可用於分配車輛完成這次拜訪所需的額外時間 (請參閱 Vehicle.extra_visit_duration_for_visit_type)。

一個類型只能出現一次。

label

string

指定這個 VisitRequest 的標籤。這個標籤會在回應中以對應的 ShipmentRoute.Visit 中的 visit_label 回報。

avoid_u_turns

bool

指定是否應避免在該地點的駕駛路線上進行 U 轉。系統會盡力避免 U 形迴轉,但無法保證完全避免。這是實驗性功能,行為可能會變更。

ShipmentModel

運送模型包含一組運送作業,必須由一組車輛執行,同時盡可能降低整體成本,也就是下列項目的總和:

  • 車輛路線的費用 (所有車輛的總時間費用、每趟行程費用和固定費用總和)。
  • 未完成出貨的處罰。
  • 運送作業的全球持續時間成本
欄位
shipments[]

Shipment

模型中必須執行的運送作業集合。

vehicles[]

Vehicle

可用於執行拜訪的車輛組合。

global_start_time

Timestamp

模型的全球開始和結束時間:系統不會將範圍外的時間視為有效時間。

模型的時間跨度不得超過一年,也就是 global_end_timeglobal_start_time 之間的時間差不得超過 31536000 秒。

使用 cost_per_*hour 欄位時,您可能會將這個時間範圍設為較短的間隔,以提升效能 (例如,如果您模擬單日,應將全域時間限制設為該日)。如果未設定,系統會預設使用 1970 年 1 月 1 日 00:00:00 UTC (即秒數:0,納秒數:0)。

global_end_time

Timestamp

如果未設定,系統會使用 1971 年 1 月 1 日 00:00:00 世界標準時間 (即秒數:31536000,奈秒:0) 做為預設值。

global_duration_cost_per_hour

double

整體企劃書的「全球時間長度」是指所有車輛最早有效開始時間和最晚有效結束時間的差異。使用者可以為該數量指派每小時成本,以便盡早完成工作。這個成本必須與 Shipment.penalty_cost 使用相同的單位。

duration_distance_matrices[]

DurationDistanceMatrix

指定模型中使用的時間和距離矩陣。如果這個欄位空白,系統會根據 use_geodesic_distances 欄位的值,改用 Google 地圖或大地測量距離。如果不是空白,use_geodesic_distances 就不會是 true,且 duration_distance_matrix_src_tagsduration_distance_matrix_dst_tags 都不能為空白。

使用範例:

  • 有兩個位置:locA 和 locB。
  • 1 輛車輛的路線起點和終點皆為 locA。
  • 在 locB 有 1 個上車地點要求。
model {
  vehicles { start_tags: "locA"  end_tags: "locA" }
  shipments { pickups { tags: "locB" } }
  duration_distance_matrix_src_tags: "locA"
  duration_distance_matrix_src_tags: "locB"
  duration_distance_matrix_dst_tags: "locA"
  duration_distance_matrix_dst_tags: "locB"
  duration_distance_matrices {
    rows {  # from: locA
      durations { seconds: 0 }   meters: 0    # to: locA
      durations { seconds: 100 } meters: 1000 # to: locB
    }
    rows {  # from: locB
      durations { seconds: 102 } meters: 990 # to: locA
      durations { seconds: 0 }   meters: 0   # to: locB
    }
  }
}
  • 有三個位置:locA、locB 和 locC。
  • 1 輛車輛從 locA 開始路線,並在 locB 結束,使用矩陣「fast」。
  • 1 輛車輛從 locB 開始路線,並在 locB 結束,使用矩陣「slow」。
  • 1 輛車輛從 locB 開始路線,並在 locB 結束,使用矩陣「fast」。
  • 在 locC 有 1 個取件訪問要求。
model {
  vehicles { start_tags: "locA" end_tags: "locB" start_tags: "fast" }
  vehicles { start_tags: "locB" end_tags: "locB" start_tags: "slow" }
  vehicles { start_tags: "locB" end_tags: "locB" start_tags: "fast" }
  shipments { pickups { tags: "locC" } }
  duration_distance_matrix_src_tags: "locA"
  duration_distance_matrix_src_tags: "locB"
  duration_distance_matrix_src_tags: "locC"
  duration_distance_matrix_dst_tags: "locB"
  duration_distance_matrix_dst_tags: "locC"
  duration_distance_matrices {
    vehicle_start_tag: "fast"
    rows {  # from: locA
      durations { seconds: 1000 } meters: 2000 # to: locB
      durations { seconds: 600 }  meters: 1000 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }   meters: 0    # to: locB
      durations { seconds: 700 } meters: 1200 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 702 } meters: 1190 # to: locB
      durations { seconds: 0 }   meters: 0    # to: locC
    }
  }
  duration_distance_matrices {
    vehicle_start_tag: "slow"
    rows {  # from: locA
      durations { seconds: 1800 } meters: 2001 # to: locB
      durations { seconds: 900 }  meters: 1002 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }    meters: 0    # to: locB
      durations { seconds: 1000 } meters: 1202 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 1001 } meters: 1195 # to: locB
      durations { seconds: 0 }    meters: 0    # to: locC
    }
  }
}
duration_distance_matrix_src_tags[]

string

定義時間長度和距離矩陣來源的標記;duration_distance_matrices(i).rows(j) 定義標記 duration_distance_matrix_src_tags(j) 與矩陣 i 中其他造訪之間的時間長度和距離。

標記對應至 VisitRequest.tagsVehicle.start_tags。給定的 VisitRequestVehicle 必須與這個欄位中僅有一個標記相符。請注意,Vehicle 的來源、目的地和矩陣標記可能相同;同樣地,VisitRequest 的來源和目的地標記也可能相同。所有標記都必須不同,且不得為空字串。如果這個欄位不為空白,duration_distance_matrices 就必須非空白。

duration_distance_matrix_dst_tags[]

string

定義時間和距離矩陣目的地的標記;duration_distance_matrices(i).rows(j).durations(k) (resp. duration_distance_matrices(i).rows(j).meters(k)) 會定義矩陣 i 中,從標記為 duration_distance_matrix_src_tags(j) 的造訪轉換為標記為 duration_distance_matrix_dst_tags(k) 的造訪所需的時間 (或距離)。

標記對應至 VisitRequest.tagsVehicle.start_tags。給定的 VisitRequestVehicle 必須與這個欄位中僅有一個標記相符。請注意,Vehicle 的來源、目的地和矩陣標記可能相同;同樣地,VisitRequest 的來源和目的地標記也可能相同。所有標記都必須不同,且不得為空字串。如果這個欄位不為空白,duration_distance_matrices 就必須非空白。

transition_attributes[]

TransitionAttributes

新增至模型的轉場屬性。

shipment_type_incompatibilities[]

ShipmentTypeIncompatibility

不相容的 shipment_types 組合 (請參閱 ShipmentTypeIncompatibility)。

shipment_type_requirements[]

ShipmentTypeRequirement

shipment_type 需求集 (請參閱 ShipmentTypeRequirement)。

precedence_rules[]

PrecedenceRule

模型中必須強制執行的優先順序規則集。

max_active_vehicles

int32

限制有效車輛數量上限。如果車輛的路線至少執行一筆運送作業,就會視為有效。在駕駛人數少於車輛數量,且車隊車輛種類不一的情況下,您可以使用這個選項限制路線數量。系統就會選取最適合的車輛子集。必須為正值。

DurationDistanceMatrix

指定從造訪和車輛起點到造訪和車輛終點的時間和距離矩陣。

欄位
rows[]

Row

指定時間長度和距離矩陣的資料列。必須與 ShipmentModel.duration_distance_matrix_src_tags 具有相同數量的元素。

vehicle_start_tag

string

標記定義這個時間長度和距離矩陣適用於哪些車輛。如果留空,則會套用至所有車輛,且只能有單一矩陣。

每個車輛啟動都必須與單一矩陣相符,也就是說,其中的 start_tags 欄位必須與矩陣的 vehicle_start_tag 相符 (且只相符一個矩陣)。

所有矩陣都必須有不同的 vehicle_start_tag

指定時間長度和距離矩陣的資料列。

欄位
durations[]

Duration

特定資料列的時間長度值。必須與 ShipmentModel.duration_distance_matrix_dst_tags 具有相同數量的元素。

meters[]

double

特定資料列的距離值。如果模型中沒有任何成本或限制參照距離,可以將這個屬性設為空白;否則,這個屬性必須包含與 durations 相同數量的元素。

PrecedenceRule

兩個事件之間的優先順序規則 (每個事件都是提貨或出貨):第二個事件必須在第一個事件開始後至少 offset_duration 才會開始。

多個優先順序可以參照相同 (或相關) 事件,例如「B 的取件發生在 A 送達後」和「C 的取件發生在 B 取件後」。

此外,優先順序只會在兩次出貨都執行時才會套用,否則會遭到忽略。

欄位
first_is_delivery

bool

指出「first」事件是否為放送事件。

second_is_delivery

bool

指出「第二」事件是否為傳送事件。

offset_duration

Duration

「first」和「second」事件之間的偏移量。可以是負值。

first_index

int32

「first」事件的出貨索引。必須指定這個欄位。

second_index

int32

「second」事件的出貨索引。必須指定這個欄位。

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     |       |           |         |         ||
  ||     |       |           |       |           |         |         ||
--++-----------------------------------------------------------------++-->
欄位
vehicle_index

int32

執行路線的車輛,可透過來源 ShipmentModel 中的索引識別。

vehicle_label

string

執行此路線的車輛標籤,等於 ShipmentModel.vehicles(vehicle_index).label (如有指定)。

vehicle_start_time

Timestamp

車輛開始行駛的時間。

vehicle_end_time

Timestamp

車輛完成路線的時間。

visits[]

Visit

代表路線的排序造訪序列。visits[i] 是路線的第 i 次造訪。如果這個欄位為空白,系統會將車輛視為未使用。

transitions[]

Transition

路線的轉場效果排序清單。

has_traffic_infeasibilities

bool

如果 OptimizeToursRequest.consider_road_traffic 設為 true,這個欄位表示系統會使用以交通狀況為依據的預估行程時間,預測路線時間的差異。在第一個訪客到達前或最後一個訪客離開後,可能沒有足夠的時間完成經過交通調整的移動、延誤和兩次造訪之間的休息時間,同時還要滿足訪客和車輛的時間限制。例如:

  start_time(previous_visit) + duration(previous_visit) +
  travel_duration(previous_visit, next_visit) > start_time(next_visit)

由於交通狀況,預估的到達時間 travel_duration(previous_visit, next_visit) 會增加,因此 next_visit 的到達時間可能會比目前的時間窗口晚。此外,由於預估的移動時間增加,且訪問或休息時間窗口受到限制,因此休息時間可能會與訪問時間重疊。

route_polyline

EncodedPolyline

路線的編碼折線表示法。只有在 OptimizeToursRequest.populate_polylines 設為 True 時,才會填入這個欄位。

breaks[]

Break

這條路線的車輛預定休息時間。breaks 序列代表時間間隔,每個間隔都從對應的 start_time 開始,持續 duration 秒。

metrics

AggregatedMetrics

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

route_costs

map<string, double>

路線的費用,依費用相關要求欄位細分。鍵是相對於輸入 OptimizeToursRequest 的 proto 路徑,例如「model.shipments.pickups.cost」,而值則是相應費用欄位產生的總費用,並在整個路線上進行匯總。換句話說,costs["model.shipments.pickups.cost"] 是路線上所有提貨費用的總和。這裡會詳細列出模型中定義的所有費用,但 TransitionAttributes 相關費用除外,因為這類費用自 2022 年 1 月起只會以匯總方式呈報。

route_total_cost

double

路線的總費用。費用圖表中所有費用的總和。

休息時間

代表執行中斷點的資料。

欄位
start_time

Timestamp

廣告插播的開始時間。

duration

Duration

休息時間長度。

EncodedPolyline

折線的編碼表示法。如要進一步瞭解多邊形編碼,請參閱以下網頁:https://developers.google.com/maps/documentation/utilities/polylinealgorithm https://developers.google.com/maps/documentation/javascript/reference/geometry#encoding

欄位
points

string

代表折線編碼點的字串。

轉移

在路徑上兩個事件之間的轉換。請參閱 ShipmentRoute 的說明。

如果車輛沒有 start_location 和/或 end_location,則對應的移動指標為 0。

欄位
travel_duration

Duration

這段期間的旅遊時間。

travel_distance_meters

double

轉換期間移動的距離。

traffic_info_unavailable

bool

當透過 OptimizeToursRequest.consider_road_traffic 要求流量,但無法為 Transition 擷取流量資訊時,這個布林值會設為 true。這可能是暫時性問題 (即時交通流量伺服器偶爾發生故障) 或永久性問題 (該位置沒有資料)。

delay_duration

Duration

套用至此轉場效果的延遲時間總和。如果有延遲時間,則會在下一個事件 (造訪或車輛結束) 之前的 delay_duration 秒開始計時。查看《TransitionAttributes.delay》。

break_duration

Duration

在這個轉換期間發生的片段持續時間總和 (如有)。每個廣告插播的開始時間和持續時間詳細資料會儲存在 ShipmentRoute.breaks 中。

wait_duration

Duration

在轉換期間等待的時間。等待時間長度與閒置時間相對應,不包含休息時間。另請注意,這段等待時間可能會分為數個不連續的間隔。

total_duration

Duration

轉場效果的總時間長度 (僅供參考)。等於:

  • 下次造訪 start_time (如果是最後一次轉換,則為 vehicle_end_time) - 這個轉換是 start_time
  • 如果 ShipmentRoute.has_traffic_infeasibilities 為 false,則下列條件也成立:`total_duration = travel_duration + delay_duration
  • break_duration + wait_duration`。
start_time

Timestamp

此轉場效果的開始時間。

route_polyline

EncodedPolyline

轉換期間所遵循路線的編碼折線表示法。只有在 populate_transition_polylines 設為 True 時,才會填入這個欄位。

vehicle_loads

map<string, VehicleLoad>

在這個轉換期間載入的車輛,每個類型都會顯示在該車輛的 Vehicle.load_limits 中,或是在這個路線上執行的某些運送作業中,有非零值的 Shipment.load_demands

在第一次轉換期間的負載,是車輛路線的起始負載。接著,在每次造訪後,系統會根據造訪是取件或送件,增加或減少造訪的 load_demands,以便載入下一個轉換。

VehicleLoad

針對特定類型,回報車輛在路線某處的實際負載量 (請參閱 Transition.vehicle_loads)。

欄位
amount

int64

車輛的負載量 (以指定類型為準)。負載單位通常會以類型表示。詳情請參閱《Transition.vehicle_loads》。

前往

在路線中執行的造訪。這項拜訪對應至 Shipment 的取貨或送貨。

欄位
shipment_index

int32

來源 ShipmentModelshipments 欄位的索引。

is_pickup

bool

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

visit_request_index

int32

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

start_time

Timestamp

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

load_demands

map<string, Load>

總訪客負載需求是出貨和訪客要求 load_demands 的總和。如果造訪是指向外送訂單,則值為負值。需求的回報類型與 Transition.loads 相同 (請參閱此欄位)。

detour

Duration

由於在造訪前路線上有其他貨件,以及由於時間窗口導致的潛在等待時間,因此產生額外的繞路時間。如果是送貨行程,系統會從對應的接送行程計算繞路距離,計算方式如下:

start_time(delivery) - start_time(pickup)
- (duration(pickup) + travel duration from the pickup location
to the delivery location).

否則,系統會根據車輛 start_location 計算該值,並等於:

start_time - vehicle_start_time - travel duration from
the vehicle's `start_location` to the visit.
shipment_label

string

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

visit_label

string

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

injected_solution_location_token

int32

代表造訪地點資訊的不透明權杖。

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

ShipmentTypeIncompatibility

根據 shipment_type 指定不同出貨之間的不相容性。系統會根據不相容模式,限制在同一條路線顯示不相容的貨件。

欄位
types[]

string

不相容類型的清單。兩個出貨項目在列出的 shipment_types 中不相容。

incompatibility_mode

IncompatibilityMode

套用至不相容項目的模式。

IncompatibilityMode

定義在同一條路線上,不相容的運送作業如何顯示。

列舉
INCOMPATIBILITY_MODE_UNSPECIFIED 未指定不相容模式。請一律不要使用這個值。
NOT_PERFORMED_BY_SAME_VEHICLE 在這種模式下,兩個不相容的貨物無法共用同一輛車輛。
NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY

對於兩個使用 NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY 不相容模式的不相容類型出貨:

  • 如果兩者都是僅接送 (不含送貨) 或僅送貨 (不含接送),則完全無法共用同一輛車。
  • 如果其中一個貨件是送貨,另一個是取貨,只要前者送達前後者取貨,兩者就能共用同一輛車輛。

ShipmentTypeRequirement

根據 shipment_type 指定不同出貨之間的規定。需求的具體內容則由需求模式定義。

欄位
required_shipment_type_alternatives[]

string

dependent_shipment_types 所需的替代運送類型清單。

dependent_shipment_types[]

string

所有貨物類型在 dependent_shipment_types 欄位中,至少需要有一種 required_shipment_type_alternatives 類型貨物,才能在同一條路線中進行訪查。

注意:系統不允許要求鏈結,例如 shipment_type 依附自身。

requirement_mode

RequirementMode

套用至需求的模式。

RequirementMode

定義路線上依附運送的顯示方式。

列舉
REQUIREMENT_MODE_UNSPECIFIED 未指定的規定模式。請一律不要使用這個值。
PERFORMED_BY_SAME_VEHICLE 在這種模式下,所有「依附」運送作業都必須與至少一個「必要」運送作業共用相同的車輛。
IN_SAME_VEHICLE_AT_PICKUP_TIME

IN_SAME_VEHICLE_AT_PICKUP_TIME 模式下,所有「從屬」貨件在取件時,至少需要有一個「必要」貨件。

因此,「依附」貨件取件必須具備下列其中一種條件:

  • 在路線後方,或
  • 在路線上先行取件的「必要」貨件,如果「必要」貨件有運送作業,則必須在「從屬」貨件取件後執行。
IN_SAME_VEHICLE_AT_DELIVERY_TIME 與先前相同,但「依附」運送作業必須在送達時,與「必要」運送作業一同運送。

SkippedShipment

指定解決方案中未執行的出貨作業詳細資料。對於簡單的情況和/或我們能夠找出略過的原因,我們會在此處回報原因。

欄位
index

int32

該索引會對應至來源 ShipmentModel 中的出貨索引。

label

string

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

reasons[]

Reason

列出略過運送的原因。請參閱 Reason 上方的留言。如果我們無法瞭解訂單遭到略過的原因,就不會設定原因。

原因

如果我們可以說明出貨作業未完成的原因,會列在這個頁面。如果所有車輛的原因不同,reason 就會有多個元素。跳過的出貨單不得有重複的原因,也就是說,除了 example_vehicle_index 以外,所有欄位都必須相同。範例:

reasons {
  code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  example_vehicle_index: 1
  example_exceeded_capacity_type: "Apples"
}
reasons {
  code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  example_vehicle_index: 3
  example_exceeded_capacity_type: "Pears"
}
reasons {
  code: CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT
  example_vehicle_index: 1
}

跳過的運送作業與所有車輛都不相容。每輛車輛的原因可能不同,但至少有一輛車輛的「蘋果」容量會超出 (包括車輛 1)、至少有一輛車輛的「梨」容量會超出 (包括車輛 3),且至少有一輛車輛的距離限制會超出 (包括車輛 1)。

欄位
code

Code

請參閱程式碼的註解。

example_exceeded_capacity_type

string

如果原因代碼為 DEMAND_EXCEEDS_VEHICLE_CAPACITY,請記錄超出容量的一種容量類型。

example_vehicle_index

int32

如果原因與貨物與車輛不相容有關,這個欄位會提供相關車輛的索引。

程式碼

用來識別原因類型的代碼。這裡的順序沒有意義。特別是,如果兩者都適用,它不會指出在解決方案中,某個原因會出現在另一個原因之前。

列舉
CODE_UNSPECIFIED 請勿使用此值。
NO_VEHICLE 模型中沒有車輛,因此無法運送所有貨物。
DEMAND_EXCEEDS_VEHICLE_CAPACITY 出貨需求超過某些容量類型的車輛容量,其中之一是 example_exceeded_capacity_type
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT

執行這項運送作業所需的最短距離 (即從車輛的 start_location 到運送作業的取貨和/或送達地點,以及到車輛的終點位置) 超過車輛的 route_distance_limit

請注意,我們會使用大地測量距離進行這項計算。

CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT

執行這項運送作業所需的最短時間 (包括行車時間、等待時間和服務時間) 超過車輛的 route_duration_limit

注意:系統會以最佳情況計算行程時間,也就是以測地線距離 x 36 公尺/秒 (約 130 公里/小時) 計算。

CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT 與上述相同,但我們只會比較最短行程時間和車輛的 travel_duration_limit
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS 如果車輛在最早的開始時間開始運送,則在最佳情況下 (請參閱 CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT 瞭解時間計算方式),車輛將無法執行這項運送作業:總時間會使車輛在最晚的結束時間過後才結束。
VEHICLE_NOT_ALLOWED 貨運的 allowed_vehicle_indices 欄位並未留空,且這輛車輛不屬於該貨運。

TimeWindow

時間窗可限制事件的時間,例如造訪的到達時間,或車輛的開始和結束時間。

硬性時間範圍邊界 start_timeend_time 會強制執行事件的最早和最晚時間,例如 start_time <= event_time <= end_time。軟性時間回溯期下限 soft_start_time 表示事件發生時機為 soft_start_time 或之後,發生時間與事件發生前 soft_start_time 的時間間隔成正比,軟性時間回溯期上限 soft_end_time 表示偏好在 soft_end_time 當天或之前發生事件,發生事件的時間越晚,所需成本就越高。soft_end_timestart_timeend_timesoft_start_timesoft_end_time 應在全球時間限制內 (請參閱 ShipmentModel.global_start_timeShipmentModel.global_end_time),並應遵守下列規定:

  0 <= `start_time` <= `end_time` and
  0 <= `start_time` <= `soft_start_time` and
  0 <= `soft_end_time` <= `end_time`.
欄位
start_time

Timestamp

硬性時段開始時間。如果未指定,則會設為 ShipmentModel.global_start_time

end_time

Timestamp

硬性時間範圍的結束時間。如果未指定,則會設為 ShipmentModel.global_end_time

soft_start_time

Timestamp

時間範圍的軟性開始時間。

soft_end_time

Timestamp

時間範圍的軟性結束時間。

cost_per_hour_before_soft_start_time

double

如果事件發生時間在 soft_start_time 之前,系統會將每小時費用加進模型中的其他費用,計算方式如下:

   max(0, soft_start_time - t.seconds)
                          * cost_per_hour_before_soft_start_time / 3600,
t being the time of the event.

這個費用必須為正值,且只有在已設定 soft_start_time 時才能設定這個欄位。

cost_per_hour_after_soft_end_time

double

如果事件發生在 soft_end_time 之後,系統會將每小時費用加進模型中的其他費用,計算方式如下:

   max(0, t.seconds - soft_end_time.seconds)
                    * cost_per_hour_after_soft_end_time / 3600,
t being the time of the event.

這個費用必須為正值,且只有在設定 soft_end_time 時才能設定這個欄位。

TransitionAttributes

指定路徑上兩次連續造訪之間的轉換屬性。同一個轉換可能會套用多個 TransitionAttributes:在這種情況下,所有額外費用會加總,並套用最嚴格的限制或限制 (遵循自然的「AND」語意)。

欄位
src_tag

string

定義這些屬性套用至 (src->dst) 轉場的組合。

來源訪客或車輛啟動活動的資料是否符合條件,取決於 VisitRequest.tagsVehicle.start_tags 是否包含 src_tag,或是不包含 excluded_src_tag (取決於這兩個欄位中哪一個非空白)。

excluded_src_tag

string

請參閱 src_tagsrc_tagexcluded_src_tag 中必須有一個值不為空白。

dst_tag

string

只有在 VisitRequest.tagsVehicle.end_tags 包含 dst_tag 或不包含 excluded_dst_tag 時,才會與目的地造訪或車輛結束相符 (取決於這兩個欄位中哪一個非空白)。

excluded_dst_tag

string

請參閱 dst_tagdst_tagexcluded_dst_tag 中必須有一個值不為空白。

cost

double

指定執行此轉換作業的費用。此值的單位與模型中的所有其他成本相同,且不得為負數。這筆費用會加上所有現有費用。

cost_per_kilometer

double

指定在執行這項轉換作業時,以每公里為單位的費用套用於行駛的距離。會加總車輛上指定的所有 Vehicle.cost_per_kilometer

distance_limit

DistanceLimit

指定執行此轉場效果時的移動距離限制。

自 2021 年 6 月起,我們只支援軟性上限。

delay

Duration

指定執行這項轉換時的延遲時間。

這項延遲一律會發生在完成來源造訪「後」和開始目的地造訪「前」

車輛

模擬出貨問題中的車輛。解決運送問題時,系統會為這輛車輛建立從 start_locationend_location 的路線。路線是指造訪記錄的序列 (請參閱 ShipmentRoute)。

欄位
display_name

string

使用者定義的車輛顯示名稱。長度上限為 63 個半形字元,可以使用 UTF-8 字元。

travel_mode

TravelMode

行駛模式會影響車輛可行駛的道路和速度。另請參閱 travel_duration_multiple

start_location

LatLng

車輛開始載運貨物的地理位置。如未指定,車輛會在第一趟上車地點開始行駛。如果運送模型含有時間和距離矩陣,請勿指定 start_location

start_waypoint

Waypoint

路徑點代表車輛在取件前所在的地理位置。如果未指定 start_waypointstart_location,車輛會在第一個上車地點開始行駛。如果運送模型含有時間和距離矩陣,請勿指定 start_waypoint

end_location

LatLng

車輛完成最後一次 VisitRequest 後的終點地理位置。如果未指定,車輛的 ShipmentRoute 會在完成最後一次 VisitRequest 後立即結束。如果運送模型含有時間和距離矩陣,請勿指定 end_location

end_waypoint

Waypoint

路標代表車輛完成最後一次 VisitRequest 後的終點地理位置。如果未指定 end_waypointend_location,車輛的 ShipmentRoute 會在完成最後一次 VisitRequest 後立即結束。如果運送模型含有時間和距離矩陣,請勿指定 end_waypoint

start_tags[]

string

指定附加至車輛路線起點的標記。

不得使用空字串或重複的字串。

end_tags[]

string

指定附加在車輛路線結尾的標記。

不得使用空字串或重複的字串。

start_time_windows[]

TimeWindow

車輛可能從出發地點出發的時間範圍。必須在全球時間限制範圍內 (請參閱 ShipmentModel.global_* 欄位)。如未指定,則除了這些全球時間限制外,沒有其他限制。

屬於相同重複欄位的時間範圍必須不重疊,也就是說,每個時間範圍都不能與其他時間範圍重疊或相鄰,且必須按時間順序排列。

只有在單一時間範圍內,才能設定 cost_per_hour_after_soft_end_timesoft_end_time

end_time_windows[]

TimeWindow

車輛抵達目的地所需的時間範圍。必須在全球時間限制範圍內 (請參閱 ShipmentModel.global_* 欄位)。如未指定,則除了這些全球時間限制外,沒有其他限制。

屬於相同重複欄位的時間範圍必須不重疊,也就是說,每個時間範圍都不能與其他時間範圍重疊或相鄰,且必須按時間順序排列。

只有在單一時間範圍內,才能設定 cost_per_hour_after_soft_end_timesoft_end_time

unloading_policy

UnloadingPolicy

車輛的卸載政策。

load_limits

map<string, LoadLimit>

車輛的容量 (例如重量、體積、貨架數量)。對應表中的鍵是負載類型的 ID,與 Shipment.load_demands 欄位的鍵一致。如果這個對應表中沒有特定鍵,則系統會將對應容量視為無限。

cost_per_hour

double

車輛費用:所有費用加總,且必須與 Shipment.penalty_cost 使用相同的單位。

車輛路線的每小時費用。這筆費用會套用到路線的總用時,包括行程時間、等候時間和拜訪時間。使用 cost_per_hour 而非 cost_per_traveled_hour 可能會導致額外的延遲。

cost_per_traveled_hour

double

車輛路線的每小時行駛費用。這項費用只會套用在路線的行程時間 (即 ShipmentRoute.transitions 中回報的時間),不包括等候時間和造訪時間。

cost_per_kilometer

double

車輛行駛路線的每公里費用。這筆費用會套用至 ShipmentRoute.transitions 中回報的距離,但不會套用至從單一 VisitRequestarrival_locationdeparture_location 之間隱含的任何移動距離。

fixed_cost

double

如果這輛車輛用於處理運送作業,就會收取固定費用。

used_if_route_is_empty

bool

這個欄位只會套用至路線未提供任何貨運服務的車輛。指出在這種情況下,是否應將車輛視為二手車。

如果為 true,即使車輛沒有運送任何貨物,也會從起點前往終點,且會考量從起點到終點的時間和距離成本。

否則,車輛不會從起點移動到終點,且系統不會為該車輛排定 break_rule 或延遲 (從 TransitionAttributes 開始)。在這種情況下,車輛的 ShipmentRoute 只包含車輛索引和標籤,不含其他資訊。

route_duration_limit

DurationLimit

限制會套用至車輛路線的總時間。在特定 OptimizeToursResponse 中,車輛的路線時間長度是 vehicle_end_timevehicle_start_time 的差異。

travel_duration_limit

DurationLimit

套用至車輛路線行駛時間的限制。在特定 OptimizeToursResponse 中,路線行程時間等於所有 transitions.travel_duration 的總和。

route_distance_limit

DistanceLimit

套用至車輛路線總距離的限制。在指定的 OptimizeToursResponse 中,路線距離是所有 transitions.travel_distance_meters 的總和。

extra_visit_duration_for_visit_type

map<string, Duration>

指定從 visit_types 字串到持續時間的對應項目。時間長度是指在指定 visit_types 的造訪中,除了 VisitRequest.duration 之外所需的時間。如果指定 cost_per_hour,這段額外的造訪時間會增加費用。鍵 (例如 visit_types) 不得為空字串。

如果造訪要求包含多種類型,地圖會為每種類型新增時間長度。

break_rule

BreakRule

說明要對這輛車輛強制執行的休息時間表。如果為空白,則不會為這輛車輛安排休息時間。

label

string

指定此車輛的標籤。這個標籤會在回應中以對應 ShipmentRoutevehicle_label 回報。

ignore

bool

如果為 true,used_if_route_is_empty 必須為 false,且此車輛將保持未使用狀態。

如果在 injected_first_solution_routes 中,運送作業是由已略過的車輛執行,則系統會在第一個解決方案中略過該作業,但可在回應中執行。

如果運送作業是由 injected_solution_constraint 中遭到忽略的車輛執行,且任何相關的接送/提貨作業都受到限制,必須留在車輛上 (也就是未放寬至 RELAX_ALL_AFTER_THRESHOLD 層級),系統會在回應中略過該作業。如果運送單有非空白的 allowed_vehicle_indices 欄位,且所有允許的車輛都遭到忽略,系統就會在回應中略過該運送單。

travel_duration_multiple

double

指定可用於增加或減少此車輛行駛時間的乘數。舉例來說,如果將此值設為 2.0,表示這輛車輛的速度較慢,且行駛時間是標準車輛的兩倍。這個係數不會影響造訪時間長度。但如果指定 cost_per_hourcost_per_traveled_hour,則會影響費用。必須介於 [0.001, 1000.0] 的範圍之間。如果未設定,則車輛為標準車輛,且這個倍數會視為 1.0。

警告:在套用這個倍數後,但在執行任何數值運算之前,系統會將行程時間四捨五入至最近的秒數,因此倍數過小可能會導致精確度降低。

另請參閱下方的 extra_visit_duration_for_visit_type

DurationLimit

定義車輛路線的時間上限。可以是硬式或軟式。

定義軟性上限欄位時,必須一併定義軟性上限門檻及其相關費用。

欄位
max_duration

Duration

硬性限制,限制片段長度不得超過 max_duration。

soft_max_duration

Duration

軟性限制不會強制執行時間長度上限,但違反規定時會導致路線產生費用。這項費用會與模型中定義的其他費用相加,並使用相同的單位。

如果已定義,soft_max_duration 不得為負數。如果也定義了 max_duration,soft_max_duration 必須小於 max_duration。

quadratic_soft_max_duration

Duration

軟性限制不會強制執行最大時間長度限制,但如果違反限制,路線就會產生費用,且費用會隨著時間呈現平方關係。這項費用會與模型中定義的其他費用相加,並使用相同的單位。

如果已定義,quadratic_soft_max_duration 不得為負數。如果同時定義了 max_durationquadratic_soft_max_duration 必須小於 max_duration,且兩者差距不得超過一天:

max_duration - quadratic_soft_max_duration <= 86400 seconds

cost_per_hour_after_soft_max

double

違反 soft_max_duration 門檻時,每小時產生的費用。如果時間長度低於門檻,額外費用為 0,否則費用取決於時間長度,如下所示:

  cost_per_hour_after_soft_max * (duration - soft_max_duration)

費用必須為非負值。

cost_per_square_hour_after_quadratic_soft_max

double

違反 quadratic_soft_max_duration 門檻時,每平方小時的費用。

如果時間長度低於門檻,額外費用為 0,否則費用取決於時間長度,如下所示:

  cost_per_square_hour_after_quadratic_soft_max *
  (duration - quadratic_soft_max_duration)^2

費用必須為非負值。

LoadLimit

定義適用於車輛的負載限制,例如「這輛貨車只能載運 3500 公斤」。詳情請參閱《load_limits》。

欄位
soft_max_load

int64

負載的軟性限制。詳情請參閱《cost_per_unit_above_soft_max》。

cost_per_unit_above_soft_max

double

如果載重量超過這輛車輛路線的 soft_max_load,系統會依據下列費用懲罰機制收取費用 (每輛車輛只會收取一次):(載重量 - soft_max_load) * cost_per_unit_above_soft_max。所有費用加總起來,且必須與 Shipment.penalty_cost 使用相同的單位。

start_load_interval

Interval

車輛在路線起點的允許載客量間隔。

end_load_interval

Interval

車輛在路線結束時可接受的載客量間隔。

max_load

int64

可接受的最大負載量。

時間間隔

可接受的負載量間隔。

欄位
min

int64

可接受的最低負載。必須大於或等於 0。如果同時指定這兩個值,min 必須小於或等於 max

max

int64

可接受的最大負載。必須大於或等於 0。如果未指定,則此訊息不會限制最大負載。如果同時指定這兩個值,min 必須小於或等於 max

TravelMode

車輛可使用的行駛模式。

這些應為 Google 地圖平台路線偏好 API 的部分交通模式,請參閱:https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode

列舉
TRAVEL_MODE_UNSPECIFIED 未指定的交通方式,等同於 DRIVING
DRIVING 與駕駛路線相對應的交通模式 (汽車、...)。
WALKING 步行路線對應的交通方式。

UnloadingPolicy

車輛卸貨方式的政策。僅適用於同時包含自取和運送的貨件。

其他運送作業可在路線上的任何位置執行,不受 unloading_policy 影響。

列舉
UNLOADING_POLICY_UNSPECIFIED 未指定卸貨政策;必須在相應的接送後才可送達。
LAST_IN_FIRST_OUT 必須以相反的順序進行配送
FIRST_IN_FIRST_OUT 運送作業必須按照取貨順序進行

途經點

封裝路線點。路標會標示 VisitRequest 的到達和離開位置,以及車輛的起點和終點。

欄位
side_of_road

bool

選用設定。表示這個路線控點的位置,是為了讓車輛偏好停靠在道路的特定側邊。設定這個值後,路線會經過該位置,讓車輛停在偏離道路中心的路邊。這個選項不適用於「步行」交通模式。

聯集欄位 location_type。表示位置的方式有很多種。location_type 只能是下列其中一項:
location

Location

使用地理座標指定的點,包括選用的標頭。

place_id

string

與路標相關聯的 POI 地點 ID。