Store metadata about original OSM data, and return it in the API response, if available.
This commit is contained in:
parent
4c665b24d9
commit
8b45ff7a18
@ -4,6 +4,7 @@
|
||||
- ADDED: optionally build Node `lts` and `latest` bindings [#5347](https://github.com/Project-OSRM/osrm-backend/pull/5347)
|
||||
- Features:
|
||||
- ADDED: new waypoints parameter to the `route` plugin, enabling silent waypoints [#5345](https://github.com/Project-OSRM/osrm-backend/pull/5345)
|
||||
- ADDED: data timestamp information in the response (saved in new file `.osrm.timestamp`). [#5115](https://github.com/Project-OSRM/osrm-backend/issues/5115)
|
||||
|
||||
# 5.21.0
|
||||
- Changes from 5.20.0
|
||||
|
@ -70,6 +70,8 @@ curl 'http://router.project-osrm.org/route/v1/driving/polyline(ofp_Ik_vpAilAyu@t
|
||||
|
||||
### Responses
|
||||
|
||||
#### Code
|
||||
|
||||
Every response object has a `code` property containing one of the strings below or a service dependent code:
|
||||
|
||||
| Type | Description |
|
||||
@ -87,12 +89,17 @@ Every response object has a `code` property containing one of the strings below
|
||||
- `message` is a **optional** human-readable error message. All other status types are service dependent.
|
||||
- In case of an error the HTTP status code will be `400`. Otherwise the HTTP status code will be `200` and `code` will be `Ok`.
|
||||
|
||||
#### Data version
|
||||
|
||||
Every response object has a `data_version` propetry containing timestamp from the original OpenStreetMap file. This field is optional. It can be ommited if data_version parametr was not set on osrm-extract stage or OSM file has not `osmosis_replication_timestamp` section.
|
||||
|
||||
#### Example response
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "Ok",
|
||||
"message": "Everything worked"
|
||||
"message": "Everything worked",
|
||||
"data_version": "2017-11-17T21:43:02Z"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -75,6 +75,10 @@ module.exports = function () {
|
||||
got.message = json.message || '';
|
||||
}
|
||||
|
||||
if (headers.has('data_version')) {
|
||||
got.data_version = json.data_version || '';
|
||||
}
|
||||
|
||||
if (headers.has('#')) {
|
||||
// comment column
|
||||
got['#'] = row['#'];
|
||||
|
@ -17,9 +17,26 @@ Feature: Basic Routing
|
||||
| ab |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route |
|
||||
| a | b | ab,ab |
|
||||
| b | a | ab,ab |
|
||||
| from | to | route | data_version |
|
||||
| a | b | ab,ab | |
|
||||
| b | a | ab,ab | |
|
||||
|
||||
Scenario: Data_version test
|
||||
Given the node map
|
||||
"""
|
||||
a b
|
||||
"""
|
||||
|
||||
And the extract extra arguments "--data_version cucumber_data_version"
|
||||
|
||||
And the ways
|
||||
| nodes |
|
||||
| ab |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | data_version |
|
||||
| a | b | ab,ab | cucumber_data_version |
|
||||
| b | a | ab,ab | cucumber_data_version |
|
||||
|
||||
Scenario: Routing in between two nodes of way
|
||||
Given the node map
|
||||
|
@ -68,6 +68,11 @@ class RouteAPI : public BaseAPI
|
||||
response.values["waypoints"] = BaseAPI::MakeWaypoints(all_start_end_points);
|
||||
response.values["routes"] = std::move(jsRoutes);
|
||||
response.values["code"] = "Ok";
|
||||
auto data_timestamp = facade.GetTimestamp();
|
||||
if (!data_timestamp.empty())
|
||||
{
|
||||
response.values["data_version"] = data_timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -137,6 +137,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
extractor::Datasources *m_datasources;
|
||||
|
||||
std::uint32_t m_check_sum;
|
||||
StringView m_data_timestamp;
|
||||
util::vector_view<util::Coordinate> m_coordinate_list;
|
||||
extractor::PackedOSMIDsView m_osmnodeid_list;
|
||||
util::vector_view<std::uint32_t> m_lane_description_offsets;
|
||||
@ -183,6 +184,8 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
m_check_sum = *index.GetBlockPtr<std::uint32_t>("/common/connectivity_checksum");
|
||||
|
||||
m_data_timestamp = make_timestamp_view(index, "/common/timestamp");
|
||||
|
||||
std::tie(m_coordinate_list, m_osmnodeid_list) =
|
||||
make_nbn_data_view(index, "/common/nbn_data");
|
||||
|
||||
@ -432,6 +435,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
|
||||
std::uint32_t GetCheckSum() const override final { return m_check_sum; }
|
||||
|
||||
std::string GetTimestamp() const override final
|
||||
{
|
||||
return std::string(m_data_timestamp.begin(), m_data_timestamp.end());
|
||||
}
|
||||
|
||||
GeometryID GetGeometryIndex(const NodeID id) const override final
|
||||
{
|
||||
return edge_based_node_data.GetGeometryID(id);
|
||||
|
@ -74,6 +74,8 @@ class BaseDataFacade
|
||||
|
||||
virtual std::uint32_t GetCheckSum() const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
||||
// node and edge information access
|
||||
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
|
||||
|
||||
|
@ -55,6 +55,7 @@ struct ExtractorConfig final : storage::IOConfig
|
||||
".osrm.geometry",
|
||||
".osrm.nbg_nodes",
|
||||
".osrm.ebg_nodes",
|
||||
".osrm.timestamp",
|
||||
".osrm.edges",
|
||||
".osrm.ebg",
|
||||
".osrm.ramIndex",
|
||||
@ -82,6 +83,7 @@ struct ExtractorConfig final : storage::IOConfig
|
||||
boost::filesystem::path input_path;
|
||||
boost::filesystem::path profile_path;
|
||||
std::vector<boost::filesystem::path> location_dependent_data_paths;
|
||||
std::string data_version;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
unsigned small_component_size;
|
||||
|
@ -308,6 +308,26 @@ inline void writeTurnLaneData(const boost::filesystem::path &path,
|
||||
storage::serialization::write(writer, "/common/turn_lanes/data", turn_lane_data);
|
||||
}
|
||||
|
||||
// reads .osrm.timestamp
|
||||
template <typename TimestampDataT>
|
||||
inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT ×tamp)
|
||||
{
|
||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||
storage::tar::FileReader reader{path, fingerprint};
|
||||
|
||||
storage::serialization::read(reader, "/common/timestamp", timestamp);
|
||||
}
|
||||
|
||||
// writes .osrm.timestamp
|
||||
template <typename TimestampDataT>
|
||||
inline void writeTimestamp(const boost::filesystem::path &path, const TimestampDataT ×tamp)
|
||||
{
|
||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||
storage::tar::FileWriter writer{path, fingerprint};
|
||||
|
||||
storage::serialization::write(writer, "/common/timestamp", timestamp);
|
||||
}
|
||||
|
||||
// reads .osrm.maneuver_overrides
|
||||
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
||||
inline void readManeuverOverrides(const boost::filesystem::path &path,
|
||||
|
@ -58,6 +58,7 @@ struct StorageConfig final : IOConfig
|
||||
".osrm.turn_duration_penalties",
|
||||
".osrm.datasource_names",
|
||||
".osrm.names",
|
||||
".osrm.timestamp",
|
||||
".osrm.properties",
|
||||
".osrm.icd",
|
||||
".osrm.maneuver_overrides"},
|
||||
|
@ -272,6 +272,11 @@ inline auto make_partition_view(const SharedDataIndex &index, const std::string
|
||||
level_data_ptr, std::move(partition), std::move(cell_to_children)};
|
||||
}
|
||||
|
||||
inline auto make_timestamp_view(const SharedDataIndex &index, const std::string &name)
|
||||
{
|
||||
return util::StringView(index.GetBlockPtr<char>(name), index.GetBlockEntries(name));
|
||||
}
|
||||
|
||||
inline auto make_cell_storage_view(const SharedDataIndex &index, const std::string &name)
|
||||
{
|
||||
auto source_boundary = make_vector_view<NodeID>(index, name + "/source_boundary");
|
||||
|
@ -79,6 +79,7 @@ using EdgeDistance = float;
|
||||
using SegmentWeight = std::uint32_t;
|
||||
using SegmentDuration = std::uint32_t;
|
||||
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
|
||||
using DataTimestamp = std::string;
|
||||
|
||||
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/index/map/flex_mem.hpp>
|
||||
#include <osmium/io/any_input.hpp>
|
||||
#include <osmium/osm/timestamp.hpp>
|
||||
#include <osmium/thread/pool.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
@ -425,6 +426,14 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
// write .timestamp data file
|
||||
std::string timestamp = header.get("osmosis_replication_timestamp");
|
||||
if (config.data_version == "osmosis")
|
||||
{
|
||||
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
files::writeTimestamp(config.GetPath(".osrm.timestamp").string(), config.data_version);
|
||||
}
|
||||
if (timestamp.empty())
|
||||
{
|
||||
timestamp = "n/a";
|
||||
|
@ -302,6 +302,7 @@ std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
|
||||
{REQUIRED, config.GetPath(".osrm.ebg_nodes")},
|
||||
{REQUIRED, config.GetPath(".osrm.tls")},
|
||||
{REQUIRED, config.GetPath(".osrm.tld")},
|
||||
{REQUIRED, config.GetPath(".osrm.timestamp")},
|
||||
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
|
||||
{REQUIRED, config.GetPath(".osrm.edges")},
|
||||
{REQUIRED, config.GetPath(".osrm.names")},
|
||||
@ -401,6 +402,17 @@ void Storage::PopulateStaticData(const SharedDataIndex &index)
|
||||
extractor::files::readNames(config.GetPath(".osrm.names"), name_table);
|
||||
}
|
||||
|
||||
// Timestamp mark
|
||||
{
|
||||
auto timestamp_ref = make_timestamp_view(index, "/common/timestamp");
|
||||
std::string ts;
|
||||
extractor::files::readTimestamp(config.GetPath(".osrm.timestamp"), ts);
|
||||
if (!ts.empty())
|
||||
{
|
||||
memcpy(const_cast<char *>(timestamp_ref.data()), ts.data(), ts.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Turn lane data
|
||||
{
|
||||
auto turn_lane_data = make_lane_data_view(index, "/common/turn_lanes");
|
||||
|
@ -43,6 +43,10 @@ return_code parseArguments(int argc,
|
||||
boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path)
|
||||
->default_value("profiles/car.lua"),
|
||||
"Path to LUA routing profile")(
|
||||
"data_version,d",
|
||||
boost::program_options::value<std::string>(&extractor_config.data_version)
|
||||
->default_value(""),
|
||||
"Data version. Leave blank to avoid. osmosis - to get timestamp from file")(
|
||||
"threads,t",
|
||||
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
|
||||
->default_value(tbb::task_scheduler_init::default_num_threads()),
|
||||
|
@ -341,6 +341,7 @@ class ContiguousInternalMemoryDataFacade<routing_algorithms::offline::Algorithm>
|
||||
StringView GetDestinationsForID(const NameID /*id*/) const override { return StringView{}; }
|
||||
StringView GetExitsForID(const NameID /*id*/) const override { return StringView{}; }
|
||||
bool GetContinueStraightDefault() const override { return false; }
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
double GetMapMatchingMaxSpeed() const override { return 0; }
|
||||
const char *GetWeightName() const override { return ""; }
|
||||
unsigned GetWeightPrecision() const override { return 0; }
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "extractor/turn_lane_types.hpp"
|
||||
#include "guidance/turn_bearing.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
#include "guidance/turn_instruction.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/datafacade/algorithm_datafacade.hpp"
|
||||
@ -54,6 +53,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
NodeForwardRange GetUncompressedForwardGeometry(const EdgeID /* id */) const override
|
||||
{
|
||||
static NodeID data[] = {0, 1, 2, 3};
|
||||
|
Loading…
Reference in New Issue
Block a user