Skip to content

Commit

Permalink
OSRM routing request seems to work. TODO:
Browse files Browse the repository at this point in the history
* check result to see if every property is valid and exact.
* adapt getcapabilities to OSRM API capabilities.
  • Loading branch information
XavDmz committed Jan 17, 2024
1 parent d1998ef commit 300c00f
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 45 deletions.
2 changes: 1 addition & 1 deletion docker/distributions/debian/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ RUN apt-get update && \
libsqlite3-mod-spatialite libzmq3-dev libczmq-dev

### Installation prime-server
COPY --from=build /usr/local/lib/libprime_server.so.0.7.0 /usr/lib/libprime_server.so.0.0.0
COPY --from=build /usr/local/lib/libprime_server.so.0.7.1 /usr/lib/libprime_server.so.0.0.0
COPY --from=build /usr/local/lib/libprime_server.so.0 /usr/lib/libprime_server.so.0
COPY --from=build /usr/local/lib/libprime_server.so /usr/lib/libprime_server.so

Expand Down
117 changes: 83 additions & 34 deletions src/js/apis/osrm/1.0.0/controller/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
const log4js = require('log4js');

const polyline = require('@mapbox/polyline');
const Turf = require('@turf/turf');

const copyManager = require('../../../../utils/copyManager')
const copyManager = require('../../../../utils/copyManager');
const Distance = require('../../../../geography/distance');
const Duration = require('../../../../time/duration');
const errorManager = require('../../../../utils/errorManager');
const NearestRequest = require('../../../../requests/nearestRequest');
const Point = require('../../../../geometry/point');
const RouteRequest = require('../../../../requests/routeRequest');

var LOGGER = log4js.getLogger("CONTROLLER");
let LOGGER = log4js.getLogger("CONTROLLER");

