deTrack/elasticroute

免费、智能的物流路由,现在支持PHP。

2.0beta1 2019-07-25 07:16 UTC

This package is auto-updated.

Last update: 2024-09-04 16:54:39 UTC


README

Latest Stable Version Build Status Coverage Status Total Downloads License

ElasticRoute for PHP

ElasticRoute Logo

自2021年1月2日起,我们将停止支持此客户端库,并将不再提供更新。如果您目前正在使用此客户端库,基于它的集成仍应能正常工作。未来,我们建议使用我们的API文档(仪表板路由引擎)来构建您的集成。

解决大规模旅行推销员/车队路由问题的API

您有一支仅包含10辆车的车队,要服务城市中的500个地点。一些车辆仅在白天可用。一些停靠点只能在夜间提供服务。您会如何解决这个问题?

您不需要这么做。只需向我们提供一个停靠点、车辆和仓库的数组,我们将为您完成繁重的工作。路由即服务!

BETA版本:ElasticRoute可以免费使用,直到2021年4月30日!

前言

ElasticRoute根据您的需求提供两个API,本文档的不同部分根据您希望与之交互的API而有所不同。

  • 路由引擎API – 如果您已经拥有自己的车队管理系统,并且只想使用ElasticRoute来解决路由问题并检查解决方案。这实际上是使用ElasticRoute在无头环境中,也称为“路由即服务”。
  • 仪表板API – 如果您的团队使用ElasticRoute网络应用程序在地图上查看停靠点和车辆,并且您希望将来自现有应用程序的数据推送到ElasticRoute仪表板。

无论您如何使用ElasticRoute,此客户端库都可以与这两个服务进行交互。

快速入门指南(路由引擎API)

如果您有一个单独的应用程序来在地图、表格或其他您偏好的方式上显示结果,请参考本节,只要您不是直接使用ElasticRoute仪表板即可。

使用composer安装

composer require detrack/elasticroute

在您的代码中设置默认API密钥(您可以从网络应用程序的仪表板中获取它)

use Detrack\ElasticRoute\Plan;
Plan::$defaultApiKey = "my_super_secret_key";

创建一个新的Plan对象并给它一个名称/ID

$plan = new Plan();
$plan->id = "my_first_plan";

给我们一个停靠点的数组

$plan->stops = [
    [
        "name" => "Changi Airport",
        "address" => "80 Airport Boulevard (S)819642",
    ],
    [
        "name" => "Gardens By the Bay",
        "lat" => "1.281407",
        "lng" => "103.865770",
    ],
    // add more stops!
    // both human-readable addresses and machine-friendly coordinates work!
];

给我们一个您可用的车辆的数组

$plan->vehicles = [
    [
        "name" => "Van 1"
    ],
    [
        "name" => "Van 2"
    ],
];

给我们一个仓库的数组

$plan->depots = [
    [
        "name" => "Main Warehouse",
        "address" => "61 Kaki Bukit Ave 1 #04-34, Shun Li Ind Park Singapore 417943",
    ],
];

设置您的国家和时区(用于准确的地标编码)

$plan->generalSettings["country"] = "SG";
$plan->generalSettings["timezone"] = "Asia/Singapore";

调用solve()并将结果保存到变量中

$solution = $plan->solve();

检查解决方案!

foreach($solution->stops as $stop){
    // $stop is an instance of \Detrack\ElasticRoute\Stop, more details below
    print("Stop ".$stop->name." will be served by ".$stop->assign_to." at time".$stop->eta);
}

快速提示

  • 单个停靠点、车辆和仓库可以作为关联数组或Detrack\ElasticRoute\StopDetrack\ElasticRoute\VehicleDetrack\ElasticRoute\Depot的实例传递到Plan中。相应的属性与关联数组的键相同。
  • 解决计划返回一个Detrack\ElasticRoute\Solution实例,它具有与Detrack\ElasticRoute\Plan大部分相同的属性,但不是相同的函数(请参阅高级使用)
  • 与创建Plan不同,Solution->stops|vehicles|depots返回相应的StopVehicleDepot实例,而不是关联数组。
  • 此方法创建的停靠点(附加到Detrack\ElasticRoute\Plan对象)在ElasticRoute网络应用程序的仪表板中**无法**看到。请参阅仪表板API。

