Skip to content

Commit

Permalink
Merge f89ca2b into 0a1d190
Browse files Browse the repository at this point in the history
  • Loading branch information
ghoshkaj committed Apr 18, 2018
2 parents 0a1d190 + f89ca2b commit 5c04bf6
Show file tree
Hide file tree
Showing 34 changed files with 1,842 additions and 521 deletions.
103 changes: 100 additions & 3 deletions docs/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ curl 'http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397

### Table service

Computes the duration of the fastest route between all pairs of supplied coordinates.
Computes the duration of the fastest route between all pairs of supplied coordinates. Also returns the distances between the coordinate pairs. Note that the distances are not the shortest distance between two coordinates, but rather the distances of the fastest routes.

```endpoint
GET /table/v1/{profile}/{coordinates}?{sources}=[{elem}...];&destinations=[{elem}...]
Expand Down Expand Up @@ -268,17 +268,114 @@ curl 'http://router.project-osrm.org/table/v1/driving/polyline(egs_Iq_aqAppHzbHu
- `code` if the request was successful `Ok` otherwise see the service dependent and general status codes.
- `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. Can be `null` if no route between `i` and `j` can be found.
- `distances` array of arrays that stores the matrix in row-major order. `distances[i][j]` gives the travel distance from
the i-th waypoint to the j-th waypoint. Values are given in meters. Can be `null` if no route between `i` and `j` can be found.
- `sources` array of `Waypoint` objects describing all sources in order
- `destinations` array of `Waypoint` objects describing all destinations in order

In case of error the following `code`s are supported in addition to the general ones:

| Type | Description |
|-------------------|-----------------|
| Type | Description |
|------------------|-----------------|
| `NoTable` | No route found. |

All other properties might be undefined.

#### Example Response

```json
{
"sources": [
{
"location": [
13.3888,
52.517033
],
"hint": "PAMAgEVJAoAUAAAAIAAAAAcAAAAAAAAArss0Qa7LNEHiVIRA4lSEQAoAAAAQAAAABAAAAAAAAADMAAAAAEzMAKlYIQM8TMwArVghAwEA3wps52D3",
"name": "Friedrichstraße"
},
{
"location": [
13.397631,
52.529432
],
"hint": "WIQBgL6mAoAEAAAABgAAAAAAAAA7AAAAhU6PQHvHj0IAAAAAQbyYQgQAAAAGAAAAAAAAADsAAADMAAAAf27MABiJIQOCbswA_4ghAwAAXwVs52D3",
"name": "Torstraße"
},
{
"location": [
13.428554,
52.523239
],
"hint": "7UcAgP___38fAAAAUQAAACYAAABTAAAAhSQKQrXq5kKRbiZCWJo_Qx8AAABRAAAAJgAAAFMAAADMAAAASufMAOdwIQNL58wA03AhAwMAvxBs52D3",
"name": "Platz der Vereinten Nationen"
}
],
"durations": [
[
0,
192.6,
382.8
],
[
199,
0,
283.9
],
[
344.7,
222.3,
0
]
],
"destinations": [
{
"location": [
13.3888,
52.517033
],
"hint": "PAMAgEVJAoAUAAAAIAAAAAcAAAAAAAAArss0Qa7LNEHiVIRA4lSEQAoAAAAQAAAABAAAAAAAAADMAAAAAEzMAKlYIQM8TMwArVghAwEA3wps52D3",
"name": "Friedrichstraße"
},
{
"location": [
13.397631,
52.529432
],
"hint": "WIQBgL6mAoAEAAAABgAAAAAAAAA7AAAAhU6PQHvHj0IAAAAAQbyYQgQAAAAGAAAAAAAAADsAAADMAAAAf27MABiJIQOCbswA_4ghAwAAXwVs52D3",
"name": "Torstraße"
},
{
"location": [
13.428554,
52.523239
],
"hint": "7UcAgP___38fAAAAUQAAACYAAABTAAAAhSQKQrXq5kKRbiZCWJo_Qx8AAABRAAAAJgAAAFMAAADMAAAASufMAOdwIQNL58wA03AhAwMAvxBs52D3",
"name": "Platz der Vereinten Nationen"
}
],
"code": "Ok",
"distances": [
[
0,
1886.89,
3791.3
],
[
1824,
0,
2838.09
],
[
3275.36,
2361.73,
0
]
]
}
```


### Match service

Map matching matches/snaps given GPS points to the road network in the most plausible way.
Expand Down
136 changes: 75 additions & 61 deletions features/step_definitions/distance_matrix.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,88 @@
var util = require('util');

