此场景通过简单的 费用参数。这是最简单的路线优化操作模式, 确保在指定时间范围内访问所有经停点。
以下示例展示了一个基本场景,其中包含一辆车辆和三笔运输,所有这些运输均来自一个名为仓库的单个位置。
查看示例请求
{ "populatePolylines": true, "populateTransitionPolylines": true, "model": { "globalStartTime": "2023-01-13T16:00:00-08:00", "globalEndTime": "2023-01-14T16:00:00-08:00", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0, "costPerHour": 40.0 } ] } }
路由优化请求字段
正如概览中所述,最重要的路线优化请求
属性为 vehicles
和 shipments
。
除了车辆和运单之外,该请求还包含以下内容 字段:
多段线
populatePolylines
和 populateTransitionPolylines
用于指定是否使用路由
优化应返回多段线。
该服务使用 Maps JS 多段线编解码器对多段线进行编码,该编解码器表示
使用可打印的 ASCII 字符的二进制多段线数据。您可以使用
交互式多段线编码器实用程序,用于直观呈现
路线优化。本指南中的示例设置了 populatePolylines
和
将 populateTransitionPolylines
设为 true,但根据其他指南将 false 设为 false,
来缩减响应大小
有关编码的说明,请参阅编码多段线算法格式。 格式。
全球时间限制
model.globalStartTime
和 model.globalEndTime
设置为任意 24
小时。这样,输出时间戳更易于解读。
造访地点
示例请求仅使用 model.shipments[].pickups[].arrivalLocation
和
model.shipments[].deliveries[].arrivalLocation
。还有一个
departureLocation
属性(适用于车辆离开当前地点的情况)
与到达地点不同,例如设有入口的停车场
在建筑物的一侧,在另一侧有一个出口。在此指南及后续指南中,我们假定到达点和出发点相同。
到达和出发时间 waypoint
也存在,作为 latLng
的替代选项。
Waypoint
字段支持使用 Google 地点 ID 来替代 LatLng
,
还可以指定车辆的朝向。请参阅参考文档
(REST、gRPC)。
示例中的限制
此场景通过以下几种方式限制优化器:
- 所有活动都必须在全局开始时间与结束时间之间完成。 在这种情况下,开始时间和结束时间是一个非常宽松的约束条件, 而且全球范围较广。
- 所有发货都必须完成。执行上述操作时,
shipments
没有指明处罚费用。 - 在车辆上设置
costPerKilometer
和costPerHour
。
费用在费用模型参数中进行说明。
路由优化响应属性
查看对示例请求的响应
{ "routes": [ { "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:36:41Z", "visits": [ { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-14T00:02:30Z", "detour": "150s" }, { "isPickup": true, "startTime": "2023-01-14T00:05:00Z", "detour": "300s" }, { "startTime": "2023-01-14T00:11:25Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-14T00:19:29Z", "detour": "503s" }, { "shipmentIndex": 2, "startTime": "2023-01-14T00:29:02Z", "detour": "1324s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:02:30Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:05:00Z", "routePolyline": {} }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-14T00:07:30Z", "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "travelDuration": "234s", "travelDistanceMeters": 793, "waitDuration": "0s", "totalDuration": "234s", "startTime": "2023-01-14T00:15:35Z", "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "travelDuration": "323s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "323s", "startTime": "2023-01-14T00:23:39Z", "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "travelDuration": "209s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "209s", "startTime": "2023-01-14T00:33:12Z", "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@RWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@STY@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" }, "metrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "travelSteps": [ { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "227s", "distanceMeters": 794, "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "duration": "233s", "distanceMeters": 791, "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "duration": "322s", "distanceMeters": 1205, "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "duration": "208s", "distanceMeters": 666, "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "vehicleDetour": "2201s", "routeCosts": { "model.vehicles.cost_per_hour": 24.455555555555556, "model.vehicles.cost_per_kilometer": 34.57 }, "routeTotalCost": 59.025555555555556 } ], "totalCost": 59.025555555555556, "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-14T00:00:00Z", "latestVehicleEndTime": "2023-01-14T00:36:41Z", "totalCost": 59.025555555555556, "costs": { "model.vehicles.cost_per_kilometer": 34.57, "model.vehicles.cost_per_hour": 24.455555555555556 } } }
路线优化响应包含一个顶级 routes
字段,该字段用于
表示建议的路线,每辆车对应一条路线。因为这个示例
本指南中的请求仅指定了一辆车,routes
包含一辆车
ShipmentRoute
条消息。
ShipmentRoute
个房源
ShipmentRoute
消息类型的两个最重要的属性是
visits
和transitions
。
每个 Visit
均表示已完成以下某个订单的自提或送货:
请求消息的 VisitRequest
。一次访问就是有效将工作分配给
在某些地点和时间由车辆完成。
每个 Transition
表示从一个位置行驶到
继续。中转可在车辆的起点和终点之间发生,
位置和车辆端点。
如需重建车辆的完整路线,必须将 ShipmentRoute
的 visits
和 transitions
合并。字段组合为
车辆活动代码如下所示:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
ShipmentRoute
始终比 visits
多一个 transitions
,因为
车辆必须从出发地前往首次造访的起始地点
以及从最后一次访问到路线结束时的终点位置
。如果车辆缺少开始位置或结束位置,仍然会有
比 visits
多 transitions
,因为第一次或最后一次访问的位置是
分别用作车辆的起点或终点位置。
在此示例中,前三次提货访问之间存在转换 距离和持续时间为零,因为这三个上车点 在请求中共用同一个营业地点。
如需了解详情,请参阅 ShipmentRoute
参考文档(REST、gRPC)
。
简单的航点顺序优化
正如此示例所示,路线优化将访问建模为
并且不具有航点或停靠点的概念,
实体。不过,可以将经停点或航点表示为运单
且只能提供 1 个VisitRequest
作为自提或送餐服务。车辆仍必须分配 costPerHour
或 costPerKilometer
,以便优化器找到最佳路线(而不是找到任何可行路线)。