Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# CHANGELOG

## 3.0.0
CHANGED:
- (breaking) Updated OSRM to 6.0.0
- Dockerfile now uses Node 24.12 on debian trixie
- Valhalla source now uses JS binding instead of child process

UPDATED:
- Updated all package.json dependencies to last versions (08/01/2026)

## 2.3.1
FIXED:
- invalid isochrone geometries
Expand Down
9 changes: 3 additions & 6 deletions docker/distributions/debian/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
### TODO : Supprimer la compilation et l'installation de Valhalla dès que l'on aura un binding NodeJS pour lui et donc repasser sur une image node
FROM ghcr.io/valhalla/valhalla@sha256:6fb108a960bdc63c12b1c92ab04517a0c56a019ef45c9b9c8cf847d8de9db72b
FROM node:24.12-trixie-slim

### Mise à jour des
### Mise à jour des paquets
RUN apt-get update && apt-get upgrade -y
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \
apt-get install -y nodejs

### Dossier contenant la configuration de Road2
WORKDIR /home/docker/config
Expand All @@ -19,7 +16,7 @@ COPY documentation/apis ./documentation/apis
COPY *.json ./

### Installation des dépendances de l'application NodeJS
RUN npm install && npm install -g mocha eslint jsdoc nyc
RUN npm install --no-optional && npm install -g mocha eslint jsdoc nyc

