Skip to content

Commit

Permalink
Return datasource names along with datasource annotation (#4973)
Browse files Browse the repository at this point in the history
* Add new `datasource_names` annotation that returns the string version of the `datasources` annotation
  • Loading branch information
danpat authored Apr 3, 2018
1 parent 8a63ad9 commit b5a4ffe
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- ADDED: Add documentation about OSM node ids in nearest service response [#4436](https://github.com/Project-OSRM/osrm-backend/pull/4436)
- Performance
- FIXED: Speed up response time when lots of legs exist and geojson is used with `steps=true` [#4936](https://github.com/Project-OSRM/osrm-backend/pull/4936)
- Misc:
- ADDED: expose name for datasource annotations as metadata [#4973](https://github.com/Project-OSRM/osrm-backend/pull/4973)

# 5.16.0
- Changes from 5.15.2:
Expand Down
6 changes: 5 additions & 1 deletion docs/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ With `steps=false` and `annotations=true`:
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] },
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
"speed": [0.3, 0.3, 0.3, 0.3, 0.3]
}
Expand All @@ -561,10 +562,12 @@ Annotation of the whole route leg with fine-grained information about each segme

- `distance`: The distance, in metres, between each pair of coordinates
- `duration`: The duration between each pair of coordinates, in seconds. Does not include the duration of any turns.
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`. String-like names are in the `metadata.datasource_names` array.
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
- `weight`: The weights between each pair of coordinates. Does not include any turn costs.
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
- `metadata`: Metadata related to other annotations
- `datasource_names`: The names of the datasources used for the speed between each pair of coordinates. `lua profile` is the default profile, other values arethe filenames supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`

#### Example

Expand All @@ -573,6 +576,7 @@ Annotation of the whole route leg with fine-grained information about each segme
"distance": [5,5,10,5,5],
"duration": [15,15,40,15,15],
"datasources": [1,0,0,0,1],
"metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] },
"nodes": [49772551,49772552,49786799,49786800,49786801,49786802],
"weight": [15,15,40,15,15]
}
Expand Down
16 changes: 14 additions & 2 deletions features/support/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,26 @@ module.exports = function () {

var merged = {};
instructions.legs.map(l => {
Object.keys(l.annotation).forEach(a => {
Object.keys(l.annotation).filter(a => !a.match(/metadata/)).forEach(a => {
if (!merged[a]) merged[a] = [];
merged[a].push(l.annotation[a].join(':'));
});
if (l.annotation.metadata) {
merged.metadata = {};
Object.keys(l.annotation.metadata).forEach(a => {
if (!merged.metadata[a]) merged.metadata[a] = [];
merged.metadata[a].push(l.annotation.metadata[a].join(':'));
});
}
});
Object.keys(merged).map(a => {
Object.keys(merged).filter(k => !k.match(/metadata/)).map(a => {
merged[a] = merged[a].join(',');
});
if (merged.metadata) {
Object.keys(merged.metadata).map(a => {
merged.metadata[a] = merged.metadata[a].join(',');
});
}
return merged;
};

Expand Down
10 changes: 9 additions & 1 deletion features/support/shared_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,22 @@ module.exports = function () {
// if header matches 'a:*', parse out the values for *
// and return in that header
headers.forEach((k) => {
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed'];
let whitelist = ['duration', 'distance', 'datasources', 'nodes', 'weight', 'speed' ];
let metadata_whitelist = [ 'datasource_names' ];
if (k.match(/^a:/)) {
let a_type = k.slice(2);
if (whitelist.indexOf(a_type) == -1)
return cb(new Error('Unrecognized annotation field', a_type));
if (annotation && !annotation[a_type])
return cb(new Error('Annotation not found in response', a_type));
got[k] = annotation && annotation[a_type] || '';
} else if (k.match(/^am:/)) {
let a_type = k.slice(3);
if (metadata_whitelist.indexOf(a_type) == -1)
return cb(new Error('Unrecognized annotation field', a_type));
if (annotation && (!annotation.metadata || !annotation.metadata[a_type]))
return cb(new Error('Annotation not found in response', a_type));
got[k] = (annotation && annotation.metadata && annotation.metadata[a_type]) || '';
}
});

Expand Down
33 changes: 33 additions & 0 deletions features/testbot/annotations.feature
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,39 @@ Feature: Annotations
| a | i | abcdefghi,abcdefghi | 1:0:1:0:1:0:0:0 | 50:10:50:10:50:10:10:10 |
| i | a | abcdefghi,abcdefghi | 0:1:0:0:0:0:0:1 | 10:50:10:10:10:10:10:50 |

Scenario: datasource name annotations
Given the profile "testbot"

And the node map
"""
a b c
"""

And the ways
| nodes |
| abc |

And the contract extra arguments "--segment-speed-file {speeds_file}"
And the customize extra arguments "--segment-speed-file {speeds_file}"

And the speed file
"""
1,2,180,1
2,1,180,1
"""

And the query options
| annotations | datasources |

# Note - the source names here are specific to how the tests are constructed,
# so if this test is moved around (changes line number) or support code
# changes how the filenames are generated, this test will need to be updated
When I route I should get
| from | to | route | am:datasource_names |
| a | c | abc,abc | lua profile:63_datasource_name_annotations_speeds |
| c | a | abc,abc | lua profile:63_datasource_name_annotations_speeds |


Scenario: Speed annotations should handle zero segments
Given the profile "testbot"

Expand Down
17 changes: 17 additions & 0 deletions include/engine/api/route_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,23 @@ class RouteAPI : public BaseAPI
}
annotation.values["nodes"] = std::move(nodes);
}
// Add any supporting metadata, if needed
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
const auto MAX_DATASOURCE_ID = 255u;
util::json::Object metadata;
util::json::Array datasource_names;
for (auto i = 0u; i < MAX_DATASOURCE_ID; i++)
{
const auto name = facade.GetDatasourceName(i);
// Length of 0 indicates the first empty name, so we can stop here
if (name.size() == 0)
break;
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
}
metadata.values["datasource_names"] = datasource_names;
annotation.values["metadata"] = metadata;
}

annotations.push_back(std::move(annotation));
}
Expand Down
2 changes: 1 addition & 1 deletion unit_tests/library/route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property)
.values["annotation"]
.get<json::Object>()
.values;
BOOST_CHECK_EQUAL(annotations.size(), 5);
BOOST_CHECK_EQUAL(annotations.size(), 6);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit b5a4ffe

Please sign in to comment.