高级使用

设置时间约束

可以使用fromtill键/属性来设置停止点和车辆的时间约束

$morningOnlyStop = new Stop();
$morningOnlyStop->name  = "Morning Delivery 1";
$morningOnlyStop->from = 900;
$morningOnlyStop->till = 1200;
// add address and add to plan...
$morningShiftVan = new Vehicle();
$morningShiftVan->name = "Morning Shift 1";
$morningShiftVan->from = 900;
$morningShiftVan->till = 1200;
// add to plan and solve...

从任一类别中删除fromtill键会导致它们在Plan->generalSettings关联数组中默认为avail_fromavail_to键,这些键默认为5001700

设置家仓库

可以为停止点和车辆设置“家仓库”。停止点的仓库表示车辆在到达之前必须在哪里取货,而车辆的仓库表示车辆行程的起点和终点(这隐式地分配了车辆可以接受的可能的任务)。默认情况下,对于每个停止点和车辆,如果未指定仓库字段,我们将假设它为第一个仓库。

$commonStop = new Stop();
$commonStop->name = "Normal Delivery 1";
$commonStop->depot = "Main Warehouse";
// set stop address and add to plan...
$rareStop = new Stop();
$rareStop->name = "Uncommon Delivery 1";
$rareStop->depot = "Auxillary Warehouse";
// set stop address and add to plan...
$plan->vehicles = [
    [
        "name" => "Van 1",
        "depot" => "Main Warehouse",
    ],
    [
        "name" => "Van 2",
        "depot" => "Auxillary Warehouse",
    ],
];
$plan->depots = [
    [
        "name" => "Main Warehouse",
        "address" => "Somewhere",
    ],
    [
        "name" => "Auxillary Warehouse",
        "address" => "Somewhere else",
    ]
];
// solve and get results...

重要: depot字段的值必须与同一计划中具有相同名称的匹配Depot对应!

设置载重约束

每辆车都可以设置累积最大重量、体积和(非累积)座位容量,这些可以用来确定在它必须返回仓库之前可以服务多少个停靠点。相反,每个停靠点也可以分配重量、体积和座位负载。对于停靠点是weight_loadvolume_loadseating_load,对于车辆是weight_capacityvolume_capacityseating_capacity

备用连接类型(适用于大型数据集)

默认情况下,所有请求都是同步方式进行的。大多数小型到中型数据集可以在10秒内解决,但对于生产使用,你可能需要在以下方式中首先关闭HTTP连接并轮询更新

$plan = new Plan();
$plan->connectionType = "poll";
// do the usual stuff
$solution = $plan->solve();
while($solution->status != "planned"){
    $solution->refresh();
    sleep(2);
}

connectionType设置为"poll"会导致服务器在解析请求数据后立即返回响应。您可以在使用refresh()方法获取更新时使用statusprogress属性来监控状态。

此外,将connectionType设置为"webhook"也会导致服务器将响应的副本发布到您指定的webhook。可以通过Plan对象的webhook属性指定webhook的确切位置。

快速入门指南(仪表板API)

如果您希望将数据推送到仪表板API,以便组织中的其他用户可以审查,请参阅本节。

如果尚未安装库,请安装它

composer require detrack/elasticroute

服务围绕着Detrack\ElasticRoute\DashboardClient对象。它负责将您的Detrack\ElasticRoute\StopDetrack\ElasticRoute\Vehicle推送到弹性路由仪表板,在那里您的团队可以审查和编辑。

设置默认API密钥(从仪表板获取,此密钥可以用于路由引擎API和仪表板API)

use Detrack\ElasticRoute\DashboardClient;

DashboardClient::$defaultApiKey = "your-super-secret-key";

