UNPKG

@geoapify/route-planner-sdk

Version:

TypeScript SDK for the Geoapify Route Planner API. Supports route optimization, delivery planning, and timeline visualization in browser and Node.js

169 lines (168 loc) 9.03 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { RouteResultEditorBase } from "./route-result-editor-base"; import { RoutePlanner } from "../../route-planner"; import { Utils } from "../utils"; export class RouteResultShipmentEditor extends RouteResultEditorBase { assignShipments(agentIndex, shipmentIndexes, newPriority) { var _a; return __awaiter(this, void 0, void 0, function* () { this.validateAgent(agentIndex); this.validateShipments(shipmentIndexes, agentIndex); for (const shipmentIndex of shipmentIndexes) { this.setShipmentPriority(shipmentIndex, newPriority); } const inputDataCopy = Utils.cloneObject(this.result.getRawData().properties.params); if ((_a = this.result.getRawData().properties.issues) === null || _a === void 0 ? void 0 : _a.unassigned_shipments) { this.markShipmentsUnassigned(inputDataCopy.shipments, this.result.getRawData().properties.issues.unassigned_shipments); } this.markShipmentsForAgent(inputDataCopy.shipments, shipmentIndexes, agentIndex); this.markRemainingShipmentsWithAgentRequirement(inputDataCopy.shipments, shipmentIndexes); this.addAgentCapabilities(inputDataCopy.agents); const planner = new RoutePlanner(this.result.getOptions(), inputDataCopy); const newResult = yield planner.plan(); this.updateResult(newResult); return true; }); } removeShipments(shipmentIndexes) { var _a; return __awaiter(this, void 0, void 0, function* () { this.validateShipments(shipmentIndexes); const inputDataCopy = Utils.cloneObject(this.result.getRawData().properties.params); this.markShipmentsUnassigned(inputDataCopy.shipments, shipmentIndexes); if ((_a = this.result.getRawData().properties.issues) === null || _a === void 0 ? void 0 : _a.unassigned_shipments) { this.markShipmentsUnassigned(inputDataCopy.shipments, this.result.getRawData().properties.issues.unassigned_shipments); } this.markRemainingShipmentsWithAgentRequirement(inputDataCopy.shipments, shipmentIndexes); this.addAgentCapabilities(inputDataCopy.agents); const planner = new RoutePlanner(this.result.getOptions(), inputDataCopy); const newResult = yield planner.plan(); this.updateResult(newResult); return true; }); } markShipmentsUnassigned(shipments, shipmentIndexes) { shipmentIndexes.forEach(shipmentIndex => { if (shipments[shipmentIndex]) { if (!shipments[shipmentIndex].requirements) { shipments[shipmentIndex].requirements = []; } if (!shipments[shipmentIndex].requirements.includes(this.unassignedReq)) { shipments[shipmentIndex].requirements.push(this.unassignedReq); } } }); } markRemainingShipmentsWithAgentRequirement(shipments, shipmentIndexes) { for (let i = 0; i < shipments.length; i++) { if (!shipmentIndexes.includes(i)) { // This is a remaining shipment, find which agent it belongs to const shipmentInfo = this.result.getShipmentInfoByIndex(i); if (shipmentInfo) { const agentIndex = shipmentInfo.getAgent().getAgentIndex(); const assignAgentReq = `${this.assignAgentReqStart}${agentIndex}`; if (!shipments[i].requirements) { shipments[i].requirements = []; } if (!shipments[i].requirements.includes(assignAgentReq)) { shipments[i].requirements.push(assignAgentReq); } } } } } addNewShipments(agentIndex, shipments) { var _a; return __awaiter(this, void 0, void 0, function* () { let shipmentsRaw = shipments.map(shipment => shipment.getRaw()); this.validateAgent(agentIndex); this.validateNewShipments(shipmentsRaw); // Add new shipments to the original data (permanent change) const initialShipmentsCount = this.result.getRawData().properties.params.shipments.length; this.result.getRawData().properties.params.shipments.push(...shipmentsRaw); // Get the indexes of the newly added shipments const newShipmentIndexes = shipmentsRaw.map((_, index) => initialShipmentsCount + index); // Clone the input data for planning const inputDataCopy = Utils.cloneObject(this.result.getRawData().properties.params); // Apply temporary requirements and capabilities for planning if ((_a = this.result.getRawData().properties.issues) === null || _a === void 0 ? void 0 : _a.unassigned_shipments) { this.markShipmentsUnassigned(inputDataCopy.shipments, this.result.getRawData().properties.issues.unassigned_shipments); } this.markShipmentsForAgent(inputDataCopy.shipments, newShipmentIndexes, agentIndex); this.markRemainingShipmentsWithAgentRequirement(inputDataCopy.shipments, newShipmentIndexes); this.addAgentCapabilities(inputDataCopy.agents); const planner = new RoutePlanner(this.result.getOptions(), inputDataCopy); const newResult = yield planner.plan(); this.updateResult(newResult); return true; }); } validateShipments(shipmentIndexes, agentIndex) { if (shipmentIndexes.length == 0) { throw new Error("No shipments provided"); } if (!this.checkIfArrayIsUnique(shipmentIndexes)) { throw new Error("Shipments are not unique"); } shipmentIndexes.forEach((shipmentIndex) => { let shipmentInfo = this.result.getShipmentInfoByIndex(shipmentIndex); if (shipmentInfo == undefined) { this.validateShipmentExists(shipmentIndex); } if (agentIndex != undefined) { if ((shipmentInfo === null || shipmentInfo === void 0 ? void 0 : shipmentInfo.getAgent().getAgentIndex()) == agentIndex) { throw new Error(`Shipment with index ${shipmentIndex} already assigned to agent with index ${agentIndex}`); } } }); } validateShipmentExists(shipmentIndex) { let shipmentFound = this.getShipmentByIndex(shipmentIndex); if (!shipmentFound) { throw new Error(`Shipment with index ${shipmentIndex} not found`); } else { let isUnassignedShipment = this.result.getRawData().properties.issues.unassigned_shipments.includes(shipmentIndex); if (!isUnassignedShipment) { throw new Error(`Shipment with index ${shipmentIndex} is invalid`); } } } validateNewShipments(shipments) { if (shipments.length == 0) { throw new Error("No shipments provided"); } if (!this.checkIfArrayIsUnique(shipments)) { throw new Error("Shipments are not unique"); } } setShipmentPriority(jobIndex, newPriority) { if (newPriority != undefined) { this.result.getRawData().properties.params.shipments[jobIndex].priority = newPriority; } } markShipmentsForAgent(shipments, shipmentIndexes, agentIndex) { shipmentIndexes.forEach(shipmentIndex => { if (shipments[shipmentIndex]) { const assignAgentReq = `assign-agent-${agentIndex}`; if (!shipments[shipmentIndex].requirements) { shipments[shipmentIndex].requirements = []; } if (shipments[shipmentIndex].requirements.includes('unassigned')) { shipments[shipmentIndex].requirements.splice(shipments[shipmentIndex].requirements.indexOf('unassigned'), 1); } if (!shipments[shipmentIndex].requirements.includes(assignAgentReq)) { shipments[shipmentIndex].requirements.push(assignAgentReq); } } }); } }