From a46241e45cb4bb1147a0b9ac682426a71f946bf8 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sun, 28 Aug 2022 21:56:09 +0200 Subject: [PATCH 1/4] Add Node docs for exclude and skip_waypoints options (#6342) --- docs/nodejs/api.md | 2 ++ src/nodejs/node_osrm.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/nodejs/api.md b/docs/nodejs/api.md index 30358e4e2..2237cf6c5 100644 --- a/docs/nodejs/api.md +++ b/docs/nodejs/api.md @@ -51,6 +51,7 @@ Returns the fastest route between two or more coordinates while visiting the way Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. - `options.radiuses` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`. - `options.hints` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. + - `options.exclude` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** List of classes to avoid, order does not matter. - `options.generate_hints` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`) - `options.alternatives` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Search for alternative routes. (optional, default `false`) - `options.alternatives` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Search for up to this many alternative routes. @@ -64,6 +65,7 @@ Returns the fastest route between two or more coordinates while visiting the way `null`/`true`/`false` - `options.waypoints` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index. - `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. + - `options.skip_waypoints` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of response and do not want to transfer waste data. (optional, default `false`) - `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** **Examples** diff --git a/src/nodejs/node_osrm.cpp b/src/nodejs/node_osrm.cpp index 5c8c486a5..ba82947d3 100644 --- a/src/nodejs/node_osrm.cpp +++ b/src/nodejs/node_osrm.cpp @@ -286,6 +286,7 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo &info, * Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`. * @param {Array} [options.radiuses] Limits the coordinate snapping to streets in the given radius in meters. Can be `null` (unlimited, default) or `double >= 0`. * @param {Array} [options.hints] Hints for the coordinate snapping. Array of base64 encoded strings. + * @param {Array} [options.exclude] List of classes to avoid, order does not matter. * @param {Boolean} [options.generate_hints=true] Whether or not adds a Hint to the response which can be used in subsequent requests. * @param {Boolean} [options.alternatives=false] Search for alternative routes. * @param {Number} [options.alternatives=0] Search for up to this many alternative routes. @@ -299,6 +300,7 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo &info, * `null`/`true`/`false` * @param {Array} [options.waypoints] Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index. * @param {String} [options.snapping] Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. + * @param {Boolean} [options.skip_waypoints=false] Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of response and do not want to transfer waste data. * @param {Function} callback * * @returns {Object} An array of [Waypoint](#waypoint) objects representing all waypoints in order AND an array of [`Route`](#route) objects ordered by descending recommendation rank. From 18e5faa1130e446a94eec6a3b700e9332b4f0639 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Sun, 28 Aug 2022 23:59:09 +0200 Subject: [PATCH 2/4] Remove Appveyor status from README.md (#6347) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 611b1b9c2..1f6b096cb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ## Open Source Routing Machine -| Linux / macOS | Windows | Code Coverage | -| ------------- | ------- | ------------- | -| [![osrm-backend CI](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml/badge.svg)](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) | [![Codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) | +| Linux / macOS / Windows | Code Coverage | +| ----------------------- | ------------- | +| [![osrm-backend CI](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml/badge.svg)](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) | [![Codecov](https://codecov.io/gh/Project-OSRM/osrm-backend/branch/master/graph/badge.svg)](https://codecov.io/gh/Project-OSRM/osrm-backend) | High performance routing engine written in C++14 designed to run on OpenStreetMap data. From 06719be2b1903c339115f16ded66609b9e290c3e Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 29 Aug 2022 00:03:03 +0200 Subject: [PATCH 3/4] Use Lua 5.4 in Docker image (#6346) --- CHANGELOG.md | 1 + docker/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25c8aa337..37628bc35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - NodeJS: - FIXED: Support `skip_waypoints` in Node bindings [#6060](https://github.com/Project-OSRM/osrm-backend/pull/6060) - Misc: + - CHANGED: Use Lua 5.4 in Docker image. [#6346](https://github.com/Project-OSRM/osrm-backend/pull/6346) - CHANGED: Remove redundant nullptr check. [#6326](https://github.com/Project-OSRM/osrm-backend/pull/6326) - CHANGED: missing files list is included in exception message. [#5360](https://github.com/Project-OSRM/osrm-backend/pull/5360) - CHANGED: Do not use deprecated Callback::Call overload in Node bindings. [#6318](https://github.com/Project-OSRM/osrm-backend/pull/6318) diff --git a/docker/Dockerfile b/docker/Dockerfile index 4f2e77838..094bedee7 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -5,7 +5,7 @@ RUN mkdir -p /src && mkdir -p /opt RUN apt-get update && \ apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \ - libzip-dev libboost1.74-all-dev lua5.2 liblua5.2-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 + libzip-dev libboost1.74-all-dev lua5.4 liblua5.4-dev -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \ ldconfig /usr/local/lib && \ @@ -51,7 +51,7 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends libboost-program-options1.74.0 libboost-regex1.74.0 \ libboost-date-time1.74.0 libboost-chrono1.74.0 libboost-filesystem1.74.0 \ libboost-iostreams1.74.0 libboost-system1.74.0 libboost-thread1.74.0 \ - expat liblua5.2-0 && \ + expat liblua5.4-0 && \ rm -rf /var/lib/apt/lists/* && \ # add /usr/local/lib to ldconfig to allow loading libraries from there ldconfig /usr/local/lib From b4142cf1a2ae3dd871168262443b4b9b8a24ca6a Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Mon, 29 Aug 2022 22:01:26 +0200 Subject: [PATCH 4/4] Add Flatbuffers support to NodeJS bindings (#6338) --- CHANGELOG.md | 1 + docs/http.md | 2 +- docs/nodejs/api.md | 19 ++++--- include/nodejs/node_osrm_support.hpp | 78 ++++++++++++++++++++++++---- src/nodejs/node_osrm.cpp | 66 ++++++++++++++++------- test/nodejs/match.js | 18 +++++++ test/nodejs/nearest.js | 18 +++++++ test/nodejs/route.js | 45 ++++++++++++++++ test/nodejs/table.js | 18 +++++++ test/nodejs/trip.js | 11 ++++ 10 files changed, 238 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37628bc35..e650d38ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased - Changes from 5.26.0 - API: + - ADDED: Add Flatbuffers support to NodeJS bindings. [#6338](https://github.com/Project-OSRM/osrm-backend/pull/6338) - CHANGED: Add `data_version` field to responses of all services. [#5387](https://github.com/Project-OSRM/osrm-backend/pull/5387) - FIXED: Use Boost.Beast to parse HTTP request. [#6294](https://github.com/Project-OSRM/osrm-backend/pull/6294) - FIXED: Fix inefficient osrm-routed connection handling [#6113](https://github.com/Project-OSRM/osrm-backend/pull/6113) diff --git a/docs/http.md b/docs/http.md index abad2a906..07acc968a 100644 --- a/docs/http.md +++ b/docs/http.md @@ -956,7 +956,7 @@ The object is used to describe the waypoint on a route. The default response format is `json`, but OSRM supports binary [`flatbuffers`](https://google.github.io/flatbuffers/) format, which is much faster in serialization/deserialization, comparing to `json`. -The format itself is described in message descriptors, located at `include/engine/api/flatbuffers directory`. Those descriptors could +The format itself is described in message descriptors, located at `include/engine/api/flatbuffers` directory. Those descriptors could be compiled to provide protocol parsers in Go/Javascript/Typescript/Java/Dart/C#/Python/Lobster/Lua/Rust/PHP/Kotlin. Precompiled protocol parser for C++ is supplied with OSRM. diff --git a/docs/nodejs/api.md b/docs/nodejs/api.md index 2237cf6c5..39d0a9786 100644 --- a/docs/nodejs/api.md +++ b/docs/nodejs/api.md @@ -64,6 +64,7 @@ Returns the fastest route between two or more coordinates while visiting the way - `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. `null`/`true`/`false` - `options.waypoints` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index. + - `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). - `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. - `options.skip_waypoints` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of response and do not want to transfer waste data. (optional, default `false`) - `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** @@ -99,6 +100,7 @@ Note: `coordinates` in the general options only supports a single `{longitude},{ - `options.number` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned. Must be an integer greater than or equal to `1`. (optional, default `1`) - `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. + - `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). - `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. - `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** @@ -334,12 +336,15 @@ specific behaviours. - `plugin_config` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Object literal containing parameters for the trip query. - `plugin_config.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The format of the result object to various API calls. - Valid options are `object` (default), which returns a - standard Javascript object, as described above, and `json_buffer`, which will return a NodeJS - **[Buffer](https://nodejs.org/api/buffer.html)** object, containing a JSON string. The latter has - the advantage that it can be immediately serialized to disk/sent over the network, and the - generation of the string is performed outside the main NodeJS event loop. This option is ignored - by the `tile` plugin. + Valid options are `object` (default if `options.format` is + `json`), which returns a standard Javascript object, as described above, and `buffer`(default if + `options.format` is `flatbuffers`), which will return a NodeJS + **[Buffer](https://nodejs.org/api/buffer.html)** object, containing a JSON string or Flatbuffers + object. The latter has the advantage that it can be immediately serialized to disk/sent over the + network, and the generation of the string is performed outside the main NodeJS event loop. This + option is ignored by the `tile` plugin. Also note that `options.format` set to `flatbuffers` + cannot be used with `plugin_config.format` set to `object`. `json_buffer` is deprecated alias for + `buffer`. **Examples** @@ -351,7 +356,7 @@ var options = { [13.374481201171875, 52.506191342034576] ] }; -osrm.route(options, { format: "json_buffer" }, function(err, response) { +osrm.route(options, { format: "buffer" }, function(err, response) { if (err) throw err; console.log(response.toString("utf-8")); }); diff --git a/include/nodejs/node_osrm_support.hpp b/include/nodejs/node_osrm_support.hpp index 25f96661d..f1e288226 100644 --- a/include/nodejs/node_osrm_support.hpp +++ b/include/nodejs/node_osrm_support.hpp @@ -2,8 +2,7 @@ #define OSRM_BINDINGS_NODE_SUPPORT_HPP #include "nodejs/json_v8_renderer.hpp" -#include "util/json_renderer.hpp" - +#include "engine/api/flatbuffers/fbresult_generated.h" #include "osrm/approach.hpp" #include "osrm/bearing.hpp" #include "osrm/coordinate.hpp" @@ -18,6 +17,7 @@ #include "osrm/table_parameters.hpp" #include "osrm/tile_parameters.hpp" #include "osrm/trip_parameters.hpp" +#include "util/json_renderer.hpp" #include #include @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ using table_parameters_ptr = std::unique_ptr; struct PluginParameters { - bool renderJSONToBuffer = false; + bool renderToBuffer = false; }; using ObjectOrString = typename mapbox::util::variant; @@ -96,6 +97,17 @@ inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &r } inline void ParseResult(const osrm::Status & /*result_status*/, const std::string & /*unused*/) {} +inline void ParseResult(const osrm::Status &result_status, + const flatbuffers::FlatBufferBuilder &fbs_builder) +{ + auto fbs_result = osrm::engine::api::fbresult::GetFBResult(fbs_builder.GetBufferPointer()); + + if (result_status == osrm::Status::Error) + { + BOOST_ASSERT(fbs_result->code()); + throw std::logic_error(fbs_result->code()->message()->c_str()); + } +} inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo &args) { @@ -725,6 +737,36 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo &arg } } + if (Nan::Has(obj, Nan::New("format").ToLocalChecked()).FromJust()) + { + v8::Local format = + Nan::Get(obj, Nan::New("format").ToLocalChecked()).ToLocalChecked(); + if (format.IsEmpty()) + { + return false; + } + + if (!format->IsString()) + { + Nan::ThrowError("format must be a string: \"json\" or \"flatbuffers\""); + return false; + } + + std::string format_str = *Nan::Utf8String(format); + if (format_str == "json") + { + params->format = osrm::engine::api::BaseParameters::OutputFormatType::JSON; + } + else if (format_str == "flatbuffers") + { + params->format = osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS; + } + else + { + Nan::ThrowError("format must be a string: \"json\" or \"flatbuffers\""); + return false; + } + } return true; } @@ -885,17 +927,18 @@ inline bool parseCommonParameters(const v8::Local &obj, ParamType &p return true; } -inline PluginParameters -argumentsToPluginParameters(const Nan::FunctionCallbackInfo &args) +inline PluginParameters argumentsToPluginParameters( + const Nan::FunctionCallbackInfo &args, + const boost::optional &output_format = {}) { if (args.Length() < 3 || !args[1]->IsObject()) { - return {}; + // output to buffer by default for Flatbuffers + return {output_format == osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS}; } v8::Local obj = Nan::To(args[1]).ToLocalChecked(); if (Nan::Has(obj, Nan::New("format").ToLocalChecked()).FromJust()) { - v8::Local format = Nan::Get(obj, Nan::New("format").ToLocalChecked()).ToLocalChecked(); if (format.IsEmpty()) @@ -905,7 +948,7 @@ argumentsToPluginParameters(const Nan::FunctionCallbackInfo &args) if (!format->IsString()) { - Nan::ThrowError("format must be a string: \"object\" or \"json_buffer\""); + Nan::ThrowError("format must be a string: \"object\" or \"buffer\""); return {}; } @@ -914,20 +957,35 @@ argumentsToPluginParameters(const Nan::FunctionCallbackInfo &args) if (format_str == "object") { + if (output_format == osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS) + { + Nan::ThrowError("Flatbuffers result can only output to buffer."); + return {true}; + } return {false}; } + else if (format_str == "buffer") + { + return {true}; + } else if (format_str == "json_buffer") { + if (output_format && + output_format != osrm::engine::api::BaseParameters::OutputFormatType::JSON) + { + Nan::ThrowError("Deprecated `json_buffer` can only be used with JSON format"); + } return {true}; } else { - Nan::ThrowError("format must be a string: \"object\" or \"json_buffer\""); + Nan::ThrowError("format must be a string: \"object\" or \"buffer\""); return {}; } } - return {}; + // output to buffer by default for Flatbuffers + return {output_format == osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS}; } inline route_parameters_ptr diff --git a/src/nodejs/node_osrm.cpp b/src/nodejs/node_osrm.cpp index ba82947d3..37944d60c 100644 --- a/src/nodejs/node_osrm.cpp +++ b/src/nodejs/node_osrm.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -128,8 +129,7 @@ inline void async(const Nan::FunctionCallbackInfo &info, auto params = argsToParams(info, requires_multiple_coordinates); if (!params) return; - - auto pluginParams = argumentsToPluginParameters(info); + auto pluginParams = argumentsToPluginParameters(info, params->format); BOOST_ASSERT(params->IsValid()); @@ -156,20 +156,41 @@ inline void async(const Nan::FunctionCallbackInfo &info, void Execute() override try { - osrm::engine::api::ResultT r; - r = osrm::util::json::Object(); - const auto status = ((*osrm).*(service))(*params, r); - auto json_result = r.get(); - ParseResult(status, json_result); - if (pluginParams.renderJSONToBuffer) + switch ( + params->format.value_or(osrm::engine::api::BaseParameters::OutputFormatType::JSON)) { - std::ostringstream buf; - osrm::util::json::render(buf, json_result); - result = buf.str(); + case osrm::engine::api::BaseParameters::OutputFormatType::JSON: + { + osrm::engine::api::ResultT r; + r = osrm::util::json::Object(); + const auto status = ((*osrm).*(service))(*params, r); + auto &json_result = r.get(); + ParseResult(status, json_result); + if (pluginParams.renderToBuffer) + { + std::ostringstream buf; + osrm::util::json::render(buf, json_result); + result = buf.str(); + } + else + { + result = json_result; + } } - else + break; + case osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS: { - result = json_result; + osrm::engine::api::ResultT r = flatbuffers::FlatBufferBuilder(); + const auto status = ((*osrm).*(service))(*params, r); + const auto &fbs_result = r.get(); + ParseResult(status, fbs_result); + BOOST_ASSERT(pluginParams.renderToBuffer); + std::string result_str( + reinterpret_cast(fbs_result.GetBufferPointer()), + fbs_result.GetSize()); + result = std::move(result_str); + } + break; } } catch (const std::exception &e) @@ -299,6 +320,7 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo &info, * @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. * `null`/`true`/`false` * @param {Array} [options.waypoints] Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index. + * @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). * @param {String} [options.snapping] Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. * @param {Boolean} [options.skip_waypoints=false] Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of response and do not want to transfer waste data. * @param {Function} callback @@ -340,6 +362,7 @@ NAN_METHOD(Engine::route) // * @param {Number} [options.number=1] Number of nearest segments that should be returned. * Must be an integer greater than or equal to `1`. * @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. + * @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). * @param {String} [options.snapping] Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph. * @param {Function} callback * @@ -606,12 +629,15 @@ NAN_METHOD(Engine::trip) // * @name Configuration * @param {Object} [plugin_config] - Object literal containing parameters for the trip query. * @param {String} [plugin_config.format] The format of the result object to various API calls. - * Valid options are `object` (default), which returns a - * standard Javascript object, as described above, and `json_buffer`, which will return a NodeJS - * **[Buffer](https://nodejs.org/api/buffer.html)** object, containing a JSON string. The latter has - * the advantage that it can be immediately serialized to disk/sent over the network, and the - * generation of the string is performed outside the main NodeJS event loop. This option is ignored - * by the `tile` plugin. + * Valid options are `object` (default if `options.format` is + * `json`), which returns a standard Javascript object, as described above, and `buffer`(default if + * `options.format` is `flatbuffers`), which will return a NodeJS + * **[Buffer](https://nodejs.org/api/buffer.html)** object, containing a JSON string or Flatbuffers + * object. The latter has the advantage that it can be immediately serialized to disk/sent over the + * network, and the generation of the string is performed outside the main NodeJS event loop. This + * option is ignored by the `tile` plugin. Also note that `options.format` set to `flatbuffers` + * cannot be used with `plugin_config.format` set to `object`. `json_buffer` is deprecated alias for + * `buffer`. * * @example * var osrm = new OSRM('network.osrm'); @@ -621,7 +647,7 @@ NAN_METHOD(Engine::trip) // * [13.374481201171875, 52.506191342034576] * ] * }; - * osrm.route(options, { format: "json_buffer" }, function(err, response) { + * osrm.route(options, { format: "buffer" }, function(err, response) { * if (err) throw err; * console.log(response.toString("utf-8")); * }); diff --git a/test/nodejs/match.js b/test/nodejs/match.js index 3161060e9..611a47f14 100644 --- a/test/nodejs/match.js +++ b/test/nodejs/match.js @@ -4,6 +4,24 @@ var data_path = require('./constants').data_path; var mld_data_path = require('./constants').mld_data_path; var three_test_coordinates = require('./constants').three_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates; +const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; +const FBResult = require('../../features/support/fbresult_generated').osrm.engine.api.fbresult.FBResult; + + +test('match: match in Monaco with flatbuffers format', function(assert) { + assert.plan(2); + var osrm = new OSRM(data_path); + var options = { + coordinates: three_test_coordinates, + timestamps: [1424684612, 1424684616, 1424684620], + format: 'flatbuffers' + }; + osrm.match(options, function(err, response) { + assert.ifError(err); + const fb = FBResult.getRootAsFBResult(new flatbuffers.ByteBuffer(response)); + assert.equal(fb.routesLength(), 1); + }); +}); test('match: match in Monaco', function(assert) { assert.plan(5); diff --git a/test/nodejs/nearest.js b/test/nodejs/nearest.js index 1fce37af0..02879910b 100644 --- a/test/nodejs/nearest.js +++ b/test/nodejs/nearest.js @@ -4,8 +4,26 @@ var data_path = require('./constants').data_path; var mld_data_path = require('./constants').mld_data_path; var three_test_coordinates = require('./constants').three_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates; +const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; +const FBResult = require('../../features/support/fbresult_generated').osrm.engine.api.fbresult.FBResult; +test('nearest with flatbuffers format', function(assert) { + assert.plan(5); + var osrm = new OSRM(data_path); + osrm.nearest({ + coordinates: [three_test_coordinates[0]], + format: 'flatbuffers' + }, function(err, result) { + assert.ifError(err); + assert.ok(result instanceof Buffer); + const fb = FBResult.getRootAsFBResult(new flatbuffers.ByteBuffer(result)); + assert.equals(fb.waypointsLength(), 1); + assert.ok(fb.waypoints(0).location()); + assert.ok(fb.waypoints(0).name()); + }); +}); + test('nearest', function(assert) { assert.plan(4); var osrm = new OSRM(data_path); diff --git a/test/nodejs/route.js b/test/nodejs/route.js index 7d27639ea..0e4033843 100644 --- a/test/nodejs/route.js +++ b/test/nodejs/route.js @@ -5,6 +5,51 @@ var monaco_mld_path = require('./constants').mld_data_path; var monaco_corech_path = require('./constants').corech_data_path; var three_test_coordinates = require('./constants').three_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates; +const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; +const FBResult = require('../../features/support/fbresult_generated').osrm.engine.api.fbresult.FBResult; + +test('route: routes Monaco and can return result in flatbuffers', function(assert) { + assert.plan(5); + var osrm = new OSRM(monaco_path); + osrm.route({coordinates: two_test_coordinates, format: 'flatbuffers'}, function(err, result) { + assert.ifError(err); + assert.ok(result instanceof Buffer); + const fb = FBResult.getRootAsFBResult(new flatbuffers.ByteBuffer(result)); + assert.equals(fb.waypointsLength(), 2); + assert.equals(fb.routesLength(), 1); + assert.ok(fb.routes(0).polyline); + }); +}); + +test('route: routes Monaco and can return result in flatbuffers if output format is passed explicitly', function(assert) { + assert.plan(5); + var osrm = new OSRM(monaco_path); + osrm.route({coordinates: two_test_coordinates, format: 'flatbuffers'}, {output: 'buffer'}, function(err, result) { + assert.ifError(err); + assert.ok(result instanceof Buffer); + var buf = new flatbuffers.ByteBuffer(result); + const fb = FBResult.getRootAsFBResult(buf); + assert.equals(fb.waypointsLength(), 2); + assert.equals(fb.routesLength(), 1); + assert.ok(fb.routes(0).polyline); + }); +}); + +test('route: throws error if required output is object in flatbuffers format', function(assert) { + assert.plan(1); + var osrm = new OSRM(monaco_path); + assert.throws(function() { + osrm.route({coordinates: two_test_coordinates, format: 'flatbuffers'}, {format: 'object'}, function(err, result) {}); + }); +}); + +test('route: throws error if required output is json_buffer in flatbuffers format', function(assert) { + assert.plan(1); + var osrm = new OSRM(monaco_path); + assert.throws(function() { + osrm.route({coordinates: two_test_coordinates, format: 'flatbuffers'}, {format: 'json_buffer'}, function(err, result) {}); + }); +}); test('route: routes Monaco', function(assert) { diff --git a/test/nodejs/table.js b/test/nodejs/table.js index d2c50d83f..b73d74b7f 100644 --- a/test/nodejs/table.js +++ b/test/nodejs/table.js @@ -4,6 +4,24 @@ var data_path = require('./constants').data_path; var mld_data_path = require('./constants').mld_data_path; var three_test_coordinates = require('./constants').three_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates; +const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; +const FBResult = require('../../features/support/fbresult_generated').osrm.engine.api.fbresult.FBResult; + +test('table: flatbuffer format', function(assert) { + assert.plan(3); + var osrm = new OSRM(data_path); + var options = { + coordinates: [three_test_coordinates[0], three_test_coordinates[1]], + format: 'flatbuffers' + }; + osrm.table(options, function(err, table) { + assert.ifError(err); + assert.ok(table instanceof Buffer); + const fb = FBResult.getRootAsFBResult(new flatbuffers.ByteBuffer(table)); + assert.ok(fb.table()); + + }); +}); test('table: test annotations paramater combination', function(assert) { assert.plan(12); diff --git a/test/nodejs/trip.js b/test/nodejs/trip.js index 683032b3c..4b777fe15 100644 --- a/test/nodejs/trip.js +++ b/test/nodejs/trip.js @@ -4,7 +4,18 @@ var data_path = require('./constants').data_path; var mld_data_path = require('./constants').mld_data_path; var three_test_coordinates = require('./constants').three_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates; +const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; +const FBResult = require('../../features/support/fbresult_generated').osrm.engine.api.fbresult.FBResult; +test('trip: trip in Monaco with flatbuffers format', function(assert) { + assert.plan(2); + var osrm = new OSRM(data_path); + osrm.trip({coordinates: two_test_coordinates, format: 'flatbuffers'}, function(err, trip) { + assert.ifError(err); + const fb = FBResult.getRootAsFBResult(new flatbuffers.ByteBuffer(trip)); + assert.equal(fb.routesLength(), 1); + }); +}); test('trip: trip in Monaco', function(assert) { assert.plan(2);