接下来,您可以创建一系列停靠点,可以是关联数组或Detrack\ElasticRoute\Stop对象的实例

use Detrack\ElasticRoute\Stop;

$stop1 = [
    'name' => 'SUTD',
    'address' => '8 Somapah Road Singapore 487372',
];
$stop2 = [
    'name' => 'Changi Airport',
    'address' => '80 Airport Boulevard (S)819642',
],
$stop3 = new Stop();
$stop3->name = 'Gardens By the Bay';
$stop3->address = '18 Marina Gardens Drive Singapore 018953';
$stop4 = new Stop();
$stop4->name = 'Singapore Zoo';
$stop4->address = '80 Mandai Lake Road Singapore 729826';

$stops = [$stop1, $stop2, $stop3, $stop4];

使用uploadStopsOnDate方法将它们推送到仪表板

$client = new DashboardClient();
$client->uploadStopsOnDate($stops, date('Y-m-d'));

这将设置今天的仪表板以显示这些停靠点。使用第二个参数以YYYY-MM-DD格式传递一个字符串,以更改您想要上传这些停靠点的日期。

要检索仪表板上的现有停靠点,请使用listAllStopsOnDate方法

$stops = $client->listAllStopsOnDate(date('Y-m-d'));

默认情况下,这将在该日期列出100个停靠点。传递第二个参数以指定您想要检索的数量

$stops = $client->listAllStopsOnDate(date('Y-m-d'), 50);

并第三个参数用于分页

$stops = $client->listAllStopsOnDate(date('Y-m-d'), 50, 2);

要删除日期上的所有停靠点,请使用deleteAllStopsOnDate方法

$client->deleteAllStopsOnDate(date('Y-m-d'));

Stop对象还具有用于对单个停靠点执行CRUD操作的方法

$stop = new Stop();
$stop->client = $client; // instance of Detrack\ElasticRoute\DashboardClient
$stop->name = "Test Stop";
$stop->address = "8 Somapah Road";
$stop->date = date('Y-m-d'); // the date must be present if CRUDing individual stops

// create – will throw error if a stop with the same name already exists on the same date
$stop->create();

// read – will return null if a stop with specified name is not found on date (but the object itself is not changed)
$stop->retrieve();

// update – will throw error if a stop with the specified name is not found on date
$stop->name = "Singapore Zoo";
$stop->address = "80 Mandai Lake Road Singapore 729826";
$stop->update();

// delete – will throw error if a stop with the specified name is not found on date
$stop->delete();

车辆

车辆也可以通过使用 uploadVehicles 方法推送到仪表板(在仪表板设置中找到)

use Detrack\ElasticRoute\Vehicle;

$vehicle1 = [
	'name' => 'Van 1',
]

$vehicle2 = new Vehicle();
$vehicle2->name = 'Van 1';

$vehicles = [$vehicle1, $vehicle2];

$client->uploadVehicles($vehicles);

Vehicle 对象还具有对单个停靠点进行 CRUD 操作的方法

$vehicle = new Vehicle();
$vehicle->client = $client; // instance of Detrack\ElasticRoute\DashboardClient
$vehicle->name = "Test Van";
$vehicle->avail_from = 900;
$vehicle->avail_till = 1500;

// create – will throw error if a vehicle with the same name already exists on the same account
$vehicle->create();

// read – will return null if a vehicle with specified name is not found (but the object itself will not be changed)
$vehicle->retrieve();

// update – will throw error if a vehicle with the specified name is not found on the same account
$vehicle->avail_till = 1700;
$vehicle->update();

// delete – will throw error if a stop with the specified name is not found on date
$vehicle->delete();

规划

可以使用 startPlanningOnDate 方法启动给定日期/日期的规划过程

$client->startPlanningOnDate(date('Y-m-d'));

这将自动在仪表板上启动规划过程。请注意,与路由引擎 API 不同,您 不能 通过仪表板 API 检查路线规划的结果,您或您的团队必须使用 ElasticRoute 网络应用程序打开仪表板来检查解决方案。