Add script to generate formatted report.

This commit is contained in:
Daniel Patterson 2018-02-06 11:23:21 -08:00
parent 3f2d0afcac
commit e5b4a14dfd
No known key found for this signature in database
GPG Key ID: 19C12BE1725A028B
6 changed files with 6098 additions and 669 deletions

View File

@ -12,6 +12,9 @@ const errorReason = require('../lib/utils').errorReason;
const child_process = require('child_process');
const osmtogeojson = require('osmtogeojson');
const osmxmltojson = require('osmtogeojson/parse_osmxml');
module.exports = function () {
this.setGridSize = (meters) => {
// the constant is calculated (with BigDecimal as: 1.0/(DEG_TO_RAD*EARTH_RADIUS_IN_METERS
@ -170,13 +173,18 @@ module.exports = function () {
if (exists) callback();
else {
this.OSMDB.toXML((xml) => {
fs.writeFile(this.scenarioCacheFile, xml, (err) => {
if (err) callback(err);
var q = d3.queue(1);
q.defer(fs.writeFile, this.scenarioCacheFile, xml);
q.defer((cb) => {
var json = osmxmltojson.parseFromString(xml);
var geojson = osmtogeojson(json);
fs.writeFile(`${this.scenarioCacheFile}.geojson`,JSON.stringify(geojson),cb);
});
var params = ['cat',this.scenarioCacheFile,'-O','-o',this.scenarioCacheFilePBF, '--no-progress'];
let child = child_process.execFile('/usr/local/bin/osmium', params, {maxBuffer: 1024 * 1024 * 1000, env: {}}, (err,stdout,stderr) => {
callback(err);
});
});
q.defer(child_process.execFile,'/usr/local/bin/osmium', params, {maxBuffer: 1024 * 1024 * 1000, env: {}});
q.awaitAll(callback);
});
}
});

View File

@ -25,10 +25,12 @@ module.exports = function () {
this.profile = this.OSRM_PROFILE || this.DEFAULT_PROFILE;
this.profileFile = path.join(this.PROFILES_PATH, this.profile + '.lua');
this.setupFeatureCache(feature);
this.feature = feature;
callback();
});
this.Before((scenario, callback) => {
this.scenario = scenario;
this.osrmLoader.setLoadMethod(this.DEFAULT_LOAD_METHOD);
this.setGridSize(this.DEFAULT_GRID_SIZE);
this.setOrigin(this.DEFAULT_ORIGIN);

View File

@ -2,6 +2,8 @@
var util = require('util');
var assert = require('assert');
var polyline = require('polyline');
var fs = require('fs');
module.exports = function () {
this.ShouldGetAResponse = () => {
@ -28,10 +30,11 @@ module.exports = function () {
if (e) return callback(e);
var headers = new Set(table.raw()[0]);
var requestRow = (row, ri, cb) => {
var requestRow = (row, rowIndex, cb) => {
var got;
var afterRequest = (err, res, body) => {
console.log(waypoints);
if (err) return cb(err);
if (body && body.length) {
let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes,
@ -76,6 +79,67 @@ module.exports = function () {
weight_name = this.weightName(route);
weights = this.weightList(route);
approaches = this.approachList(route);
var resultdata = {
feature: this.feature.getName(),
scenario: this.scenario.getName(),
row: rowIndex,
expected: {
route: table.hashes()[rowIndex]["route"],
turns: table.hashes()[rowIndex]["turns"],
},
got: {
route: instructions,
turns: turns
}
}
fs.writeFileSync(`${this.scenarioCacheFile}_${rowIndex}_results.json`,JSON.stringify(resultdata));
var geojson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: { type: 'startpoint' },
geometry: {
type: 'Point',
coordinates: [parseFloat(waypoints[0].lon),parseFloat(waypoints[0].lat)]
}
}
,
{
type: 'Feature',
properties: { type: 'endpoint' },
geometry: {
type: 'Point',
coordinates: [parseFloat(waypoints[1].lon), parseFloat(waypoints[1].lat)]
}
},
{
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: []
},
properties: {}
}
]
};
// Extract Valhalla route geometry
if (this.osrmLoader.method === 'valhalla') {
geojson.features[2].geometry.coordinates = polyline.decode(route.legs[0].shape,6).map(c => c.reverse());
} else {
// OSRM route geometry
// TODO: Assume polyline5 for now
if (typeof route.geometry === 'string') {
geojson.features[2].geometry.coordinates = polyline.decode(route.geometry).map(c => c.reverse());
} else {
geojson.features[2].geometry = route.geometry;
}
}
fs.writeFileSync(`${this.scenarioCacheFile}_${rowIndex}_shape.geojson`,JSON.stringify(geojson));
}
if (headers.has('status')) {

6483
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,13 @@
"private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
"dependencies": {
"carto": "^0.18.2",
"mapnik": "^3.6.2",
"mkdirp": "^0.5.1",
"nan": "^2.6.2",
"node-cmake": "^2.3.2",
"node-pre-gyp": "^0.6.36",
"osmtogeojson": "^3.0.0-beta.3"
"rimraf": "^2.5.4"
},
"browserify": {

193
scripts/tests2doc.js Normal file
View File

@ -0,0 +1,193 @@
"use strict"
const fs = require('fs');
const path = require('path');
const d3 = require('d3-queue');
var mapnik = require('mapnik');
mapnik.register_default_input_plugins();
mapnik.register_system_fonts()
//console.log(mapnik.fonts());
const find = (dir) =>
fs.readdirSync(dir)
.reduce((files, file) =>
fs.statSync(path.join(dir, file)).isDirectory() ?
files.concat(find(path.join(dir, file))) :
files.concat(path.join(dir, file)),
[]);
function makemappng(basefile, routefile, callback) {
var stylesheet = `
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map[]>
<Map srs="+init=epsg:3857" buffer-size="8">
<Style name="testmap" filter-mode="all">
<Rule>
<Filter>[highway] = 'motorway'</Filter>
<LineSymbolizer stroke-width="12" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#aacc77" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-10'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='10'>'highway=' + [highway]</TextSymbolizer>
</Rule>
<Rule>
<Filter>[highway] = 'motorway_link'</Filter>
<LineSymbolizer stroke-width="12" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#77aacc" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-10'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='10'>'highway=' + [highway]</TextSymbolizer>
</Rule>
<Rule>
<Filter>[highway] = 'trunk'</Filter>
<LineSymbolizer stroke-width="12" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#ccaa77" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-10'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='10'>'highway=' + [highway]</TextSymbolizer>
</Rule>
<Rule>
<Filter>[highway] = 'trunk_link'</Filter>
<LineSymbolizer stroke-width="12" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#aa77cc" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-10'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='10'>'highway=' + [highway]</TextSymbolizer>
</Rule>
<Rule>
<Filter>[highway] = 'primary'</Filter>
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="8" stroke-linejoin="round" stroke-linecap="round" stroke="#77ccaa" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-8'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='8'>'highway=' + [highway]</TextSymbolizer>
</Rule>
<Rule>
<Filter>[highway] = 'primary_link'</Filter>
<LineSymbolizer stroke-width="10" stroke-linejoin="round" stroke-linecap="round" stroke="#bbbbbb" />
<LineSymbolizer stroke-width="8" stroke-linejoin="round" stroke-linecap="round" stroke="#aa77cc" />
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='-8'>'name=' + [name]</TextSymbolizer>
<TextSymbolizer face-name="Arial Regular" size="10" fill="black" placement="line" allow-overlap="false" dy='8'>'highway=' + [highway]</TextSymbolizer>
</Rule>
</Style>
<Layer name="testmap" srs="+init=epsg:4326">
<StyleName>testmap</StyleName>
<Datasource>
<Parameter name="type">geojson</Parameter>
<Parameter name="file">${basefile}</Parameter>
</Datasource>
</Layer>
<Style name="testroute-line" filter-mode="all">
<Rule>
<LineSymbolizer stroke-width="5" stroke-linejoin="round" stroke-linecap="round" stroke="#000077" offset="6"/>
<LineSymbolizer stroke-width="3" stroke-linejoin="round" stroke-linecap="round" stroke="#0000ff" offset="6"/>
</Rule>
</Style>
<Style name="testroute-markers" filter-mode="all">
<Rule>
<Filter>[type] = 'startpoint'</Filter>
<MarkersSymbolizer fill="green" width="20" height="20" stroke="green"/>
</Rule>
<Rule>
<Filter>[type] = 'endpoint'</Filter>
<MarkersSymbolizer fill="red" width="20" height="20" stroke="red"/>
</Rule>
</Style>
<Layer name="testroute" srs="+init=epsg:4326">
<StyleName>testroute-line</StyleName>
<StyleName>testroute-markers</StyleName>
<Datasource>
<Parameter name="type">geojson</Parameter>
<Parameter name="file">${routefile}</Parameter>
</Datasource>
</Layer>
</Map>`;
var map = new mapnik.Map(300, 200);
map.fromStringSync(stylesheet,{strict:true});
map.zoomAll();
var extent = map.extent;
extent[0] = extent[0] - Math.abs(extent[0]) * 0.00001;
extent[1] = extent[1] - Math.abs(extent[1]) * 0.00001;
extent[2] = extent[2] + Math.abs(extent[2]) * 0.00001;
extent[3] = extent[3] + Math.abs(extent[3]) * 0.00001;
map.zoomToBox(extent);
var buffer = new mapnik.Image(300,200)
map.render(buffer, {}, (err,image) => {
callback(image.encodeSync('png'));
});
}
var report = "";
var toc = [];
find('test/cache').filter((f) => f.match(/[0-9]+_results.json$/)).forEach((f) => {
var files = f.match(/(.*?)_([0-9]+)_results.json$/,f);
var results = JSON.parse(fs.readFileSync(f));
// Generate map image
var imagefile = `${files[1]}_${files[2]}`.replace(/\//g,'_');
var png = makemappng(`${files[1]}.geojson`, `${files[1]}_${files[2]}_shape.geojson`, (png) => {
fs.writeFileSync(`report/${imagefile}`,png);
});
toc.push({ title: `${results.feature} - ${results.scenario}`, link: imagefile });
report += `<div class='scenario ${results.got.turns == results.expected.turns ? 'ok' : 'error'}'>
<h2><a name="${imagefile}">${results.feature} - ${results.scenario}</a></h2>
<table class="row">
<tr>
<td>
<img src="${imagefile}"/>
</td>
<td>
<table class="results">
<tr><th/><th style='text-align: left'>Route</th><th style='text-align: left'>Turns</th></tr>
<tr><th style='text-align: right'>Expected</th><td>${results.expected.route}</td><td>${results.expected.turns}</td></tr>
<tr><th style='text-align: right'>Got</th><td>${results.got.route}</td><td class='${results.got.turns == results.expected.turns ? 'ok' : 'error'}'>${results.got.turns}</td></tr>
</table>
</td></tr></table>
</div>
<hr/>
`;
// Generate HTML table
});
console.log(`
<!DOCYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; }
.results td { padding-left: 1em; font-family: monospace; }
.results th { padding-left: 1em; }
.scenario.error { background: #fbb; }
.error { color: red; }
</style>
<body>
`);
toc.forEach(r => {
console.log(`<a href='#${r.link}'>${r.title}</a><br/>`);
});
console.log(report);
console.log(`
</body>
</html>
`);