@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
178 lines (177 loc) • 8.2 kB
JavaScript
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";
export class RouteResultJobEditor extends RouteResultEditorBase {
assignJobs(agentIndex, jobIndexes, newPriority) {
return __awaiter(this, void 0, void 0, function* () {
this.validateAgent(agentIndex);
this.validateJobs(jobIndexes, agentIndex);
for (const jobIndex of jobIndexes) {
this.setJobPriority(jobIndex, newPriority);
yield this.assignJob(jobIndex, agentIndex);
}
return true;
});
}
removeJobs(jobIndexes) {
return __awaiter(this, void 0, void 0, function* () {
this.validateJobs(jobIndexes);
for (const jobIndex of jobIndexes) {
yield this.removeJob(jobIndex);
}
return true;
});
}
addNewJobs(agentIndex, jobs) {
return __awaiter(this, void 0, void 0, function* () {
let jobsRaw = jobs.map(job => job.getRaw());
this.validateAgent(agentIndex);
this.validateNewJobs(jobsRaw);
yield this.addNewJobsToAgent(agentIndex, jobsRaw);
return true;
});
}
assignJob(jobIndex, agentIndex) {
return __awaiter(this, void 0, void 0, function* () {
let jobInfo = this.result.getJobInfoByIndex(jobIndex);
let newAgentSolution = this.result.getAgentSolutionByIndex(agentIndex);
if (newAgentSolution && jobInfo) {
yield this.removeJobFromExistingAgent(jobInfo);
yield this.addJobToExistingAgent(agentIndex, jobIndex);
}
if (newAgentSolution && !jobInfo) {
yield this.addJobToExistingAgent(agentIndex, jobIndex);
}
if (!newAgentSolution && jobInfo) {
yield this.removeJobFromExistingAgent(jobInfo);
yield this.addJobToNonExistingAgent(agentIndex, jobIndex);
}
if (!newAgentSolution && !jobInfo) {
yield this.addJobToNonExistingAgent(agentIndex, jobIndex);
}
});
}
removeJob(jobIndex) {
return __awaiter(this, void 0, void 0, function* () {
let jobInfo = this.result.getJobInfoByIndex(jobIndex);
if (jobInfo) {
yield this.removeJobFromExistingAgent(jobInfo);
}
else {
this.result.getRawData().properties.issues.unassigned_jobs =
this.result.getRawData().properties.issues.unassigned_jobs.filter((nextJobIndex) => nextJobIndex !== jobIndex);
}
});
}
addNewJobsToAgent(agentIndex, jobs) {
return __awaiter(this, void 0, void 0, function* () {
let existingAgentSolution = this.result.getAgentSolutionByIndex(agentIndex);
let initialJobsCount = this.result.getRawData().properties.params.jobs.length;
this.result.getRawData().properties.params.jobs.push(...jobs);
let newAgentInput = this.addJobsToAgent(agentIndex, jobs.map((job, index) => initialJobsCount + index), existingAgentSolution);
let optimizedRouterPlan = yield this.optimizeRoute(newAgentInput);
this.updateAgent(optimizedRouterPlan, agentIndex);
});
}
addJobToNonExistingAgent(agentIndex, jobIndex) {
return __awaiter(this, void 0, void 0, function* () {
let newAgentInput = this.addJobsToAgent(agentIndex, [jobIndex]);
let optimizedRouterPlan = yield this.optimizeRoute(newAgentInput);
this.updateAgent(optimizedRouterPlan, agentIndex);
});
}
addJobToExistingAgent(agentIndex, jobIndex) {
return __awaiter(this, void 0, void 0, function* () {
let existingAgentSolution = this.result.getAgentSolutionByIndex(agentIndex);
let newAgentInput = this.addJobsToAgent(agentIndex, [jobIndex], existingAgentSolution);
let optimizedRouterPlan = yield this.optimizeRoute(newAgentInput);
this.updateAgent(optimizedRouterPlan, agentIndex);
});
}
removeJobFromExistingAgent(jobInfo) {
return __awaiter(this, void 0, void 0, function* () {
let existingAgentSolution = jobInfo.getAgent();
let newAgentInput = this.removeJobFromAgent(existingAgentSolution, jobInfo.getActions()[0].getJobIndex());
this.addUnassignedJob(jobInfo);
if (newAgentInput.agentShipmentIndexes.size == 0 && newAgentInput.agentJobIndexes.size == 0) {
this.removeAgent(existingAgentSolution.getAgentIndex());
}
else {
let optimizedRouterPlan = yield this.optimizeRoute(newAgentInput);
this.updateAgent(optimizedRouterPlan, existingAgentSolution.getAgentIndex());
}
});
}
addJobsToAgent(agentIndex, jobIndexes, existingAgent) {
let optimizedAgentInput = this.generateOptimizeAgentInput(agentIndex, existingAgent);
jobIndexes.forEach(jobIndex => {
optimizedAgentInput.agentJobIndexes.add(jobIndex);
});
return optimizedAgentInput;
}
removeJobFromAgent(existingAgent, jobIndex) {
let optimizedAgentInput = this.generateOptimizeAgentInput(existingAgent.getAgentIndex(), existingAgent);
optimizedAgentInput.agentJobIndexes.delete(jobIndex);
return optimizedAgentInput;
}
validateJobs(jobIndexes, agentIndex) {
if (jobIndexes.length == 0) {
throw new Error("No jobs provided");
}
if (!this.checkIfArrayIsUnique(jobIndexes)) {
throw new Error("Jobs are not unique");
}
jobIndexes.forEach((jobIndex) => {
let jobInfo = this.result.getJobInfoByIndex(jobIndex);
if (jobInfo == undefined) {
this.validateJobExists(jobIndex);
}
if (agentIndex != undefined) {
if ((jobInfo === null || jobInfo === void 0 ? void 0 : jobInfo.getAgent().getAgentIndex()) == agentIndex) {
throw new Error(`Job with index ${jobIndex} already assigned to agent with index ${agentIndex}`);
}
}
});
}
validateJobExists(jobIndex) {
let jobFound = this.getJobByIndex(jobIndex);
if (!jobFound) {
throw new Error(`Job with index ${jobFound} not found`);
}
else {
let isUnassignedJob = this.result.getRawData().properties.issues.unassigned_jobs.includes(jobIndex);
if (!isUnassignedJob) {
throw new Error(`Job with id ${jobIndex} is invalid`);
}
}
}
validateNewJobs(jobs) {
if (jobs.length == 0) {
throw new Error("No jobs provided");
}
if (!this.checkIfArrayIsUnique(jobs)) {
throw new Error("Jobs are not unique");
}
jobs.forEach((job) => {
if (job.id == undefined) {
throw new Error("Job id is undefined");
}
});
}
addUnassignedJob(jobInfo) {
this.generateEmptyUnassignedJobsIfNeeded();
this.result.getRawData().properties.issues.unassigned_jobs.push(jobInfo.getActions()[0].getJobIndex());
}
setJobPriority(jobIndex, newPriority) {
if (newPriority != undefined) {
this.result.getRawData().properties.params.jobs[jobIndex].priority = newPriority;
}
}
}