### Volume partagé pour lire les données
VOLUME ["/home/docker/data"]
Expand Down
32 changes: 17 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "road2",
"version": "2.2.8",
"version": "3.0.0",
"description": "Calcul d'itinéraire",
"author": "RDEV - IGN",
"main": "src/js/road2.js",
Expand All @@ -16,22 +16,23 @@
"debug": "env NODE_ENV=debug node --inspect=0.0.0.0:9229 ./src/js/road2.js"
},
"dependencies": {
"@mapbox/polyline": "1.1.1",
"@turf/turf": "6.5.0",
"assert": "2.0.0",
"@mapbox/polyline": "1.2.1",
"@turf/turf": "7.3.0",
"assert": "2.1.0",
"cors": "2.8.5",
"express": "4.18.2",
"got": "11.8.2",
"helmet": "6.0.1",
"https-proxy-agent": "5.0.1",
"log4js": "6.7.1",
"nconf": "0.12.0",
"proj4": "2.8.0",
"swagger-ui-express": "4.6.3"
"express": "5.2.1",
"got": "14.6.6",
"helmet": "8.1.0",
"https-proxy-agent": "7.0.6",
"log4js": "6.9.1",
"nconf": "0.13.0",
"proj4": "2.20.2",
"swagger-ui-express": "5.0.1"
},
"optionalDependencies": {
"osrm": "5.26.0",
"pg": "8.9.0"
"@project-osrm/osrm": "6.0.0",
"pg": "8.16.3",
"@valhallajs/valhallajs": "3.6.1"
},
"devDependencies": {
"sinon": "^7.2.7",
Expand All @@ -46,7 +47,8 @@
"express",
"log4js",
"nconf",
"osrm",
"@project-osrm/osrm",
"@valhallajs/valhallajs",
"pg",
"@mapbox/polyline",
"@turf/turf",
Expand Down
16 changes: 8 additions & 8 deletions src/js/sources/osrmSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ module.exports = class osrmSource extends Source {

// Chargement du fichier OSRM
if (OSRM) {
this._osrm = new OSRM(osrmFile);
this._osrm = new OSRM({path: osrmFile, algorithm: "CH"});
super.connected = true;
} else {
throw errorManager.createError("OSRM is not available");
Expand Down Expand Up @@ -311,7 +311,7 @@ module.exports = class osrmSource extends Source {
LOGGER.error("osrm error for nearest :");
LOGGER.error(err);
reject("Internal OSRM error");

} else {

LOGGER.debug("osrm response for nearest :");
Expand Down Expand Up @@ -569,7 +569,7 @@ module.exports = class osrmSource extends Source {
}
nativeSteps[k].intersections = nativeIntersections;

// Add maneuver extra
// Add maneuver extra
let nativeManeuver = {};
// Test with hasOwnProperty because it can be 0 inside this property
if (currentOsrmRouteStep.maneuver.hasOwnProperty("bearing_before")) {
Expand All @@ -585,7 +585,7 @@ module.exports = class osrmSource extends Source {
}
nativeManeuver.location = [location.x, location.y];
}

nativeSteps[k].maneuver = nativeManeuver;

}
Expand Down Expand Up @@ -616,7 +616,7 @@ module.exports = class osrmSource extends Source {
* Ce traitement est placé ici car c'est à la source de renvoyer une réponse adaptée au proxy.
* C'est cette fonction qui doit vérifier le contenu de la réponse. Une fois la réponse envoyée
* au proxy, on considère qu'elle est correcte.
* @param {nearestRequest} nearestRequest - Objet nearestRequest
* @param {nearestRequest} nearestRequest - Objet nearestRequest
* @param {osrmResponse} osrmResponse - Objet osrmResponse, réponse renvoyée par osrm
*
*/
Expand All @@ -633,13 +633,13 @@ module.exports = class osrmSource extends Source {
// Création de la réponse
let nearestResponse = new NearestResponse(nearestRequest.resource, nearestRequest.coordinates);

// Récupération de l'ensemble des points de la réponse d'OSRM
// Récupération de l'ensemble des points de la réponse d'OSRM
if (osrmResponse.waypoints) {
LOGGER.debug(osrmResponse);
if (osrmResponse.waypoints.length < 1) {
throw errorManager.createError(" OSRM response is invalid: the number of waypoints is lower than 1. ");
} else {

for (let i=0; i < osrmResponse.waypoints.length; i++) {

if (osrmResponse.waypoints[i].location) {
Expand Down Expand Up @@ -668,7 +668,7 @@ module.exports = class osrmSource extends Source {
} else {
throw errorManager.createError(" OSRM response is invalid: no waypoints. ");
}

return nearestResponse;

}
Expand Down
88 changes: 35 additions & 53 deletions src/js/sources/valhallaSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ const Step = require('../responses/step');
const Distance = require('../geography/distance');
const Duration = require('../time/duration');
const errorManager = require('../utils/errorManager');
const { exec } = require('child_process');
const turf = require('@turf/turf');
const { Actor } = require("@valhallajs/valhallajs")

// Création du LOGGER
const log4js = require('log4js');
const LOGGER = log4js.getLogger("VALHALLASOURCE");
// Récupération de la valeur du maxBuffer en variable d'environment variable ou valorisation par défaut (1MB)
const maxBuffer = process.env.EXEC_MAX_BUFFER_SIZE ? parseInt(process.env.EXEC_MAX_BUFFER_SIZE, 10) : 1024 * 1024;
// Récupération de la valeur du timeout pour l'execution du valhalla_service en variable d'environnement ou valorisation par défaut (0)
const execTimeout = process.env.EXEC_TIMEOUT ? parseInt(process.env.EXEC_TIMEOUT, 10) : 0;

/**
*
Expand Down Expand Up @@ -195,39 +191,32 @@ module.exports = class valhallaSource extends Source {
costingOptionsString += "}}";
// Permet de grandement se simplifier le parsing !!
const optionsString = `"directions_options":{"format":"osrm"}`;
const commandString = `valhalla_service ${this._configuration.storage.config} route '{${locationsString},${costingString},${costingOptionsString},${optionsString}}' `;
const options = { maxBuffer: maxBuffer, timeout: execTimeout };
const commandString = `{${locationsString},${costingString},${costingOptionsString},${optionsString}}`;
LOGGER.info(commandString);

return new Promise( (resolve, reject) => {

try {
exec(commandString, options, (err, stdout, stderr) => {

// Du moment qu'OSRM a répondu, on considère que la source est joignable
this.state = "green";

if (err) {
// mais on ne renvoie pas l'erreur à l'utilisateur
reject(errorManager.createError(" No path found ", 404));
LOGGER.error("valhalla error for route :");
LOGGER.error(err);

} else {
Actor.fromConfigFile(this._configuration.storage.config).then((valhallaActor) => {
valhallaActor.route(commandString).then((valhallaResponse) => {
// Du moment que Valhalla a répondu, on considère que la source est joignable
this.state = "green";

LOGGER.debug("valhalla response for route :");
LOGGER.debug(stdout);
LOGGER.debug(valhallaResponse);

try {
resolve(this.writeRouteResponse(request, stdout));
resolve(this.writeRouteResponse(request, valhallaResponse));
} catch (error) {
reject(error);
}

}

}).catch((err) => {
// mais on ne renvoie pas l'erreur à l'utilisateur
reject(errorManager.createError(" No path found ", 404));
LOGGER.error("valhalla error for route :");
LOGGER.error(err);
});
});

} catch (error) {
// Pour une raison que l'on ignore, la source n'est plus joignable
this.state = "red";
Expand Down Expand Up @@ -303,39 +292,32 @@ module.exports = class valhallaSource extends Source {
const contoursString = `"contours":[{"${request.costType}":${costValue}}]`;
const reverseString = `"reverse":${reverse}`;
const polygonsString = `"polygons":true`;
const commandString = `valhalla_service ${this._configuration.storage.config} isochrone '{${locationsString},${costingString},${costingOptionsString},${contoursString},${reverseString},${polygonsString}}' `;
const options = { maxBuffer: maxBuffer, timeout: execTimeout };
const commandString = `{${locationsString},${costingString},${costingOptionsString},${contoursString},${reverseString},${polygonsString}}`;
LOGGER.info(commandString);

return new Promise( (resolve, reject) => {

try {
exec(commandString, options, (err, stdout, stderr) => {

// Du moment qu'OSRM a répondu, on considère que la source est joignable
this.state = "green";

if (err) {
// mais on ne renvoie pas l'erreur à l'utilisateur
LOGGER.error("valhalla error for route :");
LOGGER.error(err);
reject(errorManager.createError(" No path found ", 404));

} else {

LOGGER.debug("valhalla response for iso :");
LOGGER.debug(stdout);

try {
resolve(this.writeIsochroneResponse(request, stdout));
} catch (error) {
reject(error);
}

}

});

Actor.fromConfigFile(this._configuration.storage.config).then((valhallaActor) => {
valhallaActor.isochrone(commandString).then((valhallaResponse) => {
// Du moment que Valhalla a répondu, on considère que la source est joignable
this.state = "green";

LOGGER.debug("valhalla response for iso :");
LOGGER.debug(valhallaResponse);

try {
resolve(this.writeIsochroneResponse(request, valhallaResponse));
} catch (error) {
reject(error);
}
}).catch((err) => {
// mais on ne renvoie pas l'erreur à l'utilisateur
reject(errorManager.createError(" No path found ", 404));
LOGGER.error("valhalla error for route :");
LOGGER.error(err);
});
});
} catch (error) {
// Pour une raison que l'on ignore, la source n'est plus joignable
this.state = "red";
Expand Down
Loading