diff --git a/libosrmc/osrmc.cc b/libosrmc/osrmc.cc index cb6217d..c61d9fc 100644 --- a/libosrmc/osrmc.cc +++ b/libosrmc/osrmc.cc @@ -211,6 +211,31 @@ float osrmc_route_response_duration(osrmc_route_response_t response, osrmc_error return INFINITY; } +osrmc_table_annotations_t osrmc_table_annotations_construct(osrmc_error_t* error) try { + auto* out = new osrm::TableParameters::AnnotationsType{osrm::TableParameters::AnnotationsType::Duration}; + return reinterpret_cast(out); +} catch (const std::exception& e) { + osrmc_error_from_exception(e, error); + return nullptr; +} + +void osrmc_table_annotations_destruct(osrmc_table_annotations_t annotations) { + delete reinterpret_cast(annotations); +} + +void osrmc_table_annotations_enable_distance(osrmc_table_annotations_t annotations, bool enable, osrmc_error_t* error) try { + using AnnotationsType = osrm::TableParameters::AnnotationsType; + auto* annotations_typed = reinterpret_cast(annotations); + + if (enable) { + *annotations_typed |= AnnotationsType::Distance; + } else { + *annotations_typed = static_cast(static_cast(*annotations_typed) ^ static_cast(AnnotationsType::Distance)); + } +} catch (const std::exception& e) { + osrmc_error_from_exception(e, error); +} + osrmc_table_params_t osrmc_table_params_construct(osrmc_error_t* error) try { auto* out = new osrm::TableParameters; return reinterpret_cast(out); @@ -237,6 +262,14 @@ void osrmc_table_params_add_destination(osrmc_table_params_t params, size_t inde osrmc_error_from_exception(e, error); } +void osrmc_table_params_set_annotations(osrmc_table_params_t params, osrmc_table_annotations_t annotations, osrmc_error_t* error) try { + auto* params_typed = reinterpret_cast(params); + auto* annotations_typed = reinterpret_cast(annotations); + params_typed->annotations = *annotations_typed; +} catch (const std::exception& e) { + osrmc_error_from_exception(e, error); +} + osrmc_table_response_t osrmc_table(osrmc_osrm_t osrm, osrmc_table_params_t params, osrmc_error_t* error) try { auto* osrm_typed = reinterpret_cast(osrm); auto* params_typed = reinterpret_cast(params); @@ -262,9 +295,20 @@ float osrmc_table_response_duration(osrmc_table_response_t response, unsigned lo osrmc_error_t* error) try { auto* response_typed = reinterpret_cast(response); + if (response_typed->values.find("durations") == response_typed->values.end()) { + *error = new osrmc_error{"NoTable", "Table request not configured to return durations"}; + return INFINITY; + } + auto& durations = response_typed->values["durations"].get(); auto& durations_from_to_all = durations.values.at(from).get(); - auto duration = durations_from_to_all.values.at(to).get().value; + auto nullable = durations_from_to_all.values.at(to); + + if (nullable.is()) { + *error = new osrmc_error{"NoRoute", "Impossible route between points"}; + return INFINITY; + } + auto duration = nullable.get().value; return duration; } catch (const std::exception& e) { @@ -272,6 +316,31 @@ float osrmc_table_response_duration(osrmc_table_response_t response, unsigned lo return INFINITY; } +float osrmc_table_response_distance(osrmc_table_response_t response, unsigned long from, unsigned long to, + osrmc_error_t* error) try { + auto* response_typed = reinterpret_cast(response); + + if (response_typed->values.find("distances") == response_typed->values.end()) { + *error = new osrmc_error{"NoTable", "Table request not configured to return distances"}; + return INFINITY; + } + + auto& distances = response_typed->values["distances"].get(); + auto& distances_from_to_all = distances.values.at(from).get(); + auto nullable = distances_from_to_all.values.at(to); + + if (nullable.is()) { + *error = new osrmc_error{"NoRoute", "Impossible route between points"}; + return INFINITY; + } + auto distance = nullable.get().value; + + return distance; +} catch (const std::exception& e) { + *error = new osrmc_error{e.what()}; + return INFINITY; +} + osrmc_nearest_params_t osrmc_nearest_params_construct(osrmc_error_t* error) try { auto* out = new osrm::NearestParameters; return reinterpret_cast(out); diff --git a/libosrmc/osrmc.h b/libosrmc/osrmc.h index 92bf9ef..d873033 100644 --- a/libosrmc/osrmc.h +++ b/libosrmc/osrmc.h @@ -1,3 +1,5 @@ +#include + #ifndef OSRMC_H_ #define OSRMC_H_ @@ -144,6 +146,7 @@ typedef struct osrmc_params* osrmc_params_t; typedef struct osrmc_route_params* osrmc_route_params_t; typedef struct osrmc_table_params* osrmc_table_params_t; +typedef struct osrmc_table_annotations* osrmc_table_annotations_t; typedef struct osrmc_nearest_params* osrmc_nearest_params_t; typedef struct osrmc_match_params* osrmc_match_params_t; @@ -194,15 +197,26 @@ OSRMC_API float osrmc_route_response_duration(osrmc_route_response_t response, o /* Table service */ +OSRMC_API osrmc_table_annotations_t osrmc_table_annotations_construct(osrmc_error_t* error); +OSRMC_API void osrmc_table_annotations_destruct(osrmc_table_annotations_t annotations); +OSRMC_API void osrmc_table_annotations_enable_distance(osrmc_table_annotations_t annotations, bool enable, osrmc_error_t* error); + OSRMC_API osrmc_table_params_t osrmc_table_params_construct(osrmc_error_t* error); OSRMC_API void osrmc_table_params_destruct(osrmc_table_params_t params); +OSRMC_API void osrmc_table_params_set_annotations(osrmc_table_params_t params, osrmc_table_annotations_t annotations, osrmc_error_t* error); OSRMC_API void osrmc_table_params_add_source(osrmc_table_params_t params, size_t index, osrmc_error_t* error); OSRMC_API void osrmc_table_params_add_destination(osrmc_table_params_t params, size_t index, osrmc_error_t* error); OSRMC_API osrmc_table_response_t osrmc_table(osrmc_osrm_t osrm, osrmc_table_params_t params, osrmc_error_t* error); OSRMC_API void osrmc_table_response_destruct(osrmc_table_response_t response); + +// INFINITY will be returned if there is no route between the from/to. +// An error will also be returned with a code of 'NoRoute'. OSRMC_API float osrmc_table_response_duration(osrmc_table_response_t response, unsigned long from, unsigned long to, osrmc_error_t* error); +OSRMC_API float osrmc_table_response_distance(osrmc_table_response_t response, unsigned long from, unsigned long to, + osrmc_error_t* error); + /* Nearest service */ OSRMC_API osrmc_nearest_params_t osrmc_nearest_params_construct(osrmc_error_t* error);