@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
107 lines (106 loc) • 4.29 kB
JavaScript
/**
* Shared helper for managing requirements on jobs and shipments
*/
export class RequirementHelper {
static createAssignAgentRequirement(agentIndex) {
return `${this.ASSIGN_AGENT_PREFIX}${agentIndex}`;
}
static ensureRequirementsArray(item) {
if (!item.requirements) {
item.requirements = [];
}
}
static addRequirement(requirements, req) {
if (!requirements.includes(req)) {
requirements.push(req);
}
}
static removeRequirement(requirements, req) {
const index = requirements.indexOf(req);
if (index !== -1) {
requirements.splice(index, 1);
}
}
static markAsUnassigned(item) {
this.ensureRequirementsArray(item);
this.addRequirement(item.requirements, this.UNASSIGNED_REQ);
}
static assignToAgent(item, agentIndex) {
const assignAgentReq = this.createAssignAgentRequirement(agentIndex);
this.ensureRequirementsArray(item);
this.removeRequirement(item.requirements, this.UNASSIGNED_REQ);
this.addRequirement(item.requirements, assignAgentReq);
}
// ===== Batch operations =====
static markItemsAsUnassigned(items, indexes) {
for (const index of indexes) {
if (items[index]) {
this.markAsUnassigned(items[index]);
}
}
}
static assignItemsToAgent(items, indexes, agentIndex) {
for (const index of indexes) {
if (items[index]) {
this.assignToAgent(items[index], agentIndex);
}
}
}
static markExistingUnassignedJobs(context, jobs) {
var _a;
const unassignedJobs = (_a = context.getRawData().properties.issues) === null || _a === void 0 ? void 0 : _a.unassigned_jobs;
if (unassignedJobs) {
this.markItemsAsUnassigned(jobs, unassignedJobs);
}
}
static markExistingUnassignedShipments(context, shipments) {
var _a;
const unassignedShipments = (_a = context.getRawData().properties.issues) === null || _a === void 0 ? void 0 : _a.unassigned_shipments;
if (unassignedShipments) {
this.markItemsAsUnassigned(shipments, unassignedShipments);
}
}
static markRemainingJobsWithAgentRequirement(context, jobs, excludeIndexes) {
for (let i = 0; i < jobs.length; i++) {
if (excludeIndexes.includes(i))
continue;
const agentIndexForJob = context.getAgentIndexForJob(i);
if (agentIndexForJob === undefined)
continue;
this.assignToAgent(jobs[i], agentIndexForJob);
}
}
static markRemainingShipmentsWithAgentRequirement(context, shipments, excludeIndexes) {
for (let i = 0; i < shipments.length; i++) {
if (excludeIndexes.includes(i))
continue;
const agentIndexForShipment = context.getAgentIndexForShipment(i);
if (agentIndexForShipment === undefined)
continue;
this.assignToAgent(shipments[i], agentIndexForShipment);
}
}
static extendAgentTimeWindows(agent) {
var _a, _b, _c;
const startTime = (_c = (_b = (_a = agent === null || agent === void 0 ? void 0 : agent.time_windows) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : 0;
agent.time_windows = [[startTime, 4102444800]];
}
static restrictAssignmentsToTargetSet(items, targetIndexes) {
for (let index = 0; index < items.length; index++) {
const item = items[index];
if (!item) {
continue;
}
if (targetIndexes.has(index)) {
delete item.requirements;
continue;
}
this.ensureRequirementsArray(item);
this.addRequirement(item.requirements, this.NON_ASSIGNABLE_REQUIREMENT);
}
}
}
RequirementHelper.UNASSIGNED_REQ = "unassigned";
RequirementHelper.ASSIGN_AGENT_PREFIX = "assign-agent-";
// TODO optimize: replace NON_ASSIGNABLE marker-based filtering with a cheaper scoped planning input.
RequirementHelper.NON_ASSIGNABLE_REQUIREMENT = "NON_ASSIGNABLE";