salix/back/methods/osrm-config/optimize.js

96 lines
3.5 KiB
JavaScript
Raw Normal View History

const UserError = require('vn-loopback/util/user-error');
const axios = require('axios');
module.exports = Self => {
Self.remoteMethod('optimize', {
description: 'Return optimized coords',
accessType: 'READ',
accepts: [{
arg: 'addressIds',
type: 'array',
required: true
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/optimize`,
verb: 'GET'
}
});
Self.optimize = async addressIds => {
const models = Self.app.models;
try {
2024-12-09 09:01:59 +00:00
const osrmConfig = await models.OsrmConfig.findOne();
if (!osrmConfig) throw new UserError(`OSRM service is not configured`);
let coords = [];
2024-12-09 13:45:31 +00:00
const address = await models.Address.findById(32308); // Aquí irá el address asociada a la zona
if (address.latitude && address.longitude) {
coords.push({
2024-12-09 13:45:31 +00:00
addressId: address.id,
latitude: address.latitude.toFixed(6),
longitude: address.longitude.toFixed(6)
});
}
2024-12-09 13:45:31 +00:00
for (const addressId of addressIds) {
const address = await models.Address.findById(addressId);
if (address.latitude && address.longitude) {
coords.push({
addressId,
latitude: address.latitude.toFixed(6),
longitude: address.longitude.toFixed(6)
});
}
}
const concatCoords = coords
.map(coord => `${coord.longitude},${coord.latitude}`)
.join(';');
const response = await axios.post(`
2024-12-09 13:45:31 +00:00
${osrmConfig.url}/trip/v1/driving/${concatCoords}?source=first&roundtrip=true
`);
2024-12-09 09:01:59 +00:00
const tolerance = osrmConfig.tolerance;
for (waypoint of response.data.waypoints) {
const longitude = waypoint.location[0];
const latitude = waypoint.location[1];
const matchedAddress = coords.find(coord =>
coord.position === undefined &&
Math.abs(coord.latitude - latitude) <= tolerance &&
Math.abs(coord.longitude - longitude) <= tolerance
);
if (matchedAddress)
matchedAddress.position = waypoint.waypoint_index;
}
coords.sort((a, b) => {
const posA = a.position !== undefined ? a.position : Infinity;
const posB = b.position !== undefined ? b.position : Infinity;
return posA - posB;
});
const coordsString = coords
.map(item => `point=${item.latitude},${item.longitude}`)
.join('&');
return {
coords,
view: `https://graphhopper.com/maps/?${coordsString}&profile=small_truck`
};
} catch (err) {
switch (err.response?.data?.code) {
case 'NoTrips':
throw new UserError('No trips found because input coordinates are not connected');
case 'NotImplemented':
throw new UserError('This request is not supported');
case 'InvalidOptions':
throw new UserError('Invalid options or too many coordinates');
default:
throw err;
}
}
};
};