module.exports = function () {
this.When(/^I request a travel time matrix I should get$/, (table, callback) => {
var NO_ROUTE = 2147483647; // MAX_INT
const durationsRegex = new RegExp(/^I request a travel time matrix I should get$/);
const distancesRegex = new RegExp(/^I request a travel distance matrix I should get$/);

var tableRows = table.raw();
const DURATIONS_NO_ROUTE = 2147483647; // MAX_INT
const DISTANCES_NO_ROUTE = 3.40282e+38; // MAX_FLOAT

if (tableRows[0][0] !== '') throw new Error('*** Top-left cell of matrix table must be empty');
this.When(durationsRegex, function(table, callback) {tableParse.call(this, table, DURATIONS_NO_ROUTE, 'durations', callback);}.bind(this));
this.When(distancesRegex, function(table, callback) {tableParse.call(this, table, DISTANCES_NO_ROUTE, 'distances', callback);}.bind(this));
};

var waypoints = [],
columnHeaders = tableRows[0].slice(1),
rowHeaders = tableRows.map((h) => h[0]).slice(1),
symmetric = columnHeaders.length == rowHeaders.length && columnHeaders.every((ele, i) => ele === rowHeaders[i]);
const durationsParse = function(v) { return isNaN(parseInt(v)); };
const distancesParse = function(v) { return isNaN(parseFloat(v)); };

if (symmetric) {
columnHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'loc' });
});
} else {
columnHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'dst' });
});
rowHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'src' });
function tableParse(table, noRoute, annotation, callback) {

const parse = annotation == 'distances' ? distancesParse : durationsParse;
const params = this.queryParams;
params.annotations = annotation == 'distances' ? 'distance' : 'duration';

var tableRows = table.raw();

if (tableRows[0][0] !== '') throw new Error('*** Top-left cell of matrix table must be empty');

var waypoints = [],
columnHeaders = tableRows[0].slice(1),
rowHeaders = tableRows.map((h) => h[0]).slice(1),
symmetric = columnHeaders.length == rowHeaders.length && columnHeaders.every((ele, i) => ele === rowHeaders[i]);

if (symmetric) {
columnHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'loc' });
});
} else {
columnHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'dst' });
});
rowHeaders.forEach((nodeName) => {
var node = this.findNodeByName(nodeName);
if (!node) throw new Error(util.format('*** unknown node "%s"', nodeName));
waypoints.push({ coord: node, type: 'src' });
});
}

var actual = [];
actual.push(table.headers);

this.reprocessAndLoadData((e) => {
if (e) return callback(e);
// compute matrix

this.requestTable(waypoints, params, (err, response) => {
if (err) return callback(err);
if (!response.body.length) return callback(new Error('Invalid response body'));

var json = JSON.parse(response.body);

var result = json[annotation].map(row => {
var hashes = {};
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = parse(v) ? '' : v; });
return hashes;
});
}

var actual = [];
actual.push(table.headers);

this.reprocessAndLoadData((e) => {
if (e) return callback(e);
// compute matrix
var params = this.queryParams;

this.requestTable(waypoints, params, (err, response) => {
if (err) return callback(err);
if (!response.body.length) return callback(new Error('Invalid response body'));

var json = JSON.parse(response.body);

var result = json['durations'].map(row => {
var hashes = {};
row.forEach((v, i) => { hashes[tableRows[0][i+1]] = isNaN(parseInt(v)) ? '' : v; });
return hashes;
});

var testRow = (row, ri, cb) => {
for (var k in result[ri]) {
if (this.FuzzyMatch.match(result[ri][k], row[k])) {
result[ri][k] = row[k];
} else if (row[k] === '' && result[ri][k] === NO_ROUTE) {
result[ri][k] = '';
} else {
result[ri][k] = result[ri][k].toString();
}

var testRow = (row, ri, cb) => {
for (var k in result[ri]) {
if (this.FuzzyMatch.match(result[ri][k], row[k])) { // for floating points, we should do an epsilon check which is find the difference and check > or < 0.000001 -- do this in fuzzy match
result[ri][k] = row[k];
} else if (row[k] === '' && result[ri][k] === noRoute) {
result[ri][k] = '';
} else {
result[ri][k] = result[ri][k].toString();
}
}

result[ri][''] = row[''];
cb(null, result[ri]);
};
result[ri][''] = row[''];
cb(null, result[ri]);
};

this.processRowsAndDiff(table, testRow, callback);
});
this.processRowsAndDiff(table, testRow, callback);
});
});
};
}
2 changes: 1 addition & 1 deletion features/support/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module.exports = function () {
.defer(rimraf, this.scenarioLogFile)
.awaitAll(callback);
// uncomment to get path to logfile
// console.log(" Writing logging output to " + this.scenarioLogFile)
// console.log(' Writing logging output to ' + this.scenarioLogFile);
});

this.After((scenario, callback) => {
Expand Down
Loading

0 comments on commit 5c04bf6

Please sign in to comment.