wip
This commit is contained in:
parent
24e5d3b0af
commit
0a558c036d
@ -1,68 +1,65 @@
|
|||||||
// #ifndef OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
#ifndef OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
||||||
// #define OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
#define OSRM_BINDINGS_NODE_JSON_V8_RENDERER_HPP
|
||||||
|
|
||||||
// #include "osrm/json_container.hpp"
|
#include "osrm/json_container.hpp"
|
||||||
|
#include <napi.h>
|
||||||
|
|
||||||
// #pragma GCC diagnostic push
|
#include <functional>
|
||||||
// #pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
||||||
// #include <nan.h>
|
|
||||||
// #pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
// #include <functional>
|
namespace node_osrm
|
||||||
|
{
|
||||||
|
|
||||||
// namespace node_osrm
|
struct V8Renderer
|
||||||
// {
|
{
|
||||||
|
explicit V8Renderer(const Napi::Env& env, Napi::Value &out) : env(env), out(out) {}
|
||||||
|
|
||||||
// struct V8Renderer
|
void operator()(const osrm::json::String &string) const
|
||||||
// {
|
{
|
||||||
// explicit V8Renderer(v8::Local<v8::Value> &_out) : out(_out) {}
|
out = Napi::String::New(env, string.value);
|
||||||
|
}
|
||||||
|
|
||||||
// void operator()(const osrm::json::String &string) const
|
void operator()(const osrm::json::Number &number) const { out = Napi::Number::New(env, number.value); }
|
||||||
// {
|
|
||||||
// out = Nan::New(std::cref(string.value)).ToLocalChecked();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void operator()(const osrm::json::Number &number) const { out = Nan::New(number.value); }
|
void operator()(const osrm::json::Object &object) const
|
||||||
|
{
|
||||||
|
Napi::Object obj = Napi::Object::New(env);
|
||||||
|
for (const auto &keyValue : object.values)
|
||||||
|
{
|
||||||
|
Napi::Value child;
|
||||||
|
mapbox::util::apply_visitor(V8Renderer(env, child), keyValue.second);
|
||||||
|
obj.Set(keyValue.first, child);
|
||||||
|
}
|
||||||
|
out = obj;
|
||||||
|
}
|
||||||
|
|
||||||
// void operator()(const osrm::json::Object &object) const
|
void operator()(const osrm::json::Array &array) const
|
||||||
// {
|
{
|
||||||
// v8::Local<v8::Object> obj = Nan::New<v8::Object>();
|
Napi::Array a = Napi::Array::New(env, array.values.size());
|
||||||
// for (const auto &keyValue : object.values)
|
for (auto i = 0u; i < array.values.size(); ++i)
|
||||||
// {
|
{
|
||||||
// v8::Local<v8::Value> child;
|
Napi::Value child;
|
||||||
// mapbox::util::apply_visitor(V8Renderer(child), keyValue.second);
|
mapbox::util::apply_visitor(V8Renderer(env, child), array.values[i]);
|
||||||
// Nan::Set(obj, Nan::New(keyValue.first).ToLocalChecked(), child);
|
a.Set(i, child);
|
||||||
// }
|
}
|
||||||
// out = obj;
|
out = a;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// void operator()(const osrm::json::Array &array) const
|
void operator()(const osrm::json::True &) const { out = Napi::Boolean::New(env, true); }
|
||||||
// {
|
|
||||||
// v8::Local<v8::Array> a = Nan::New<v8::Array>(array.values.size());
|
|
||||||
// for (auto i = 0u; i < array.values.size(); ++i)
|
|
||||||
// {
|
|
||||||
// v8::Local<v8::Value> child;
|
|
||||||
// mapbox::util::apply_visitor(V8Renderer(child), array.values[i]);
|
|
||||||
// Nan::Set(a, i, child);
|
|
||||||
// }
|
|
||||||
// out = a;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void operator()(const osrm::json::True &) const { out = Nan::New(true); }
|
void operator()(const osrm::json::False &) const { out = Napi::Boolean::New(env, false); }
|
||||||
|
|
||||||
// void operator()(const osrm::json::False &) const { out = Nan::New(false); }
|
void operator()(const osrm::json::Null &) const { out = env.Null(); }
|
||||||
|
|
||||||
// void operator()(const osrm::json::Null &) const { out = Nan::Null(); }
|
private:
|
||||||
|
const Napi::Env& env;
|
||||||
|
Napi::Value &out;
|
||||||
|
};
|
||||||
|
|
||||||
// private:
|
inline void renderToV8(const Napi::Env& env, Napi::Value &out, const osrm::json::Object &object)
|
||||||
// v8::Local<v8::Value> &out;
|
{
|
||||||
// };
|
V8Renderer renderer(env, out);
|
||||||
|
renderer(object);
|
||||||
|
}
|
||||||
|
} // namespace node_osrm
|
||||||
|
|
||||||
// inline void renderToV8(v8::Local<v8::Value> &out, const osrm::json::Object &object)
|
#endif // JSON_V8_RENDERER_HPP
|
||||||
// {
|
|
||||||
// V8Renderer renderer(out);
|
|
||||||
// renderer(object);
|
|
||||||
// }
|
|
||||||
// } // namespace node_osrm
|
|
||||||
|
|
||||||
// #endif // JSON_V8_RENDERER_HPP
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class Engine : public Napi::ObjectWrap<Engine> {
|
|||||||
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
||||||
Engine(const Napi::CallbackInfo& info);
|
Engine(const Napi::CallbackInfo& info);
|
||||||
|
|
||||||
|
std::shared_ptr<osrm::OSRM> this_;
|
||||||
private:
|
private:
|
||||||
Napi::Value route(const Napi::CallbackInfo& info);
|
Napi::Value route(const Napi::CallbackInfo& info);
|
||||||
Napi::Value nearest(const Napi::CallbackInfo& info);
|
Napi::Value nearest(const Napi::CallbackInfo& info);
|
||||||
@ -22,7 +23,6 @@ private:
|
|||||||
Napi::Value match(const Napi::CallbackInfo& info);
|
Napi::Value match(const Napi::CallbackInfo& info);
|
||||||
Napi::Value trip(const Napi::CallbackInfo& info);
|
Napi::Value trip(const Napi::CallbackInfo& info);
|
||||||
|
|
||||||
std::shared_ptr<osrm::OSRM> this_;
|
|
||||||
// Napi::Value PlusOne(const Napi::CallbackInfo& info);
|
// Napi::Value PlusOne(const Napi::CallbackInfo& info);
|
||||||
// Napi::Value Multiply(const Napi::CallbackInfo& info);
|
// Napi::Value Multiply(const Napi::CallbackInfo& info);
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,62 @@ struct PluginParameters
|
|||||||
|
|
||||||
using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>;
|
using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>;
|
||||||
|
|
||||||
|
template <typename ResultT> inline Napi::Value render(const Napi::Env& env, const ResultT &result);
|
||||||
|
|
||||||
|
template <> Napi::Value inline render(const Napi::Env& env, const std::string &result)
|
||||||
|
{
|
||||||
|
return Napi::Buffer<char>::Copy(env, result.data(), result.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> Napi::Value inline render(const Napi::Env& env, const ObjectOrString &result)
|
||||||
|
{
|
||||||
|
if (result.is<osrm::json::Object>())
|
||||||
|
{
|
||||||
|
// Convert osrm::json object tree into matching v8 object tree
|
||||||
|
Napi::Value value;
|
||||||
|
renderToV8(env, value, result.get<osrm::json::Object>());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Return the string object as a node Buffer
|
||||||
|
return Napi::Buffer<char>::Copy(env, result.get<std::string>().data(), result.get<std::string>().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &result)
|
||||||
|
{
|
||||||
|
const auto code_iter = result.values.find("code");
|
||||||
|
const auto end_iter = result.values.end();
|
||||||
|
|
||||||
|
BOOST_ASSERT(code_iter != end_iter);
|
||||||
|
|
||||||
|
if (result_status == osrm::Status::Error)
|
||||||
|
{
|
||||||
|
throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
result.values.erase(code_iter);
|
||||||
|
const auto message_iter = result.values.find("message");
|
||||||
|
if (message_iter != end_iter)
|
||||||
|
{
|
||||||
|
result.values.erase(message_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 void ThrowError(const Napi::Env& env, const char* message)
|
inline void ThrowError(const Napi::Env& env, const char* message)
|
||||||
{
|
{
|
||||||
@ -1089,6 +1145,558 @@ argumentsToRouteParameter(const Napi::CallbackInfo &args,
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline tile_parameters_ptr
|
||||||
|
argumentsToTileParameters(const Napi::CallbackInfo &args, bool /*unused*/)
|
||||||
|
{
|
||||||
|
tile_parameters_ptr params = std::make_unique<osrm::TileParameters>();
|
||||||
|
|
||||||
|
if (args.Length() < 2)
|
||||||
|
{
|
||||||
|
ThrowTypeError(args.Env(), "Coordinate object and callback required");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[0].IsArray())
|
||||||
|
{
|
||||||
|
ThrowTypeError(args.Env(), "Parameter must be an array [x, y, z]");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Napi::Array array = args[0].As<Napi::Array>();
|
||||||
|
|
||||||
|
if (array.Length() != 3)
|
||||||
|
{
|
||||||
|
ThrowTypeError(args.Env(), "Parameter must be an array [x, y, z]");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Napi::Value x = array.Get(static_cast<uint32_t>(0));
|
||||||
|
Napi::Value y = array.Get(static_cast<uint32_t>(1));
|
||||||
|
Napi::Value z = array.Get(static_cast<uint32_t>(2));
|
||||||
|
if (x.IsEmpty() || y.IsEmpty() || z.IsEmpty())
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
|
||||||
|
if (!x.IsNumber() && !x.IsUndefined())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Tile x coordinate must be unsigned interger");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
if (!y.IsNumber() && !y.IsUndefined())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Tile y coordinate must be unsigned interger");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
if (!z.IsNumber() && !z.IsUndefined())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Tile z coordinate must be unsigned interger");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->x = x.ToNumber().Uint32Value();
|
||||||
|
params->y = y.ToNumber().Uint32Value();
|
||||||
|
params->z = z.ToNumber().Uint32Value();
|
||||||
|
|
||||||
|
if (!params->IsValid())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Invalid tile coordinates");
|
||||||
|
return tile_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline nearest_parameters_ptr
|
||||||
|
argumentsToNearestParameter(const Napi::CallbackInfo &args,
|
||||||
|
bool requires_multiple_coordinates)
|
||||||
|
{
|
||||||
|
nearest_parameters_ptr params = std::make_unique<osrm::NearestParameters>();
|
||||||
|
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||||
|
if (!has_base_params)
|
||||||
|
return nearest_parameters_ptr();
|
||||||
|
|
||||||
|
Napi::Object obj = args[0].As<Napi::Object>();
|
||||||
|
if (obj.IsEmpty())
|
||||||
|
return nearest_parameters_ptr();
|
||||||
|
|
||||||
|
if (obj.Has("number"))
|
||||||
|
{
|
||||||
|
Napi::Value number =
|
||||||
|
obj.Get("number");
|
||||||
|
|
||||||
|
if (!number.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Number must be an integer greater than or equal to 1");
|
||||||
|
return nearest_parameters_ptr();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned number_value = number.ToNumber().Uint32Value();
|
||||||
|
|
||||||
|
if (number_value < 1)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Number must be an integer greater than or equal to 1");
|
||||||
|
return nearest_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->number_of_results = number_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline table_parameters_ptr
|
||||||
|
argumentsToTableParameter(const Napi::CallbackInfo &args,
|
||||||
|
bool requires_multiple_coordinates)
|
||||||
|
{
|
||||||
|
table_parameters_ptr params = std::make_unique<osrm::TableParameters>();
|
||||||
|
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||||
|
if (!has_base_params)
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
Napi::Object obj = args[0].As<Napi::Object>();
|
||||||
|
if (obj.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (obj.Has("sources"))
|
||||||
|
{
|
||||||
|
Napi::Value sources = obj.Get("sources");
|
||||||
|
if (sources.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (!sources.IsArray())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Sources must be an array of indices (or undefined)");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Napi::Array sources_array = sources.As<Napi::Array>();
|
||||||
|
for (uint32_t i = 0; i < sources_array.Length(); ++i)
|
||||||
|
{
|
||||||
|
Napi::Value source = sources_array.Get(i);
|
||||||
|
if (source.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (source.IsNumber())
|
||||||
|
{
|
||||||
|
size_t source_value = source.ToNumber().Uint32Value();
|
||||||
|
if (source_value >= params->coordinates.size())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Source indices must be less than the number of coordinates");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->sources.push_back(source.ToNumber().Uint32Value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Source must be an integer");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("destinations"))
|
||||||
|
{
|
||||||
|
Napi::Value destinations =obj.Get("destinations");
|
||||||
|
if (destinations.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (!destinations.IsArray())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Destinations must be an array of indices (or undefined)");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Napi::Array destinations_array = destinations.As<Napi::Array>();
|
||||||
|
for (uint32_t i = 0; i < destinations_array.Length(); ++i)
|
||||||
|
{
|
||||||
|
Napi::Value destination = destinations_array.Get(i);
|
||||||
|
if (destination.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (destination.IsNumber())
|
||||||
|
{
|
||||||
|
size_t destination_value = destination.ToNumber().Uint32Value();
|
||||||
|
if (destination_value >= params->coordinates.size())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Destination indices must be less than the number "
|
||||||
|
"of coordinates");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->destinations.push_back(destination_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Destination must be an integer");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("annotations"))
|
||||||
|
{
|
||||||
|
Napi::Value annotations =obj.Get("annotations");
|
||||||
|
if (annotations.IsEmpty())
|
||||||
|
return table_parameters_ptr();
|
||||||
|
|
||||||
|
if (!annotations.IsArray())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(),
|
||||||
|
"Annotations must an array containing 'duration' or 'distance', or both");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->annotations = osrm::TableParameters::AnnotationsType::None;
|
||||||
|
|
||||||
|
Napi::Array annotations_array = annotations.As<Napi::Array>();
|
||||||
|
for (std::size_t i = 0; i < annotations_array.Length(); ++i)
|
||||||
|
{
|
||||||
|
std::string annotations_str = annotations_array.Get(i).ToString().Utf8Value();
|
||||||
|
|
||||||
|
if (annotations_str == "duration")
|
||||||
|
{
|
||||||
|
params->annotations =
|
||||||
|
params->annotations | osrm::TableParameters::AnnotationsType::Duration;
|
||||||
|
}
|
||||||
|
else if (annotations_str == "distance")
|
||||||
|
{
|
||||||
|
params->annotations =
|
||||||
|
params->annotations | osrm::TableParameters::AnnotationsType::Distance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "this 'annotations' param is not supported");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("fallback_speed"))
|
||||||
|
{
|
||||||
|
auto fallback_speed = obj.Get("fallback_speed");
|
||||||
|
|
||||||
|
if (!fallback_speed.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "fallback_speed must be a number");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
else if (fallback_speed.ToNumber().DoubleValue() <= 0)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "fallback_speed must be > 0");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->fallback_speed = fallback_speed.ToNumber().DoubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("fallback_coordinate"))
|
||||||
|
{
|
||||||
|
auto fallback_coordinate =obj.Get("fallback_coordinate");
|
||||||
|
|
||||||
|
if (!fallback_coordinate.IsString())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "fallback_coordinate must be a string: [input, snapped]");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fallback_coordinate_str = fallback_coordinate.ToString().Utf8Value();
|
||||||
|
|
||||||
|
if (fallback_coordinate_str == "snapped")
|
||||||
|
{
|
||||||
|
params->fallback_coordinate_type =
|
||||||
|
osrm::TableParameters::FallbackCoordinateType::Snapped;
|
||||||
|
}
|
||||||
|
else if (fallback_coordinate_str == "input")
|
||||||
|
{
|
||||||
|
params->fallback_coordinate_type = osrm::TableParameters::FallbackCoordinateType::Input;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "'fallback_coordinate' param must be one of [input, snapped]");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("scale_factor"))
|
||||||
|
{
|
||||||
|
auto scale_factor = obj.Get("scale_factor");
|
||||||
|
|
||||||
|
if (!scale_factor.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "scale_factor must be a number");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
else if (scale_factor.ToNumber().DoubleValue() <= 0)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "scale_factor must be > 0");
|
||||||
|
return table_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->scale_factor = scale_factor.ToNumber().DoubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline trip_parameters_ptr
|
||||||
|
argumentsToTripParameter(const Napi::CallbackInfo &args,
|
||||||
|
bool requires_multiple_coordinates)
|
||||||
|
{
|
||||||
|
trip_parameters_ptr params = std::make_unique<osrm::TripParameters>();
|
||||||
|
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||||
|
if (!has_base_params)
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
|
||||||
|
Napi::Object obj = args[0].As<Napi::Object>();
|
||||||
|
|
||||||
|
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||||
|
if (!parsedSuccessfully)
|
||||||
|
{
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("roundtrip"))
|
||||||
|
{
|
||||||
|
auto roundtrip = obj.Get("roundtrip");
|
||||||
|
if (roundtrip.IsEmpty())
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
|
||||||
|
if (roundtrip.IsBoolean())
|
||||||
|
{
|
||||||
|
params->roundtrip =roundtrip.ToBoolean().Value();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "'roundtrip' param must be a boolean");
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("source"))
|
||||||
|
{
|
||||||
|
Napi::Value source =
|
||||||
|
obj.Get("source");
|
||||||
|
if (source.IsEmpty())
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
|
||||||
|
if (!source.IsString())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Source must be a string: [any, first]");
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string source_str = source.ToString().Utf8Value();
|
||||||
|
|
||||||
|
if (source_str == "first")
|
||||||
|
{
|
||||||
|
params->source = osrm::TripParameters::SourceType::First;
|
||||||
|
}
|
||||||
|
else if (source_str == "any")
|
||||||
|
{
|
||||||
|
params->source = osrm::TripParameters::SourceType::Any;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "'source' param must be one of [any, first]");
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("destination"))
|
||||||
|
{
|
||||||
|
Napi::Value destination =
|
||||||
|
obj.Get("destination");
|
||||||
|
if (destination.IsEmpty())
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
|
||||||
|
if (!destination.IsString())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Destination must be a string: [any, last]");
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string destination_str = destination.ToString().Utf8Value();
|
||||||
|
|
||||||
|
if (destination_str == "last")
|
||||||
|
{
|
||||||
|
params->destination = osrm::TripParameters::DestinationType::Last;
|
||||||
|
}
|
||||||
|
else if (destination_str == "any")
|
||||||
|
{
|
||||||
|
params->destination = osrm::TripParameters::DestinationType::Any;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "'destination' param must be one of [any, last]");
|
||||||
|
return trip_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline match_parameters_ptr
|
||||||
|
argumentsToMatchParameter(const Napi::CallbackInfo &args,
|
||||||
|
bool requires_multiple_coordinates)
|
||||||
|
{
|
||||||
|
match_parameters_ptr params = std::make_unique<osrm::MatchParameters>();
|
||||||
|
bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates);
|
||||||
|
if (!has_base_params)
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
Napi::Object obj = args[0].As<Napi::Object>();
|
||||||
|
|
||||||
|
if (obj.Has("timestamps"))
|
||||||
|
{
|
||||||
|
Napi::Value timestamps =
|
||||||
|
obj.Get("timestamps");
|
||||||
|
if (timestamps.IsEmpty())
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
if (!timestamps.IsArray())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Timestamps must be an array of integers (or undefined)");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Napi::Array timestamps_array = timestamps.As<Napi::Array>();
|
||||||
|
|
||||||
|
if (params->coordinates.size() != timestamps_array.Length())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Timestamp array must have the same size as the coordinates "
|
||||||
|
"array");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < timestamps_array.Length(); ++i)
|
||||||
|
{
|
||||||
|
Napi::Value timestamp = timestamps_array.Get(i);
|
||||||
|
if (timestamp.IsEmpty())
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
if (!timestamp.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Timestamps array items must be numbers");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
params->timestamps.emplace_back(timestamp.ToNumber().Int64Value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("gaps"))
|
||||||
|
{
|
||||||
|
Napi::Value gaps =
|
||||||
|
obj.Get("gaps");
|
||||||
|
if (gaps.IsEmpty())
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
if (!gaps.IsString())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Gaps must be a string: [split, ignore]");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string gaps_str = gaps.ToString().Utf8Value();
|
||||||
|
|
||||||
|
if (gaps_str == "split")
|
||||||
|
{
|
||||||
|
params->gaps = osrm::MatchParameters::GapsType::Split;
|
||||||
|
}
|
||||||
|
else if (gaps_str == "ignore")
|
||||||
|
{
|
||||||
|
params->gaps = osrm::MatchParameters::GapsType::Ignore;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "'gaps' param must be one of [split, ignore]");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("tidy"))
|
||||||
|
{
|
||||||
|
Napi::Value tidy =
|
||||||
|
obj.Get("tidy");
|
||||||
|
if (tidy.IsEmpty())
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
if (!tidy.IsBoolean())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "tidy must be of type Boolean");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
params->tidy = tidy.ToBoolean().Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.Has("waypoints"))
|
||||||
|
{
|
||||||
|
Napi::Value waypoints =
|
||||||
|
obj.Get("waypoints");
|
||||||
|
if (waypoints.IsEmpty())
|
||||||
|
return match_parameters_ptr();
|
||||||
|
|
||||||
|
// must be array
|
||||||
|
if (!waypoints.IsArray())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(),
|
||||||
|
"Waypoints must be an array of integers corresponding to the input coordinates.");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto waypoints_array = waypoints.As<Napi::Array>();
|
||||||
|
// must have at least two elements
|
||||||
|
if (waypoints_array.Length() < 2)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "At least two waypoints must be provided");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
auto coords_size = params->coordinates.size();
|
||||||
|
auto waypoints_array_size = waypoints_array.Length();
|
||||||
|
|
||||||
|
const auto first_index = waypoints_array.Get(static_cast<uint32_t>(0)).ToNumber().Uint32Value();
|
||||||
|
const auto last_index = waypoints_array.Get(waypoints_array_size - 1).ToNumber().Uint32Value();
|
||||||
|
if (first_index != 0 || last_index != coords_size - 1)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "First and last waypoints values must correspond to first and last "
|
||||||
|
"coordinate indices");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < waypoints_array_size; ++i)
|
||||||
|
{
|
||||||
|
Napi::Value waypoint_value = waypoints_array.Get(i);
|
||||||
|
// all elements must be numbers
|
||||||
|
if (!waypoint_value.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Waypoint values must be an array of integers");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
// check that the waypoint index corresponds with an inpute coordinate
|
||||||
|
const auto index = waypoint_value.ToNumber().Uint32Value();
|
||||||
|
if (index >= coords_size)
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "Waypoints must correspond with the index of an input coordinate");
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
params->waypoints.emplace_back(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parsedSuccessfully = parseCommonParameters(obj, params);
|
||||||
|
if (!parsedSuccessfully)
|
||||||
|
{
|
||||||
|
return match_parameters_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace node_osrm
|
} // namespace node_osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "osrm/trip_parameters.hpp"
|
#include "osrm/trip_parameters.hpp"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <napi.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -26,7 +27,14 @@ Napi::Object Engine::Init(Napi::Env env, Napi::Object exports) {
|
|||||||
Napi::Function func =
|
Napi::Function func =
|
||||||
DefineClass(env,
|
DefineClass(env,
|
||||||
"OSRM",
|
"OSRM",
|
||||||
{InstanceMethod("route", &Engine::route)});
|
{
|
||||||
|
InstanceMethod("route", &Engine::route),
|
||||||
|
InstanceMethod("nearest", &Engine::nearest),
|
||||||
|
InstanceMethod("table", &Engine::table),
|
||||||
|
InstanceMethod("tile", &Engine::tile),
|
||||||
|
InstanceMethod("match", &Engine::match),
|
||||||
|
InstanceMethod("trip", &Engine::trip),
|
||||||
|
});
|
||||||
|
|
||||||
Napi::FunctionReference* constructor = new Napi::FunctionReference();
|
Napi::FunctionReference* constructor = new Napi::FunctionReference();
|
||||||
*constructor = Napi::Persistent(func);
|
*constructor = Napi::Persistent(func);
|
||||||
@ -45,11 +53,11 @@ Engine::Engine(const Napi::CallbackInfo& info)
|
|||||||
if (!config)
|
if (!config)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this_ = std::make_shared<osrm::OSRM>(std::move(*config));
|
this_ = std::make_shared<osrm::OSRM>(*config);
|
||||||
}
|
}
|
||||||
catch (const std::exception &ex)
|
catch (const std::exception &ex)
|
||||||
{
|
{
|
||||||
return ThrowTypeError(info.Env(), ex.what());
|
ThrowTypeError(info.Env(), ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +77,7 @@ inline void async(const Napi::CallbackInfo& info,
|
|||||||
if (!info[info.Length() - 1].IsFunction())
|
if (!info[info.Length() - 1].IsFunction())
|
||||||
return ThrowTypeError(info.Env(), "last argument must be a callback function");
|
return ThrowTypeError(info.Env(), "last argument must be a callback function");
|
||||||
|
|
||||||
auto *const self = Napi::ObjectWrap::Unwrap<Engine>(info.Holder());
|
auto *const self = Napi::ObjectWrap<Engine>::Unwrap(info.This().As<Napi::Object>());
|
||||||
using ParamPtr = decltype(params);
|
using ParamPtr = decltype(params);
|
||||||
|
|
||||||
struct Worker final : Napi::AsyncWorker
|
struct Worker final : Napi::AsyncWorker
|
||||||
@ -132,9 +140,9 @@ inline void async(const Napi::CallbackInfo& info,
|
|||||||
|
|
||||||
void OnOK() override
|
void OnOK() override
|
||||||
{
|
{
|
||||||
Napi::HandleScope scope(Napi::Env());
|
Napi::HandleScope scope{Env()};
|
||||||
|
|
||||||
Callback().Call({Env().Null(), render(result)});
|
Callback().Call({Env().Null(), render(Env(), result)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keeps the OSRM object alive even after shutdown until we're done with callback
|
// Keeps the OSRM object alive even after shutdown until we're done with callback
|
||||||
@ -151,6 +159,117 @@ inline void async(const Napi::CallbackInfo& info,
|
|||||||
worker->Queue();
|
worker->Queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ParameterParser, typename ServiceMemFn>
|
||||||
|
inline void asyncForTiles(const Napi::CallbackInfo &info,
|
||||||
|
ParameterParser argsToParams,
|
||||||
|
ServiceMemFn service,
|
||||||
|
bool requires_multiple_coordinates)
|
||||||
|
{
|
||||||
|
auto params = argsToParams(info, requires_multiple_coordinates);
|
||||||
|
if (!params)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto pluginParams = argumentsToPluginParameters(info);
|
||||||
|
|
||||||
|
BOOST_ASSERT(params->IsValid());
|
||||||
|
|
||||||
|
if (!info[info.Length() - 1].IsFunction())
|
||||||
|
return ThrowTypeError(info.Env(), "last argument must be a callback function");
|
||||||
|
|
||||||
|
auto *const self = Napi::ObjectWrap<Engine>::Unwrap(info.This().As<Napi::Object>());
|
||||||
|
using ParamPtr = decltype(params);
|
||||||
|
|
||||||
|
struct Worker final : Napi::AsyncWorker
|
||||||
|
{
|
||||||
|
Worker(std::shared_ptr<osrm::OSRM> osrm_,
|
||||||
|
ParamPtr params_,
|
||||||
|
ServiceMemFn service,
|
||||||
|
Napi::Function callback,
|
||||||
|
PluginParameters pluginParams_)
|
||||||
|
: Napi::AsyncWorker(callback), osrm{std::move(osrm_)},
|
||||||
|
service{std::move(service)}, params{std::move(params_)}, pluginParams{
|
||||||
|
std::move(pluginParams_)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute() override
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = std::string();
|
||||||
|
const auto status = ((*osrm).*(service))(*params, result);
|
||||||
|
auto str_result = result.get<std::string>();
|
||||||
|
ParseResult(status, str_result);
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
SetError(e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnOK() override
|
||||||
|
{
|
||||||
|
Napi::HandleScope scope{Env()};
|
||||||
|
|
||||||
|
Callback().Call({Env().Null(), render(Env(), result.get<std::string>())});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keeps the OSRM object alive even after shutdown until we're done with callback
|
||||||
|
std::shared_ptr<osrm::OSRM> osrm;
|
||||||
|
ServiceMemFn service;
|
||||||
|
const ParamPtr params;
|
||||||
|
const PluginParameters pluginParams;
|
||||||
|
|
||||||
|
osrm::engine::api::ResultT result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Napi::Function callback = info[info.Length() - 1].As<Napi::Function>();
|
||||||
|
auto worker = new Worker(self->this_, std::move(params), service, callback, std::move(pluginParams));
|
||||||
|
worker->Queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* Returns the fastest route between two or more coordinates while visiting the waypoints in order.
|
||||||
|
*
|
||||||
|
* @name route
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Object} options Object literal containing parameters for the route query.
|
||||||
|
* @param {Array} [options.coordinates] The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||||
|
* @param {Array} [options.bearings] Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||||
|
* 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.
|
||||||
|
* *Please note that even if alternative routes are requested, a result cannot be guaranteed.*
|
||||||
|
* @param {Boolean} [options.steps=false] Return route steps for each route leg.
|
||||||
|
* @param {Array|Boolean} [options.annotations=false] An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all.
|
||||||
|
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview and per step). Can also be `geojson`.
|
||||||
|
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`).
|
||||||
|
* @param {Boolean} [options.continue_straight] Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
|
||||||
|
* @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
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM("berlin-latest.osrm");
|
||||||
|
* osrm.route({coordinates: [[52.519930,13.438640], [52.513191,13.415852]]}, function(err, result) {
|
||||||
|
* if(err) throw err;
|
||||||
|
* console.log(result.waypoints); // array of Waypoint objects representing all waypoints in order
|
||||||
|
* console.log(result.routes); // array of Route objects ordered by descending recommendation rank
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
Napi::Value Engine::route(const Napi::CallbackInfo& info) {
|
Napi::Value Engine::route(const Napi::CallbackInfo& info) {
|
||||||
osrm::Status (osrm::OSRM::*route_fn)(const osrm::RouteParameters ¶ms,
|
osrm::Status (osrm::OSRM::*route_fn)(const osrm::RouteParameters ¶ms,
|
||||||
osrm::engine::api::ResultT &result) const =
|
osrm::engine::api::ResultT &result) const =
|
||||||
@ -159,6 +278,380 @@ Napi::Value Engine::route(const Napi::CallbackInfo& info) {
|
|||||||
return info.Env().Undefined();
|
return info.Env().Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* Snaps a coordinate to the street network and returns the nearest n matches.
|
||||||
|
*
|
||||||
|
* Note: `coordinates` in the general options only supports a single `{longitude},{latitude}` entry.
|
||||||
|
*
|
||||||
|
* @name nearest
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Object} options - Object literal containing parameters for the nearest query.
|
||||||
|
* @param {Array} [options.coordinates] The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||||
|
* @param {Array} [options.bearings] Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||||
|
* 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 {Boolean} [options.generate_hints=true] Whether or not adds a Hint to the response which can be used in subsequent requests.
|
||||||
|
* @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
|
||||||
|
*
|
||||||
|
* @returns {Object} containing `waypoints`.
|
||||||
|
* **`waypoints`**: array of [`Ẁaypoint`](#waypoint) objects sorted by distance to the input coordinate.
|
||||||
|
* Each object has an additional `distance` property, which is the distance in meters to the supplied input coordinate.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM('network.osrm');
|
||||||
|
* var options = {
|
||||||
|
* coordinates: [[13.388860,52.517037]],
|
||||||
|
* number: 3,
|
||||||
|
* bearings: [[0,20]]
|
||||||
|
* };
|
||||||
|
* osrm.nearest(options, function(err, response) {
|
||||||
|
* console.log(response.waypoints); // array of Waypoint objects
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
Napi::Value Engine::nearest(const Napi::CallbackInfo& info)
|
||||||
|
{
|
||||||
|
osrm::Status (osrm::OSRM::*nearest_fn)(const osrm::NearestParameters ¶ms,
|
||||||
|
osrm::engine::api::ResultT &result) const =
|
||||||
|
&osrm::OSRM::Nearest;
|
||||||
|
async(info, &argumentsToNearestParameter, nearest_fn, false);
|
||||||
|
return info.Env().Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* Computes duration table for the given locations. Allows for both symmetric and asymmetric tables.
|
||||||
|
* Optionally returns distance table.
|
||||||
|
*
|
||||||
|
* @name table
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Object} options - Object literal containing parameters for the table query.
|
||||||
|
* @param {Array} [options.coordinates] The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||||
|
* @param {Array} [options.bearings] Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||||
|
* 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 {Boolean} [options.generate_hints=true] Whether or not adds a Hint to the response which can be used in subsequent requests.
|
||||||
|
* @param {Array} [options.sources] An array of `index` elements (`0 <= integer < #coordinates`) to use
|
||||||
|
* location with given index as source. Default is to use all.
|
||||||
|
* @param {Array} [options.destinations] An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all.
|
||||||
|
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
||||||
|
* @param {Number} [options.fallback_speed] Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
|
||||||
|
* @param {String} [options.fallback_coordinate] Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies distance between two points.
|
||||||
|
* @param {Number} [options.scale_factor] Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
|
||||||
|
* @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 {Array} [options.annotations] Return the requested table or tables in response. Can be `['duration']` (return the duration matrix, default), `[distance']` (return the distance matrix), or `['duration', distance']` (return both the duration matrix and the distance matrix).
|
||||||
|
* @param {Function} callback
|
||||||
|
*
|
||||||
|
* @returns {Object} containing `durations`, `distances`, `sources`, and `destinations`.
|
||||||
|
* **`durations`**: array of arrays that stores the matrix in row-major order. `durations[i][j]` gives the travel time from the i-th waypoint to the j-th waypoint.
|
||||||
|
* Values are given in seconds.
|
||||||
|
* **`distances`**: array of arrays that stores the matrix in row-major order. `distances[i][j]` gives the travel time from the i-th waypoint to the j-th waypoint.
|
||||||
|
* Values are given in meters.
|
||||||
|
* **`sources`**: array of [`Ẁaypoint`](#waypoint) objects describing all sources in order.
|
||||||
|
* **`destinations`**: array of [`Ẁaypoint`](#waypoint) objects describing all destinations in order.
|
||||||
|
* **`fallback_speed_cells`**: (optional) if `fallback_speed` is used, will be an array of arrays of `row,column` values, indicating which cells contain estimated values.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM('network.osrm');
|
||||||
|
* var options = {
|
||||||
|
* coordinates: [
|
||||||
|
* [13.388860,52.517037],
|
||||||
|
* [13.397634,52.529407],
|
||||||
|
* [13.428555,52.523219]
|
||||||
|
* ]
|
||||||
|
* };
|
||||||
|
* osrm.table(options, function(err, response) {
|
||||||
|
* console.log(response.durations); // array of arrays, matrix in row-major order
|
||||||
|
* console.log(response.distances); // array of arrays, matrix in row-major order
|
||||||
|
* console.log(response.sources); // array of Waypoint objects
|
||||||
|
* console.log(response.destinations); // array of Waypoint objects
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
Napi::Value Engine::table(const Napi::CallbackInfo& info)
|
||||||
|
{
|
||||||
|
osrm::Status (osrm::OSRM::*table_fn)(const osrm::TableParameters ¶ms,
|
||||||
|
osrm::engine::api::ResultT &result) const =
|
||||||
|
&osrm::OSRM::Table;
|
||||||
|
async(info, &argumentsToTableParameter, table_fn, true);
|
||||||
|
return info.Env().Undefined();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* This generates [Mapbox Vector Tiles](https://mapbox.com/vector-tiles) that can be viewed with a
|
||||||
|
* vector-tile capable slippy-map viewer. The tiles contain road geometries and metadata that can
|
||||||
|
* be used to examine the routing graph. The tiles are generated directly from the data in-memory,
|
||||||
|
* so are in sync with actual routing results, and let you examine which roads are actually
|
||||||
|
* routable,
|
||||||
|
* and what weights they have applied.
|
||||||
|
*
|
||||||
|
* @name tile
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Array} ZXY - an array consisting of `x`, `y`, and `z` values representing tile coordinates like
|
||||||
|
* [wiki.openstreetmap.org/wiki/Slippy_map_tilenames](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames)
|
||||||
|
* and are supported by vector tile viewers like [Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api/).
|
||||||
|
* @param {Function} callback
|
||||||
|
*
|
||||||
|
* @returns {Buffer} contains a Protocol Buffer encoded vector tile.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM('network.osrm');
|
||||||
|
* osrm.tile([0, 0, 0], function(err, response) {
|
||||||
|
* if (err) throw err;
|
||||||
|
* fs.writeFileSync('./tile.vector.pbf', response); // write the buffer to a file
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
Napi::Value Engine::tile(const Napi::CallbackInfo& info)
|
||||||
|
{
|
||||||
|
osrm::Status (osrm::OSRM::*tile_fn)(const osrm::TileParameters ¶ms,
|
||||||
|
osrm::engine::api::ResultT &result) const =
|
||||||
|
&osrm::OSRM::Tile;
|
||||||
|
asyncForTiles(info, &argumentsToTileParameters, tile_fn, {/*unused*/});
|
||||||
|
return info.Env().Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* Map matching matches given GPS points to the road network in the most plausible way.
|
||||||
|
* Please note the request might result multiple sub-traces. Large jumps in the timestamps
|
||||||
|
* (>60s) or improbable transitions lead to trace splits if a complete matching could
|
||||||
|
* not be found. The algorithm might not be able to match all points. Outliers are removed
|
||||||
|
* if they can not be matched successfully.
|
||||||
|
*
|
||||||
|
* @name match
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Object} options - Object literal containing parameters for the match query.
|
||||||
|
* @param {Array} [options.coordinates] The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||||
|
* @param {Array} [options.bearings] Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||||
|
* Can be `null` or an array of `[{value},{range}]` with `integer 0 .. 360,integer 0 .. 180`.
|
||||||
|
* @param {Array} [options.hints] Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||||
|
* @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.steps=false] Return route steps for each route.
|
||||||
|
* @param {Array|Boolean} [options.annotations=false] An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all.
|
||||||
|
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview and per step). Can also be `geojson`.
|
||||||
|
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`).
|
||||||
|
* @param {Array<Number>} [options.timestamps] Timestamp of the input location (integers, UNIX-like timestamp).
|
||||||
|
* @param {Array} [options.radiuses] Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy. Can be `null` for default value `5` meters or `double >= 0`.
|
||||||
|
* @param {String} [options.gaps=split] Allows the input track splitting based on huge timestamp gaps between points. Either `split` or `ignore`.
|
||||||
|
* @param {Boolean} [options.tidy=false] Allows the input track modification to obtain better matching quality for noisy tracks.
|
||||||
|
* @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 {Function} callback
|
||||||
|
*
|
||||||
|
* @returns {Object} containing `tracepoints` and `matchings`.
|
||||||
|
* **`tracepoints`** Array of [`Ẁaypoint`](#waypoint) objects representing all points of the trace in order.
|
||||||
|
* If the trace point was ommited by map matching because it is an outlier, the entry will be null.
|
||||||
|
* Each `Waypoint` object has the following additional properties,
|
||||||
|
* 1) `matchings_index`: Index to the
|
||||||
|
* [`Route`](#route) object in matchings the sub-trace was matched to,
|
||||||
|
* 2) `waypoint_index`: Index of
|
||||||
|
* the waypoint inside the matched route.
|
||||||
|
* 3) `alternatives_count`: Number of probable alternative matchings for this trace point. A value of zero indicate that this point was matched unambiguously. Split the trace at these points for incremental map matching.
|
||||||
|
* **`matchings`** is an array of [`Route`](#route) objects that assemble the trace. Each `Route` object has an additional `confidence` property,
|
||||||
|
* which is the confidence of the matching. float value between `0` and `1`. `1` is very confident that the matching is correct.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM('network.osrm');
|
||||||
|
* var options = {
|
||||||
|
* coordinates: [[13.393252,52.542648],[13.39478,52.543079],[13.397389,52.542107]],
|
||||||
|
* timestamps: [1424684612, 1424684616, 1424684620]
|
||||||
|
* };
|
||||||
|
* osrm.match(options, function(err, response) {
|
||||||
|
* if (err) throw err;
|
||||||
|
* console.log(response.tracepoints); // array of Waypoint objects
|
||||||
|
* console.log(response.matchings); // array of Route objects
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
Napi::Value Engine::match(const Napi::CallbackInfo& info)
|
||||||
|
{
|
||||||
|
osrm::Status (osrm::OSRM::*match_fn)(const osrm::MatchParameters ¶ms,
|
||||||
|
osrm::engine::api::ResultT &result) const =
|
||||||
|
&osrm::OSRM::Match;
|
||||||
|
async(info, &argumentsToMatchParameter, match_fn, true);
|
||||||
|
return info.Env().Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* The trip plugin solves the Traveling Salesman Problem using a greedy heuristic
|
||||||
|
* (farthest-insertion algorithm) for 10 or * more waypoints and uses brute force for less than 10
|
||||||
|
* waypoints. The returned path does not have to be the shortest path, * as TSP is NP-hard it is
|
||||||
|
* only an approximation.
|
||||||
|
*
|
||||||
|
* Note that all input coordinates have to be connected for the trip service to work.
|
||||||
|
* Currently, not all combinations of `roundtrip`, `source` and `destination` are supported.
|
||||||
|
* Right now, the following combinations are possible:
|
||||||
|
*
|
||||||
|
* | roundtrip | source | destination | supported |
|
||||||
|
* | :-- | :-- | :-- | :-- |
|
||||||
|
* | true | first | last | **yes** |
|
||||||
|
* | true | first | any | **yes** |
|
||||||
|
* | true | any | last | **yes** |
|
||||||
|
* | true | any | any | **yes** |
|
||||||
|
* | false | first | last | **yes** |
|
||||||
|
* | false | first | any | no |
|
||||||
|
* | false | any | last | no |
|
||||||
|
* | false | any | any | no |
|
||||||
|
*
|
||||||
|
* @name trip
|
||||||
|
* @memberof OSRM
|
||||||
|
* @param {Object} options - Object literal containing parameters for the trip query.
|
||||||
|
* @param {Array} [options.coordinates] The coordinates this request will use, coordinates as `[{lon},{lat}]` values, in decimal degrees.
|
||||||
|
* @param {Array} [options.bearings] Limits the search to segments with given bearing in degrees towards true north in clockwise direction.
|
||||||
|
* 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 `double >= 0` or `null` (unlimited, default).
|
||||||
|
* @param {Array} [options.hints] Hints for the coordinate snapping. Array of base64 encoded strings.
|
||||||
|
* @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.steps=false] Return route steps for each route.
|
||||||
|
* @param {Array|Boolean} [options.annotations=false] An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all.
|
||||||
|
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview and per step). Can also be `geojson`.
|
||||||
|
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified`
|
||||||
|
* @param {Function} callback
|
||||||
|
* @param {Boolean} [options.roundtrip=true] Return route is a roundtrip.
|
||||||
|
* @param {String} [options.source=any] Return route starts at `any` or `first` coordinate.
|
||||||
|
* @param {String} [options.destination=any] Return route ends at `any` or `last` coordinate.
|
||||||
|
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @returns {Object} containing `waypoints` and `trips`.
|
||||||
|
* **`waypoints`**: an array of [`Waypoint`](#waypoint) objects representing all waypoints in input order.
|
||||||
|
* Each Waypoint object has the following additional properties,
|
||||||
|
* 1) `trips_index`: index to trips of the sub-trip the point was matched to, and
|
||||||
|
* 2) `waypoint_index`: index of the point in the trip.
|
||||||
|
* **`trips`**: an array of [`Route`](#route) objects that assemble the trace.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var osrm = new OSRM('network.osrm');
|
||||||
|
* var options = {
|
||||||
|
* coordinates: [
|
||||||
|
* [13.36761474609375, 52.51663871100423],
|
||||||
|
* [13.374481201171875, 52.506191342034576]
|
||||||
|
* ],
|
||||||
|
* source: "first",
|
||||||
|
* destination: "last",
|
||||||
|
* roundtrip: false
|
||||||
|
* }
|
||||||
|
* osrm.trip(options, function(err, response) {
|
||||||
|
* if (err) throw err;
|
||||||
|
* console.log(response.waypoints); // array of Waypoint objects
|
||||||
|
* console.log(response.trips); // array of Route objects
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
Napi::Value Engine::trip(const Napi::CallbackInfo& info)
|
||||||
|
{
|
||||||
|
osrm::Status (osrm::OSRM::*trip_fn)(const osrm::TripParameters ¶ms,
|
||||||
|
osrm::engine::api::ResultT &result) const =
|
||||||
|
&osrm::OSRM::Trip;
|
||||||
|
async(info, &argumentsToTripParameter, trip_fn, true);
|
||||||
|
return info.Env().Undefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All plugins support a second additional object that is available to configure some NodeJS
|
||||||
|
* specific behaviours.
|
||||||
|
*
|
||||||
|
* @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 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');
|
||||||
|
* var options = {
|
||||||
|
* coordinates: [
|
||||||
|
* [13.36761474609375, 52.51663871100423],
|
||||||
|
* [13.374481201171875, 52.506191342034576]
|
||||||
|
* ]
|
||||||
|
* };
|
||||||
|
* osrm.route(options, { format: "buffer" }, function(err, response) {
|
||||||
|
* if (err) throw err;
|
||||||
|
* console.log(response.toString("utf-8"));
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Responses
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a route through (potentially multiple) waypoints.
|
||||||
|
*
|
||||||
|
* @name Route
|
||||||
|
* @memberof Responses
|
||||||
|
*
|
||||||
|
* @param {documentation} external in
|
||||||
|
* [`osrm-backend`](../http.md#route-object)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a route between two waypoints.
|
||||||
|
*
|
||||||
|
* @name RouteLeg
|
||||||
|
* @memberof Responses
|
||||||
|
*
|
||||||
|
* @param {documentation} external in
|
||||||
|
* [`osrm-backend`](../http.md#routeleg-object)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A step consists of a maneuver such as a turn or merge, followed by a distance of travel along a
|
||||||
|
* single way to the subsequent step.
|
||||||
|
*
|
||||||
|
* @name RouteStep
|
||||||
|
* @memberof Responses
|
||||||
|
*
|
||||||
|
* @param {documentation} external in
|
||||||
|
* [`osrm-backend`](../http.md#routestep-object)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @name StepManeuver
|
||||||
|
* @memberof Responses
|
||||||
|
*
|
||||||
|
* @param {documentation} external in
|
||||||
|
* [`osrm-backend`](../http.md#stepmaneuver-object)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object used to describe waypoint on a route.
|
||||||
|
*
|
||||||
|
* @name Waypoint
|
||||||
|
* @memberof Responses
|
||||||
|
*
|
||||||
|
* @param {documentation} external in
|
||||||
|
* [`osrm-backend`](../http.md#waypoint-object)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
} // namespace node_osrm
|
} // namespace node_osrm
|
||||||
|
|
||||||
Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
|
Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user