// #ifndef OSRM_BINDINGS_NODE_SUPPORT_HPP // #define OSRM_BINDINGS_NODE_SUPPORT_HPP // #include "nodejs/json_v8_renderer.hpp" // #include "engine/api/flatbuffers/fbresult_generated.h" // #include "osrm/approach.hpp" // #include "osrm/bearing.hpp" // #include "osrm/coordinate.hpp" // #include "osrm/engine_config.hpp" // #include "osrm/json_container.hpp" // #include "osrm/match_parameters.hpp" // #include "osrm/nearest_parameters.hpp" // #include "osrm/osrm.hpp" // #include "osrm/route_parameters.hpp" // #include "osrm/status.hpp" // #include "osrm/storage_config.hpp" // #include "osrm/table_parameters.hpp" // #include "osrm/tile_parameters.hpp" // #include "osrm/trip_parameters.hpp" // #include "util/json_renderer.hpp" // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // namespace node_osrm // { // using engine_config_ptr = std::unique_ptr; // using route_parameters_ptr = std::unique_ptr; // using trip_parameters_ptr = std::unique_ptr; // using tile_parameters_ptr = std::unique_ptr; // using match_parameters_ptr = std::unique_ptr; // using nearest_parameters_ptr = std::unique_ptr; // using table_parameters_ptr = std::unique_ptr; // struct PluginParameters // { // bool renderToBuffer = false; // }; // using ObjectOrString = typename mapbox::util::variant; // template inline v8::Local render(const ResultT &result); // template <> v8::Local inline render(const std::string &result) // { // return Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked(); // } // template <> v8::Local inline render(const ObjectOrString &result) // { // if (result.is()) // { // // Convert osrm::json object tree into matching v8 object tree // v8::Local value; // renderToV8(value, result.get()); // return value; // } // else // { // // Return the string object as a node Buffer // return Nan::CopyBuffer(result.get().data(), result.get().size()) // .ToLocalChecked(); // } // } // 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().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 engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo &args) // { // Nan::HandleScope scope; // auto engine_config = std::make_unique(); // if (args.Length() == 0) // { // return engine_config; // } // else if (args.Length() > 1) // { // Nan::ThrowError("Only accepts one parameter"); // return engine_config_ptr(); // } // BOOST_ASSERT(args.Length() == 1); // if (args[0]->IsString()) // { // engine_config->storage_config = // osrm::StorageConfig(*Nan::Utf8String(Nan::To(args[0]).ToLocalChecked())); // engine_config->use_shared_memory = false; // return engine_config; // } // else if (!args[0]->IsObject()) // { // Nan::ThrowError("Parameter must be a path or options object"); // return engine_config_ptr(); // } // BOOST_ASSERT(args[0]->IsObject()); // auto params = Nan::To(args[0]).ToLocalChecked(); // auto path = Nan::Get(params, Nan::New("path").ToLocalChecked()).ToLocalChecked(); // if (path.IsEmpty()) // return engine_config_ptr(); // auto memory_file = Nan::Get(params, Nan::New("memory_file").ToLocalChecked()).ToLocalChecked(); // if (memory_file.IsEmpty()) // return engine_config_ptr(); // auto shared_memory = // Nan::Get(params, Nan::New("shared_memory").ToLocalChecked()).ToLocalChecked(); // if (shared_memory.IsEmpty()) // return engine_config_ptr(); // auto mmap_memory = Nan::Get(params, Nan::New("mmap_memory").ToLocalChecked()).ToLocalChecked(); // if (mmap_memory.IsEmpty()) // return engine_config_ptr(); // if (!memory_file->IsUndefined()) // { // if (path->IsUndefined()) // { // Nan::ThrowError("memory_file option requires a path to a file."); // return engine_config_ptr(); // } // engine_config->memory_file = // *Nan::Utf8String(Nan::To(memory_file).ToLocalChecked()); // } // auto dataset_name = // Nan::Get(params, Nan::New("dataset_name").ToLocalChecked()).ToLocalChecked(); // if (dataset_name.IsEmpty()) // return engine_config_ptr(); // if (!dataset_name->IsUndefined()) // { // if (dataset_name->IsString()) // { // engine_config->dataset_name = // *Nan::Utf8String(Nan::To(dataset_name).ToLocalChecked()); // } // else // { // Nan::ThrowError("dataset_name needs to be a string"); // return engine_config_ptr(); // } // } // if (!path->IsUndefined()) // { // engine_config->storage_config = // osrm::StorageConfig(*Nan::Utf8String(Nan::To(path).ToLocalChecked())); // engine_config->use_shared_memory = false; // } // if (!shared_memory->IsUndefined()) // { // if (shared_memory->IsBoolean()) // { // engine_config->use_shared_memory = Nan::To(shared_memory).FromJust(); // } // else // { // Nan::ThrowError("Shared_memory option must be a boolean"); // return engine_config_ptr(); // } // } // if (!mmap_memory->IsUndefined()) // { // if (mmap_memory->IsBoolean()) // { // engine_config->use_mmap = Nan::To(mmap_memory).FromJust(); // } // else // { // Nan::ThrowError("mmap_memory option must be a boolean"); // return engine_config_ptr(); // } // } // if (path->IsUndefined() && !engine_config->use_shared_memory) // { // Nan::ThrowError("Shared_memory must be enabled if no path is " // "specified"); // return engine_config_ptr(); // } // auto algorithm = Nan::Get(params, Nan::New("algorithm").ToLocalChecked()).ToLocalChecked(); // if (algorithm.IsEmpty()) // return engine_config_ptr(); // if (algorithm->IsString()) // { // auto algorithm_str = Nan::To(algorithm).ToLocalChecked(); // if (*Nan::Utf8String(algorithm_str) == std::string("CH")) // { // engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; // } // else if (*Nan::Utf8String(algorithm_str) == std::string("CoreCH")) // { // engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; // } // else if (*Nan::Utf8String(algorithm_str) == std::string("MLD")) // { // engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD; // } // else // { // Nan::ThrowError("algorithm option must be one of 'CH', 'CoreCH', or 'MLD'."); // return engine_config_ptr(); // } // } // else if (!algorithm->IsUndefined()) // { // Nan::ThrowError("algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'."); // return engine_config_ptr(); // } // // Set EngineConfig system-wide limits on construction, if requested // auto max_locations_trip = // Nan::Get(params, Nan::New("max_locations_trip").ToLocalChecked()).ToLocalChecked(); // auto max_locations_viaroute = // Nan::Get(params, Nan::New("max_locations_viaroute").ToLocalChecked()).ToLocalChecked(); // auto max_locations_distance_table = // Nan::Get(params, Nan::New("max_locations_distance_table").ToLocalChecked()) // .ToLocalChecked(); // auto max_locations_map_matching = // Nan::Get(params, Nan::New("max_locations_map_matching").ToLocalChecked()).ToLocalChecked(); // auto max_results_nearest = // Nan::Get(params, Nan::New("max_results_nearest").ToLocalChecked()).ToLocalChecked(); // auto max_alternatives = // Nan::Get(params, Nan::New("max_alternatives").ToLocalChecked()).ToLocalChecked(); // auto max_radius_map_matching = // Nan::Get(params, Nan::New("max_radius_map_matching").ToLocalChecked()).ToLocalChecked(); // if (!max_locations_trip->IsUndefined() && !max_locations_trip->IsNumber()) // { // Nan::ThrowError("max_locations_trip must be an integral number"); // return engine_config_ptr(); // } // if (!max_locations_viaroute->IsUndefined() && !max_locations_viaroute->IsNumber()) // { // Nan::ThrowError("max_locations_viaroute must be an integral number"); // return engine_config_ptr(); // } // if (!max_locations_distance_table->IsUndefined() && !max_locations_distance_table->IsNumber()) // { // Nan::ThrowError("max_locations_distance_table must be an integral number"); // return engine_config_ptr(); // } // if (!max_locations_map_matching->IsUndefined() && !max_locations_map_matching->IsNumber()) // { // Nan::ThrowError("max_locations_map_matching must be an integral number"); // return engine_config_ptr(); // } // if (!max_results_nearest->IsUndefined() && !max_results_nearest->IsNumber()) // { // Nan::ThrowError("max_results_nearest must be an integral number"); // return engine_config_ptr(); // } // if (!max_alternatives->IsUndefined() && !max_alternatives->IsNumber()) // { // Nan::ThrowError("max_alternatives must be an integral number"); // return engine_config_ptr(); // } // if (max_locations_trip->IsNumber()) // engine_config->max_locations_trip = Nan::To(max_locations_trip).FromJust(); // if (max_locations_viaroute->IsNumber()) // engine_config->max_locations_viaroute = Nan::To(max_locations_viaroute).FromJust(); // if (max_locations_distance_table->IsNumber()) // engine_config->max_locations_distance_table = // Nan::To(max_locations_distance_table).FromJust(); // if (max_locations_map_matching->IsNumber()) // engine_config->max_locations_map_matching = // Nan::To(max_locations_map_matching).FromJust(); // if (max_results_nearest->IsNumber()) // engine_config->max_results_nearest = Nan::To(max_results_nearest).FromJust(); // if (max_alternatives->IsNumber()) // engine_config->max_alternatives = Nan::To(max_alternatives).FromJust(); // if (max_radius_map_matching->IsNumber()) // engine_config->max_radius_map_matching = // Nan::To(max_radius_map_matching).FromJust(); // return engine_config; // } // inline boost::optional> // parseCoordinateArray(const v8::Local &coordinates_array) // { // Nan::HandleScope scope; // boost::optional> resulting_coordinates; // std::vector temp_coordinates; // for (uint32_t i = 0; i < coordinates_array->Length(); ++i) // { // v8::Local coordinate = Nan::Get(coordinates_array, i).ToLocalChecked(); // if (coordinate.IsEmpty()) // return resulting_coordinates; // if (!coordinate->IsArray()) // { // Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs"); // return resulting_coordinates; // } // v8::Local coordinate_pair = v8::Local::Cast(coordinate); // if (coordinate_pair->Length() != 2) // { // Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs"); // return resulting_coordinates; // } // if (!Nan::Get(coordinate_pair, 0).ToLocalChecked()->IsNumber() || // !Nan::Get(coordinate_pair, 1).ToLocalChecked()->IsNumber()) // { // Nan::ThrowError("Each member of a coordinate pair must be a number"); // return resulting_coordinates; // } // double lon = Nan::To(Nan::Get(coordinate_pair, 0).ToLocalChecked()).FromJust(); // double lat = Nan::To(Nan::Get(coordinate_pair, 1).ToLocalChecked()).FromJust(); // if (std::isnan(lon) || std::isnan(lat) || std::isinf(lon) || std::isinf(lat)) // { // Nan::ThrowError("Lng/Lat coordinates must be valid numbers"); // return resulting_coordinates; // } // if (lon > 180 || lon < -180 || lat > 90 || lat < -90) // { // Nan::ThrowError("Lng/Lat coordinates must be within world bounds " // "(-180 < lng < 180, -90 < lat < 90)"); // return resulting_coordinates; // } // temp_coordinates.emplace_back(osrm::util::FloatLongitude{std::move(lon)}, // osrm::util::FloatLatitude{std::move(lat)}); // } // resulting_coordinates = boost::make_optional(std::move(temp_coordinates)); // return resulting_coordinates; // } // // Parses all the non-service specific parameters // template // inline bool argumentsToParameter(const Nan::FunctionCallbackInfo &args, // ParamType ¶ms, // bool requires_multiple_coordinates) // { // Nan::HandleScope scope; // if (args.Length() < 2) // { // Nan::ThrowTypeError("Two arguments required"); // return false; // } // if (!args[0]->IsObject()) // { // Nan::ThrowTypeError("First arg must be an object"); // return false; // } // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // v8::Local coordinates = // Nan::Get(obj, Nan::New("coordinates").ToLocalChecked()).ToLocalChecked(); // if (coordinates.IsEmpty()) // return false; // if (coordinates->IsUndefined()) // { // Nan::ThrowError("Must provide a coordinates property"); // return false; // } // else if (coordinates->IsArray()) // { // auto coordinates_array = v8::Local::Cast(coordinates); // if (coordinates_array->Length() < 2 && requires_multiple_coordinates) // { // Nan::ThrowError("At least two coordinates must be provided"); // return false; // } // else if (!requires_multiple_coordinates && coordinates_array->Length() != 1) // { // Nan::ThrowError("Exactly one coordinate pair must be provided"); // return false; // } // auto maybe_coordinates = parseCoordinateArray(coordinates_array); // if (maybe_coordinates) // { // std::copy(maybe_coordinates->begin(), // maybe_coordinates->end(), // std::back_inserter(params->coordinates)); // } // else // { // return false; // } // } // else if (!coordinates->IsUndefined()) // { // BOOST_ASSERT(!coordinates->IsArray()); // Nan::ThrowError("Coordinates must be an array of (lon/lat) pairs"); // return false; // } // if (Nan::Has(obj, Nan::New("approaches").ToLocalChecked()).FromJust()) // { // v8::Local approaches = // Nan::Get(obj, Nan::New("approaches").ToLocalChecked()).ToLocalChecked(); // if (approaches.IsEmpty()) // return false; // if (!approaches->IsArray()) // { // Nan::ThrowError("Approaches must be an arrays of strings"); // return false; // } // auto approaches_array = v8::Local::Cast(approaches); // if (approaches_array->Length() != params->coordinates.size()) // { // Nan::ThrowError("Approaches array must have the same length as coordinates array"); // return false; // } // for (uint32_t i = 0; i < approaches_array->Length(); ++i) // { // v8::Local approach_raw = Nan::Get(approaches_array, i).ToLocalChecked(); // if (approach_raw.IsEmpty()) // return false; // if (approach_raw->IsNull()) // { // params->approaches.emplace_back(); // } // else if (approach_raw->IsString()) // { // const Nan::Utf8String approach_utf8str(approach_raw); // std::string approach_str{*approach_utf8str, // *approach_utf8str + approach_utf8str.length()}; // if (approach_str == "curb") // { // params->approaches.push_back(osrm::Approach::CURB); // } // else if (approach_str == "unrestricted") // { // params->approaches.push_back(osrm::Approach::UNRESTRICTED); // } // else // { // Nan::ThrowError("'approaches' param must be one of [curb, unrestricted]"); // return false; // } // } // else // { // Nan::ThrowError("Approach must be a string: [curb, unrestricted] or null"); // return false; // } // } // } // if (Nan::Has(obj, Nan::New("bearings").ToLocalChecked()).FromJust()) // { // v8::Local bearings = // Nan::Get(obj, Nan::New("bearings").ToLocalChecked()).ToLocalChecked(); // if (bearings.IsEmpty()) // return false; // if (!bearings->IsArray()) // { // Nan::ThrowError("Bearings must be an array of arrays of numbers"); // return false; // } // auto bearings_array = v8::Local::Cast(bearings); // if (bearings_array->Length() != params->coordinates.size()) // { // Nan::ThrowError("Bearings array must have the same length as coordinates array"); // return false; // } // for (uint32_t i = 0; i < bearings_array->Length(); ++i) // { // v8::Local bearing_raw = Nan::Get(bearings_array, i).ToLocalChecked(); // if (bearing_raw.IsEmpty()) // return false; // if (bearing_raw->IsNull()) // { // params->bearings.emplace_back(); // } // else if (bearing_raw->IsArray()) // { // auto bearing_pair = v8::Local::Cast(bearing_raw); // if (bearing_pair->Length() == 2) // { // if (!Nan::Get(bearing_pair, 0).ToLocalChecked()->IsNumber() || // !Nan::Get(bearing_pair, 1).ToLocalChecked()->IsNumber()) // { // Nan::ThrowError("Bearing values need to be numbers in range 0..360"); // return false; // } // const auto bearing = // Nan::To(Nan::Get(bearing_pair, 0).ToLocalChecked()).FromJust(); // const auto range = // Nan::To(Nan::Get(bearing_pair, 1).ToLocalChecked()).FromJust(); // if (bearing < 0 || bearing > 360 || range < 0 || range > 180) // { // Nan::ThrowError("Bearing values need to be in range 0..360, 0..180"); // return false; // } // params->bearings.push_back( // osrm::Bearing{static_cast(bearing), static_cast(range)}); // } // else // { // Nan::ThrowError("Bearing must be an array of [bearing, range] or null"); // return false; // } // } // else // { // Nan::ThrowError("Bearing must be an array of [bearing, range] or null"); // return false; // } // } // } // if (Nan::Has(obj, Nan::New("hints").ToLocalChecked()).FromJust()) // { // v8::Local hints = // Nan::Get(obj, Nan::New("hints").ToLocalChecked()).ToLocalChecked(); // if (hints.IsEmpty()) // return false; // if (!hints->IsArray()) // { // Nan::ThrowError("Hints must be an array of strings/null"); // return false; // } // v8::Local hints_array = v8::Local::Cast(hints); // if (hints_array->Length() != params->coordinates.size()) // { // Nan::ThrowError("Hints array must have the same length as coordinates array"); // return false; // } // for (uint32_t i = 0; i < hints_array->Length(); ++i) // { // v8::Local hint = Nan::Get(hints_array, i).ToLocalChecked(); // if (hint.IsEmpty()) // return false; // if (hint->IsString()) // { // if (Nan::To(hint).ToLocalChecked()->Length() == 0) // { // Nan::ThrowError("Hint cannot be an empty string"); // return false; // } // params->hints.push_back(osrm::engine::Hint::FromBase64(*Nan::Utf8String(hint))); // } // else if (hint->IsNull()) // { // params->hints.emplace_back(); // } // else // { // Nan::ThrowError("Hint must be null or string"); // return false; // } // } // } // if (Nan::Has(obj, Nan::New("radiuses").ToLocalChecked()).FromJust()) // { // v8::Local radiuses = // Nan::Get(obj, Nan::New("radiuses").ToLocalChecked()).ToLocalChecked(); // if (radiuses.IsEmpty()) // return false; // if (!radiuses->IsArray()) // { // Nan::ThrowError("Radiuses must be an array of non-negative doubles or null"); // return false; // } // v8::Local radiuses_array = v8::Local::Cast(radiuses); // if (radiuses_array->Length() != params->coordinates.size()) // { // Nan::ThrowError("Radiuses array must have the same length as coordinates array"); // return false; // } // for (uint32_t i = 0; i < radiuses_array->Length(); ++i) // { // v8::Local radius = Nan::Get(radiuses_array, i).ToLocalChecked(); // if (radius.IsEmpty()) // return false; // if (radius->IsNull()) // { // params->radiuses.emplace_back(); // } // else if (radius->IsNumber() && Nan::To(radius).FromJust() >= 0) // { // params->radiuses.push_back(Nan::To(radius).FromJust()); // } // else // { // Nan::ThrowError("Radius must be non-negative double or null"); // return false; // } // } // } // if (Nan::Has(obj, Nan::New("generate_hints").ToLocalChecked()).FromJust()) // { // v8::Local generate_hints = // Nan::Get(obj, Nan::New("generate_hints").ToLocalChecked()).ToLocalChecked(); // if (generate_hints.IsEmpty()) // return false; // if (!generate_hints->IsBoolean()) // { // Nan::ThrowError("generate_hints must be of type Boolean"); // return false; // } // params->generate_hints = Nan::To(generate_hints).FromJust(); // } // if (Nan::Has(obj, Nan::New("skip_waypoints").ToLocalChecked()).FromJust()) // { // v8::Local skip_waypoints = // Nan::Get(obj, Nan::New("skip_waypoints").ToLocalChecked()).ToLocalChecked(); // if (skip_waypoints.IsEmpty()) // return false; // if (!skip_waypoints->IsBoolean()) // { // Nan::ThrowError("skip_waypoints must be of type Boolean"); // return false; // } // params->skip_waypoints = Nan::To(skip_waypoints).FromJust(); // } // if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust()) // { // v8::Local exclude = // Nan::Get(obj, Nan::New("exclude").ToLocalChecked()).ToLocalChecked(); // if (exclude.IsEmpty()) // return false; // if (!exclude->IsArray()) // { // Nan::ThrowError("Exclude must be an array of strings or empty"); // return false; // } // v8::Local exclude_array = v8::Local::Cast(exclude); // for (uint32_t i = 0; i < exclude_array->Length(); ++i) // { // v8::Local class_name = Nan::Get(exclude_array, i).ToLocalChecked(); // if (class_name.IsEmpty()) // return false; // if (class_name->IsString()) // { // std::string class_name_str = *Nan::Utf8String(class_name); // params->exclude.emplace_back(class_name_str); // } // else // { // Nan::ThrowError("Exclude must be an array of strings or empty"); // return false; // } // } // } // 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; // } // } // if (Nan::Has(obj, Nan::New("snapping").ToLocalChecked()).FromJust()) // { // v8::Local snapping = // Nan::Get(obj, Nan::New("snapping").ToLocalChecked()).ToLocalChecked(); // if (snapping.IsEmpty()) // return false; // if (!snapping->IsString()) // { // Nan::ThrowError("Snapping must be a string: [default, any]"); // return false; // } // const Nan::Utf8String snapping_utf8str(snapping); // std::string snapping_str{*snapping_utf8str, *snapping_utf8str + snapping_utf8str.length()}; // if (snapping_str == "default") // { // params->snapping = osrm::RouteParameters::SnappingType::Default; // } // else if (snapping_str == "any") // { // params->snapping = osrm::RouteParameters::SnappingType::Any; // } // else // { // Nan::ThrowError("'snapping' param must be one of [default, any]"); // return false; // } // } // return true; // } // template // inline bool parseCommonParameters(const v8::Local &obj, ParamType ¶ms) // { // if (Nan::Has(obj, Nan::New("steps").ToLocalChecked()).FromJust()) // { // auto steps = Nan::Get(obj, Nan::New("steps").ToLocalChecked()).ToLocalChecked(); // if (steps.IsEmpty()) // return false; // if (steps->IsBoolean()) // { // params->steps = Nan::To(steps).FromJust(); // } // else // { // Nan::ThrowError("'steps' param must be a boolean"); // return false; // } // } // if (Nan::Has(obj, Nan::New("annotations").ToLocalChecked()).FromJust()) // { // auto annotations = Nan::Get(obj, Nan::New("annotations").ToLocalChecked()).ToLocalChecked(); // if (annotations.IsEmpty()) // return false; // if (annotations->IsBoolean()) // { // params->annotations = Nan::To(annotations).FromJust(); // params->annotations_type = params->annotations // ? osrm::RouteParameters::AnnotationsType::All // : osrm::RouteParameters::AnnotationsType::None; // } // else if (annotations->IsArray()) // { // v8::Local annotations_array = v8::Local::Cast(annotations); // for (std::size_t i = 0; i < annotations_array->Length(); i++) // { // const Nan::Utf8String annotations_utf8str( // Nan::Get(annotations_array, i).ToLocalChecked()); // std::string annotations_str{*annotations_utf8str, // *annotations_utf8str + annotations_utf8str.length()}; // if (annotations_str == "duration") // { // params->annotations_type = // params->annotations_type | osrm::RouteParameters::AnnotationsType::Duration; // } // else if (annotations_str == "nodes") // { // params->annotations_type = // params->annotations_type | osrm::RouteParameters::AnnotationsType::Nodes; // } // else if (annotations_str == "distance") // { // params->annotations_type = // params->annotations_type | osrm::RouteParameters::AnnotationsType::Distance; // } // else if (annotations_str == "weight") // { // params->annotations_type = // params->annotations_type | osrm::RouteParameters::AnnotationsType::Weight; // } // else if (annotations_str == "datasources") // { // params->annotations_type = params->annotations_type | // osrm::RouteParameters::AnnotationsType::Datasources; // } // else if (annotations_str == "speed") // { // params->annotations_type = // params->annotations_type | osrm::RouteParameters::AnnotationsType::Speed; // } // else // { // Nan::ThrowError("this 'annotations' param is not supported"); // return false; // } // params->annotations = // params->annotations_type != osrm::RouteParameters::AnnotationsType::None; // } // } // else // { // Nan::ThrowError("this 'annotations' param is not supported"); // return false; // } // } // if (Nan::Has(obj, Nan::New("geometries").ToLocalChecked()).FromJust()) // { // v8::Local geometries = // Nan::Get(obj, Nan::New("geometries").ToLocalChecked()).ToLocalChecked(); // if (geometries.IsEmpty()) // return false; // if (!geometries->IsString()) // { // Nan::ThrowError("Geometries must be a string: [polyline, polyline6, geojson]"); // return false; // } // const Nan::Utf8String geometries_utf8str(geometries); // std::string geometries_str{*geometries_utf8str, // *geometries_utf8str + geometries_utf8str.length()}; // if (geometries_str == "polyline") // { // params->geometries = osrm::RouteParameters::GeometriesType::Polyline; // } // else if (geometries_str == "polyline6") // { // params->geometries = osrm::RouteParameters::GeometriesType::Polyline6; // } // else if (geometries_str == "geojson") // { // params->geometries = osrm::RouteParameters::GeometriesType::GeoJSON; // } // else // { // Nan::ThrowError("'geometries' param must be one of [polyline, polyline6, geojson]"); // return false; // } // } // if (Nan::Has(obj, Nan::New("overview").ToLocalChecked()).FromJust()) // { // v8::Local overview = // Nan::Get(obj, Nan::New("overview").ToLocalChecked()).ToLocalChecked(); // if (overview.IsEmpty()) // return false; // if (!overview->IsString()) // { // Nan::ThrowError("Overview must be a string: [simplified, full, false]"); // return false; // } // const Nan::Utf8String overview_utf8str(overview); // std::string overview_str{*overview_utf8str, *overview_utf8str + overview_utf8str.length()}; // if (overview_str == "simplified") // { // params->overview = osrm::RouteParameters::OverviewType::Simplified; // } // else if (overview_str == "full") // { // params->overview = osrm::RouteParameters::OverviewType::Full; // } // else if (overview_str == "false") // { // params->overview = osrm::RouteParameters::OverviewType::False; // } // else // { // Nan::ThrowError("'overview' param must be one of [simplified, full, false]"); // return false; // } // } // return true; // } // inline PluginParameters argumentsToPluginParameters( // const Nan::FunctionCallbackInfo &args, // const boost::optional &output_format = {}) // { // if (args.Length() < 3 || !args[1]->IsObject()) // { // // 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()) // { // return {}; // } // if (!format->IsString()) // { // Nan::ThrowError("format must be a string: \"object\" or \"buffer\""); // return {}; // } // const Nan::Utf8String format_utf8str(format); // std::string format_str{*format_utf8str, *format_utf8str + format_utf8str.length()}; // 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 \"buffer\""); // return {}; // } // } // // output to buffer by default for Flatbuffers // return {output_format == osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS}; // } // inline route_parameters_ptr // argumentsToRouteParameter(const Nan::FunctionCallbackInfo &args, // bool requires_multiple_coordinates) // { // route_parameters_ptr params = std::make_unique(); // bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates); // if (!has_base_params) // return route_parameters_ptr(); // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // if (Nan::Has(obj, Nan::New("continue_straight").ToLocalChecked()).FromJust()) // { // auto value = Nan::Get(obj, Nan::New("continue_straight").ToLocalChecked()).ToLocalChecked(); // if (value.IsEmpty()) // return route_parameters_ptr(); // if (!value->IsBoolean() && !value->IsNull()) // { // Nan::ThrowError("'continue_straight' param must be boolean or null"); // return route_parameters_ptr(); // } // if (value->IsBoolean()) // { // params->continue_straight = Nan::To(value).FromJust(); // } // } // if (Nan::Has(obj, Nan::New("alternatives").ToLocalChecked()).FromJust()) // { // auto value = Nan::Get(obj, Nan::New("alternatives").ToLocalChecked()).ToLocalChecked(); // if (value.IsEmpty()) // return route_parameters_ptr(); // if (value->IsBoolean()) // { // params->alternatives = Nan::To(value).FromJust(); // params->number_of_alternatives = Nan::To(value).FromJust() ? 1u : 0u; // } // else if (value->IsNumber()) // { // params->alternatives = Nan::To(value).FromJust(); // params->number_of_alternatives = Nan::To(value).FromJust(); // } // else // { // Nan::ThrowError("'alternatives' param must be boolean or number"); // return route_parameters_ptr(); // } // } // if (Nan::Has(obj, Nan::New("waypoints").ToLocalChecked()).FromJust()) // { // v8::Local waypoints = // Nan::Get(obj, Nan::New("waypoints").ToLocalChecked()).ToLocalChecked(); // if (waypoints.IsEmpty()) // return route_parameters_ptr(); // // must be array // if (!waypoints->IsArray()) // { // Nan::ThrowError( // "Waypoints must be an array of integers corresponding to the input coordinates."); // return route_parameters_ptr(); // } // auto waypoints_array = v8::Local::Cast(waypoints); // // must have at least two elements // if (waypoints_array->Length() < 2) // { // Nan::ThrowError("At least two waypoints must be provided"); // return route_parameters_ptr(); // } // auto coords_size = params->coordinates.size(); // auto waypoints_array_size = waypoints_array->Length(); // const auto first_index = // Nan::To(Nan::Get(waypoints_array, 0).ToLocalChecked()).FromJust(); // const auto last_index = // Nan::To( // Nan::Get(waypoints_array, waypoints_array_size - 1).ToLocalChecked()) // .FromJust(); // if (first_index != 0 || last_index != coords_size - 1) // { // Nan::ThrowError("First and last waypoints values must correspond to first and last " // "coordinate indices"); // return route_parameters_ptr(); // } // for (uint32_t i = 0; i < waypoints_array_size; ++i) // { // v8::Local waypoint_value = Nan::Get(waypoints_array, i).ToLocalChecked(); // // all elements must be numbers // if (!waypoint_value->IsNumber()) // { // Nan::ThrowError("Waypoint values must be an array of integers"); // return route_parameters_ptr(); // } // // check that the waypoint index corresponds with an inpute coordinate // const auto index = Nan::To(waypoint_value).FromJust(); // if (index >= coords_size) // { // Nan::ThrowError("Waypoints must correspond with the index of an input coordinate"); // return route_parameters_ptr(); // } // params->waypoints.emplace_back(Nan::To(waypoint_value).FromJust()); // } // if (!params->waypoints.empty()) // { // for (std::size_t i = 0; i < params->waypoints.size() - 1; i++) // { // if (params->waypoints[i] >= params->waypoints[i + 1]) // { // Nan::ThrowError("Waypoints must be supplied in increasing order"); // return route_parameters_ptr(); // } // } // } // } // bool parsedSuccessfully = parseCommonParameters(obj, params); // if (!parsedSuccessfully) // { // return route_parameters_ptr(); // } // return params; // } // inline tile_parameters_ptr // argumentsToTileParameters(const Nan::FunctionCallbackInfo &args, bool /*unused*/) // { // tile_parameters_ptr params = std::make_unique(); // if (args.Length() < 2) // { // Nan::ThrowTypeError("Coordinate object and callback required"); // return tile_parameters_ptr(); // } // if (!args[0]->IsArray()) // { // Nan::ThrowTypeError("Parameter must be an array [x, y, z]"); // return tile_parameters_ptr(); // } // v8::Local array = v8::Local::Cast(args[0]); // if (array->Length() != 3) // { // Nan::ThrowTypeError("Parameter must be an array [x, y, z]"); // return tile_parameters_ptr(); // } // v8::Local x = Nan::Get(array, 0).ToLocalChecked(); // v8::Local y = Nan::Get(array, 1).ToLocalChecked(); // v8::Local z = Nan::Get(array, 2).ToLocalChecked(); // if (x.IsEmpty() || y.IsEmpty() || z.IsEmpty()) // return tile_parameters_ptr(); // if (!x->IsUint32() && !x->IsUndefined()) // { // Nan::ThrowError("Tile x coordinate must be unsigned interger"); // return tile_parameters_ptr(); // } // if (!y->IsUint32() && !y->IsUndefined()) // { // Nan::ThrowError("Tile y coordinate must be unsigned interger"); // return tile_parameters_ptr(); // } // if (!z->IsUint32() && !z->IsUndefined()) // { // Nan::ThrowError("Tile z coordinate must be unsigned interger"); // return tile_parameters_ptr(); // } // params->x = Nan::To(x).FromJust(); // params->y = Nan::To(y).FromJust(); // params->z = Nan::To(z).FromJust(); // if (!params->IsValid()) // { // Nan::ThrowError("Invalid tile coordinates"); // return tile_parameters_ptr(); // } // return params; // } // inline nearest_parameters_ptr // argumentsToNearestParameter(const Nan::FunctionCallbackInfo &args, // bool requires_multiple_coordinates) // { // nearest_parameters_ptr params = std::make_unique(); // bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates); // if (!has_base_params) // return nearest_parameters_ptr(); // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // if (obj.IsEmpty()) // return nearest_parameters_ptr(); // if (Nan::Has(obj, Nan::New("number").ToLocalChecked()).FromJust()) // { // v8::Local number = // Nan::Get(obj, Nan::New("number").ToLocalChecked()).ToLocalChecked(); // if (!number->IsUint32()) // { // Nan::ThrowError("Number must be an integer greater than or equal to 1"); // return nearest_parameters_ptr(); // } // else // { // unsigned number_value = Nan::To(number).FromJust(); // if (number_value < 1) // { // Nan::ThrowError("Number must be an integer greater than or equal to 1"); // return nearest_parameters_ptr(); // } // params->number_of_results = Nan::To(number).FromJust(); // } // } // return params; // } // inline table_parameters_ptr // argumentsToTableParameter(const Nan::FunctionCallbackInfo &args, // bool requires_multiple_coordinates) // { // table_parameters_ptr params = std::make_unique(); // bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates); // if (!has_base_params) // return table_parameters_ptr(); // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // if (obj.IsEmpty()) // return table_parameters_ptr(); // if (Nan::Has(obj, Nan::New("sources").ToLocalChecked()).FromJust()) // { // v8::Local sources = // Nan::Get(obj, Nan::New("sources").ToLocalChecked()).ToLocalChecked(); // if (sources.IsEmpty()) // return table_parameters_ptr(); // if (!sources->IsArray()) // { // Nan::ThrowError("Sources must be an array of indices (or undefined)"); // return table_parameters_ptr(); // } // v8::Local sources_array = v8::Local::Cast(sources); // for (uint32_t i = 0; i < sources_array->Length(); ++i) // { // v8::Local source = Nan::Get(sources_array, i).ToLocalChecked(); // if (source.IsEmpty()) // return table_parameters_ptr(); // if (source->IsUint32()) // { // size_t source_value = Nan::To(source).FromJust(); // if (source_value >= params->coordinates.size()) // { // Nan::ThrowError("Source indices must be less than the number of coordinates"); // return table_parameters_ptr(); // } // params->sources.push_back(Nan::To(source).FromJust()); // } // else // { // Nan::ThrowError("Source must be an integer"); // return table_parameters_ptr(); // } // } // } // if (Nan::Has(obj, Nan::New("destinations").ToLocalChecked()).FromJust()) // { // v8::Local destinations = // Nan::Get(obj, Nan::New("destinations").ToLocalChecked()).ToLocalChecked(); // if (destinations.IsEmpty()) // return table_parameters_ptr(); // if (!destinations->IsArray()) // { // Nan::ThrowError("Destinations must be an array of indices (or undefined)"); // return table_parameters_ptr(); // } // v8::Local destinations_array = v8::Local::Cast(destinations); // for (uint32_t i = 0; i < destinations_array->Length(); ++i) // { // v8::Local destination = Nan::Get(destinations_array, i).ToLocalChecked(); // if (destination.IsEmpty()) // return table_parameters_ptr(); // if (destination->IsUint32()) // { // size_t destination_value = Nan::To(destination).FromJust(); // if (destination_value >= params->coordinates.size()) // { // Nan::ThrowError("Destination indices must be less than the number " // "of coordinates"); // return table_parameters_ptr(); // } // params->destinations.push_back(Nan::To(destination).FromJust()); // } // else // { // Nan::ThrowError("Destination must be an integer"); // return table_parameters_ptr(); // } // } // } // if (Nan::Has(obj, Nan::New("annotations").ToLocalChecked()).FromJust()) // { // v8::Local annotations = // Nan::Get(obj, Nan::New("annotations").ToLocalChecked()).ToLocalChecked(); // if (annotations.IsEmpty()) // return table_parameters_ptr(); // if (!annotations->IsArray()) // { // Nan::ThrowError( // "Annotations must an array containing 'duration' or 'distance', or both"); // return table_parameters_ptr(); // } // params->annotations = osrm::TableParameters::AnnotationsType::None; // v8::Local annotations_array = v8::Local::Cast(annotations); // for (std::size_t i = 0; i < annotations_array->Length(); ++i) // { // const Nan::Utf8String annotations_utf8str( // Nan::Get(annotations_array, i).ToLocalChecked()); // std::string annotations_str{*annotations_utf8str, // *annotations_utf8str + annotations_utf8str.length()}; // 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 // { // Nan::ThrowError("this 'annotations' param is not supported"); // return table_parameters_ptr(); // } // } // } // if (Nan::Has(obj, Nan::New("fallback_speed").ToLocalChecked()).FromJust()) // { // auto fallback_speed = // Nan::Get(obj, Nan::New("fallback_speed").ToLocalChecked()).ToLocalChecked(); // if (!fallback_speed->IsNumber()) // { // Nan::ThrowError("fallback_speed must be a number"); // return table_parameters_ptr(); // } // else if (Nan::To(fallback_speed).FromJust() <= 0) // { // Nan::ThrowError("fallback_speed must be > 0"); // return table_parameters_ptr(); // } // params->fallback_speed = Nan::To(fallback_speed).FromJust(); // } // if (Nan::Has(obj, Nan::New("fallback_coordinate").ToLocalChecked()).FromJust()) // { // auto fallback_coordinate = // Nan::Get(obj, Nan::New("fallback_coordinate").ToLocalChecked()).ToLocalChecked(); // if (!fallback_coordinate->IsString()) // { // Nan::ThrowError("fallback_coordinate must be a string: [input, snapped]"); // return table_parameters_ptr(); // } // std::string fallback_coordinate_str = *Nan::Utf8String(fallback_coordinate); // 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 // { // Nan::ThrowError("'fallback_coordinate' param must be one of [input, snapped]"); // return table_parameters_ptr(); // } // } // if (Nan::Has(obj, Nan::New("scale_factor").ToLocalChecked()).FromJust()) // { // auto scale_factor = // Nan::Get(obj, Nan::New("scale_factor").ToLocalChecked()).ToLocalChecked(); // if (!scale_factor->IsNumber()) // { // Nan::ThrowError("scale_factor must be a number"); // return table_parameters_ptr(); // } // else if (Nan::To(scale_factor).FromJust() <= 0) // { // Nan::ThrowError("scale_factor must be > 0"); // return table_parameters_ptr(); // } // params->scale_factor = Nan::To(scale_factor).FromJust(); // } // return params; // } // inline trip_parameters_ptr // argumentsToTripParameter(const Nan::FunctionCallbackInfo &args, // bool requires_multiple_coordinates) // { // trip_parameters_ptr params = std::make_unique(); // bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates); // if (!has_base_params) // return trip_parameters_ptr(); // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // bool parsedSuccessfully = parseCommonParameters(obj, params); // if (!parsedSuccessfully) // { // return trip_parameters_ptr(); // } // if (Nan::Has(obj, Nan::New("roundtrip").ToLocalChecked()).FromJust()) // { // auto roundtrip = Nan::Get(obj, Nan::New("roundtrip").ToLocalChecked()).ToLocalChecked(); // if (roundtrip.IsEmpty()) // return trip_parameters_ptr(); // if (roundtrip->IsBoolean()) // { // params->roundtrip = Nan::To(roundtrip).FromJust(); // } // else // { // Nan::ThrowError("'roundtrip' param must be a boolean"); // return trip_parameters_ptr(); // } // } // if (Nan::Has(obj, Nan::New("source").ToLocalChecked()).FromJust()) // { // v8::Local source = // Nan::Get(obj, Nan::New("source").ToLocalChecked()).ToLocalChecked(); // if (source.IsEmpty()) // return trip_parameters_ptr(); // if (!source->IsString()) // { // Nan::ThrowError("Source must be a string: [any, first]"); // return trip_parameters_ptr(); // } // std::string source_str = *Nan::Utf8String(source); // if (source_str == "first") // { // params->source = osrm::TripParameters::SourceType::First; // } // else if (source_str == "any") // { // params->source = osrm::TripParameters::SourceType::Any; // } // else // { // Nan::ThrowError("'source' param must be one of [any, first]"); // return trip_parameters_ptr(); // } // } // if (Nan::Has(obj, Nan::New("destination").ToLocalChecked()).FromJust()) // { // v8::Local destination = // Nan::Get(obj, Nan::New("destination").ToLocalChecked()).ToLocalChecked(); // if (destination.IsEmpty()) // return trip_parameters_ptr(); // if (!destination->IsString()) // { // Nan::ThrowError("Destination must be a string: [any, last]"); // return trip_parameters_ptr(); // } // std::string destination_str = *Nan::Utf8String(destination); // if (destination_str == "last") // { // params->destination = osrm::TripParameters::DestinationType::Last; // } // else if (destination_str == "any") // { // params->destination = osrm::TripParameters::DestinationType::Any; // } // else // { // Nan::ThrowError("'destination' param must be one of [any, last]"); // return trip_parameters_ptr(); // } // } // return params; // } // inline match_parameters_ptr // argumentsToMatchParameter(const Nan::FunctionCallbackInfo &args, // bool requires_multiple_coordinates) // { // match_parameters_ptr params = std::make_unique(); // bool has_base_params = argumentsToParameter(args, params, requires_multiple_coordinates); // if (!has_base_params) // return match_parameters_ptr(); // v8::Local obj = Nan::To(args[0]).ToLocalChecked(); // if (Nan::Has(obj, Nan::New("timestamps").ToLocalChecked()).FromJust()) // { // v8::Local timestamps = // Nan::Get(obj, Nan::New("timestamps").ToLocalChecked()).ToLocalChecked(); // if (timestamps.IsEmpty()) // return match_parameters_ptr(); // if (!timestamps->IsArray()) // { // Nan::ThrowError("Timestamps must be an array of integers (or undefined)"); // return match_parameters_ptr(); // } // v8::Local timestamps_array = v8::Local::Cast(timestamps); // if (params->coordinates.size() != timestamps_array->Length()) // { // Nan::ThrowError("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) // { // v8::Local timestamp = Nan::Get(timestamps_array, i).ToLocalChecked(); // if (timestamp.IsEmpty()) // return match_parameters_ptr(); // if (!timestamp->IsNumber()) // { // Nan::ThrowError("Timestamps array items must be numbers"); // return match_parameters_ptr(); // } // params->timestamps.emplace_back(Nan::To(timestamp).FromJust()); // } // } // if (Nan::Has(obj, Nan::New("gaps").ToLocalChecked()).FromJust()) // { // v8::Local gaps = // Nan::Get(obj, Nan::New("gaps").ToLocalChecked()).ToLocalChecked(); // if (gaps.IsEmpty()) // return match_parameters_ptr(); // if (!gaps->IsString()) // { // Nan::ThrowError("Gaps must be a string: [split, ignore]"); // return match_parameters_ptr(); // } // const Nan::Utf8String gaps_utf8str(gaps); // std::string gaps_str{*gaps_utf8str, *gaps_utf8str + gaps_utf8str.length()}; // if (gaps_str == "split") // { // params->gaps = osrm::MatchParameters::GapsType::Split; // } // else if (gaps_str == "ignore") // { // params->gaps = osrm::MatchParameters::GapsType::Ignore; // } // else // { // Nan::ThrowError("'gaps' param must be one of [split, ignore]"); // return match_parameters_ptr(); // } // } // if (Nan::Has(obj, Nan::New("tidy").ToLocalChecked()).FromJust()) // { // v8::Local tidy = // Nan::Get(obj, Nan::New("tidy").ToLocalChecked()).ToLocalChecked(); // if (tidy.IsEmpty()) // return match_parameters_ptr(); // if (!tidy->IsBoolean()) // { // Nan::ThrowError("tidy must be of type Boolean"); // return match_parameters_ptr(); // } // params->tidy = Nan::To(tidy).FromJust(); // } // if (Nan::Has(obj, Nan::New("waypoints").ToLocalChecked()).FromJust()) // { // v8::Local waypoints = // Nan::Get(obj, Nan::New("waypoints").ToLocalChecked()).ToLocalChecked(); // if (waypoints.IsEmpty()) // return match_parameters_ptr(); // // must be array // if (!waypoints->IsArray()) // { // Nan::ThrowError( // "Waypoints must be an array of integers corresponding to the input coordinates."); // return match_parameters_ptr(); // } // auto waypoints_array = v8::Local::Cast(waypoints); // // must have at least two elements // if (waypoints_array->Length() < 2) // { // Nan::ThrowError("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 = // Nan::To(Nan::Get(waypoints_array, 0).ToLocalChecked()).FromJust(); // const auto last_index = // Nan::To( // Nan::Get(waypoints_array, waypoints_array_size - 1).ToLocalChecked()) // .FromJust(); // if (first_index != 0 || last_index != coords_size - 1) // { // Nan::ThrowError("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) // { // v8::Local waypoint_value = Nan::Get(waypoints_array, i).ToLocalChecked(); // // all elements must be numbers // if (!waypoint_value->IsNumber()) // { // Nan::ThrowError("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 = Nan::To(waypoint_value).FromJust(); // if (index >= coords_size) // { // Nan::ThrowError("Waypoints must correspond with the index of an input coordinate"); // return match_parameters_ptr(); // } // params->waypoints.emplace_back( // static_cast(Nan::To(waypoint_value).FromJust())); // } // } // bool parsedSuccessfully = parseCommonParameters(obj, params); // if (!parsedSuccessfully) // { // return match_parameters_ptr(); // } // return params; // } // } // namespace node_osrm // #endif