Add sidebar tab with route analysis data

- adds a new analysis tab in the sidebar
- the analysis tab shows length distribution for different way types, surface, and smoothness
- table rows can be hovered/clicked to highlight the according segments on the map (similar behaviour as the detailed data table)
- localization is implemented for `de` and `en`
- the method for finding segment edges was extracted from `js/control/TrackMessages.js` into `js/util/TrackEdges.js` as it's used in the new analysis class too (the Gulp config was changed to reflect that)

Notes:

I had the idea to use the *DataTable* plugin for rendering the tables but decided against it. The only meaningful way to sort such a table is by the length column and that's already the case. So it's just three plain, old HTML tables, rendered by jQuery.

For meaningful statistics the `processUnusedTags` setting has to be enabled in the routing profile. Only in this case the BRouter backend includes all needed tags (`highway`, `surface`, and `smoothness`) for *every* route segment in the response. I’ve enabled that setting for all profiles at my BRouter-web instance at <https://brouter.m11n.de/>.
This commit is contained in:
Marcus Jaschen 2020-06-07 16:56:50 +02:00
parent b181649dff
commit fc54c65e23
9 changed files with 682 additions and 53 deletions

View file

@ -26,6 +26,16 @@ BR.TrackMessages = L.Class.extend({
InitialCost: { title: 'initial$', className: 'dt-body-right' }
},
/**
* @type {?BR.TrackEdges}
*/
trackEdges: null,
/**
* @type {?L.Polyline}
*/
trackPolyline: null,
initialize: function(map, options) {
L.setOptions(this, options);
this._map = map;
@ -49,6 +59,9 @@ BR.TrackMessages = L.Class.extend({
return;
}
this.trackPolyline = polyline;
this.trackEdges = new BR.TrackEdges(segments);
for (i = 0; segments && i < segments.length; i++) {
messages = segments[i].feature.properties.messages;
if (messages) {
@ -80,7 +93,7 @@ BR.TrackMessages = L.Class.extend({
});
// highlight track segment (graph edge) on row hover
this._setEdges(polyline, segments);
$('#datatable tbody tr').hover(L.bind(this._handleHover, this), L.bind(this._handleHoverOut, this));
$('#datatable tbody').on('click', 'tr', L.bind(this._toggleSelected, this));
},
@ -147,59 +160,11 @@ BR.TrackMessages = L.Class.extend({
return empty;
},
_getMessageLatLng: function(message) {
var lon = message[0] / 1000000,
lat = message[1] / 1000000;
return L.latLng(lat, lon);
},
_setEdges: function(polyline, segments) {
var messages,
segLatLngs,
length,
si,
mi,
latLng,
i,
segIndex,
baseIndex = 0;
// track latLngs index for end node of edge
this._edges = [];
this._track = polyline;
for (si = 0; si < segments.length; si++) {
messages = segments[si].feature.properties.messages;
segLatLngs = segments[si].getLatLngs();
length = segLatLngs.length;
segIndex = 0;
for (mi = 1; mi < messages.length; mi++) {
latLng = this._getMessageLatLng(messages[mi]);
for (i = segIndex; i < length; i++) {
if (latLng.equals(segLatLngs[i])) {
break;
}
}
if (i === length) {
i = length - 1;
if (mi !== messages.length - 1) debugger;
}
segIndex = i + 1;
this._edges.push(baseIndex + i);
}
baseIndex += length;
}
},
_getRowEdge: function(tr) {
var row = this._table.row($(tr)),
trackLatLngs = this._track.getLatLngs(),
startIndex = row.index() > 0 ? this._edges[row.index() - 1] : 0,
endIndex = this._edges[row.index()],
trackLatLngs = this.trackPolyline.getLatLngs(),
startIndex = row.index() > 0 ? this.trackEdges.edges[row.index() - 1] : 0,
endIndex = this.trackEdges.edges[row.index()],
edgeLatLngs = trackLatLngs.slice(startIndex, endIndex + 1);
return L.polyline(edgeLatLngs, this.options.edgeStyle);