module.exports = {

Expand All @@ -36,9 +34,8 @@ module.exports = {
let end = {};
let profile;
let optimization;
let tmpStringCoordinates;
let coordinatesSequence;
let defaultProjection;
let askedProjection;

LOGGER.debug("checkRouteParameters()");

Expand Down Expand Up @@ -68,8 +65,8 @@ module.exports = {

// Get route operation to check some things
let routeOperation = resource.getOperationById("route");
defaultProjection = routeOperation.getParameterById("projection").defaultValueContent;
LOGGER.debug("default crs: " + defaultProjection);
askedProjection = routeOperation.getParameterById("projection").defaultValueContent;
LOGGER.debug("default crs: " + askedProjection);


// Profile and Optimization
Expand Down Expand Up @@ -113,17 +110,22 @@ module.exports = {
LOGGER.debug("raw coordinates:");
LOGGER.debug(parameters.coordinates);

let rawStringPattern = /^(-?\d+(\.\d+)?,-?\d+(\.\d+)?;){1,}-?\d+(\.\d+)?,-?\d+(\.\d+)?$/;
let rawStringPattern = /^-?\d+(\.\d+)?,-?\d+(\.\d+)?(;-?\d+(\.\d+)?,-?\d+(\.\d+)?)+$/;
let polylinePattern = /^polyline\(\S+\)$/;

// TODO : extract coordinates in a single format
if (rawStringPattern.test(parameters.coordinates)) {
coordinatesSequence = []
const coordinatesMatchList = parameters.coordinates.matchAll(/(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?)/g)
for (const matchItem in coordinatesMatchList) {
LOGGER.debug("coordinates are expressed in list format");
coordinatesSequence = [];
const coordinatesMatchList = parameters.coordinates.matchAll(/(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?)/g);
LOGGER.debug("coordinates matches list:");
LOGGER.debug(coordinatesMatchList);
for (const matchItem of coordinatesMatchList) {
LOGGER.debug("coordinates match:");
LOGGER.debug(matchItem);
coordinatesSequence.push([parseFloat(matchItem[1]), parseFloat(matchItem[2])]);
}
} else if (polylinePattern.test(parameters.coordinates)) {
LOGGER.debug("coordinates are expressed in polyline format");
coordinatesSequence = polyline.decode(parameters.coordinates);
} else {
throw errorManager.createError(" Parameter 'coordinates' is invalid: does not match allowed formats", 400);
Expand All @@ -136,12 +138,12 @@ module.exports = {
parameters.start = coordinatesSequence[0].join(",");
LOGGER.debug("user start:");
LOGGER.debug(parameters.start);
let validity = routeOperation.getParameterById("start").check(parameters.start, defaultProjection);
let validity = routeOperation.getParameterById("start").check(parameters.start, askedProjection);
if (validity.code !== "ok") {
throw errorManager.createError(" Parameter 'start' is invalid: " + validity.message, 400);
} else {
LOGGER.debug("user start valide")
start = new Point(coordinatesSequence[0][0], coordinatesSequence[0][1], defaultProjection);
start = new Point(coordinatesSequence[0][0], coordinatesSequence[0][1], askedProjection);
LOGGER.debug("user start in road2' object:");
LOGGER.debug(start);
}
Expand All @@ -156,7 +158,7 @@ module.exports = {
throw errorManager.createError(" Parameter 'end' is invalid: " + validity.message, 400);
} else {
LOGGER.debug("user end valide")
end = new Point(coordinatesSequence[coordinatesSequence.length-1][0], coordinatesSequence[coordinatesSequence.length-1][1], defaultProjection);
end = new Point(coordinatesSequence[coordinatesSequence.length-1][0], coordinatesSequence[coordinatesSequence.length-1][1], askedProjection);
LOGGER.debug("user end in road2' object:");
LOGGER.debug(end);
}
Expand Down Expand Up @@ -190,14 +192,14 @@ module.exports = {
finalIntermediates = finalIntermediates.concat(coordinatesSequence[coordinatesSequence.length - 2].join(","));

// Check coordinates validity
let validity = routeOperation.getParameterById("intermediates").check(finalIntermediates, defaultProjection);
let validity = routeOperation.getParameterById("intermediates").check(finalIntermediates, askedProjection);
if (validity.code !== "ok") {
throw errorManager.createError(" Parameter 'coordinates' is invalid: " + validity.message, 400);
} else {

LOGGER.debug("valid intermediates");

if (!routeOperation.getParameterById("intermediates").convertIntoTable(finalIntermediates, routeRequest.intermediates, defaultProjection)) {
if (!routeOperation.getParameterById("intermediates").convertIntoTable(finalIntermediates, routeRequest.intermediates, askedProjection)) {
throw errorManager.createError(" Parameter 'intermediates' is invalid. Wrong format or out of the bbox. ", 400);
} else {
LOGGER.debug("intermediates in a table:");
Expand All @@ -223,7 +225,7 @@ module.exports = {
} else {
LOGGER.debug("converted getSteps: " + routeRequest.computeSteps);
}

}
} else if ("defaultValueContent" in routeOperation.getParameterById("getSteps") && typeof(routeOperation.getParameterById("getSteps").defaultValueContent) !== "undefined") {
// Default value from configuration
routeRequest.computeSteps = routeOperation.getParameterById("getSteps").defaultValueContent;
Expand Down Expand Up @@ -297,7 +299,8 @@ module.exports = {
let userResponse = {
"code": routeResponse.engineExtras.code
};
let askedProjection = routeRequest.start.projection;
LOGGER.debug("Engine response code :");
LOGGER.debug(userResponse.code);

// Waypoints
let waypointArray = copyManager.deepCopy(routeResponse.engineExtras.waypoints);
Expand All @@ -308,41 +311,92 @@ module.exports = {
waypointArray[i].location = [point.x, point.y];
}
userResponse.waypoints = waypointArray;
LOGGER.debug("Waypoints :");
LOGGER.debug(userResponse.waypoints);

// Routes
let routeArray = new Array();
for (let routeIdx = 0; routeIdx < routeResponse.routes.length; routeIdx++) {
let simpleRoute = routeResponse.routes[routeIdx]; // from road2 standard response
let extraRoute = routeResponse.engineExtras.routes[routeIdx]; // from engine specific extras
let extraRoute = routeResponse.engineExtras.routes[routeIdx]; // from engine specific extrasz
// both sources will be fused to craft a response compliant with OSRM's official API definition

// Geometry
routeArray[routeIdx] = {};
routeArray[routeIdx].geometry = simpleRoute.geometry.getGeometryWithFormat(routeRequest.geometryFormat);
LOGGER.debug("Route " + routeIdx + "'s geometry: " + userResponse.geometry);

// Distance
if (!simpleRoute.distance.convert(routeRequest.distanceUnit)) {
throw errorManager.createError(" Error during conversion of route distance in response. ", 400);
} else {
routeArray[routeIdx].distance = simpleRoute.distance.value;
}

// Duration
if (!simpleRoute.duration.convert(routeRequest.timeUnit)) {
throw errorManager.createError(" Error during conversion of route duration in response. ", 400);
} else {
routeArray[routeIdx].duration = simpleRoute.duration.value;
}

// Legs (Road2's "portions")
let legArray = new Array();
for (let legIdx = 0; legIdx < simpleRoute.portions.length; legIdx++) {
LOGGER.debug("Computing leg " + legIdx + " of route " + routeIdx);
let portion = simpleRoute.portions[legIdx]; // from road2 standard response
let leg = extraRoute.legs[legIdx]; // from engine specific extras
legArray[legIdx] = {
"distance": portion.distance,
"duration": portion.duration
};
legArray[legIdx] = {};

// Distance
if (!portion.distance.convert(routeRequest.distanceUnit)) {
LOGGER.debug("error during distance conversion: distance " + portion.distance);
throw errorManager.createError(" Error during convertion of portion distance in response. ", 400);
} else {
legArray[legIdx].distance = portion.distance.value;
}

// Duration
if (!portion.duration.convert(routeRequest.timeUnit)) {
LOGGER.debug("error during duration conversion: duration " + portion.duration);
throw errorManager.createError(" Error during convertion of portion duration in response. ", 400);
} else {
legArray[legIdx].duration = portion.duration.value;
}

// Steps (optional)
let stepArray = new Array();
if (routeRequest.computeSteps && portion.steps.length !== 0) {
for (let stepIdx = 0; stepIdx < portion.steps.length; stepIdx++) {
let simpleStep = portion.steps[stepIdx]; // from road2 standard response
let extraStep = leg.steps[stepIdx]; // from engine specific extras

stepArray[stepIdx] = {
"distance": simpleStep.distance,
"duration": simpleStep.duration,
"geometry": simpleStep.geometry.getGeometryWithFormat(routeRequest.geometryFormat),
"intersections": copyManager.deepCopy(extraStep.intersections),
"maneuver": {
"type": extraStep.instruction.type
"type": simpleStep.instruction.type
},
"mode": extraStep.mode,
"name": simpleStep.name
};

// Distance
if (!simpleStep.distance.convert(routeRequest.distanceUnit)) {
LOGGER.debug("error during distance conversion: distance " + simpleStep.distance);
throw errorManager.createError(" Error during convertion of portion distance in response. ", 400);
} else {
stepArray[stepIdx].distance = simpleStep.distance.value;
}

// Duration
if (!simpleStep.duration.convert(routeRequest.timeUnit)) {
LOGGER.debug("error during duration conversion: duration " + simpleStep.duration);
throw errorManager.createError(" Error during convertion of portion duration in response. ", 400);
} else {
stepArray[stepIdx].duration = simpleStep.duration.value;
}

if (simpleStep.instruction.modifier) {
stepArray[stepIdx].maneuver.modifier = simpleStep.instruction.modifier;
}
Expand All @@ -356,12 +410,7 @@ module.exports = {
}
}

routeArray[routeIdx] = {
"distance": simpleRoute.distance,
"duration": simpleRoute.duration,
"geometry": simpleRoute.geometry.getGeometryWithFormat(routeRequest.geometryFormat),
"legs": legArray
};
routeArray[routeIdx].legs = legArray;
}

// Finalze userResponse
Expand Down
10 changes: 5 additions & 5 deletions src/js/apis/osrm/1.0.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const controller = require('./controller/controller');
const errorManager = require('../../../utils/errorManager');
const swaggerUi = require('swagger-ui-express');

var LOGGER = log4js.getLogger("OSRM");
var router = express.Router();
let LOGGER = log4js.getLogger("OSRM");
let router = express.Router();

// API entrypoint
router.all("/", function(req, res) {
Expand All @@ -19,9 +19,9 @@ router.all("/", function(req, res) {


// swagger-ui
var apiJsonPath = path.join(__dirname, '..', '..', '..','..','..', 'documentation','apis','osrm', '1.0.0', 'api.json');
let apiJsonPath = path.join(__dirname, '..', '..', '..','..','..', 'documentation','apis','osrm', '1.0.0', 'api.json');
LOGGER.info("using file '"+ apiJsonPath + "' to initialize swagger-ui for OSRM API version 1.0.0");
var swaggerDocument = require(apiJsonPath);
let swaggerDocument = require(apiJsonPath);
router.use('/openapi', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

// GetCapabilities
Expand All @@ -43,7 +43,7 @@ router.all("/resources", function(req, res) {
// Change base url in GetCapabilties if "Host" or "X-Forwarded-Host" is specified in request's headers
// Host is stored by expres in req.hostname
if (req.hostname) {
let regexpHost = /^http[s]?:\/\/[\w\d:-_\.]*\//;
let regexpHost = /^https?:\/\/[\w\d:-_.]*\//;
try {
getCapabilities.info.url = getCapabilities.info.url.replace(regexpHost, req.protocol + "://" + req.hostname + "/");
} catch(error) {
Expand Down
2 changes: 1 addition & 1 deletion src/js/apis/osrm/1.0.0/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const log4js = require('log4js');

var LOGGER = log4js.getLogger("INIT");
let LOGGER = log4js.getLogger("INIT");

module.exports = {

Expand Down
2 changes: 1 addition & 1 deletion src/js/apis/osrm/1.0.0/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const log4js = require('log4js');

var LOGGER = log4js.getLogger("INIT");
let LOGGER = log4js.getLogger("INIT");

module.exports = {

Expand Down
6 changes: 3 additions & 3 deletions src/js/sources/osrmSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Point = require('../geometry/point');
const Step = require('../responses/step');
const Distance = require('../geography/distance');
const Duration = require('../time/duration');
const copyManager = require('../../../../utils/copyManager')
const copyManager = require('../utils/copyManager')
const errorManager = require('../utils/errorManager');
const log4js = require('log4js');

Expand Down Expand Up @@ -457,7 +457,7 @@ module.exports = class osrmSource extends Source {
let portions = new Array();
let currentOsrmRoute = osrmResponse.routes[i];
engineExtras.routes[i] = {};
nativeLegs = new Array();
let nativeLegs = new Array();

// On commence par créer l'itinéraire avec les attributs obligatoires
routes[i] = new Route( new Line(currentOsrmRoute.geometry, "geojson", super.projection) );
Expand Down Expand Up @@ -552,7 +552,7 @@ module.exports = class osrmSource extends Source {

nativeSteps[k] = {};
nativeSteps[k].mode = currentOsrmRouteStep.mode;
nativeIntersections = new Array();
let nativeIntersections = new Array();
for (let intersectionIndex = 0; intersectionIndex < currentOsrmRouteStep.intersections.length; intersectionIndex++) {
let currentIntersection = currentOsrmRouteStep.intersections[intersectionIndex];
nativeIntersections[intersectionIndex] = copyManager.deepCopy(currentIntersection);
Expand Down

0 comments on commit 300c00f

Please sign in to comment.