2019-10-07 14:32:55 +02:00
<!DOCTYPE html>
< html >
< head >
< meta http-equiv = "content-type" content = "text/html; charset=UTF-8" >
< meta charset = "utf-8" >
< meta name = viewport content = "width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" >
< title > Testing BRouter profiles< / title >
< link rel = "stylesheet" href = "css/leaflet.css" >
< style >
body {
max-width: 800px;
margin: auto;
font-family: sans-serif;
font-size: 14px;
text-align: justify;
}
h1 {
text-align: center;
margin-top: 20px;
margin-bottom: 20px;
}
.summary {
font-size: 0.8em;
}
.summary li {
margin-bottom: 2px;
}
.testcase {
margin-bottom: 30px;
}
.map {
height: 300px;
}
.footer {
font-size: 0.8em;
display: flex;
}
.debug {
flex: auto;
text-align: left;
}
2019-10-08 15:16:21 +02:00
2019-10-07 14:32:55 +02:00
.back-top {
flex: auto;
text-align: right;
}
label {
display: inline-block;
text-align: left;
}
2019-10-08 15:16:21 +02:00
2019-10-07 14:32:55 +02:00
input[type="text"], textarea {
width: 100%;
display: inline-block;
}
2019-10-08 15:16:21 +02:00
2019-10-07 14:32:55 +02:00
textarea {
min-height: 300px;
}
2019-10-08 15:16:21 +02:00
2019-10-07 14:32:55 +02:00
#step2 {
display: none;
}
2019-10-08 15:16:21 +02:00
2019-10-07 14:32:55 +02:00
.center {
text-align: center;
}
.error {
font-weight: bold;
color: red;
}
2019-10-08 15:16:21 +02:00
#status {
font-weight: bold;
color: blue;
text-align: center;
}
#error {
text-align: center;
}
2019-10-07 14:32:55 +02:00
.footnote {
font-size: 0.8em;
margin-top: -10px;
}
< / style >
< / head >
< body >
< h1 id = "brouter-tester" > BRouter profiles tester< / h1 >
< p > Here are some test cases to check < a href = "http://brouter.de/" > BRouter< / a > profiles and help with development of new profiles.< / p >
< p > < strong > Important: beware that the map tiles used are the live map tiles (using up to date OSM data) contrary to the BRouter < code > segments4< / code > test files which are using a fixed dump of OSM data. Then, the map background may come out of sync with the data used by BRouter and are only there as an eyeguide.< / strong > < / p >
< p > The map show the route computed with the selected profile (in blue), the route computed by the reference profile (in grey) as well as a route computed by a human (in green). Note that the human route is not necessarily the best one or the unique valid solution.< / p >
< p > The tests assume the BRouter instance uses < a href = "https://pub.phyks.me/brouter-testing/segments4/" > these < code > segments4< / code > files< / a > which are built from the < a href = "https://download.geofabrik.de/" > Geofabrik.de< / a > extracts of metropolitan France, New York state (US) and Sachsen state (Germany) from the 10th of November, 2018. The < code > profiles2< / code > folder used to build the < code > segments4< / code > files is available < a href = "https://pub.phyks.me/brouter-testing/profiles2/" > here< / a > (including the < code > lookups.dat< / code > file). The SRTM data used to build the < code > segments4< / code > are available < a href = "https://pub.phyks.me/brouter-testing/srtm/" > here< / a > .< / p >
< h2 > Settings< / h2 >
< form id = "settings" >
< p >
< label for = "profile" > Profile content: < / label >
< textarea name = "profile" id = "profile" > < / textarea >
< / p >
< p >
< label for = "reference-profile" > Reference profile: < / label >
< input type = "text" name = "reference_profile" id = "reference-profile" value = "trekking" / >
< / p >
< p >
< label for = "brouter-url" > BRouter URL: < / label >
2019-10-08 15:20:54 +02:00
< input type = "text" name = "brouter_url" id = "brouter-url" value = "http://brouter.de:7777" / >
2019-10-07 14:32:55 +02:00
< p class = "footnote" > Your BRouter instance should provide < a href = "https://developer.mozilla.org/fr/docs/Web/HTTP/CORS" > CORS< / a > headers. Otherwise, you can use an extension such as < a href = "https://addons.mozilla.org/fr/firefox/addon/cors-everywhere/" > CORS Everywhere< / a > .< / p >
< / p >
< p >
< label for = "brouter-web-url" > BRouter web URL (for debug): < / label >
< input type = "text" name = "brouter_web_url" id = "brouter-web-url" value = "http://brouter.de/brouter-web/" / >
< / p >
< p >
< label for = "tile-url" > Tile URL: < / label >
< input type = "text" name = "tile_url" id = "tile-url" value = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" / >
< / p >
< p class = "error" id = "error" > < / p >
2019-10-08 15:16:21 +02:00
< p id = "status" > < / p >
2019-10-07 14:32:55 +02:00
< p class = "center" > < input type = "submit" value = "Run tests" / > < / p >
< / form >
< div id = "step2" >
< h2 > Summary< / h2 >
< div class = "summary" > < / div >
< template class = "testcase-template" >
< div class = "testcase" >
< p class = "description" > < / p >
< p class = "error" > < / p >
< div class = "map" > < / div >
< div class = "footer" >
< p class = "debug" > < a href = "" > Debug this test case< / a > < / p >
< p class = "back-top" > < a href = "#brouter-tester" > Back to top ↑< / a > < / p >
< / div >
< / div >
< / template >
< / div >
< script src = "js/leaflet.js" > < / script >
< script src = "tests.js" > < / script >
< script type = "text/javascript" >
2019-10-08 15:16:21 +02:00
document.querySelector('#settings').addEventListener('submit', (event) => {
2019-10-07 14:32:55 +02:00
event.preventDefault();
document.querySelector('#settings input[type="submit"]').disabled = true;
var profile = document.querySelector('#profile').value;
var referenceProfile = document.querySelector('#reference-profile').value;
var brouterUrl = document.querySelector('#brouter-url').value;
var brouterWebUrl = document.querySelector('#brouter-web-url').value;
var tileUrl = document.querySelector('#tile-url').value;
if (!profile || !referenceProfile || !brouterUrl || !brouterWebUrl) {
document.querySelector('#error').innerText = 'ERROR: Missing field.';
return;
}
fetch(brouterUrl + '/brouter/profile', {
method : "POST",
body: profile,
2019-10-08 15:16:21 +02:00
}).then(
response => response.json()
).then((response) => {
2019-10-07 14:32:55 +02:00
var profileId = response['profileid'];
document.querySelector('#step2').style.display = 'block';
2019-10-08 15:16:21 +02:00
document.querySelector('#status').innerText = 'Running tests…';
2019-10-07 14:32:55 +02:00
var idx = 0;
2019-10-08 15:16:21 +02:00
var promisesQueue = Promise.resolve(null);
Object.keys(TESTS).forEach((testCategory) => {
2019-10-07 14:32:55 +02:00
var testCategoryID = testCategory.replace(/[^a-zA-Z]/g, "");
// Create dedicated section
var h2 = document.createElement('h2');
h2.innerText = testCategory;
h2.id = testCategoryID;
document.body.appendChild(h2);
// Handle summary
var summaryTitle = document.createElement('h3');
var summaryTitleLink = document.createElement('a');
summaryTitleLink.href = '#' + testCategoryID;
summaryTitleLink.innerText = testCategory;
summaryTitle.appendChild(summaryTitleLink);
var summaryList = document.createElement('ul');
summaryList.id = testCategoryID + '-summary';
var summary = document.querySelector('.summary');
summary.appendChild(summaryTitle);
summary.appendChild(summaryList);
// Handle all test cases
2019-10-08 15:16:21 +02:00
TESTS[testCategory].forEach((testCase) => {
2019-10-07 14:32:55 +02:00
var startPoint = testCase.start_point;
var endPoint = testCase.end_point;
// Update summary
var li = document.createElement('li');
var a = document.createElement('a');
a.href = '#testcase-' + idx;
a.innerText = testCase.description;
li.appendChild(a);
document.querySelector('#' + testCategoryID + '-summary').append(li);
// Create entry with map and description
var template = document.querySelector(".testcase-template");
var clone = template.content.cloneNode(true);
clone.querySelector('.map').id = 'map_' + idx;
clone.querySelector('.error').id = 'error_' + idx;
clone.querySelector('.description').id = 'testcase-' + idx;
clone.querySelector('.description').innerText = '→ ' + testCase.description;
clone.querySelector('.debug a').href = (
document.querySelector('#brouter-web-url').value + '/#' +
'map=15/' + startPoint[1] + '/' + startPoint[0] + '/osm& ' +
'lonlats=' + startPoint.join(',') + '|' + endPoint.join(',') + '& ' +
'profile=' + document.querySelector('#reference-profile').value
);
document.body.appendChild(clone);
var map = L.map('map_' + idx);
L.tileLayer(tileUrl, {
attribution: 'Map data © < a href = "https://www.openstreetmap.org/" > OpenStreetMap< / a > contributors',
minZoom: 0,
maxZoom: 20,
}).addTo(map);
map.fitBounds(L.latLngBounds(
L.latLng(Math.min(startPoint[1], endPoint[1]), Math.min(startPoint[0], endPoint[0])),
L.latLng(Math.max(startPoint[1], endPoint[1]), Math.max(startPoint[0], endPoint[0]))
));
if (testCase.human) {
L.geoJSON(testCase.human, { style: { color: '#5CA423' } }).addTo(map);
}
function delayFetch(startPoint, endPoint, map, idx) {
return function () {
2019-10-08 15:16:21 +02:00
return new Promise(function (resolve, reject) {
2019-10-07 14:32:55 +02:00
fetch(
brouterUrl + '/brouter?' +
'lonlats=' + startPoint.join(',') + '|' + endPoint.join(',') + '& ' +
2019-10-08 15:16:21 +02:00
'profile=' + profileId + '& ' +
2019-10-07 14:32:55 +02:00
'alternativeidx=0& format=geojson'
).then(function (geojson) {
return geojson.json();
}).then(function (geojson) {
2019-10-08 15:16:21 +02:00
L.geoJSON(geojson).addTo(map);
fetch(
brouterUrl + '/brouter?' +
'lonlats=' + startPoint.join(',') + '|' + endPoint.join(',') + '& ' +
'profile=' + referenceProfile + '& ' +
'alternativeidx=0& format=geojson'
).then(function (geojson) {
return geojson.json();
}).then(function (geojson) {
L.geoJSON(geojson, { style: { color: '#666666' } }).addTo(map);
resolve(null);
});
2019-10-07 14:32:55 +02:00
}).catch(function (error) {
2019-10-08 15:16:21 +02:00
document.querySelector('#error').innerText = 'ERROR, see test results below.';
document.querySelector('#status').innerText = '';
2019-10-07 14:32:55 +02:00
document.querySelector('#error_' + idx).innerText = 'ERROR: ' + error;
});
});
};
}
// Overlay route with current profile
2019-10-08 15:16:21 +02:00
promisesQueue = promisesQueue.then(delayFetch(startPoint, endPoint, map, idx));
2019-10-07 14:32:55 +02:00
idx += 1;
});
2019-10-08 15:16:21 +02:00
promisesQueue.then(() => {
document.querySelector('#status').innerText = 'All tests done, see individual results below!';
})
2019-10-07 14:32:55 +02:00
});
2019-10-08 15:16:21 +02:00
}).catch((exc) => {
2019-10-07 14:32:55 +02:00
document.querySelector('#error').innerText = 'ERROR:' + exc;
});
});
< / script >
< / body >
< / html >