Compare commits

..

10 commits

Author SHA1 Message Date
Thomas Brockmöller
d69a38f1b6 add overpass query for railway station
Some checks are pending
build / build (push) Waiting to run
2024-10-22 10:48:16 +02:00
Marcus Jaschen
59a14356f7 use i18next interpolation instead of concatenating strings 2024-10-21 20:32:29 +02:00
Marcus Jaschen
8c21a88b15 update JSDoc
add hyphens between parameter name and description
2024-10-21 20:32:29 +02:00
Marcus Jaschen
a285751416 Add “Maximum Speed” to analysis sidebar
It shows the distribution of maximum speeds for all ways on the
current route (if that data is available, otherwise it’s summed up
under “unknown”).

`maxspeed:forward` and `maxspeed:backward` is respected in conjunction
with `reversedirection`.

Hovering/clicking table rows to highlight matching segments on the
route work the identical to the other analysis tables.

Additionally, all tags in the analysis tab (way type, surface,
smoothness) are translateable now. The values were added to `en.json`.

Some HTML is rendered with template literals now, instead of
concatenating strings.

Variable declarations were changed from `var` to `const`/`let`.
2024-10-21 20:32:29 +02:00
Simon Legner
76f31aeb2b refact: use shorthand method and property syntax 2024-10-19 13:44:15 +02:00
Marcus Jaschen
babd154596 allow additional GeoJSON MIME type
The MIME type for GeoJSON registered with IANA is application/geo+json`,
replacing the old value `application/vnd.geo+json`. The change was
published with RFC 7946 in 2016.

BRouter reponses changed to `application/geo+json` in recent versions.

With this commit BRouter-Web accepts either of both MIME type strings in
BRouter responses.
2024-10-14 20:30:53 +02:00
Marcus Jaschen
6b24a8790e add 'break' to switch to prevent fall-through 2024-07-02 18:23:19 +02:00
renovate[bot]
67547f3494 Update dependency @maplibre/maplibre-gl-leaflet to v0.0.20 2024-06-01 16:32:14 +02:00
alexcojocaru
12dc322a54 Disable gradient normalization in profile; add legend 2024-06-01 16:30:36 +02:00
alexcojocaru
135340781d Update the geo-data-exchange dependency with support for gradient normalization 2024-06-01 16:30:36 +02:00
50 changed files with 959 additions and 656 deletions

View file

@ -350,10 +350,6 @@ table.dataTable.track-analysis-table tfoot td {
padding-top: 4px;
}
.track-analysis-title {
text-transform: capitalize;
}
.track-analysis-distance {
text-align: right;
}
@ -970,12 +966,8 @@ table.dataTable.display tbody tr:hover.selected {
/*
* Heightgraph customizations;
* since the legend and the gradient types are in the way, hide them;
* since there's only the gradient layer, hide the layer selector.
*/
.legend-hover {
display: none;
}
#selectionText {
display: none;
}

View file

@ -19,9 +19,9 @@
touch = touchScreenDetectable ? touchScreen : L.Browser.touch;
BR.Browser = {
touchScreen: touchScreen,
touchScreenDetectable: touchScreenDetectable,
touch: touch,
touchScreen,
touchScreenDetectable,
touch,
download:
'Blob' in window &&
'FileReader' in window &&

View file

@ -6,7 +6,7 @@ BR.LayersConfig = L.Class.extend({
// hardcoded, built-in layers with an id set (for URL hash)
builtInLayers: ['route-quality'],
initialize: function (map) {
initialize(map) {
this._map = map;
this._overpassLoadingIndicator = new BR.Message('overpass_loading_indicator', { alert: false });
this._overpassActiveRequestCount = 0;
@ -17,7 +17,7 @@ BR.LayersConfig = L.Class.extend({
this._addLanguageDefaultLayer();
},
loadDefaultLayers: function () {
loadDefaultLayers() {
if (BR.Util.localStorageAvailable()) {
var item = localStorage.getItem('map/defaultLayers');
if (item) {
@ -28,21 +28,21 @@ BR.LayersConfig = L.Class.extend({
}
},
storeDefaultLayers: function (baseLayers, overlays) {
storeDefaultLayers(baseLayers, overlays) {
if (BR.Util.localStorageAvailable()) {
var defaultLayers = {
baseLayers: baseLayers,
overlays: overlays,
baseLayers,
overlays,
};
localStorage.setItem('map/defaultLayers', JSON.stringify(defaultLayers));
}
},
_replaceLegacyIds: function (idList) {
_replaceLegacyIds(idList) {
return idList.map((id) => (id in this.legacyNameToIdMap ? this.legacyNameToIdMap[id] : id));
},
_addLeafletProvidersLayers: function () {
_addLeafletProvidersLayers() {
var includeList = BR.confLayers.leafletProvidersIncludeList;
for (var i = 0; i < includeList.length; i++) {
@ -50,7 +50,7 @@ BR.LayersConfig = L.Class.extend({
var obj = {
geometry: null,
properties: {
id: id,
id,
name: id.replace('.', ' '),
dataSource: 'leaflet-providers',
},
@ -60,7 +60,7 @@ BR.LayersConfig = L.Class.extend({
}
},
_customizeLayers: function () {
_customizeLayers() {
var propertyOverrides = BR.confLayers.getPropertyOverrides();
for (var id in propertyOverrides) {
@ -92,7 +92,7 @@ BR.LayersConfig = L.Class.extend({
BR.layerIndex['ignf-scan25'].geometry = BR.confLayers.franceBbox;
},
_addLanguageDefaultLayer: function () {
_addLanguageDefaultLayer() {
// language code -> layer id
var languageLayersMap = {};
var i;
@ -120,7 +120,7 @@ BR.LayersConfig = L.Class.extend({
}
},
isDefaultLayer: function (id, overlay) {
isDefaultLayer(id, overlay) {
var result = false;
if (overlay) {
result = this.defaultOverlays.indexOf(id) > -1;
@ -130,15 +130,15 @@ BR.LayersConfig = L.Class.extend({
return result;
},
getBaseLayers: function () {
getBaseLayers() {
return this._getLayers(this.defaultBaseLayers);
},
getOverlays: function () {
getOverlays() {
return this._getLayers(this.defaultOverlays);
},
_getLayers: function (ids) {
_getLayers(ids) {
var layers = {};
for (var i = 0; i < ids.length; i++) {
@ -161,7 +161,7 @@ BR.LayersConfig = L.Class.extend({
// own convention: key placeholder with prefix
// e.g. ?api_key={keys_openrouteservice}
getKeyName: function (url) {
getKeyName(url) {
var result = null;
// L.Util.template only matches [\w_-]
var prefix = 'keys_';
@ -174,7 +174,7 @@ BR.LayersConfig = L.Class.extend({
if (found) {
name = found[1];
result = {
name: name,
name,
urlVar: prefix + name,
};
}
@ -182,18 +182,18 @@ BR.LayersConfig = L.Class.extend({
return result;
},
_showOverpassLoadingIndicator: function () {
_showOverpassLoadingIndicator() {
this._overpassActiveRequestCount++;
this._overpassLoadingIndicator.showLoading(i18next.t('layers.overpass-loading-indicator'));
},
_hideOverpassLoadingIndicator: function () {
_hideOverpassLoadingIndicator() {
if (--this._overpassActiveRequestCount === 0) {
this._overpassLoadingIndicator.hide();
}
},
getOverpassIconUrl: function (icon) {
getOverpassIconUrl(icon) {
const iconPrefix = /^(maki|temaki|fas)-/;
let iconUrl = null;
@ -205,7 +205,7 @@ BR.LayersConfig = L.Class.extend({
return iconUrl;
},
createOverpassLayer: function (query, icon) {
createOverpassLayer(query, icon) {
let markerSign = '<i class="fa fa-search icon-white" style="width: 25px;"></i>';
const iconUrl = this.getOverpassIconUrl(icon);
@ -216,7 +216,7 @@ BR.LayersConfig = L.Class.extend({
return Object.assign(
new OverpassLayer({
overpassFrontend: this.overpassFrontend,
query: query,
query,
minZoom: 12,
feature: {
title: '{{ tags.name }}',
@ -244,7 +244,7 @@ BR.LayersConfig = L.Class.extend({
);
},
renderOverpassPopupBody: function (overpassData) {
renderOverpassPopupBody(overpassData) {
let output = '';
output += '<table class="overpass-tags">';
@ -301,11 +301,11 @@ BR.LayersConfig = L.Class.extend({
return output;
},
createOpenStreetMapNotesLayer: function () {
createOpenStreetMapNotesLayer() {
return new leafletOsmNotes();
},
createMvtLayer: function (props, options) {
createMvtLayer(props, options) {
// remove key, only provided with local style to not add layer when not configured, see _getLayers
const styleId = props.url?.split('?')[0];
if (styleId in BR.layerIndex) {
@ -322,7 +322,7 @@ BR.LayersConfig = L.Class.extend({
return BR.maplibreGlLazyLoader(options);
},
_replaceMvtTileKey: function (style) {
_replaceMvtTileKey(style) {
if (!style) return;
// Sources can be specified by `url` (string) or `tiles` (array), we handle
@ -348,7 +348,7 @@ BR.LayersConfig = L.Class.extend({
}
},
createGeoJsonLayer: function (props) {
createGeoJsonLayer(props) {
const layer = L.geoJSON(undefined, BR.Track.getGeoJsonOptions());
fetch(props.url).then(async (response) => {
const geojson = await response.json();
@ -357,7 +357,7 @@ BR.LayersConfig = L.Class.extend({
return layer;
},
createLayer: function (layerData) {
createLayer(layerData) {
var props = layerData.properties;
var url = props.url;
var layer;

View file

@ -1,5 +1,5 @@
BR.Map = {
initMap: function () {
initMap() {
var map, layersControl;
L.setOptions(this, {
@ -20,7 +20,7 @@ BR.Map = {
zoomControl: false, // add it manually so that we can translate it
worldCopyJump: true,
minZoom: 0,
maxZoom: maxZoom,
maxZoom,
});
if (BR.Util.getResponsiveBreakpoint() >= '3md') {
@ -142,12 +142,12 @@ BR.Map = {
BR.debug.map = map;
return {
map: map,
layersControl: layersControl,
map,
layersControl,
};
},
_renderLayerCredits: function (layers) {
_renderLayerCredits(layers) {
var dl = document.getElementById('credits-maps');
var i, obj, dt, dd, attribution;

View file

@ -1,5 +1,5 @@
BR.Util = {
get: function (url, cb) {
get(url, cb) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
@ -20,7 +20,7 @@ BR.Util = {
}
},
getError: function (xhr) {
getError(xhr) {
var msg = i18next.t('warning.no-response');
if (xhr.responseText) {
msg = xhr.responseText;
@ -30,7 +30,7 @@ BR.Util = {
return new Error(msg);
},
getJson: function (url, context, cb) {
getJson(url, context, cb) {
BR.Util.get(url, function (err, data) {
if (err) {
BR.message.showError('Error getting ' + context + ': ' + err);
@ -48,7 +48,7 @@ BR.Util = {
});
},
getGeoJson: function (url, context, cb) {
getGeoJson(url, context, cb) {
BR.Util.getJson(url, context, function (err, data) {
if (err) return cb(err);
@ -70,7 +70,7 @@ BR.Util = {
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Testing_for_support_vs_availability
// by Mozilla Contributors, with modifications;
// Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/
localStorageAvailable: function () {
localStorageAvailable() {
try {
var storage = window.localStorage,
x = '__storage_test__';
@ -83,7 +83,7 @@ BR.Util = {
},
// see https://stackoverflow.com/a/37141090/1906123
getResponsiveBreakpoint: function () {
getResponsiveBreakpoint() {
var envs = { '1xs': 'd-none', '2sm': 'd-sm-none', '3md': 'd-md-none', '4lg': 'd-lg-none', '5xl': 'd-xl-none' };
var env = '';
@ -101,7 +101,7 @@ BR.Util = {
return env;
},
keyboardShortcutsAllowed: function (keyEvent) {
keyboardShortcutsAllowed(keyEvent) {
// Skip auto-repeating key events
if (keyEvent.repeat) {
return false;
@ -134,13 +134,13 @@ BR.Util = {
// this method must only be used to sanitize for textContent.
// do NOT use it to sanitize any attribute,
// see https://web.archive.org/web/20121208091505/http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/
sanitizeHTMLContent: function (str) {
sanitizeHTMLContent(str) {
var temp = document.createElement('div');
temp.textContent = str;
return temp.innerHTML;
},
isCountry: function (country, language) {
isCountry(country, language) {
// de-DE | fr-FR
var lang = i18next.languages[0].split('-');

View file

@ -1,10 +1,10 @@
BR.WhatsNew = {
newOnly: undefined,
init: function () {
init() {
var self = this;
self.dismissableMessage = new BR.Message('whats_new_message', {
onClosed: function () {
onClosed() {
document.getElementsByClassName('version')[0].classList.remove('version-new');
if (BR.Util.localStorageAvailable()) {
localStorage.setItem('changelogVersion', self.getLatestVersion());
@ -29,21 +29,21 @@ BR.WhatsNew = {
}
},
getLatestVersion: function () {
getLatestVersion() {
return BR.changelog.match('<h2 id="(.*)">')[1];
},
getCurrentVersion: function () {
getCurrentVersion() {
if (!BR.Util.localStorageAvailable()) return null;
return localStorage.getItem('changelogVersion');
},
hasNewVersions: function () {
hasNewVersions() {
return this.getCurrentVersion() && this.getCurrentVersion() !== this.getLatestVersion();
},
prepare: function (newOnly) {
prepare(newOnly) {
if (newOnly === this.newOnly) {
// do not rebuild modal content unnecessarily
return;

View file

@ -1,5 +1,5 @@
BR.ControlLayers = L.Control.Layers.extend({
getActiveLayers: function () {
getActiveLayers() {
var result = [];
for (var i = 0; i < this._layers.length; i++) {
@ -16,7 +16,7 @@ BR.ControlLayers = L.Control.Layers.extend({
return result;
},
getActiveBaseLayer: function () {
getActiveBaseLayer() {
var activeLayers = this.getActiveLayers();
for (var i = 0; i < activeLayers.length; i++) {
var obj = activeLayers[i];
@ -28,7 +28,7 @@ BR.ControlLayers = L.Control.Layers.extend({
return null;
},
removeActiveLayers: function () {
removeActiveLayers() {
var removed = [];
for (var i = 0; i < this._layers.length; i++) {
@ -42,7 +42,7 @@ BR.ControlLayers = L.Control.Layers.extend({
return removed;
},
getLayer: function (name) {
getLayer(name) {
for (var i = 0; i < this._layers.length; i++) {
var obj = this._layers[i];
if (obj.name === name) {
@ -53,19 +53,19 @@ BR.ControlLayers = L.Control.Layers.extend({
return null;
},
getBaseLayers: function () {
getBaseLayers() {
return this._layers.filter(function (obj) {
return !obj.overlay;
});
},
activateLayer: function (obj) {
activateLayer(obj) {
if (!this._map.hasLayer(obj.layer)) {
this._map.addLayer(obj.layer);
}
},
activateFirstLayer: function () {
activateFirstLayer() {
for (var i = 0; i < this._layers.length; i++) {
var obj = this._layers[i];
if (!obj.overlay) {
@ -75,14 +75,14 @@ BR.ControlLayers = L.Control.Layers.extend({
}
},
activateBaseLayerIndex: function (index) {
activateBaseLayerIndex(index) {
var baseLayers = this.getBaseLayers();
var obj = baseLayers[index];
this.activateLayer(obj);
},
_addLayer: function (layer, name, overlay) {
_addLayer(layer, name, overlay) {
L.Control.Layers.prototype._addLayer.call(this, layer, name, overlay);
// override z-index assignment to fix that base layers added later

View file

@ -7,7 +7,7 @@ BR.Export = L.Class.extend({
},
},
initialize: function (router, pois, profile) {
initialize(router, pois, profile) {
this.router = router;
this.pois = pois;
this.profile = profile;
@ -38,7 +38,7 @@ BR.Export = L.Class.extend({
this.update([]);
},
update: function (latLngs, segments) {
update(latLngs, segments) {
this.latLngs = latLngs;
this.segments = segments;
@ -49,7 +49,7 @@ BR.Export = L.Class.extend({
}
},
_warnDownload: function () {
_warnDownload() {
const hasBeeline = BR.Routing.hasBeeline(this.segments);
const isFit = $('#format-fit').prop('checked');
$('#export-download-warning').prop('hidden', !hasBeeline && !isFit);
@ -63,14 +63,14 @@ BR.Export = L.Class.extend({
document.getElementById('serverExport').title = title;
},
_turnInstructionInfo: function () {
_turnInstructionInfo() {
const turnInstructionMode = +this.profile.getProfileVar('turnInstructionMode');
$('.format-turns-enabled')
.prop('hidden', turnInstructionMode <= 1)
.attr('title', i18next.t('export.turns_enabled'));
},
_getMimeType: function (format) {
_getMimeType(format) {
const mimeTypeMap = {
gpx: 'application/gpx+xml;charset=utf-8',
kml: 'application/vnd.google-earth.kml+xml;charset=utf-8',
@ -82,7 +82,7 @@ BR.Export = L.Class.extend({
return mimeTypeMap[format];
},
_triggerDownload: function (url, name) {
_triggerDownload(url, name) {
const link = document.createElement('a');
link.href = url;
if (name) {
@ -95,11 +95,11 @@ BR.Export = L.Class.extend({
link.remove();
},
_exportServer: function (e) {
_exportServer(e) {
this._export(e, true);
},
_export: function (e, server = false) {
_export(e, server = false) {
var exportForm = document.forms['export'];
var format = exportForm['format'].value || $('#export-format input:radio:checked').val();
var name = exportForm['trackname'].value;
@ -138,7 +138,7 @@ BR.Export = L.Class.extend({
}
},
_formatTrack: function (format, name, includeWaypoints) {
_formatTrack(format, name, includeWaypoints) {
const track = BR.Export._concatTotalTrack(this.segments);
if (name) {
track.features[0].properties.name = name;
@ -166,7 +166,7 @@ BR.Export = L.Class.extend({
console.error('Export format not implemented: ' + format);
},
_addPois: function (track) {
_addPois(track) {
const markers = this.pois.getMarkers();
for (const poi of markers) {
const properties = { name: poi.name, type: 'poi' };
@ -175,7 +175,7 @@ BR.Export = L.Class.extend({
}
},
_addRouteWaypoints: function (track) {
_addRouteWaypoints(track) {
for (const [i, latLng] of this.latLngs.entries()) {
let name = 'via' + i;
let type = 'via';
@ -192,7 +192,7 @@ BR.Export = L.Class.extend({
}
},
_validationMessage: function () {
_validationMessage() {
var trackname = this.trackname;
var replaceRegex = new RegExp('[^' + this.tracknameAllowedChars + ']', 'g');
@ -205,11 +205,11 @@ BR.Export = L.Class.extend({
}
},
_selectTrackname: function () {
_selectTrackname() {
trackname.setSelectionRange(0, trackname.value.lastIndexOf(BR.Browser.download ? ' (' : ' - '));
},
_generateTrackname: function () {
_generateTrackname() {
var trackname = this.trackname;
this._getCityAtPosition(
this.latLngs[0],
@ -225,14 +225,14 @@ BR.Export = L.Class.extend({
trackname.value = null;
} else if (from === to) {
trackname.value = i18next.t('export.route-loop', {
from: from,
distance: distance,
from,
distance,
});
} else {
trackname.value = i18next.t('export.route-from-to', {
from: from,
to: to,
distance: distance,
from,
to,
distance,
});
}
@ -249,7 +249,7 @@ BR.Export = L.Class.extend({
);
},
_getCityAtPosition: function (lonlat, cb) {
_getCityAtPosition(lonlat, cb) {
var url = L.Util.template(
'https://nominatim.openstreetmap.org/reverse?lon={lng}&lat={lat}&format=json',
lonlat
@ -268,7 +268,7 @@ BR.Export = L.Class.extend({
);
},
_keydownListener: function (e) {
_keydownListener(e) {
if (
BR.Util.keyboardShortcutsAllowed(e) &&
e.keyCode === this.options.shortcut.export &&

View file

@ -1,10 +1,10 @@
BR.Itinerary = L.Class.extend({
initialize: function () {
initialize() {
this._content = document.getElementById('itinerary');
this.update();
},
update: function (polyline, segments) {
update(polyline, segments) {
var i,
j,
iter,

View file

@ -1,5 +1,5 @@
BR.Layers = L.Class.extend({
_loadLayers: function () {
_loadLayers() {
this._customLayers = {};
if (BR.Util.localStorageAvailable()) {
@ -28,7 +28,7 @@ BR.Layers = L.Class.extend({
}
},
_loadTable: function () {
_loadTable() {
var layersData = [];
for (layer in this._customLayers) {
var layerProps = this._customLayers[layer].layerData.properties;
@ -65,7 +65,7 @@ BR.Layers = L.Class.extend({
});
},
init: function (map, layersControl, baseLayers, overlays) {
init(map, layersControl, baseLayers, overlays) {
this._layersControl = layersControl;
this._map = map;
this._layers = {};
@ -95,7 +95,7 @@ BR.Layers = L.Class.extend({
};
},
_remove: function (evt) {
_remove(evt) {
var row = this._layersTable.row('.selected').data();
if (row != null) {
var name = row[0];
@ -107,7 +107,7 @@ BR.Layers = L.Class.extend({
}
},
_addFromInput: function (layerProps) {
_addFromInput(layerProps) {
var layer_name = L.DomUtil.get('layer_name').value;
var layer_url = L.DomUtil.get('layer_url').value;
@ -123,14 +123,14 @@ BR.Layers = L.Class.extend({
if (layer_name.length > 0 && layer_url.length > 0) this._addLayer(layerData);
},
_addBaseLayer: function (evt) {
_addBaseLayer(evt) {
var layerProps = {
type: 'tms',
url: L.DomUtil.get('layer_url').value,
};
this._addFromInput(layerProps);
},
_addOverlay: function (evt) {
_addOverlay(evt) {
var layerProps = {
type: 'tms',
url: L.DomUtil.get('layer_url').value,
@ -138,7 +138,7 @@ BR.Layers = L.Class.extend({
};
this._addFromInput(layerProps);
},
_addOverpassQuery: function (evt) {
_addOverpassQuery(evt) {
var layerProps = {
overlay: true,
dataSource: 'OverpassAPI',
@ -147,7 +147,7 @@ BR.Layers = L.Class.extend({
this._addFromInput(layerProps);
},
_createTmsProps: function (props) {
_createTmsProps(props) {
var tmsProps = {
type: 'tms',
...props,
@ -155,7 +155,7 @@ BR.Layers = L.Class.extend({
return tmsProps;
},
_addLayer: function (layerData) {
_addLayer(layerData) {
var props = layerData.properties;
var layerName = props.name;
@ -167,8 +167,8 @@ BR.Layers = L.Class.extend({
var layer = this._layersControl.layersConfig.createLayer(layerData);
this._customLayers[layerName] = {
layer: layer,
layerData: layerData,
layer,
layerData,
};
if (props.overlay) {
@ -185,7 +185,7 @@ BR.Layers = L.Class.extend({
}
},
_sync: function () {
_sync() {
if (BR.Util.localStorageAvailable()) {
var geojson = {
type: 'FeatureCollection',

View file

@ -3,13 +3,13 @@ BR.LayersTab = BR.ControlLayers.extend({
previewBounds: null,
saveLayers: [],
initialize: function (layersConfig, baseLayers, overlays, options) {
initialize(layersConfig, baseLayers, overlays, options) {
L.Control.Layers.prototype.initialize.call(this, baseLayers, overlays, options);
this.layersConfig = layersConfig;
},
addTo: function (map) {
addTo(map) {
this._map = map;
this.onAdd(map);
@ -22,21 +22,21 @@ BR.LayersTab = BR.ControlLayers.extend({
return this;
},
onAdd: function (map) {
onAdd(map) {
BR.ControlLayers.prototype.onAdd.call(this, map);
map.on('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this);
map.on('overlayadd overlayremove', this.updateOpacityLabel, this);
},
onRemove: function (map) {
onRemove(map) {
BR.ControlLayers.prototype.onRemove.call(this, map);
map.off('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this);
map.off('overlayadd overlayremove', this.updateOpacityLabel, this);
},
initOpacitySlider: function (map) {
initOpacitySlider(map) {
var self = this;
var overlayOpacitySlider = new BR.OpacitySlider({
id: 'overlay',
@ -44,7 +44,7 @@ BR.LayersTab = BR.ControlLayers.extend({
orientation: 'horizontal',
defaultValue: 1,
title: i18next.t('layers.opacity-slider'),
callback: function (opacity) {
callback(opacity) {
for (var i = 0; i < self._layers.length; i++) {
const layer = self._layers[i].layer;
if (!self._layers[i].overlay || !map.hasLayer(layer)) {
@ -53,7 +53,7 @@ BR.LayersTab = BR.ControlLayers.extend({
if (layer.setOpacity) {
layer.setOpacity(opacity);
} else if (layer.setStyle) {
layer.setStyle({ opacity: opacity });
layer.setStyle({ opacity });
}
}
},
@ -61,7 +61,7 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('leaflet-control-layers-overlays-opacity-slider').appendChild(overlayOpacitySlider.getElement());
},
initButtons: function () {
initButtons() {
var expandTree = function (e) {
this.jstree.open_all();
};
@ -89,7 +89,7 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('optional_layers_button').onclick = L.bind(toggleOptionalLayers, this);
},
initJsTree: function () {
initJsTree() {
var layerIndex = BR.layerIndex;
var treeData = this.toJsTree(BR.confLayers.tree);
var oldSelected = null;
@ -180,7 +180,7 @@ BR.LayersTab = BR.ControlLayers.extend({
this.jstree = $('#optional-layers-tree').jstree(true);
},
toJsTree: function (layerTree) {
toJsTree(layerTree) {
var data = {
children: [],
};
@ -218,7 +218,7 @@ BR.LayersTab = BR.ControlLayers.extend({
// when key required only add if configured
if (!keyObj || (keyObj && BR.keys[keyObj.name])) {
childNode = {
id: id,
id,
text: getText(props, parent),
icon: self.layersConfig.getOverpassIconUrl(props.icon) || false,
state: {
@ -262,12 +262,13 @@ BR.LayersTab = BR.ControlLayers.extend({
walkObject(inTree);
}
}
walkTree(layerTree, data);
return data.children;
},
storeDefaultLayers: function () {
storeDefaultLayers() {
var baseLayers = [];
var overlays = [];
@ -289,7 +290,7 @@ BR.LayersTab = BR.ControlLayers.extend({
this.layersConfig.storeDefaultLayers(baseLayers, overlays);
},
createLayer: function (layerData) {
createLayer(layerData) {
var layer = this.layersConfig.createLayer(layerData);
var overlay = layerData.properties.overlay;
@ -299,7 +300,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return layer;
},
getLayerById: function (id) {
getLayerById(id) {
for (var i = 0; i < this._layers.length; i++) {
var obj = this._layers[i];
if (obj.layer.id === id) {
@ -310,7 +311,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return null;
},
getLayerByLegacyName: function (legacyName) {
getLayerByLegacyName(legacyName) {
var obj = null;
var id = this.layersConfig.legacyNameToIdMap[legacyName];
@ -321,7 +322,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return obj;
},
activateDefaultBaseLayer: function () {
activateDefaultBaseLayer() {
var index = BR.conf.defaultBaseLayerIndex || 0;
var activeBaseLayer = this.getActiveBaseLayer();
if (!activeBaseLayer) {
@ -329,11 +330,11 @@ BR.LayersTab = BR.ControlLayers.extend({
}
},
saveRemoveActiveLayers: function () {
saveRemoveActiveLayers() {
this.saveLayers = this.removeActiveLayers();
},
restoreActiveLayers: function (overlaysOnly) {
restoreActiveLayers(overlaysOnly) {
for (var i = 0; i < this.saveLayers.length; i++) {
var obj = this.saveLayers[i];
@ -350,7 +351,7 @@ BR.LayersTab = BR.ControlLayers.extend({
this.saveLayers = [];
},
removePreviewLayer: function () {
removePreviewLayer() {
if (this.previewLayer && this._map.hasLayer(this.previewLayer)) {
this._map.removeLayer(this.previewLayer);
this.previewLayer = null;
@ -359,7 +360,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return false;
},
showPreviewBounds: function (layerData) {
showPreviewBounds(layerData) {
if (layerData.geometry) {
this.previewBounds = L.geoJson(layerData.geometry, {
// fill/mask outside of bounds polygon with Leaflet.snogylop
@ -373,21 +374,21 @@ BR.LayersTab = BR.ControlLayers.extend({
}
},
removePreviewBounds: function () {
removePreviewBounds() {
if (this.previewBounds && this._map.hasLayer(this.previewBounds)) {
this._map.removeLayer(this.previewBounds);
this.previewBounds = null;
}
},
deselectNode: function () {
deselectNode() {
var selected = this.jstree.get_selected();
if (selected.length > 0) {
this.jstree.deselect_node(selected[0]);
}
},
onBaselayerchange: function () {
onBaselayerchange() {
// execute after current input click handler,
// otherwise added overlay checkbox state doesn't update
setTimeout(
@ -401,7 +402,7 @@ BR.LayersTab = BR.ControlLayers.extend({
);
},
showPreview: function (layerData) {
showPreview(layerData) {
var layer = this.createLayer(layerData);
this._map.addLayer(layer);
this.removePreviewBounds();
@ -416,7 +417,7 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('preview').hidden = false;
},
hidePreview: function (layer) {
hidePreview(layer) {
this._map.off('baselayerchange', this.onBaselayerchange, this);
this.removePreviewBounds();
this.removePreviewLayer();
@ -425,11 +426,11 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('preview').hidden = true;
},
toLayerString: function (obj) {
toLayerString(obj) {
return obj.layer.id ? obj.layer.id : obj.name;
},
getLayerFromString: function (layerString) {
getLayerFromString(layerString) {
var obj = this.getLayerById(layerString);
if (!obj) {
@ -445,7 +446,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return obj;
},
storeActiveLayers: function () {
storeActiveLayers() {
if (BR.Util.localStorageAvailable()) {
var objList = this.getActiveLayers();
var idList = objList.map(
@ -459,7 +460,7 @@ BR.LayersTab = BR.ControlLayers.extend({
}
},
loadActiveLayers: function () {
loadActiveLayers() {
if (BR.Util.localStorageAvailable()) {
var item = localStorage.getItem('map/activeLayers');
@ -478,7 +479,7 @@ BR.LayersTab = BR.ControlLayers.extend({
}
},
updateOpacityLabel: function () {
updateOpacityLabel() {
var slider = $('#leaflet-control-layers-overlays-opacity-slider');
var overlaysCount = this.getActiveLayers().length - 1;
if (overlaysCount === 0) {

View file

@ -6,12 +6,12 @@ BR.Message = L.Class.extend({
onClosed: null,
},
initialize: function (id, options) {
initialize(id, options) {
L.setOptions(this, options);
this.id = id;
},
_show: function (msg, type) {
_show(msg, type) {
var ele = L.DomUtil.get(this.id),
iconClass,
alertClass;
@ -59,11 +59,11 @@ BR.Message = L.Class.extend({
}
},
hide: function () {
hide() {
$('#' + this.id + ' .alert').alert('close');
},
showError: function (err) {
showError(err) {
if (err && err.message) err = err.message;
if (err == 'target island detected for section 0\n') {
@ -80,15 +80,15 @@ BR.Message = L.Class.extend({
this._show(err, 'error');
},
showWarning: function (msg) {
showWarning(msg) {
this._show(msg, 'warning');
},
showInfo: function (msg) {
showInfo(msg) {
this._show(msg, 'info');
},
showLoading: function (msg) {
showLoading(msg) {
this._show(msg, 'loading');
},
});

View file

@ -5,10 +5,10 @@ BR.OpacitySlider = L.Class.extend({
orientation: 'vertical',
defaultValue: BR.conf.defaultOpacity,
title: '',
callback: function (opacity) {},
callback(opacity) {},
},
initialize: function (options) {
initialize(options) {
L.setOptions(this, options);
var input = (this.input = $('<input id="slider-' + this.options.id + '" type="text"/>')),
@ -26,7 +26,7 @@ BR.OpacitySlider = L.Class.extend({
min: 0,
max: 100,
step: 1,
value: value,
value,
orientation: this.options.orientation,
reversed: this.options.reversed,
selection: this.options.reversed ? 'before' : 'after', // inverted, serves as track style, see css
@ -51,19 +51,19 @@ BR.OpacitySlider = L.Class.extend({
}
},
_keydownListener: function (e) {
_keydownListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) {
this.options.callback(0);
}
},
_keyupListener: function (e) {
_keyupListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) {
this.options.callback(this.input.val() / 100);
}
},
getElement: function () {
getElement() {
return this.input.slider('getElement');
},
});

View file

@ -3,7 +3,7 @@ BR.OpacitySliderControl = L.Control.extend({
position: 'topleft',
},
onAdd: function (map) {
onAdd(map) {
var container = L.DomUtil.create('div', 'leaflet-bar control-slider');
// prevent also dragging map in Chrome

View file

@ -2,7 +2,7 @@ BR.Profile = L.Evented.extend({
cache: {},
saveWarningShown: false,
initialize: function () {
initialize() {
var textArea = L.DomUtil.get('profile_upload');
this.editor = CodeMirror.fromTextArea(textArea, {
lineNumbers: true,
@ -26,7 +26,7 @@ BR.Profile = L.Evented.extend({
});
},
clear: function (evt) {
clear(evt) {
var button = evt.target || evt.srcElement;
evt.preventDefault();
@ -38,7 +38,7 @@ BR.Profile = L.Evented.extend({
button.blur();
},
update: function (options, cb) {
update(options, cb) {
var profileName = options.profile,
profileUrl,
loading = false;
@ -75,17 +75,17 @@ BR.Profile = L.Evented.extend({
if (cb && !loading) cb();
},
show: function () {
show() {
this.editor.refresh();
},
onResize: function () {
onResize() {
this.editor.refresh();
},
// Returns the initial value of the given profile variable as String, as defined by the assign statement.
// Intended for all assigned variables, not just parameters with a comment declaration, i.e. no type information used.
getProfileVar: function (name) {
getProfileVar(name) {
let value;
if (this._isParamsFormActive()) {
const formValues = this._getFormValues();
@ -106,13 +106,13 @@ BR.Profile = L.Evented.extend({
},
// Returns car|bike|foot, default is foot
getTransportMode: function () {
getTransportMode() {
const isCar = !!this.getProfileVar('validForCars');
const isBike = !!this.getProfileVar('validForBikes');
return isCar ? 'car' : isBike ? 'bike' : 'foot';
},
_upload: function (evt) {
_upload(evt) {
var button = evt.target || evt.srcElement,
profile = this._getProfileText();
@ -136,7 +136,7 @@ BR.Profile = L.Evented.extend({
});
},
_buildCustomProfile: function (profileText) {
_buildCustomProfile(profileText) {
const formValues = this._getFormValues();
Object.keys(formValues).forEach((name) => {
const value = formValues[name];
@ -152,7 +152,7 @@ BR.Profile = L.Evented.extend({
return profileText;
},
_getFormValues: function () {
_getFormValues() {
const obj = {};
document.querySelectorAll('#profile_params input, #profile_params select').forEach((input) => {
const name = input.name;
@ -167,12 +167,12 @@ BR.Profile = L.Evented.extend({
return obj;
},
_save: function (evt) {
_save(evt) {
var profileText = this._buildCustomProfile(this._getProfileText());
var that = this;
this.fire('update', {
profileText: profileText,
callback: function (err, profileId, profileText) {
profileText,
callback(err, profileId, profileText) {
if (!err) {
that.profileName = profileId;
that.cache[profileId] = profileText;
@ -181,7 +181,7 @@ BR.Profile = L.Evented.extend({
});
},
_updateProfile: function (profileName, profileText) {
_updateProfile(profileName, profileText) {
const empty = !this.editor.getValue();
const clean = this.editor.isClean();
@ -201,7 +201,7 @@ BR.Profile = L.Evented.extend({
}
},
_setValue: function (profileText) {
_setValue(profileText) {
profileText = profileText || '';
var clean = this.editor.isClean();
@ -220,7 +220,7 @@ BR.Profile = L.Evented.extend({
}
},
_buildParamsForm: function (profileText) {
_buildParamsForm(profileText) {
if (!profileText) return;
// Otherwise, create user friendly form
@ -278,9 +278,9 @@ BR.Profile = L.Evented.extend({
}
params[name] = {
description: description,
description,
type: paramType,
value: value,
value,
possible_values: paramValues,
};
}
@ -359,11 +359,11 @@ BR.Profile = L.Evented.extend({
});
},
_isParamsFormActive: function () {
_isParamsFormActive() {
return L.DomUtil.get('profile_params_container').classList.contains('active');
},
_activateSecondaryTab: function () {
_activateSecondaryTab() {
var profileText = this._getProfileText();
if (this._isParamsFormActive()) {
@ -373,11 +373,11 @@ BR.Profile = L.Evented.extend({
}
},
_getProfileText: function () {
_getProfileText() {
return this.editor.getValue();
},
_getSelectedProfileText: function () {
_getSelectedProfileText() {
return this.cache[this.selectedProfileName] ?? this.editor.getValue();
},
});

View file

@ -5,7 +5,7 @@ BR.RoutingOptions = L.Evented.extend({
},
},
initialize: function () {
initialize() {
$('#profile-alternative').on('changed.bs.select', this._getChangeHandler());
var remembered_profile = this.getRememberedProfile();
@ -35,7 +35,7 @@ BR.RoutingOptions = L.Evented.extend({
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
},
refreshUI: function () {
refreshUI() {
// we do not allow to select more than one profile and/or alternative at a time
// so we disable the current selected items
$('#profile-alternative')
@ -61,7 +61,7 @@ BR.RoutingOptions = L.Evented.extend({
button.title = button.title + i18next.t('navbar.profile-tooltip', { key: 'G' });
},
getOptions: function () {
getOptions() {
var profile = $('#profile option:selected'),
alternative = $('#alternative option:selected');
this.refreshUI();
@ -72,7 +72,7 @@ BR.RoutingOptions = L.Evented.extend({
};
},
setOptions: function (options) {
setOptions(options) {
var values = [
options.profile ? options.profile : $('#profile option:selected').val(),
options.alternative ? options.alternative : $('#alternative option:selected').val(),
@ -86,7 +86,7 @@ BR.RoutingOptions = L.Evented.extend({
}
},
setCustomProfile: function (profile, noUpdate) {
setCustomProfile(profile, noUpdate) {
var profiles_grp, option;
profiles_grp = L.DomUtil.get('profile');
@ -112,7 +112,7 @@ BR.RoutingOptions = L.Evented.extend({
}
},
getCustomProfile: function () {
getCustomProfile() {
var profiles_grp = L.DomUtil.get('profile'),
option = profiles_grp.children[0],
profile = null;
@ -123,7 +123,7 @@ BR.RoutingOptions = L.Evented.extend({
return profile;
},
rememberProfile: function (profile) {
rememberProfile(profile) {
if (!BR.Util.localStorageAvailable()) {
return;
}
@ -135,7 +135,7 @@ BR.RoutingOptions = L.Evented.extend({
localStorage.setItem('routingprofile', profile);
},
getRememberedProfile: function () {
getRememberedProfile() {
if (!BR.Util.localStorageAvailable()) {
return null;
}
@ -143,14 +143,14 @@ BR.RoutingOptions = L.Evented.extend({
return localStorage.getItem('routingprofile');
},
_getChangeHandler: function () {
_getChangeHandler() {
return L.bind(function (evt) {
this.rememberProfile(evt.target.options[evt.target.options.selectedIndex].value);
this.fire('update', { options: this.getOptions() });
}, this);
},
_keydownListener: function (e) {
_keydownListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.switch) {
if (!$('#profile-alternative-form .dropdown').hasClass('show')) {
$('#profile-alternative-form button').click();

View file

@ -8,18 +8,18 @@ BR.ShareRoute = L.Class.extend({
},
},
initialize: function () {
initialize() {
L.DomUtil.get('shareButton').onclick = L.bind(this.share, this);
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
},
share: function (event) {
share(event) {
event.preventDefault();
this.services();
this.qrcode();
},
services: function () {
services() {
const self = this;
$('.share-copy-link').on('click', function () {
@ -68,7 +68,7 @@ BR.ShareRoute = L.Class.extend({
* to the length of the URL
* - displays buttons to change the size of the QR Code (small, medium, large)
*/
qrcode: function () {
qrcode() {
const exportUrl = this.createQrCodeUrl();
this.renderQrCode('share-qrcode-img', exportUrl, this.getQrCodeSizeForUrl(exportUrl));
@ -78,7 +78,7 @@ BR.ShareRoute = L.Class.extend({
});
},
getQrCodeSizeForUrl: function (url) {
getQrCodeSizeForUrl(url) {
if (url.length < 500) {
return 256;
}
@ -90,7 +90,7 @@ BR.ShareRoute = L.Class.extend({
return 512;
},
renderQrCode: function (elementId, url, size) {
renderQrCode(elementId, url, size) {
$('#share-qrcode-img').empty();
$('#qrcode-buttons').show();
$('#qrcode-msg-unknown-error').hide();
@ -119,7 +119,7 @@ BR.ShareRoute = L.Class.extend({
}
},
createQrCodeUrl: function () {
createQrCodeUrl() {
// We work on a copy of the current location instance to avoid
// reloading the page (which will happen when the `export` query
// parameter is added to the actual location object):
@ -137,7 +137,7 @@ BR.ShareRoute = L.Class.extend({
return exportLocation.toString();
},
getShareUrl: function () {
getShareUrl() {
const exportLocation = new URL(document.location.href);
const searchParams = new URLSearchParams(exportLocation.search);
searchParams.delete('export');
@ -146,7 +146,7 @@ BR.ShareRoute = L.Class.extend({
return exportLocation.toString();
},
_keydownListener: function (event) {
_keydownListener(event) {
if (
BR.Util.keyboardShortcutsAllowed(event) &&
event.keyCode === this.options.shortcut.share_action &&

View file

@ -35,7 +35,7 @@ BR.TrackAnalysis = L.Class.extend({
* @param {Map} map
* @param {object} options
*/
initialize: function (map, options) {
initialize(map, options) {
this.map = map;
L.setOptions(this, options);
},
@ -60,7 +60,7 @@ BR.TrackAnalysis = L.Class.extend({
/**
* Called by BR.Sidebar when tab is activated
*/
show: function () {
show() {
this.active = true;
this.options.requestUpdate(this);
},
@ -68,23 +68,23 @@ BR.TrackAnalysis = L.Class.extend({
/**
* Called by BR.Sidebar when tab is deactivated
*/
hide: function () {
hide() {
this.active = false;
},
/**
* Everytime the track changes this method is called:
*
* - calculate statistics (way type, surface, smoothness)
* - calculate statistics (way type, max speed, surface, smoothness)
* for the whole track
* - renders statistics tables
* - create event listeners which allow to hover/click a
* table row for highlighting matching track segments
*
* @param {Polyline} polyline
* @param {Array} segments
* @param {Array} segments - route segments between waypoints
*/
update: function (polyline, segments) {
update(polyline, segments) {
if (!this.active) {
return;
}
@ -105,7 +105,7 @@ BR.TrackAnalysis = L.Class.extend({
this.trackPolyline = polyline;
this.trackEdges = new BR.TrackEdges(segments);
var analysis = this.calcStats(polyline, segments);
const analysis = this.calcStats(polyline, segments);
this.render(analysis);
@ -129,9 +129,10 @@ BR.TrackAnalysis = L.Class.extend({
* @param segments
* @returns {Object}
*/
calcStats: function (polyline, segments) {
calcStats(polyline, segments) {
const analysis = {
highway: {},
maxspeed: {},
surface: {},
smoothness: {},
};
@ -175,14 +176,25 @@ BR.TrackAnalysis = L.Class.extend({
segments[segmentIndex].feature.properties.messages[messageIndex][3]
);
break;
case 'maxspeed':
case 'surface':
case 'smoothness':
if (typeof analysis[tagName][wayTagParts[1]] === 'undefined') {
analysis[tagName][wayTagParts[1]] = {
formatted_name: i18next.t(
let formattedName;
if (tagName.indexOf('maxspeed') === 0) {
formattedName = i18next.t('sidebar.analysis.data.maxspeed', {
maxspeed: wayTagParts[1],
});
} else {
formattedName = i18next.t([
'sidebar.analysis.data.' + tagName + '.' + wayTagParts[1],
wayTagParts[1]
),
wayTagParts[1],
]);
}
analysis[tagName][wayTagParts[1]] = {
formatted_name: formattedName,
name: wayTagParts[1],
subtype: '',
distance: 0.0,
@ -209,11 +221,15 @@ BR.TrackAnalysis = L.Class.extend({
* are dropped. If no specialized surface/smoothness tag is found, the default value
* is returned, i.e. `smoothness` or `surface`.
*
* @param wayTags tags + values for a way segment
* @param routingType currently only 'cycling' is supported, can be extended in the future (walking, driving, etc.)
* Also, maxspeed comes in different variations, e.g. `maxspeed`, `maxspeed:forward`,
* `maxspeed:backward`. Depending on the existence of the `reversedirection` field
* we can select the correct value.
*
* @param wayTags - tags + values for a way segment
* @param routingType - currently only 'cycling' is supported, can be extended in the future (walking, driving, etc.)
* @returns {*[]}
*/
normalizeWayTags: function (wayTags, routingType) {
normalizeWayTags(wayTags, routingType) {
let normalizedWayTags = {};
let surfaceTags = {};
let smoothnessTags = {};
@ -242,6 +258,19 @@ BR.TrackAnalysis = L.Class.extend({
continue;
}
if (tagName === 'maxspeed:forward' && !wayTags.includes('reversedirection=yes')) {
normalizedWayTags['maxspeed'] = tagValue;
continue;
}
if (tagName === 'maxspeed:backward' && wayTags.includes('reversedirection=yes')) {
normalizedWayTags['maxspeed'] = tagValue;
continue;
}
if (tagName === 'maxspeed') {
normalizedWayTags[tagName] = tagValue;
continue;
}
normalizedWayTags[tagName] = tagValue;
}
@ -278,11 +307,11 @@ BR.TrackAnalysis = L.Class.extend({
*
* @returns {Object}
*/
sortAnalysisData: function (analysis) {
var analysisSortable = {};
var result = {};
sortAnalysisData(analysis) {
const analysisSortable = {};
const result = {};
for (var type in analysis) {
for (const type in analysis) {
if (!analysis.hasOwnProperty(type)) {
continue;
}
@ -290,18 +319,24 @@ BR.TrackAnalysis = L.Class.extend({
result[type] = {};
analysisSortable[type] = [];
for (var name in analysis[type]) {
for (const name in analysis[type]) {
if (!analysis[type].hasOwnProperty(name)) {
continue;
}
analysisSortable[type].push(analysis[type][name]);
}
analysisSortable[type].sort(function (a, b) {
return b.distance - a.distance;
});
if (type === 'maxspeed') {
analysisSortable[type].sort(function (a, b) {
return parseInt(a.name) - parseInt(b.name);
});
} else {
analysisSortable[type].sort(function (a, b) {
return b.distance - a.distance;
});
}
for (var j = 0; j < analysisSortable[type].length; j++) {
for (let j = 0; j < analysisSortable[type].length; j++) {
result[type][analysisSortable[type][j].formatted_name] = analysisSortable[type][j];
}
}
@ -316,9 +351,9 @@ BR.TrackAnalysis = L.Class.extend({
* @param {string[]} wayTags
* @returns {string}
*/
getTrackType: function (wayTags) {
for (var i = 0; i < wayTags.length; i++) {
var wayTagParts = wayTags[i].split('=');
getTrackType(wayTags) {
for (let i = 0; i < wayTags.length; i++) {
const wayTagParts = wayTags[i].split('=');
if (wayTagParts[0] === 'tracktype') {
return wayTagParts[1];
}
@ -330,22 +365,20 @@ BR.TrackAnalysis = L.Class.extend({
/**
* @param {Object} analysis
*/
render: function (analysis) {
var $content = $('#track_statistics');
render(analysis) {
const $content = $('#track_statistics');
$content.html('');
$content.append(
$('<h4 class="track-analysis-heading">' + i18next.t('sidebar.analysis.header.highway') + '</h4>')
);
$content.append($(`<h4 class="track-analysis-heading">${i18next.t('sidebar.analysis.header.highway')}</h4>`));
$content.append(this.renderTable('highway', analysis.highway));
$content.append(
$('<h4 class="track-analysis-heading">' + i18next.t('sidebar.analysis.header.surface') + '</h4>')
);
$content.append($(`<h4 class="track-analysis-heading">${i18next.t('sidebar.analysis.header.surface')}</h4>`));
$content.append(this.renderTable('surface', analysis.surface));
$content.append(
$('<h4 class="track-analysis-heading">' + i18next.t('sidebar.analysis.header.smoothness') + '</h4>')
$(`<h4 class="track-analysis-heading">${i18next.t('sidebar.analysis.header.smoothness')}</h4>`)
);
$content.append(this.renderTable('smoothness', analysis.smoothness));
$content.append($(`<h4 class="track-analysis-heading">${i18next.t('sidebar.analysis.header.maxspeed')}</h4>`));
$content.append(this.renderTable('maxspeed', analysis.maxspeed));
},
/**
@ -355,68 +388,46 @@ BR.TrackAnalysis = L.Class.extend({
* @param {Array} data
* @returns {jQuery}
*/
renderTable: function (type, data) {
var index;
var $table = $(
'<table data-type="' + type + '" class="mini cell-border stripe dataTable track-analysis-table"></table>'
);
var $thead = $('<thead></thead>');
renderTable(type, data) {
let index;
const $table = $(`<table data-type="${type}" class="mini stripe dataTable track-analysis-table"></table>`);
const $thead = $('<thead></thead>');
$thead.append(
$('<tr>')
.append(
'<th class="track-analysis-header-category">' +
i18next.t('sidebar.analysis.table.category') +
'</th>'
`<th class="track-analysis-header-category">${i18next.t('sidebar.analysis.table.category')}</th>`
)
.append(
$(
'<th class="track-analysis-header-distance">' +
i18next.t('sidebar.analysis.table.length') +
'</th>'
)
$(`<th class="track-analysis-header-distance">${i18next.t('sidebar.analysis.table.length')}</th>`)
)
);
$table.append($thead);
var $tbody = $('<tbody></tbody>');
const $tbody = $('<tbody></tbody>');
var totalDistance = 0.0;
let totalDistance = 0.0;
for (index in data) {
if (!data.hasOwnProperty(index)) {
continue;
}
var $row = $(
'<tr data-name="' +
data[index].name +
'" data-subtype="' +
data[index].subtype +
'" data-distance="' +
data[index].distance +
'"></tr>'
);
$row.append('<td class="track-analysis-title">' + data[index].formatted_name + '</td>');
$row.append(
'<td class="track-analysis-distance">' + this.formatDistance(data[index].distance) + ' km</td>'
);
const $row = $(`<tr data-name="${data[index].name}" \
data-subtype="${data[index].subtype}" \
data-distance="${data[index].distance}"></tr>`);
$row.append(`<td class="track-analysis-title">${data[index].formatted_name}</td>`);
$row.append(`<td class="track-analysis-distance">${this.formatDistance(data[index].distance)} km</td>`);
$tbody.append($row);
totalDistance += data[index].distance;
}
if (totalDistance < this.totalRouteDistance) {
$tbody.append(
$(
'<tr data-name="internal-unknown" data-distance="' +
(this.totalRouteDistance - totalDistance) +
'"></tr>'
)
.append(
$('<td class="track-analysis-title">' + i18next.t('sidebar.analysis.table.unknown') + '</td>')
)
$(`<tr data-name="internal-unknown" data-distance="${this.totalRouteDistance - totalDistance}"></tr>`)
.append($(`<td class="track-analysis-title">${i18next.t('sidebar.analysis.table.unknown')}</td>`))
.append(
$(
'<td class="track-analysis-distance">' +
this.formatDistance(this.totalRouteDistance - totalDistance) +
' km</td>'
`<td class="track-analysis-distance">${this.formatDistance(
this.totalRouteDistance - totalDistance
)} km</td>`
)
)
);
@ -427,12 +438,12 @@ BR.TrackAnalysis = L.Class.extend({
$table.append(
$('<tfoot></tfoot>')
.append('<tr></tr>')
.append($('<td>' + i18next.t('sidebar.analysis.table.total_known') + '</td>'))
.append($(`<td>${i18next.t('sidebar.analysis.table.total_known')}</td>`))
.append(
$(
'<td class="track-analysis-distance track-analysis-distance-total">' +
this.formatDistance(totalDistance) +
' km</td>'
`<td class="track-analysis-distance track-analysis-distance-total">${this.formatDistance(
totalDistance
)} km</td>`
)
)
);
@ -446,32 +457,32 @@ BR.TrackAnalysis = L.Class.extend({
* @param {number} meters
* @returns {string}
*/
formatDistance: function (meters) {
formatDistance(meters) {
return (meters / 1000).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
},
handleHover: function (event) {
var $tableRow = $(event.currentTarget);
var $table = $tableRow.parents('table').first();
var dataType = $table.data('type');
var dataName = $tableRow.data('name');
var trackType = $tableRow.data('subtype');
handleHover(event) {
const $tableRow = $(event.currentTarget);
const $table = $tableRow.parents('table').first();
const dataType = $table.data('type');
const dataName = $tableRow.data('name');
const trackType = $tableRow.data('subtype');
var polylinesForDataType = this.getPolylinesForDataType(dataType, dataName, trackType);
const polylinesForDataType = this.getPolylinesForDataType(dataType, dataName, trackType);
this.highlightedSegments = L.layerGroup(polylinesForDataType).addTo(this.map);
},
handleHoverOut: function () {
handleHoverOut() {
this.map.removeLayer(this.highlightedSegments);
},
toggleSelected: function (event) {
var tableRow = event.currentTarget;
var $table = $(tableRow).parents('table').first();
var dataType = $table.data('type');
var dataName = $(tableRow).data('name');
var trackType = $(tableRow).data('subtype');
toggleSelected(event) {
const tableRow = event.currentTarget;
const $table = $(tableRow).parents('table').first();
const dataType = $table.data('type');
const dataName = $(tableRow).data('name');
const trackType = $(tableRow).data('subtype');
if (tableRow.classList.toggle('selected')) {
if (this.highlightedSegment) {
@ -497,21 +508,21 @@ BR.TrackAnalysis = L.Class.extend({
* track edge matches the search, create a Leaflet polyline
* and add it to the result array.
*
* @param {string} dataType `highway`, `surface`, `smoothness`
* @param {string} dataName `primary`, `track, `asphalt`, etc.
* @param {string} trackType the tracktype is passed here (e.g.
* @param {string} dataType - `highway`, `surface`, `smoothness`
* @param {string} dataName - `primary`, `track, `asphalt`, etc.
* @param {string} trackType - the tracktype is passed here (e.g.
* `grade3`), but only in the case that `dataName` is `track`
*
* @returns {Polyline[]}
*/
getPolylinesForDataType: function (dataType, dataName, trackType) {
var polylines = [];
var trackLatLngs = this.trackPolyline.getLatLngs();
getPolylinesForDataType(dataType, dataName, trackType) {
const polylines = [];
const trackLatLngs = this.trackPolyline.getLatLngs();
for (var i = 0; i < this.trackEdges.edges.length; i++) {
for (let i = 0; i < this.trackEdges.edges.length; i++) {
if (this.wayTagsMatchesData(trackLatLngs[this.trackEdges.edges[i]], dataType, dataName, trackType)) {
var matchedEdgeIndexStart = i > 0 ? this.trackEdges.edges[i - 1] : 0;
var matchedEdgeIndexEnd = this.trackEdges.edges[i] + 1;
const matchedEdgeIndexStart = i > 0 ? this.trackEdges.edges[i - 1] : 0;
const matchedEdgeIndexEnd = this.trackEdges.edges[i] + 1;
polylines.push(
L.polyline(
trackLatLngs.slice(matchedEdgeIndexStart, matchedEdgeIndexEnd),
@ -530,16 +541,16 @@ BR.TrackAnalysis = L.Class.extend({
* which matches if a tag-pair is missing. Special handling for
* tracktypes again.
*
* @param {string} wayTags The way tags as provided by brouter, e.g.
* @param {string} wayTags - The way tags as provided by brouter, e.g.
* `highway=secondary surface=asphalt smoothness=good`
* @param {string} dataType `highway`, `surface`, `smoothness`
* @param {string} dataName `primary`, `track, `asphalt`, etc.
* @param {string} trackType the tracktype is passed here (e.g.
* @param {string} dataType - `highway`, `surface`, `smoothness`
* @param {string} dataName - `primary`, `track, `asphalt`, etc.
* @param {string} trackType - the tracktype is passed here (e.g.
* `grade3`), but only in the case that `dataName` is `track`
*
* @returns {boolean}
*/
wayTagsMatchesData: function (wayTags, dataType, dataName, trackType) {
wayTagsMatchesData(wayTags, dataType, dataName, trackType) {
const parsed = this.wayTagsToObject(wayTags);
switch (dataType) {
@ -559,19 +570,44 @@ BR.TrackAnalysis = L.Class.extend({
return this.singleWayTagMatchesData('surface', parsed, dataName);
case 'smoothness':
return this.singleWayTagMatchesData('smoothness', parsed, dataName);
case 'maxspeed':
return this.singleWayTagMatchesData('maxspeed', parsed, dataName);
}
return false;
},
singleWayTagMatchesData: function (category, parsedData, lookupValue) {
var foundValue = null;
singleWayTagMatchesData(category, parsedData, lookupValue) {
if (typeof lookupValue === 'number') {
lookupValue = lookupValue.toString();
}
for (var iterationKey in parsedData) {
if (iterationKey.indexOf(category) !== -1) {
foundValue = parsedData[iterationKey];
break;
}
let foundValue = null;
// We need to handle `maxspeed:forward` and `maxspeed:backward` separately
// from all other tags, because we need to consider the `reversedirection`
// tag.
// Test URL: http://localhost:3000/#map=15/52.2292/13.6204/standard&lonlats=13.61948,52.231611;13.611327,52.227431
if (
category === 'maxspeed' &&
parsedData.hasOwnProperty('maxspeed:forward') &&
!parsedData.hasOwnProperty('reversedirection')
) {
foundValue = parsedData['maxspeed:forward'];
}
if (
category === 'maxspeed' &&
parsedData.hasOwnProperty('maxspeed:backward') &&
parsedData.hasOwnProperty('reversedirection') &&
parsedData.reversedirection === 'yes'
) {
foundValue = parsedData['maxspeed:backward'];
}
// if the special handling for `maxspeed` didn't find a result,
// check wayTags for matching property:
if (foundValue === null && parsedData.hasOwnProperty(category)) {
foundValue = parsedData[category];
}
if (lookupValue === 'internal-unknown' && foundValue === null) {
@ -586,12 +622,12 @@ BR.TrackAnalysis = L.Class.extend({
*
* 'highway=primary surface=asphalt' => { highway: 'primary', surface: 'asphalt' }
*
* @param wayTags The way tags as provided by brouter, e.g.
* @param wayTags - The way tags as provided by brouter, e.g.
* `highway=secondary surface=asphalt smoothness=good`
*
* @returns {object}
*/
wayTagsToObject: function (wayTags) {
wayTagsToObject(wayTags) {
let result = {};
const wayTagPairs = wayTags.feature.wayTags.split(' ');
@ -608,11 +644,11 @@ BR.TrackAnalysis = L.Class.extend({
*
* { 'highway' : 'path', 'surface' : 'sand' } => ['highway=path', 'surface=sand']
*
* @param wayTags The way tags in object representation
* @param wayTags - The way tags in object representation
*
* @returns {object}
*/
wayTagsToArray: function (wayTags) {
wayTagsToArray(wayTags) {
let wayTagsArray = [];
for (let wayTagKey in wayTags) {
wayTagsArray.push(wayTagKey + '=' + wayTags[wayTagKey]);

View file

@ -38,7 +38,7 @@ BR.TrackMessages = L.Class.extend({
segments: null,
initialize: function (map, options) {
initialize(map, options) {
L.setOptions(this, options);
this._map = map;
@ -53,7 +53,7 @@ BR.TrackMessages = L.Class.extend({
this._mapMouseOutHandlerBound = this.mapMouseOutHandler.bind(this);
},
update: function (polyline, segments, layer) {
update(polyline, segments, layer) {
var i,
messages,
columns,
@ -89,8 +89,8 @@ BR.TrackMessages = L.Class.extend({
this._table = $('#datatable').DataTable({
destroy: true,
data: data,
columns: columns,
data,
columns,
paging: false,
searching: false,
info: false,
@ -109,7 +109,7 @@ BR.TrackMessages = L.Class.extend({
this.listenMapEvents(layer, true);
},
listenMapEvents: function (layer, on) {
listenMapEvents(layer, on) {
if (layer) {
if (on) {
layer.on('mousemove', this._mapMouseMoveHandlerBound);
@ -121,16 +121,16 @@ BR.TrackMessages = L.Class.extend({
}
},
show: function () {
show() {
this.active = true;
this.options.requestUpdate(this);
},
hide: function () {
hide() {
this.active = false;
},
_destroyTable: function () {
_destroyTable() {
var ele;
if ($.fn.DataTable.isDataTable('#datatable')) {
@ -147,7 +147,7 @@ BR.TrackMessages = L.Class.extend({
return ele || document.getElementById('datatable');
},
_destroyEdges: function () {
_destroyEdges() {
if (this._selectedEdge) {
this._map.removeLayer(this._selectedEdge);
this._selectedEdge = null;
@ -158,7 +158,7 @@ BR.TrackMessages = L.Class.extend({
}
},
_getColumns: function (headings, data) {
_getColumns(headings, data) {
var columns = [],
defaultOptions,
options,
@ -175,7 +175,7 @@ BR.TrackMessages = L.Class.extend({
return columns;
},
_getEmptyColumns: function (data) {
_getEmptyColumns(data) {
var empty = new Array(data[0].length),
i;
@ -192,7 +192,7 @@ BR.TrackMessages = L.Class.extend({
return empty;
},
_getRowEdge: function (tr) {
_getRowEdge(tr) {
var row = this._table.row($(tr)),
trackLatLngs = this.trackPolyline.getLatLngs(),
startIndex = row.index() > 0 ? this.trackEdges.edges[row.index() - 1] : 0,
@ -202,7 +202,7 @@ BR.TrackMessages = L.Class.extend({
return L.polyline(edgeLatLngs, this.options.edgeStyle);
},
_handleHover: function (evt) {
_handleHover(evt) {
var tr = evt.currentTarget;
this._hoveredEdge = this._getRowEdge(tr).addTo(this._map);
@ -211,12 +211,12 @@ BR.TrackMessages = L.Class.extend({
}
},
_handleHoverOut: function (evt) {
_handleHoverOut(evt) {
this._map.removeLayer(this._hoveredEdge);
this._hoveredEdge = null;
},
_toggleSelected: function (evt) {
_toggleSelected(evt) {
var tr = evt.currentTarget;
if (tr.classList.toggle('selected')) {
@ -237,14 +237,14 @@ BR.TrackMessages = L.Class.extend({
}
},
_toggleSyncMap: function (evt) {
_toggleSyncMap(evt) {
var button = evt.currentTarget;
button.classList.toggle('active');
this.options.syncMap = !this.options.syncMap;
},
mapMouseMoveHandler: function (evt) {
mapMouseMoveHandler(evt) {
// initialize the vars for the closest item calculation
let closestPointIdx = null;
// large enough to be trumped by any point on the chart
@ -292,7 +292,7 @@ BR.TrackMessages = L.Class.extend({
}
},
mapMouseOutHandler: function () {
mapMouseOutHandler() {
if (this._mapHoveredRow) {
this._mapHoveredRow.classList.remove('hoverRoute');
}

View file

@ -1,5 +1,5 @@
BR.TrackStats = L.Class.extend({
update: function (polyline, segments) {
update(polyline, segments) {
if (segments.length == 0) {
$('#stats-container').hide();
$('#stats-info').show();
@ -44,7 +44,7 @@ BR.TrackStats = L.Class.extend({
$('#meanenergy').html(meanEnergy);
},
calcStats: function (polyline, segments) {
calcStats(polyline, segments) {
var stats = {
trackLength: 0,
filteredAscend: 0,

View file

@ -1,5 +1,5 @@
BR.Csv = {
format: function (geoJson) {
format(geoJson) {
const separator = '\t';
const newline = '\n';
const messages = geoJson.features[0].properties.messages;

View file

@ -1,5 +1,5 @@
BR.Fit = {
format: function (geoJson, turnInstructionMode = 0) {
format(geoJson, turnInstructionMode = 0) {
if (!geoJson?.features) return '';
function calcDistance(p1, p2) {

View file

@ -1,6 +1,6 @@
// derived from BRouter btools.router.OsmTrack.formatAsGpx
BR.Gpx = {
format: function (geoJson, turnInstructionMode = 0, transportMode = 'bike') {
format(geoJson, turnInstructionMode = 0, transportMode = 'bike') {
if (!geoJson?.features) return '';
class GpxTransform {
@ -55,9 +55,9 @@ BR.Gpx = {
let gpx = togpx(geoJson, {
creator: (BR.conf.appName || 'BRouter-Web') + ' ' + BR.version,
featureTitle: function () {},
featureDescription: function () {},
featureCoordTimes: function () {},
featureTitle() {},
featureDescription() {},
featureCoordTimes() {},
transform: gpxTransform,
});
const statsComment = BR.Gpx._statsComment(geoJson);
@ -67,7 +67,7 @@ BR.Gpx = {
},
// <!-- track-length = 319 filtered ascend = 2 plain-ascend = -1 cost=533 energy=.0kwh time=44s -->
_statsComment: function (geoJson) {
_statsComment(geoJson) {
const props = geoJson.features?.[0].properties;
if (!props) return '';

View file

@ -1,5 +1,5 @@
BR.Kml = {
format: function (geoJson) {
format(geoJson) {
// don't export properties as <ExtendedData>, probably no need for it
geoJson.features[0].properties = { name: geoJson.features[0].properties.name };
return BR.Xml.pretty(tokml(geoJson));

View file

@ -235,7 +235,7 @@
const wpt = {
ele: coord[2],
name: cmd.message,
extensions: extensions,
extensions,
};
if (wpt.ele === undefined || wpt.ele === null) {

View file

@ -2,7 +2,7 @@ BR.Xml = {
// modified version of
// https://gist.github.com/sente/1083506#gistcomment-2254622
// MIT License, Copyright (c) 2016 Stuart Powers, ES6 version by Jonathan Gruber
pretty: function (xml, indentSize = 1) {
pretty(xml, indentSize = 1) {
const PADDING = ' '.repeat(indentSize);
const newline = '\n';

View file

@ -58,7 +58,7 @@
{
stateName: 'deactivate-draw',
icon: 'fa-pencil active',
onClick: function (control) {
onClick(control) {
routing.draw(false);
control.state('activate-draw');
},
@ -70,7 +70,7 @@
{
stateName: 'activate-draw',
icon: 'fa-pencil',
onClick: function (control) {
onClick(control) {
routing.draw(true);
control.state('deactivate-draw');
},
@ -103,13 +103,13 @@
stateName: 'activate-beeline',
icon: svg.replace(' active', ''),
onClick: beelineClickHandler,
title: title,
title,
},
{
stateName: 'deactivate-beeline',
icon: svg,
onClick: beelineClickHandler,
title: title,
title,
},
],
});
@ -188,10 +188,10 @@
},
],
value: ['route'],
onShown: function () {
onShown() {
$('button.bootbox-accept', $(this)).focus();
},
callback: function (result) {
callback(result) {
if (result !== null) {
if (result.indexOf('route') !== -1) {
routing.clear();
@ -290,10 +290,10 @@
routingOptions.setCustomProfile(null);
});
trackMessages = new BR.TrackMessages(map, {
requestUpdate: requestUpdate,
requestUpdate,
});
trackAnalysis = new BR.TrackAnalysis(map, {
requestUpdate: requestUpdate,
requestUpdate,
});
routingPathQuality = new BR.RoutingPathQuality(map, layersControl);
@ -500,7 +500,7 @@
urlHash.onHashChangeCb = onHashChangeCb;
urlHash.onInvalidHashChangeCb = onInvalidHashChangeCb;
urlHash.init(map, {
layersControl: layersControl,
layersControl,
});
// activate configured default base layer or first if no hash,

View file

@ -6,7 +6,7 @@ BR.BingLayer = L.BingLayer.extend({
' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)',
},
initialize: function (key, options) {
initialize(key, options) {
L.BingLayer.prototype.initialize.call(this, key, options);
this._logo = L.control({ position: 'bottomleft' });
@ -18,12 +18,12 @@ BR.BingLayer = L.BingLayer.extend({
};
},
onAdd: function (map) {
onAdd(map) {
L.BingLayer.prototype.onAdd.call(this, map);
map.addControl(this._logo);
},
onRemove: function (map) {
onRemove(map) {
L.BingLayer.prototype.onRemove.call(this, map);
map.removeControl(this._logo);
},

View file

@ -20,14 +20,14 @@ BR.CircleGoArea = L.Control.extend({
},
},
initialize: function (routing, nogos, pois, options) {
initialize(routing, nogos, pois, options) {
this.routing = routing;
this.nogos = nogos;
this.pois = pois;
L.setOptions(this, options);
},
onAdd: function (map) {
onAdd(map) {
var self = this;
this.map = map;
@ -38,7 +38,7 @@ BR.CircleGoArea = L.Control.extend({
{
stateName: 'activate-circlego',
icon: 'fa-circle-o',
onClick: function () {
onClick() {
self.draw(true);
},
title: i18next.t('keyboard.generic-shortcut', {
@ -49,7 +49,7 @@ BR.CircleGoArea = L.Control.extend({
{
stateName: 'deactivate-circlego',
icon: 'fa-circle-o active',
onClick: function () {
onClick() {
self.draw(false);
},
title: i18next.t('keyboard.generic-shortcut', {
@ -88,7 +88,7 @@ BR.CircleGoArea = L.Control.extend({
return container;
},
draw: function (enable) {
draw(enable) {
this.drawButton.state(enable ? 'deactivate-circlego' : 'activate-circlego');
if (enable) {
this.routing.draw(false);
@ -109,7 +109,7 @@ BR.CircleGoArea = L.Control.extend({
}
},
_keydownListener: function (e) {
_keydownListener(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
@ -120,7 +120,7 @@ BR.CircleGoArea = L.Control.extend({
}
},
_getBoundary: function (center, adminLevel, adminLevelFallback) {
_getBoundary(center, adminLevel, adminLevelFallback) {
adminLevel = adminLevel || 8;
var query =
'[out:json]; is_in(' +
@ -165,7 +165,7 @@ BR.CircleGoArea = L.Control.extend({
);
},
_setBoundary: function (geoJson) {
_setBoundary(geoJson) {
// drop admin_centre nodes
geoJson.features = geoJson.features.filter(function (feature) {
return feature.geometry.type !== 'Point';
@ -173,7 +173,7 @@ BR.CircleGoArea = L.Control.extend({
var boundaryLine = turf.polygonToLine(geoJson.features[0]);
this.boundaryLayer = L.geoJson(boundaryLine, {
style: function (feature) {
style(feature) {
return {
weight: 1,
color: 'black',
@ -199,7 +199,7 @@ BR.CircleGoArea = L.Control.extend({
this.setOutsideArea(ring);
},
_getPolygonForPoint: function (center, featureCollection) {
_getPolygonForPoint(center, featureCollection) {
var polygon = null;
var point = turf.point(center);
@ -216,15 +216,15 @@ BR.CircleGoArea = L.Control.extend({
return polygon;
},
_getState: function (center) {
_getState(center) {
return this._getPolygonForPoint(center, this.states);
},
_getCountry: function (center) {
_getCountry(center) {
return this._getPolygonForPoint(center, this.countries);
},
_applyStateRules: function (center) {
_applyStateRules(center) {
var state = this._getState(center);
if (state) {
@ -255,7 +255,7 @@ BR.CircleGoArea = L.Control.extend({
}
},
_applyCountryRules: function (center) {
_applyCountryRules(center) {
var country = this._getCountry(center);
if (country) {
@ -294,7 +294,7 @@ BR.CircleGoArea = L.Control.extend({
},
// debugging
_logStates: function (states) {
_logStates(states) {
for (var i = 0; i < states.features.length; i++) {
var state = states.features[i];
console.log(
@ -304,12 +304,12 @@ BR.CircleGoArea = L.Control.extend({
},
// debugging
_addGeoJsonLayer: function (states, options) {
_addGeoJsonLayer(states, options) {
// delay, otherwise triggers premature hash update through mapmove
setTimeout(
L.bind(function () {
L.geoJson(states, {
style: function (feature) {
style(feature) {
return L.extend(
{
weight: 1,
@ -327,7 +327,7 @@ BR.CircleGoArea = L.Control.extend({
);
},
_loadStates: function () {
_loadStates() {
if (this.statesLoading) return;
this.statesLoading = true;
@ -349,7 +349,7 @@ BR.CircleGoArea = L.Control.extend({
);
},
_loadCountries: function () {
_loadCountries() {
BR.Util.getJson(
this.options.countriesUrl,
'countries',
@ -364,7 +364,7 @@ BR.CircleGoArea = L.Control.extend({
renderer: this.maskRenderer,
// use Leaflet.snogylop plugin here, turf.mask too slow (~4s) for some reason
invert: true,
style: function (feature) {
style(feature) {
return {
weight: 1,
color: 'darkgreen',
@ -388,25 +388,25 @@ BR.CircleGoArea = L.Control.extend({
);
},
_setNogo: function (ring) {
_setNogo(ring) {
this.nogoPolylines = L.geoJson(ring, BR.NogoAreas.prototype.polylineOptions);
this.nogos.addNogos(null, this.nogoPolylines.getLayers(), null);
},
_removeNogo: function () {
_removeNogo() {
if (this.nogoPolylines) {
this.nogos.removeNogos(null, this.nogoPolylines.getLayers(), null);
this.nogoPolylines = null;
}
},
_setNogoCircle: function (center) {
_setNogoCircle(center) {
var polygon = this.circleToPolygon(center, this.radius);
this._setNogo(polygon);
this.setOutsideArea(polygon);
},
setNogoRing: function (center) {
setNogoRing(center) {
this._clearLayers();
this._removeNogo();
@ -428,7 +428,7 @@ BR.CircleGoArea = L.Control.extend({
}
},
_lockOutsideArea: function () {
_lockOutsideArea() {
if (this.outsideArea) {
this.outsideArea.eachLayer(function (layer) {
layer._path.classList.add('circlego-outside');
@ -437,7 +437,7 @@ BR.CircleGoArea = L.Control.extend({
}
},
_unlockOutsideArea: function () {
_unlockOutsideArea() {
if (this.outsideArea) {
this.outsideArea.eachLayer(function (layer) {
layer._path.classList.remove('circlego-outside');
@ -446,12 +446,12 @@ BR.CircleGoArea = L.Control.extend({
}
},
setOutsideArea: function (ring) {
setOutsideArea(ring) {
var mask = turf.mask(turf.polygonize(ring));
this.outsideArea = L.geoJson(mask, {
renderer: this.maskRenderer,
style: function (feature) {
style(feature) {
return {
weight: 4,
color: 'black',
@ -466,11 +466,11 @@ BR.CircleGoArea = L.Control.extend({
this._lockOutsideArea();
},
onMapClick: function (e) {
onMapClick(e) {
this.setCircle([e.latlng.lng, e.latlng.lat]);
},
setOptions: function (opts) {
setOptions(opts) {
this.radius = opts.circlego[2];
if (opts.polylines) {
this.nogoPolylines = L.featureGroup(opts.polylines, BR.NogoAreas.prototype.polylineOptions);
@ -478,7 +478,7 @@ BR.CircleGoArea = L.Control.extend({
this.setCircle([opts.circlego[0], opts.circlego[1]], opts.polylines);
},
setCircle: function (center, polylines) {
setCircle(center, polylines) {
var marker = (this.marker = this._createMarker(center));
this.clear();
@ -503,7 +503,7 @@ BR.CircleGoArea = L.Control.extend({
this.draw(false);
},
_createMarker: function (center) {
_createMarker(center) {
var self = this;
var icon = (this.icon = L.VectorMarkers.icon({
icon: 'home',
@ -519,7 +519,7 @@ BR.CircleGoArea = L.Control.extend({
'<button id="remove-ringgo-marker" class="btn btn-secondary"><i class="fa fa-trash"></i></button>';
var marker = L.marker([center[1], center[0]], {
icon: icon,
icon,
draggable: true,
// prevent being on top of route markers
zIndexOffset: -500,
@ -547,7 +547,7 @@ BR.CircleGoArea = L.Control.extend({
return marker;
},
_onPopupOpen: function (popup, popupContent) {
_onPopupOpen(popup, popupContent) {
var exportName = '';
var html = '<p>';
if (this.radius) {
@ -580,7 +580,7 @@ BR.CircleGoArea = L.Control.extend({
if (this.nogoPolylines) {
var link = location.href.replace(/&polylines=[^&]*/, '');
var geoJson = this.nogoPolylines.toGeoJSON();
var gpx = togpx(geoJson, { metadata: { name: exportName, link: link } });
var gpx = togpx(geoJson, { metadata: { name: exportName, link } });
this._setDownloadUrl(gpx, 'application/gpx+xml', 'ringgo-download-gpx');
this._setDownloadUrl(
JSON.stringify(geoJson, null, 2),
@ -599,12 +599,12 @@ BR.CircleGoArea = L.Control.extend({
);
},
_onPopupClose: function (evt) {
_onPopupClose(evt) {
this._revokeDownloadUrl('ringgo-download-gpx');
this._revokeDownloadUrl('ringgo-download-geojson');
},
_setDownloadUrl: function (text, mimeType, elementId) {
_setDownloadUrl(text, mimeType, elementId) {
var blob = new Blob([text], {
type: mimeType + ';charset=utf-8',
});
@ -613,14 +613,14 @@ BR.CircleGoArea = L.Control.extend({
download.href = objectUrl;
},
_revokeDownloadUrl: function (elementId) {
_revokeDownloadUrl(elementId) {
var download = document.getElementById(elementId);
if (download) {
URL.revokeObjectURL(download.href);
}
},
_clearLayers: function () {
_clearLayers() {
if (this.outsideArea) {
this.map.removeLayer(this.outsideArea);
this.outsideArea = null;
@ -631,16 +631,16 @@ BR.CircleGoArea = L.Control.extend({
}
},
clear: function () {
clear() {
this.circleLayer.clearLayers();
this._clearLayers();
},
getButton: function () {
getButton() {
return this.drawButton;
},
getCircle: function () {
getCircle() {
var circle = this.circleLayer.getLayers().map(function (it) {
return it.getLatLng();
});
@ -651,15 +651,15 @@ BR.CircleGoArea = L.Control.extend({
}
},
toRadians: function (angleInDegrees) {
toRadians(angleInDegrees) {
return (angleInDegrees * Math.PI) / 180;
},
toDegrees: function (angleInRadians) {
toDegrees(angleInRadians) {
return (angleInRadians * 180) / Math.PI;
},
offset: function (c1, distance, bearing) {
offset(c1, distance, bearing) {
var lon1 = this.toRadians(c1[0]);
var lat1 = this.toRadians(c1[1]);
var dByR = distance / 6378137; // distance divided by 6378137 (radius of the earth) wgs84
@ -673,7 +673,7 @@ BR.CircleGoArea = L.Control.extend({
return [this.toDegrees(lon), this.toDegrees(lat)];
},
circleToPolygon: function (center, radius, numberOfSegments) {
circleToPolygon(center, radius, numberOfSegments) {
var n = numberOfSegments ? numberOfSegments : 64;
var inner = [];

View file

@ -11,49 +11,137 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
expandControls: false,
mappings: {
gradient: {
'-16': {
text: '< -15%',
color: '#81A850',
},
'-15': {
text: '-15%',
color: '#89AA55',
},
'-14': {
text: '-14%',
color: '#91AD59',
},
'-13': {
text: '-13%',
color: '#99AF5E',
},
'-12': {
text: '-12%',
color: '#A1B162',
},
'-11': {
text: '-11%',
color: '#A8B367',
},
'-10': {
text: '-10%',
color: '#B0B66B',
},
'-9': {
text: '-9%',
color: '#B8B870',
},
'-8': {
text: '-8%',
color: '#C0BA75',
},
'-7': {
text: '-7%',
color: '#C8BC79',
},
'-6': {
text: '-6%',
color: '#D0BF7E',
},
'-5': {
text: '- 16%+',
color: '#028306',
text: '-5%',
color: '#D8C182',
},
'-4': {
text: '- 10-15%',
color: '#2AA12E',
text: '-4%',
color: '#E0C387',
},
'-3': {
text: '- 7-9%',
color: '#53BF56',
text: '-3%',
color: '#E7C58B',
},
'-2': {
text: '- 4-6%',
color: '#7BDD7E',
text: '-2%',
color: '#EFC890',
},
'-1': {
text: '- 1-3%',
color: '#A4FBA6',
text: '-1%',
color: '#F7CA94',
},
0: {
text: '0%',
color: '#ffcc99',
color: '#FFCC99',
},
1: {
text: '1-3%',
color: '#F29898',
text: '1%',
color: '#FCC695',
},
2: {
text: '4-6%',
color: '#E07575',
text: '2%',
color: '#FAC090',
},
3: {
text: '7-9%',
color: '#CF5352',
text: '3%',
color: '#F7BA8C',
},
4: {
text: '10-15%',
color: '#BE312F',
text: '4%',
color: '#F5B588',
},
5: {
text: '16%+',
color: '#AD0F0C',
text: '5%',
color: '#F2AF83',
},
6: {
text: '6%',
color: '#F0A97F',
},
7: {
text: '7%',
color: '#EDA37A',
},
8: {
text: '8%',
color: '#EB9D76',
},
9: {
text: '9%',
color: '#E89772',
},
10: {
text: '10%',
color: '#E5916D',
},
11: {
text: '11%',
color: '#E38B69',
},
12: {
text: '12%',
color: '#E08665',
},
13: {
text: '13%',
color: '#DE8060',
},
14: {
text: '14%',
color: '#DB7A5C',
},
15: {
text: '15%',
color: '#D97457',
},
16: {
text: '> 15%',
color: '#D66E53',
},
},
},
@ -63,7 +151,7 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
},
},
addBelow: function (map) {
addBelow(map) {
// waiting for https://github.com/MrMufflon/Leaflet.Elevation/pull/66
// this.width($('#map').outerWidth());
this.options.width = $('#content').outerWidth();
@ -75,6 +163,7 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
function setParent(el, newParent) {
newParent.appendChild(el);
}
this.addTo(map);
// move elevation graph outside of the map
@ -114,7 +203,7 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
this.update();
},
initCollapse: function (map) {
initCollapse(map) {
var self = this;
var onHide = function () {
$('#elevation-btn').removeClass('active');
@ -143,13 +232,13 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
});
},
_keydownListener: function (e) {
_keydownListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggle) {
$('#elevation-btn').click();
}
},
update: function (track, layer) {
update(track, layer) {
// bring height indicator to front, because of track casing in BR.Routing
if (this._mouseHeightFocus) {
var g = this._mouseHeightFocus._groups[0][0].parentNode;
@ -167,7 +256,11 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
} else {
$('#no-elevation-data').hide();
}
var geojsonFeatures = geoDataExchange.buildGeojsonFeatures(track.getLatLngs());
var geojsonFeatures = geoDataExchange.buildGeojsonFeatures(track.getLatLngs(), {
interpolate: false,
normalize: false,
});
this.addData(geojsonFeatures);
// re-add handlers
@ -197,6 +290,109 @@ BR.Heightgraph = function (map, layersControl, routing, pois) {
$('#elevation-chart').collapse('hide');
}
},
_createLegend() {
if (this._categories.length > 0) {
// find the min and the max gradients for the current profile
var minGradient = 16;
var maxGradient = -16;
// this legend object has the profile gradients as keys; it was built by heightgraph
var allLegend = this._categories[this.options.selectedAttributeIdx].legend;
for (key in allLegend) {
var gradient = parseInt(key);
if (minGradient > gradient) {
minGradient = gradient;
}
if (maxGradient < gradient) {
maxGradient = gradient;
}
}
// define the simplified legend with all known gradients
var simplifiedLegend = [
{
type: -16,
text: this.options.mappings.gradient['-16'].text,
color: this.options.mappings.gradient['-16'].color,
},
{
type: -10,
text: this.options.mappings.gradient['-10'].text,
color: this.options.mappings.gradient['-10'].color,
},
{
type: -5,
text: this.options.mappings.gradient['-5'].text,
color: this.options.mappings.gradient['-5'].color,
},
{
type: 0,
text: this.options.mappings.gradient['0'].text,
color: this.options.mappings.gradient['0'].color,
},
{
type: 5,
text: this.options.mappings.gradient['5'].text,
color: this.options.mappings.gradient['5'].color,
},
{
type: 10,
text: this.options.mappings.gradient['10'].text,
color: this.options.mappings.gradient['10'].color,
},
{
type: 16,
text: this.options.mappings.gradient['16'].text,
color: this.options.mappings.gradient['16'].color,
},
];
// then, keep only the range relevant to the current profile
// (e.g. if min gradient of profile is -6, remove -16 and -15 from range)
for (var i = 0; i < simplifiedLegend.length; i++) {
if (simplifiedLegend[i].type > minGradient) {
simplifiedLegend.splice(0, i - 1);
break;
}
}
for (var i = simplifiedLegend.length - 1; i > -1; i--) {
if (simplifiedLegend[i].type < maxGradient) {
simplifiedLegend.splice(i + 2);
break;
}
}
this._categories[this.options.selectedAttributeIdx].legend = simplifiedLegend;
}
var existingLegend = document.querySelector('.legend-container');
if (existingLegend !== null) {
existingLegend.remove();
}
var legend = L.DomUtil.create('div', 'legend-container', this._container);
// hack to keep the chart from getting too tall,
// and to keep it from growing vertically on window resize
legend.style.setProperty('position', 'absolute');
// naively align the legend vertically with the y-axis
legend.style.setProperty('margin-left', '65px');
legend.style.setProperty('margin-top', '-18px');
var legendLabel = L.DomUtil.create('span', 'legend-hover legend-text', legend);
legendLabel.textContent = this._getTranslation('legend') + ':';
this._categories[this.options.selectedAttributeIdx].legend.forEach((l) => {
var color = L.DomUtil.create('span', 'legend-rect', legend);
color.style.setProperty('padding-left', '10px');
color.style.setProperty('padding-right', '3px');
color.style.setProperty('width', '6px');
color.style.setProperty('height', '6px');
color.style.setProperty('color', l.color);
color.innerHTML = '&#9632;';
var label = L.DomUtil.create('span', 'legend-text', legend);
label.textContent = l.text;
});
},
});
var heightgraphControl = new Heightgraph();

View file

@ -40,11 +40,11 @@ BR.NogoAreas = L.Control.extend({
smoothFactor: 0.5,
},
initialize: function () {
initialize() {
this._wasRouteDrawing = false;
},
onAdd: function (map) {
onAdd(map) {
var self = this;
$('#submitNogos').on('click', L.bind(this.uploadNogos, this));
@ -149,7 +149,7 @@ BR.NogoAreas = L.Control.extend({
return L.DomUtil.create('div');
},
_keydownListener: function (e) {
_keydownListener(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
@ -170,17 +170,17 @@ BR.NogoAreas = L.Control.extend({
}
},
displayUploadError: function (message) {
displayUploadError(message) {
$('#nogoError').text(message ? message : '');
$('#nogoError').css('display', message ? 'block' : 'none');
},
onFileChanged: function (e) {
onFileChanged(e) {
if (!e.target.files[0]) return;
$(e.target).next('label').text(e.target.files[0].name);
},
uploadNogos: function () {
uploadNogos() {
var self = this;
var geoJSONPromise;
@ -253,7 +253,7 @@ BR.NogoAreas = L.Control.extend({
}
var geoJSON = L.geoJson(turf.featureCollection(cleanedGeoJSONFeatures), {
onEachFeature: function (feature, layer) {
onEachFeature(feature, layer) {
layer.options.nogoWeight = feature.properties.nogoWeight || nogoWeight;
if (feature.geometry.type === 'LineString') {
L.setOptions(layer, self.polylineOptions);
@ -266,7 +266,7 @@ BR.NogoAreas = L.Control.extend({
nogosPoints = nogosPoints.map(function (item) {
var radius = item.feature.properties.radius || nogoRadius;
if (radius > 0) {
return L.circle(item.getLatLng(), { radius: radius });
return L.circle(item.getLatLng(), { radius });
}
return null;
});
@ -303,7 +303,7 @@ BR.NogoAreas = L.Control.extend({
},
// prevent route waypoint added after circle create (map click after up)
preventRoutePointOnCreate: function (routing) {
preventRoutePointOnCreate(routing) {
this.editTools.on(
'editable:drawing:start',
function (e) {
@ -327,7 +327,7 @@ BR.NogoAreas = L.Control.extend({
);
},
getOptions: function () {
getOptions() {
return {
nogos: this.drawnItems.getLayers().filter(function (e) {
return e instanceof L.Circle;
@ -341,7 +341,7 @@ BR.NogoAreas = L.Control.extend({
};
},
setOptions: function (options) {
setOptions(options) {
var nogos = options.nogos;
var polylines = options.polylines;
var polygons = options.polygons;
@ -349,12 +349,12 @@ BR.NogoAreas = L.Control.extend({
this._addNogos(nogos, polylines, polygons);
},
addNogos: function (nogos, polylines, polygons) {
addNogos(nogos, polylines, polygons) {
this._addNogos(nogos, polylines, polygons);
this._fireUpdate();
},
_addNogos: function (nogos, polylines, polygons) {
_addNogos(nogos, polylines, polygons) {
if (nogos) {
for (var i = 0; i < nogos.length; i++) {
nogos[i].setStyle(this.style);
@ -375,7 +375,7 @@ BR.NogoAreas = L.Control.extend({
}
},
removeNogos: function (nogos, polylines, polygons) {
removeNogos(nogos, polylines, polygons) {
if (nogos) {
for (var i = 0; i < nogos.length; i++) {
this.drawnItems.removeLayer(nogos[i]);
@ -395,28 +395,28 @@ BR.NogoAreas = L.Control.extend({
this._fireUpdate();
},
_clear: function () {
_clear() {
this.drawnItems.clearLayers();
},
clear: function () {
clear() {
this._clear();
this._fireUpdate();
},
_fireUpdate: function () {
_fireUpdate() {
this.fire('update', { options: this.getOptions() });
},
getFeatureGroup: function () {
getFeatureGroup() {
return this.drawnItems;
},
getEditGroup: function () {
getEditGroup() {
return this.editTools.editLayer;
},
getButton: function () {
getButton() {
return this.button;
},
});
@ -430,7 +430,7 @@ BR.Editable = L.Editable.extend({
// Also, we generally disable the Tap handler in the map options for route dragging,
// see Map.js, so we always need to enable for drawing.
initialize: function (map, options) {
initialize(map, options) {
L.Editable.prototype.initialize.call(this, map, options);
if (!this.map.tap) {
@ -439,7 +439,7 @@ BR.Editable = L.Editable.extend({
}
},
registerForDrawing: function (editor) {
registerForDrawing(editor) {
this._tapEnabled = this.map.tap.enabled();
if (!this._tapEnabled) {
this.map.tap.enable();
@ -448,7 +448,7 @@ BR.Editable = L.Editable.extend({
L.Editable.prototype.registerForDrawing.call(this, editor);
},
unregisterForDrawing: function (editor) {
unregisterForDrawing(editor) {
if (!this._tapEnabled) {
this.map.tap.disable();
}
@ -456,7 +456,7 @@ BR.Editable = L.Editable.extend({
L.Editable.prototype.unregisterForDrawing.call(this, editor);
},
createVertexIcon: function (options) {
createVertexIcon(options) {
return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
},
});
@ -466,13 +466,13 @@ BR.EditingTooltip = L.Handler.extend({
closeTimeout: 2000,
},
initialize: function (map, editTools, button) {
initialize(map, editTools, button) {
this.map = map;
this.editTools = editTools;
this.button = button;
},
addHooks: function () {
addHooks() {
// hack: listen to EasyButton click (instead of editable:drawing:start),
// to get mouse position from event for initial tooltip location
L.DomEvent.addListener(this.button.button, 'click', this._addCreate, this);
@ -484,7 +484,7 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.on('editable:disable', this._disable, this);
},
removeHooks: function () {
removeHooks() {
L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this);
this.editTools.featuresLayer.off('layeradd', this._bind, this);
@ -494,7 +494,7 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.off('editable:disable', this._disable, this);
},
_bind: function (e) {
_bind(e) {
// Position tooltip at bottom of circle, less distracting than
// sticky with cursor or at center.
@ -517,7 +517,7 @@ BR.EditingTooltip = L.Handler.extend({
};
},
_addCreate: function (e) {
_addCreate(e) {
// button cancel
if (!this.editTools.drawing()) return;
@ -564,7 +564,7 @@ BR.EditingTooltip = L.Handler.extend({
}
},
_setCloseTimeout: function (layer) {
_setCloseTimeout(layer) {
var timeoutId = setTimeout(function () {
layer.closeTooltip();
}, this.options.closeTimeout);
@ -575,7 +575,7 @@ BR.EditingTooltip = L.Handler.extend({
});
},
_postCreate: function () {
_postCreate() {
// editing is disabled by another handler, tooltip won't stay open before
this.editTools.once(
'editable:disable',
@ -588,7 +588,7 @@ BR.EditingTooltip = L.Handler.extend({
);
},
_enable: function (e) {
_enable(e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED);
this.editTools.once(
@ -600,42 +600,42 @@ BR.EditingTooltip = L.Handler.extend({
);
},
_disable: function (e) {
_disable(e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED);
this._setCloseTimeout(e.layer);
},
});
BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
_computeDeleteLatLng: function () {
_computeDeleteLatLng() {
// While circle is not added to the map, _radius is not set.
var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
point = this.map.project(this.feature._latlng);
return this.map.unproject([point.x - delta, point.y - delta]);
},
_updateDeleteLatLng: function () {
_updateDeleteLatLng() {
this._deleteLatLng.update(this._computeDeleteLatLng());
this._deleteLatLng.__vertex.update();
},
_addDeleteMarker: function () {
_addDeleteMarker() {
if (!this.enabled()) return;
this._deleteLatLng = this._computeDeleteLatLng();
return new BR.DeleteMarker(this._deleteLatLng, this);
},
_delete: function () {
_delete() {
this.disable();
this.tools.featuresLayer.removeLayer(this.feature);
},
delete: function () {
delete() {
this._delete();
this.fireAndForward('editable:deleted');
},
initialize: function (map, feature, options) {
initialize(map, feature, options) {
L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options);
this._deleteLatLng = this._computeDeleteLatLng();
@ -643,7 +643,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
this.editLayer = new L.FeatureGroup();
},
addHooks: function () {
addHooks() {
L.Editable.CircleEditor.prototype.addHooks.call(this);
if (this.feature) {
this._addDeleteMarker();
@ -651,12 +651,12 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
return this;
},
reset: function () {
reset() {
L.Editable.CircleEditor.prototype.reset.call(this);
this._addDeleteMarker();
},
onDrawingMouseDown: function (e) {
onDrawingMouseDown(e) {
this._deleteLatLng.update(e.latlng);
L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e);
},
@ -664,7 +664,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
// override to cancel/remove created circle when added by click instead of drag, because:
// - without resize, edit handles stacked on top of each other
// - makes event handling more complicated (editable:vertex:dragend not called)
onDrawingMouseUp: function (e) {
onDrawingMouseUp(e) {
if (this.feature.getRadius() > 0) {
this.commitDrawing(e);
} else {
@ -675,7 +675,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
},
onVertexMarkerDrag: function (e) {
onVertexMarkerDrag(e) {
this._updateDeleteLatLng();
L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e);
},
@ -690,7 +690,7 @@ BR.DeleteMarker = L.Marker.extend({
}),
},
initialize: function (latlng, editor, options) {
initialize(latlng, editor, options) {
// derived from L.Editable.VertexMarker.initialize
// We don't use this._latlng, because on drag Leaflet replace it while
@ -707,18 +707,18 @@ BR.DeleteMarker = L.Marker.extend({
this.setZIndexOffset(editor.tools._lastZIndex);
},
onAdd: function (map) {
onAdd(map) {
L.Marker.prototype.onAdd.call(this, map);
this.on('click', this.onClick);
},
onRemove: function (map) {
onRemove(map) {
delete this.latlng.__vertex;
this.off('click', this.onClick);
L.Marker.prototype.onRemove.call(this, map);
},
onClick: function (e) {
onClick(e) {
this.editor.delete();
},
});

View file

@ -10,12 +10,12 @@ BR.PoiMarkers = L.Control.extend({
},
},
},
initialize: function (routing) {
initialize(routing) {
this.routing = routing;
this.circlego = null;
},
onAdd: function (map) {
onAdd(map) {
var self = this;
this.map = map;
@ -26,7 +26,7 @@ BR.PoiMarkers = L.Control.extend({
{
stateName: 'activate-poi',
icon: 'fa-hand-o-right',
onClick: function () {
onClick() {
self.draw(true);
},
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-poi-start)', key: 'P' }),
@ -34,7 +34,7 @@ BR.PoiMarkers = L.Control.extend({
{
stateName: 'deactivate-poi',
icon: 'fa-hand-o-right active',
onClick: function () {
onClick() {
self.draw(false);
},
title: i18next.t('keyboard.generic-shortcut', {
@ -55,7 +55,7 @@ BR.PoiMarkers = L.Control.extend({
return container;
},
draw: function (enable) {
draw(enable) {
this.drawButton.state(enable ? 'deactivate-poi' : 'activate-poi');
if (enable) {
this.routing.draw(false);
@ -68,7 +68,7 @@ BR.PoiMarkers = L.Control.extend({
}
},
_keydownListener: function (e) {
_keydownListener(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
@ -79,13 +79,13 @@ BR.PoiMarkers = L.Control.extend({
}
},
onMapClick: function (e) {
onMapClick(e) {
var self = this;
bootbox.prompt({
title: i18next.t('map.enter-poi-name'),
// allow empty name with client-side formatting
required: !BR.Browser.download,
callback: function (result) {
callback(result) {
if (result !== null) {
self.addMarker(e.latlng, result);
}
@ -93,7 +93,7 @@ BR.PoiMarkers = L.Control.extend({
});
},
addMarker: function (latlng, name) {
addMarker(latlng, name) {
var icon = L.VectorMarkers.icon({
icon: 'star',
markerColor: BR.conf.markerColors.poi,
@ -107,7 +107,7 @@ BR.PoiMarkers = L.Control.extend({
'<p><button id="remove-poi-marker" class="btn btn-secondary"><i class="fa fa-trash"></i></button></p>';
var self = this;
var marker = L.marker(latlng, { icon: icon, draggable: true, name: name })
var marker = L.marker(latlng, { icon, draggable: true, name })
.bindPopup(contentWithAction)
.on('dragend', function () {
self.fire('update');
@ -132,11 +132,11 @@ BR.PoiMarkers = L.Control.extend({
}
},
clear: function () {
clear() {
this.markersLayer.clearLayers();
},
setMarkers: function (latLngNames) {
setMarkers(latLngNames) {
this.clear();
if (!latLngNames) return;
@ -147,7 +147,7 @@ BR.PoiMarkers = L.Control.extend({
}
},
getMarkers: function () {
getMarkers() {
return this.markersLayer.getLayers().map(function (it) {
return {
latlng: it.getLatLng(),

View file

@ -20,7 +20,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
},
},
setDialogDraggable: function (jqDlgHeader) {
setDialogDraggable(jqDlgHeader) {
jqDlgHeader.on('mousedown', function (mousedownEvt) {
var $draggable = $(this);
var x = mousedownEvt.pageX - $draggable.offset().left,
@ -40,15 +40,15 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
});
},
getSimplifiedCoords: function (tolerance) {
getSimplifiedCoords(tolerance) {
var simplifiedLine = turf.simplify(this._trackPoints.geometry, {
tolerance: tolerance,
tolerance,
highQuality: true,
});
return simplifiedLine.coordinates;
},
refreshTestLayer: function () {
refreshTestLayer() {
this.onBusyChanged(true);
this._testLayer.clearLayers();
@ -73,7 +73,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
return true;
},
cleanup: function (e) {
cleanup(e) {
this._testLayer.clearLayers();
if (
this._trackLayer &&
@ -98,7 +98,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
};
},
setSliderRange: function () {
setSliderRange() {
$slider = $('#simplify_tolerance');
$slider.prop('min', -500);
var guessedTolerance = this.guessSimplifyTolerance(this._trackPoints);
@ -116,7 +116,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
this.refreshTestLayer();
},
onToleranceSlider: function (e) {
onToleranceSlider(e) {
var guess = parseFloat($(e.target).data('guess'));
var f = parseFloat(e.target.value);
var frac = parseFloat($(e.target).prop('max'));
@ -145,7 +145,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
}
},
findLowestTolerance: function (min, max, guess, frac) {
findLowestTolerance(min, max, guess, frac) {
if (Math.abs(max - min) <= 2) return max;
var meridian = Math.round((max + min) / 2);
@ -157,7 +157,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
else return this.findLowestTolerance(min, meridian, guess, frac);
},
onBusyChanged: function (isBusy) {
onBusyChanged(isBusy) {
if (typeof isBusy === undefined) {
isBusy = false;
}
@ -165,7 +165,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
else $('#loadedittrack #msg_busy').addClass('invisible');
},
onManualCollapse: function (e) {
onManualCollapse(e) {
//workaround for starting with closed collapse
if ($('#loadedittrack').is(':hidden')) return;
this._options.isTestMode = $(e.target).hasClass('show');
@ -176,7 +176,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
} else this.cleanup();
},
onAdd: function (map) {
onAdd(map) {
$('#loadedittrack').on(
'hidden.bs.modal',
function (e) {
@ -238,11 +238,11 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
return dummy;
},
onRemove: function (map) {
onRemove(map) {
// Nothing to do here
},
onFileChanged: function (e) {
onFileChanged(e) {
if (!e.target.files[0]) return;
$(e.target).next('label').text(e.target.files[0].name);
var testmode = this._options.isTestMode;
@ -254,7 +254,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
}
},
setLayerNameFromGeojson: function (geoJSON) {
setLayerNameFromGeojson(geoJSON) {
if (geoJSON.type == 'Feature' && geoJSON.properties && geoJSON.properties.name) {
this._layerName = geoJSON.properties.name;
return;
@ -270,7 +270,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
}
},
getOptions: function () {
getOptions() {
this._options.showTrackLayer = $('#cb_showtracklayer')[0].checked;
this._options.showPointAsPoi = $('#cb_showpois')[0].checked;
@ -278,7 +278,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
this._bounds = undefined;
},
convertTrackLocal: function () {
convertTrackLocal() {
if ($('#loadedittrackFile')[0].files.length == 0) return;
this.onBusyChanged(true);
@ -295,7 +295,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
reader.readAsText(trackFile);
},
addTrackOverlay: function (geoJSON) {
addTrackOverlay(geoJSON) {
this._trackLayer = L.geoJSON(geoJSON, BR.Track.getGeoJsonOptions(layersControl, true)).addTo(map);
layersControl.addOverlay(this._trackLayer, BR.Util.sanitizeHTMLContent(this._layerName));
@ -305,7 +305,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
if (this._bounds) map.fitBounds(this._bounds);
},
getLineStringsFromGeoJSON: function (geoJSON) {
getLineStringsFromGeoJSON(geoJSON) {
var allLinePoints = [];
var flat = turf.flatten(geoJSON);
turf.featureEach(flat, function (feature, idx) {
@ -321,13 +321,13 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
return linesGeoJSON;
},
guessSimplifyTolerance: function (trackPoints) {
guessSimplifyTolerance(trackPoints) {
var tolerance = trackPoints.length / 1000000;
if (tolerance > 0.8) tolerance = 0.8;
return tolerance;
},
addRoutingPoints: function (geoJSON) {
addRoutingPoints(geoJSON) {
if (this._options.simplifyTolerance < 0)
this._options.simplifyTolerance = this.guessSimplifyTolerance(this._trackPoints);
@ -361,7 +361,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
}
},
processFile: function (e) {
processFile(e) {
var res = e.target.result;
var geoJSON = null;
switch (this._options.format) {
@ -391,7 +391,7 @@ BR.routeLoader = function (map, layersControl, routing, pois) {
this.onBusyChanged(false);
},
keydownListener: function (e) {
keydownListener(e) {
if (
BR.Util.keyboardShortcutsAllowed(e) &&
e.keyCode === this._options.shortcut.open &&

View file

@ -23,7 +23,7 @@ BR.Routing = L.Routing.extend({
// width as base number, multiplied by number of digits + one for padding
iconSize: [6, 18],
offset: 5000,
textFunction: function (distance) {
textFunction(distance) {
return distance / 1000;
},
},
@ -42,13 +42,13 @@ BR.Routing = L.Routing.extend({
},
},
initialize: function (profile, options) {
initialize(profile, options) {
L.Routing.prototype.initialize.call(this, options);
this.profile = profile;
},
onAdd: function (map) {
onAdd(map) {
this.options.tooltips.waypoint = i18next.t('map.route-tooltip-waypoint');
this.options.tooltips.segment = i18next.t('map.route-tooltip-segment');
@ -178,16 +178,19 @@ BR.Routing = L.Routing.extend({
this._show();
}
}
var hide = function () {
if (!this._hidden && this._parent._waypoints._first) {
this._hide();
}
}.bind(this._draw);
function hideOverControl(e) {
hide();
// prevent showing trailer when clicking state buttons (causes event that propagates to map)
L.DomEvent.stopPropagation(e);
}
this._draw.on('enabled', function () {
this._map.on('mouseout', hide, this);
this._map.on('mouseover', show, this);
@ -246,7 +249,7 @@ BR.Routing = L.Routing.extend({
return container;
},
_addSegmentCasing: function (e) {
_addSegmentCasing(e) {
// extend layer style to inherit beeline dashArray
const casingStyle = Object.assign({}, e.layer.options, this.options.styles.trackCasing);
const casing = L.polyline(e.layer.getLatLngs(), Object.assign({}, casingStyle, { interactive: false }));
@ -255,11 +258,11 @@ BR.Routing = L.Routing.extend({
this._segments.bringToFront();
},
_removeSegmentCasing: function (e) {
_removeSegmentCasing(e) {
this._segmentsCasing.removeLayer(e.layer._casing);
},
setOpacity: function (opacity) {
setOpacity(opacity) {
// Due to the second Polyline layer for casing, the combined opacity is less
// transparent than with a single layer and the slider is non-linear. The
// inverted formula is used to get the same result as with a single layer.
@ -286,11 +289,11 @@ BR.Routing = L.Routing.extend({
}
},
_setMarkerOpacity: function (e) {
_setMarkerOpacity(e) {
e.layer.setOpacity(this.options.icons.opacity);
},
_removeMarkerEvents: function (marker) {
_removeMarkerEvents(marker) {
marker.off('mouseover', this._fireWaypointEvent, this);
marker.off('mouseout', this._fireWaypointEvent, this);
marker.off('dragstart', this._fireWaypointEvent, this);
@ -299,7 +302,7 @@ BR.Routing = L.Routing.extend({
marker.off('click', this._fireWaypointEvent, this);
},
clear: function () {
clear() {
var drawEnabled = this._draw._enabled;
var current = this._waypoints._first;
@ -326,7 +329,7 @@ BR.Routing = L.Routing.extend({
}
},
setWaypoints: function (latLngs, beelineFlags, cb) {
setWaypoints(latLngs, beelineFlags, cb) {
var i;
var callbackCount = 0;
var firstErr;
@ -367,7 +370,7 @@ BR.Routing = L.Routing.extend({
// patch to fix error when line is null or error line
// (when called while still segments to calculate, e.g. permalink or fast drawing)
toPolyline: function () {
toPolyline() {
var latLngs = [];
this._eachSegment(function (m1, m2, line) {
@ -381,7 +384,7 @@ BR.Routing = L.Routing.extend({
return L.polyline(latLngs);
},
_routeSegment: function (m1, m2, cb) {
_routeSegment(m1, m2, cb) {
var loadingTrailer;
// change segment color before request to indicate recalculation (mark old)
@ -413,7 +416,7 @@ BR.Routing = L.Routing.extend({
);
},
getSegments: function () {
getSegments() {
var segments = [];
this._eachSegment(function (m1, m2, line) {
@ -427,7 +430,7 @@ BR.Routing = L.Routing.extend({
return segments;
},
_keydownListener: function (e) {
_keydownListener(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
@ -446,17 +449,17 @@ BR.Routing = L.Routing.extend({
}
},
_keyupListener: function (e) {
_keyupListener(e) {
if (e.keyCode === this.options.shortcut.draw.beelineModifier) {
this._draw._setTrailerStyle(false);
}
},
isDrawing: function () {
isDrawing() {
return this._draw._enabled;
},
reverse: function () {
reverse() {
const waypoints = this.getWaypoints();
const beelineFlags = this.getBeelineFlags();
waypoints.reverse();
@ -465,19 +468,19 @@ BR.Routing = L.Routing.extend({
this.setWaypoints(waypoints, beelineFlags);
},
deleteLastPoint: function () {
deleteLastPoint() {
if ((lastPoint = this.getLast())) {
this.removeWaypoint(lastPoint, function (err, data) {});
}
},
_removeDistanceMarkers: function () {
_removeDistanceMarkers() {
if (this._map && this._distanceMarkers) {
this._map.removeLayer(this._distanceMarkers);
}
},
_updateDistanceMarkers: function (e) {
_updateDistanceMarkers(e) {
this._removeDistanceMarkers();
if (this._map) {
@ -487,7 +490,7 @@ BR.Routing = L.Routing.extend({
}
},
_distance: function (latLng1, latLng2) {
_distance(latLng1, latLng2) {
//return Math.round(latLng1.distanceTo(latLng2));
const [ilon1, ilat1] = btools.util.CheapRuler.toIntegerLngLat([latLng1.lng, latLng1.lat]);
const [ilon2, ilat2] = btools.util.CheapRuler.toIntegerLngLat([latLng2.lng, latLng2.lat]);
@ -495,7 +498,7 @@ BR.Routing = L.Routing.extend({
return btools.util.CheapRuler.calcDistance(ilon1, ilat1, ilon2, ilat2);
},
_computeKinematic: function (distance, deltaHeight, costFactor) {
_computeKinematic(distance, deltaHeight, costFactor) {
const rc = new BR.RoutingContext(this.profile);
rc.expctxWay = new BR.BExpressionContextWay(undefined, costFactor);
const stdPath = new BR.StdPath();
@ -504,7 +507,7 @@ BR.Routing = L.Routing.extend({
return stdPath;
},
_getCostFactor: function (line) {
_getCostFactor(line) {
let costFactor;
if (line) {
const props = line.feature.properties;
@ -517,7 +520,7 @@ BR.Routing = L.Routing.extend({
return costFactor;
},
_interpolateBeelines: function (serialBeelines, before, after) {
_interpolateBeelines(serialBeelines, before, after) {
let altStart = before?.getLatLngs()[before.getLatLngs().length - 1].alt;
const altEnd = after?.getLatLngs()[0].alt ?? altStart;
altStart ?? (altStart = altEnd);
@ -562,7 +565,7 @@ BR.Routing = L.Routing.extend({
}
},
_updateBeelines: function () {
_updateBeelines() {
L.Routing.prototype._updateBeelines.call(this);
let serialBeelines = [];
@ -585,7 +588,7 @@ BR.Routing = L.Routing.extend({
}
},
createBeeline: function (latLng1, latLng2) {
createBeeline(latLng1, latLng2) {
const layer = L.Routing.prototype.createBeeline.call(this, latLng1, latLng2);
// remove alt from cloned LatLngs to show gap in elevation graph to indicate no data inbetween
delete layer.getLatLngs()[0].alt;

View file

@ -6,7 +6,7 @@ BR.RoutingPathQuality = L.Control.extend({
},
},
initialize: function (map, layersControl, options) {
initialize(map, layersControl, options) {
L.setOptions(this, options);
// hotline uses canvas and cannot be moved in front of the svg, so we create another pane
@ -35,9 +35,9 @@ BR.RoutingPathQuality = L.Control.extend({
1.0: '#ff0000', // red
},
outlineColor: 'dimgray',
renderer: renderer,
renderer,
},
valueFunction: function (latLng, prevLatLng) {
valueFunction(latLng, prevLatLng) {
var deltaAltitude = latLng.alt - prevLatLng.alt, // in m
distance = prevLatLng.distanceTo(latLng); // in m
if (distance === 0) {
@ -53,9 +53,9 @@ BR.RoutingPathQuality = L.Control.extend({
provider: new HotLineQualityProvider({
hotlineOptions: {
outlineColor: 'dimgray',
renderer: renderer,
renderer,
},
valueFunction: function (latLng) {
valueFunction(latLng) {
return latLng.alt;
},
}),
@ -65,7 +65,7 @@ BR.RoutingPathQuality = L.Control.extend({
icon: 'fa-road',
provider: new HotLineQualityProvider({
hotlineOptions: {
renderer: renderer,
renderer,
palette: {
// normal range
0.0: 'red',
@ -103,6 +103,7 @@ BR.RoutingPathQuality = L.Control.extend({
case 'concrete:lanes':
case 'concrete:plates':
surface = 0.6;
break;
case 'sett':
case 'gravel':
case 'pebblestone':
@ -228,9 +229,9 @@ BR.RoutingPathQuality = L.Control.extend({
// disables line simplification, so short segments won't disappear on some zoom levels
smoothFactor: 0,
outlineColor: 'dimgray',
renderer: renderer,
renderer,
},
valueFunction: function (latLng) {
valueFunction(latLng) {
var feature = latLng.feature;
var cost = feature.cost.perKm;
var distance = feature.distance / 1000; // in km
@ -251,7 +252,7 @@ BR.RoutingPathQuality = L.Control.extend({
this._muted = false;
},
onAdd: function (map) {
onAdd(map) {
this._map = map;
map.on(
@ -310,28 +311,28 @@ BR.RoutingPathQuality = L.Control.extend({
}
this.routingPathButton = new L.easyButton({
states: states,
states,
}).addTo(map);
return new L.DomUtil.create('div');
},
_activate: function (btn) {
_activate(btn) {
this._active = true;
this._getIcon(btn).classList.add('active');
this._routingSegments.addTo(this._map);
},
_deactivate: function (btn) {
_deactivate(btn) {
this._active = false;
this._getIcon(btn).classList.remove('active');
this._map.removeLayer(this._routingSegments);
},
_getIcon: function (btn) {
_getIcon(btn) {
return btn.button.firstChild.firstChild;
},
update: function (track, layer) {
update(track, layer) {
var segments = [];
layer.eachLayer(function (layer) {
segments.push(layer);
@ -340,12 +341,12 @@ BR.RoutingPathQuality = L.Control.extend({
this._update(this.segments);
},
setProvider: function (provider) {
setProvider(provider) {
this.selectedProvider = provider;
this._update(this.segments);
},
_update: function (segments) {
_update(segments) {
this._routingSegments.clearLayers();
var layers = this.providers[this.selectedProvider].provider.computeLayers(segments);
if (layers) {
@ -355,7 +356,7 @@ BR.RoutingPathQuality = L.Control.extend({
}
},
_keydownListener: function (e) {
_keydownListener(e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
@ -368,7 +369,7 @@ BR.RoutingPathQuality = L.Control.extend({
}
},
_keyupListener: function (e) {
_keyupListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && this._muted && e.keyCode === this.options.shortcut.muteKeyCode) {
this._muted = false;
this._activate(this.routingPathButton);
@ -377,12 +378,12 @@ BR.RoutingPathQuality = L.Control.extend({
});
var HotLineQualityProvider = L.Class.extend({
initialize: function (options) {
initialize(options) {
this.hotlineOptions = options.hotlineOptions;
this.valueFunction = options.valueFunction;
},
computeLayers: function (segments) {
computeLayers(segments) {
var layers = [];
if (segments) {
var segmentLatLngs = [];
@ -414,7 +415,7 @@ var HotLineQualityProvider = L.Class.extend({
return layers;
},
_computeLatLngVals: function (segment) {
_computeLatLngVals(segment) {
var latLngVals = [],
segmentLatLngs = segment.getLatLngs(),
segmentLength = segmentLatLngs.length;
@ -432,11 +433,11 @@ var HotLineQualityProvider = L.Class.extend({
return latLngVals;
},
_convertToArray: function (latLng, val) {
_convertToArray(latLng, val) {
return [latLng.lat, latLng.lng, val];
},
_calcMinMaxValues: function (lines, pct) {
_calcMinMaxValues(lines, pct) {
lines.sort(function (a, b) {
return a[2] - b[2];
});
@ -446,8 +447,8 @@ var HotLineQualityProvider = L.Class.extend({
max = min + 1;
}
return {
min: min,
max: max,
min,
max,
};
},
});

View file

@ -17,7 +17,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
listeningTabs: {},
},
initialize: function (id, options) {
initialize(id, options) {
L.Control.Sidebar.prototype.initialize.call(this, id, options);
this.oldTab = null;
@ -25,7 +25,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
},
addTo: function (map) {
addTo(map) {
L.Control.Sidebar.prototype.addTo.call(this, map);
this.on('content', this._notifyOnContent, this);
@ -59,14 +59,14 @@ BR.Sidebar = L.Control.Sidebar.extend({
return this;
},
showPanel: function (id) {
showPanel(id) {
var tab = this._getTab(id);
tab.hidden = false;
return this;
},
_rememberTabState: function () {
_rememberTabState() {
if (BR.Util.localStorageAvailable()) {
this.on('content closing', this._storeActiveTab, this);
@ -85,42 +85,42 @@ BR.Sidebar = L.Control.Sidebar.extend({
}
},
_notifyShow: function (tab) {
_notifyShow(tab) {
if (tab && tab.show) {
tab.show();
}
},
_notifyHide: function (tab) {
_notifyHide(tab) {
if (tab && tab.hide) {
tab.hide();
}
},
_notifyOnContent: function (e) {
_notifyOnContent(e) {
var tab = this.options.listeningTabs[e.id];
this._notifyHide(this.oldTab);
this._notifyShow(tab);
this.oldTab = tab;
},
_notifyOnClose: function (e) {
_notifyOnClose(e) {
this._notifyHide(this.oldTab);
this.oldTab = null;
},
_notifyOnResize: function (e) {
_notifyOnResize(e) {
var tab = this.oldTab;
if (tab && tab.onResize) {
tab.onResize();
}
},
_storeActiveTab: function (e) {
_storeActiveTab(e) {
localStorage.setItem(this.storageId, e.id || '');
},
_keydownListener: function (e) {
_keydownListener(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleTabs) {
if ($('#sidebarTabs > ul > li[class=active]').length) {
// sidebar is currently open, close current tab

View file

@ -19,7 +19,7 @@ BR.tracksLoader = function (map, layersControl, routing, pois) {
},
},
_initContainer: function () {
_initContainer() {
var thisLoader = this.loader;
var fileInput;
@ -60,7 +60,7 @@ BR.tracksLoader = function (map, layersControl, routing, pois) {
return dummy;
},
_keydownListener: function (e) {
_keydownListener(e) {
if (
BR.Util.keyboardShortcutsAllowed(e) &&
e.keyCode === this.options.shortcut.open &&

View file

@ -24,7 +24,7 @@
*/
L.DistanceMarkers = L.LayerGroup.extend({
initialize: function (line, map, options) {
initialize(line, map, options) {
options = options || {};
var offset = options.offset || 1000;
var showAll = Math.min(map.getMaxZoom(), options.showAll || 12);
@ -69,7 +69,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
// width as base number, one for padding + multiply by number of digits
var size = [iconSize[0] + iconSize[0] * ('' + text).length, iconSize[1]];
var icon = L.divIcon({ className: cssClass, html: text, iconSize: size });
var marker = L.marker(position.latLng, { title: text, icon: icon, interactive: false });
var marker = L.marker(position.latLng, { title: text, icon, interactive: false });
// visible only starting at a specific zoom level
var zoom = this._minimumZoomLevelForItem(i, showAll);
@ -106,7 +106,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
updateMarkerVisibility();
},
setOpacity: function (opacity) {
setOpacity(opacity) {
var i,
keys = Object.keys(this._zoomLayers),
l = keys.length;
@ -119,7 +119,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
}
},
_minimumZoomLevelForItem: function (item, showAllLevel) {
_minimumZoomLevelForItem(item, showAllLevel) {
var zoom = showAllLevel,
i = item;
while (i > 0 && i % 2 === 0) {

View file

@ -29,9 +29,9 @@
} else {
return {
center: new L.LatLng(lat, lon),
zoom: zoom,
layers: layers,
additional: additional,
zoom,
layers,
additional,
};
}
} else {
@ -65,7 +65,7 @@
parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash,
init: function (map, options) {
init(map, options) {
this.map = map;
L.Util.setOptions(this, options);
@ -78,7 +78,7 @@
}
},
_parseLayers: function (layersParam, layerSeparator) {
_parseLayers(layersParam, layerSeparator) {
var layers = layersParam.split(layerSeparator).map(
L.bind(function (layerEncoded) {
var obj = null;
@ -95,7 +95,7 @@
return layers;
},
parseLayers: function (layersParam) {
parseLayers(layersParam) {
var countFoundLayers = function (count, obj) {
if (obj) {
count++;
@ -119,7 +119,7 @@
return layers;
},
activateLayers: function (layers) {
activateLayers(layers) {
var layersControl = this.options.layersControl;
var added = false;
@ -147,7 +147,7 @@
}
},
formatLayers: function () {
formatLayers() {
var objList = this.options.layersControl.getActiveLayers();
// exclude vector layers (loaded tracks), but not when id set (route quality coding)
objList = objList.filter(function (obj) {
@ -162,7 +162,7 @@
return layerList.join(this.options.layerSeparator);
},
removeFrom: function (map) {
removeFrom(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
@ -174,7 +174,7 @@
this.map = null;
},
onMapMove: function () {
onMapMove() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
@ -190,7 +190,7 @@
},
movingMap: false,
update: function () {
update() {
var hash = location.hash;
if (hash === this.lastHash) {
return;
@ -226,7 +226,7 @@
// defer hash change updates every 100ms
changeDefer: 100,
changeTimeout: null,
onHashChange: function () {
onHashChange() {
// throttle calls to update() so that they only happen every
// `changeDefer` ms
if (!this.changeTimeout) {
@ -240,7 +240,7 @@
isListening: false,
hashChangeInterval: null,
startListening: function () {
startListening() {
this.map.on('moveend layeradd layerremove', this.onMapMove, this);
if (HAS_HASHCHANGE) {
@ -252,7 +252,7 @@
this.isListening = true;
},
stopListening: function () {
stopListening() {
this.map.off('moveend layeradd layerremove', this.onMapMove, this);
if (HAS_HASHCHANGE) {
@ -263,7 +263,7 @@
this.isListening = false;
},
_keyByValue: function (obj, value) {
_keyByValue(obj, value) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] === value) {

View file

@ -10,15 +10,16 @@ L.BRouter = L.Class.extend({
GROUP_SEPARATOR: '|',
ABORTED_ERROR: 'aborted',
CUSTOM_PREFIX: 'custom_',
SUPPORTED_BROUTER_VERSIONS: '< 1.7.0 || >=1.7.2', // compatibility string should be in npm package versioning format
isCustomProfile: function (profileName) {
SUPPORTED_BROUTER_VERSIONS: '< 1.7.0 || >=1.7.2',
// compatibility string should be in npm package versioning format
isCustomProfile(profileName) {
return profileName && profileName.substring(0, 7) === L.BRouter.CUSTOM_PREFIX;
},
},
options: {},
initialize: function (options) {
initialize(options) {
L.setOptions(this, options);
this.queue = async.queue(
@ -29,11 +30,11 @@ L.BRouter = L.Class.extend({
);
},
setOptions: function (options) {
setOptions(options) {
L.setOptions(this, options);
},
getUrlParams: function (latLngs, beelineFlags, pois, circlego, format) {
getUrlParams(latLngs, beelineFlags, pois, circlego, format) {
params = {};
if (this._getLonLatsString(latLngs) != null) params.lonlats = this._getLonLatsString(latLngs);
@ -75,7 +76,7 @@ L.BRouter = L.Class.extend({
return params;
},
parseUrlParams: function (params) {
parseUrlParams(params) {
var opts = {};
if (params.lonlats) {
opts.lonlats = this._parseLonLats(params.lonlats);
@ -116,7 +117,7 @@ L.BRouter = L.Class.extend({
return opts;
},
getUrl: function (latLngs, beelineFlags, pois, circlego, format, trackname, exportWaypoints) {
getUrl(latLngs, beelineFlags, pois, circlego, format, trackname, exportWaypoints) {
var urlParams = this.getUrlParams(latLngs, beelineFlags, pois, circlego, format);
var args = [];
if (urlParams.lonlats != null && urlParams.lonlats.length > 0)
@ -133,7 +134,7 @@ L.BRouter = L.Class.extend({
if (trackname)
args.push(
L.Util.template('trackname={trackname}', {
trackname: trackname,
trackname,
})
);
if (exportWaypoints) args.push('exportWaypoints=1');
@ -143,7 +144,7 @@ L.BRouter = L.Class.extend({
return (prepend_host ? BR.conf.host : '') + '/brouter?' + args.join('&');
},
getRoute: function (latLngs, cb) {
getRoute(latLngs, cb) {
var url = this.getUrl(latLngs, null, null, null, 'geojson'),
xhr = new XMLHttpRequest();
@ -164,14 +165,15 @@ L.BRouter = L.Class.extend({
xhr.send();
},
_handleRouteResponse: function (xhr, cb) {
_handleRouteResponse(xhr, cb) {
var layer, geojson;
if (
xhr.status === 200 &&
xhr.responseText &&
// application error when not GeoJSON format (text/plain for errors)
xhr.getResponseHeader('Content-Type').split(';')[0] === 'application/vnd.geo+json'
(xhr.getResponseHeader('Content-Type').split(';')[0] === 'application/geo+json' ||
xhr.getResponseHeader('Content-Type').split(';')[0] === 'application/vnd.geo+json')
) {
// leaflet.spin
//gpxLayer.fire('data:loaded');
@ -192,7 +194,7 @@ L.BRouter = L.Class.extend({
},
versionCheckDone: false,
checkBRouterVersion: function (creator) {
checkBRouterVersion(creator) {
if (this.versionCheckDone) {
return;
}
@ -216,11 +218,11 @@ L.BRouter = L.Class.extend({
}
},
getRouteSegment: function (l1, l2, cb) {
getRouteSegment(l1, l2, cb) {
this.queue.push({ segment: [l1, l2] }, cb);
},
uploadProfile: function (profileId, profileText, cb) {
uploadProfile(profileId, profileText, cb) {
var url = L.BRouter.URL_PROFILE_UPLOAD;
xhr = new XMLHttpRequest();
@ -240,7 +242,7 @@ L.BRouter = L.Class.extend({
xhr.send(profileText);
},
_assignFeatures: function (segment) {
_assignFeatures(segment) {
if (segment.feature.properties.messages) {
var featureMessages = segment.feature.properties.messages,
segmentLatLngs = segment.getLatLngs(),
@ -267,14 +269,14 @@ L.BRouter = L.Class.extend({
return segment;
},
_getFeatureLatLng: function (message) {
_getFeatureLatLng(message) {
var lon = message[0] / 1000000,
lat = message[1] / 1000000;
return L.latLng(lat, lon);
},
_handleProfileResponse: function (xhr, cb) {
_handleProfileResponse(xhr, cb) {
var response;
if (xhr.status === 200 && xhr.responseText && xhr.responseText.length > 0) {
@ -285,7 +287,7 @@ L.BRouter = L.Class.extend({
}
},
_getLonLatsString: function (latLngs) {
_getLonLatsString(latLngs) {
var s = '';
for (var i = 0; i < latLngs.length; i++) {
s += this._formatLatLng(latLngs[i]);
@ -296,7 +298,7 @@ L.BRouter = L.Class.extend({
return s;
},
_parseLonLats: function (s) {
_parseLonLats(s) {
var groups,
numbers,
lonlats = [];
@ -315,7 +317,7 @@ L.BRouter = L.Class.extend({
return lonlats;
},
_getBeelineString: function (beelineFlags) {
_getBeelineString(beelineFlags) {
var indexes = [];
for (var i = 0; i < beelineFlags.length; i++) {
if (beelineFlags[i]) {
@ -325,7 +327,7 @@ L.BRouter = L.Class.extend({
return indexes.join(',');
},
_parseBeelines: function (s, lonlats) {
_parseBeelines(s, lonlats) {
if (!lonlats || lonlats.length < 2) return [];
const beelineFlags = new Array(lonlats.length - 1);
@ -336,7 +338,7 @@ L.BRouter = L.Class.extend({
return beelineFlags;
},
_getLonLatsNameString: function (latLngNames) {
_getLonLatsNameString(latLngNames) {
var s = '';
for (var i = 0; i < latLngNames.length; i++) {
s += this._formatLatLng(latLngNames[i].latlng);
@ -350,7 +352,7 @@ L.BRouter = L.Class.extend({
return s;
},
_parseLonLatNames: function (s) {
_parseLonLatNames(s) {
var groups,
part,
lonlatnames = [];
@ -369,7 +371,7 @@ L.BRouter = L.Class.extend({
return lonlatnames;
},
_getNogosString: function (nogos) {
_getNogosString(nogos) {
var s = '';
for (var i = 0, circle; i < nogos.length; i++) {
circle = nogos[i];
@ -392,7 +394,7 @@ L.BRouter = L.Class.extend({
return s;
},
_parseNogos: function (s) {
_parseNogos(s) {
var groups,
numbers,
nogos = [];
@ -418,7 +420,7 @@ L.BRouter = L.Class.extend({
return nogos;
},
_getNogosPolylinesString: function (nogos) {
_getNogosPolylinesString(nogos) {
var s = '';
for (var i = 0, polyline, vertices; i < nogos.length; i++) {
polyline = nogos[i];
@ -445,7 +447,7 @@ L.BRouter = L.Class.extend({
return s;
},
_parseNogosPolylines: function (s) {
_parseNogosPolylines(s) {
var groups,
numbers,
latlngs,
@ -465,14 +467,14 @@ L.BRouter = L.Class.extend({
if (j < numbers.length) {
nogoWeight = Number.parseFloat(numbers[j++]);
}
var options = L.extend(BR.NogoAreas.prototype.polylineOptions, { nogoWeight: nogoWeight });
var options = L.extend(BR.NogoAreas.prototype.polylineOptions, { nogoWeight });
nogos.push(L.polyline(latlngs, options));
}
}
return nogos;
},
_getNogosPolygonsString: function (nogos) {
_getNogosPolygonsString(nogos) {
var s = '';
for (var i = 0, polygon, vertices; i < nogos.length; i++) {
polygon = nogos[i];
@ -499,7 +501,7 @@ L.BRouter = L.Class.extend({
return s;
},
_parseNogosPolygons: function (s) {
_parseNogosPolygons(s) {
var groups,
numbers,
latlngs,
@ -519,13 +521,13 @@ L.BRouter = L.Class.extend({
if (j < numbers.length) {
nogoWeight = Number.parseFloat(numbers[j++]);
}
nogos.push(L.polygon(latlngs, { nogoWeight: nogoWeight }));
nogos.push(L.polygon(latlngs, { nogoWeight }));
}
}
return nogos;
},
_parseProfile: function (profile) {
_parseProfile(profile) {
if (BR.conf.profilesRename?.[profile]) {
return BR.conf.profilesRename[profile];
}
@ -534,7 +536,7 @@ L.BRouter = L.Class.extend({
},
// formats L.LatLng object as lng,lat string
_formatLatLng: function (latLng) {
_formatLatLng(latLng) {
var s = '';
s += L.Util.formatNum(latLng.lng ?? latLng[1], L.BRouter.PRECISION);
s += L.BRouter.NUMBER_SEPARATOR;

View file

@ -24,6 +24,6 @@ var brouterCgi = (function () {
}
return {
getUrl: getUrl,
getUrl,
};
})();

View file

@ -15,16 +15,16 @@ BR.ClickTolerantBoxZoom = L.Map.BoxZoom.extend({
// already signals dragging to map and thus prevents click
_preMoved: false,
moved: function () {
moved() {
return this._preMoved || this._moved;
},
_resetState: function () {
_resetState() {
L.Map.BoxZoom.prototype._resetState.call(this);
this._preMoved = false;
},
_onMouseMove: function (e) {
_onMouseMove(e) {
if (!this._moved) {
const point = this._map.mouseEventToContainerPoint(e);
@ -44,7 +44,7 @@ BR.ClickTolerantBoxZoom = L.Map.BoxZoom.extend({
L.Map.BoxZoom.prototype._onMouseMove.call(this, e);
},
_onMouseUp: function (e) {
_onMouseUp(e) {
L.Map.BoxZoom.prototype._onMouseUp.call(this, e);
if (!this._moved && this._preMoved) {

View file

@ -33,11 +33,11 @@
* Only load Maplibre bundles when layer is actually added, using dynamic imports
*/
BR.MaplibreGlLazyLoader = L.Layer.extend({
initialize: function (options) {
initialize(options) {
this.options = options;
},
onAdd: function (map) {
onAdd(map) {
if (!('maplibreGL' in L)) {
this._load();
} else {
@ -46,7 +46,7 @@
return this;
},
onRemove: function (map) {
onRemove(map) {
if (this.glLayer) {
this._map.removeLayer(this.glLayer);
}
@ -55,12 +55,12 @@
},
// needed when overlay, also requires `position: absolute` (see css)
setZIndex: function (zIndex) {
setZIndex(zIndex) {
this.options.zIndex = zIndex;
return this;
},
setOpacity: function (opacity) {
setOpacity(opacity) {
if (this.glLayer) {
const glMap = this.glLayer.getMaplibreMap();
if (glMap.getLayer('hillshading')) {
@ -71,14 +71,14 @@
}
},
_load: async function () {
async _load() {
await importPolyfill('./maplibre-gl.js');
await importPolyfill('./leaflet-maplibre-gl.js');
this._addGlLayer();
},
_addGlLayer: function () {
_addGlLayer() {
this.glLayer = L.maplibreGL(this.options);
// see LayersConfig.createLayer
this.glLayer.getAttribution = function () {
@ -89,7 +89,7 @@
this._updateZIndex();
},
_updateZIndex: function () {
_updateZIndex() {
if (this.glLayer && this.glLayer.getContainer() && this.options.zIndex != null) {
this.glLayer.getContainer().style.zIndex = this.options.zIndex;
}

View file

@ -10,7 +10,7 @@ BR.Track = {
*
* @returns {Object} to pass as `options` parameter to `L.geoJson`
*/
getGeoJsonOptions: function (layersControl, filterPois = false) {
getGeoJsonOptions(layersControl, filterPois = false) {
// https://github.com/mapbox/simplestyle-spec/tree/master/1.1.0
const styleMapping = [
['stroke', 'color'],
@ -20,7 +20,7 @@ BR.Track = {
['fill-opacity', 'fillOpacity'],
];
return {
style: function (geoJsonFeature) {
style(geoJsonFeature) {
var currentLayerId = layersControl?.getActiveBaseLayer().layer.id;
const featureStyle = {
color: currentLayerId === 'cyclosm' ? 'yellow' : 'blue',
@ -34,14 +34,14 @@ BR.Track = {
return featureStyle;
},
interactive: false,
filter: function (geoJsonFeature) {
filter(geoJsonFeature) {
if (filterPois) {
// remove POIs, added separately, see `addPoiMarkers`
return !BR.Track.isPoiPoint(geoJsonFeature);
}
return true;
},
pointToLayer: function (geoJsonPoint, latlng) {
pointToLayer(geoJsonPoint, latlng) {
// route waypoint (type=from/via/to)
return L.marker(latlng, {
interactive: false,
@ -60,7 +60,7 @@ BR.Track = {
* @param {BR.PoiMarkers} pois POI control instance
* @param {Object} geoJson GeoJSON object
*/
addPoiMarkers: function (pois, geoJson) {
addPoiMarkers(pois, geoJson) {
turf.featureEach(geoJson, function (feature, idx) {
if (BR.Track.isPoiPoint(feature)) {
var coord = turf.getCoord(feature);
@ -80,7 +80,7 @@ BR.Track = {
*
* @param {Object} geoJsonPointFeature GeoJSON Point feature
*/
isRouteWaypoint: function (geoJsonPointFeature) {
isRouteWaypoint(geoJsonPointFeature) {
var props = geoJsonPointFeature.properties;
if (props && props.type) {
var wptType = props.type;
@ -96,7 +96,7 @@ BR.Track = {
*
* @param {Object} geoJsonFeature GeoJSON feature
*/
isPoiPoint: function (geoJsonFeature) {
isPoiPoint(geoJsonFeature) {
return turf.getType(geoJsonFeature) === 'Point' && !BR.Track.isRouteWaypoint(geoJsonFeature);
},
};

View file

@ -6,7 +6,7 @@
*/
BR.TrackEdges = L.Class.extend({
statics: {
getFeature: function (featureMessage) {
getFeature(featureMessage) {
//["Longitude", "Latitude", "Elevation", "Distance", "CostPerKm", "ElevCost", "TurnCost", "NodeCost", "InitialCost", "WayTags", "NodeTags"]
return {
cost: {
@ -35,7 +35,7 @@ BR.TrackEdges = L.Class.extend({
/**
* @param {Array} segments
*/
initialize: function (segments) {
initialize(segments) {
this.edges = this.getTrackEdges(segments);
},
@ -48,7 +48,7 @@ BR.TrackEdges = L.Class.extend({
*
* @return {number[]}
*/
getTrackEdges: function (segments) {
getTrackEdges(segments) {
var messages,
segLatLngs,
length,
@ -88,7 +88,7 @@ BR.TrackEdges = L.Class.extend({
return edges;
},
getMessageLatLng: function (message) {
getMessageLatLng(message) {
var lon = message[0] / 1000000,
lat = message[1] / 1000000;

View file

@ -146,6 +146,7 @@ BR.confLayers.tree = {
'parking_entrance',
'parking',
'parking_space',
'railway_station',
'taxi',
'vehicle_inspection',
]

View file

@ -0,0 +1,13 @@
{
"geometry": null,
"properties": {
"name": "Railway station",
"id": "railway_station",
"overlay": true,
"dataSource": "OverpassAPI",
"icon": "temaki-train",
"query": "nwr[railway=station];"
},
"type": "Feature"
}

View file

@ -285,10 +285,67 @@
},
"sidebar": {
"analysis": {
"data": {
"highway": {
"footway": "Footway",
"path": "Path",
"residential": "Residential",
"cycleway": "Cycleway",
"track": "Track",
"service": "Service",
"tertiary": "Tertiary",
"secondary": "Secondary",
"primary": "Primary",
"trunk": "Trunk",
"motorway": "Motorway",
"motorway_link": "Motorway Link",
"primary_link": "Primary Link",
"secondary_link": "Secondary Link",
"tertiary_link": "Tertiary Link",
"trunk_link": "Trunk Link",
"living_street": "Living Street",
"pedestrian": "Pedestrian",
"road": "Road",
"bridleway": "Bridleway",
"steps": "Steps",
"sidewalk": "Sidewalk",
"crossing": "Crossing",
"unclassified": "Unclassified"
},
"surface": {
"asphalt": "Asphalt",
"cobblestone": "Cobblestone",
"compacted": "Compacted",
"dirt": "Dirt",
"fine_gravel": "Fine Gravel",
"grass": "Grass",
"gravel": "Gravel",
"ground": "Ground",
"paved": "Paved",
"sand": "Sand",
"unpaved": "Unpaved",
"wood": "Wood",
"concrete": "Concrete",
"paving_stones": "Paving Stones",
"sett": "Sett"
},
"smoothness": {
"excellent": "Excellent",
"good": "Good",
"intermediate": "Intermediate",
"bad": "Bad",
"very_bad": "Very Bad",
"horrible": "Horrible",
"very_horrible": "Very Horrible",
"impassable": "Impassable"
},
"maxspeed": "{{maxspeed}} km/h"
},
"header": {
"highway": "Highway",
"smoothness": "Smoothness",
"surface": "Surface"
"surface": "Surface",
"maxspeed": "Maximum Speed"
},
"table": {
"category": "Category",

View file

@ -39,7 +39,7 @@
"@mapbox/maki": "8.0.1",
"@mapbox/polyline": "1.1.1",
"@mapbox/togeojson": "0.16.2",
"@maplibre/maplibre-gl-leaflet": "0.0.19",
"@maplibre/maplibre-gl-leaflet": "0.0.20",
"@turf/turf": "6.5.0",
"Leaflet.vector-markers": "nrenner/Leaflet.vector-markers#2ef80c9",
"abortcontroller-polyfill": "1.7.5",
@ -54,7 +54,7 @@
"datatables": "1.10.18",
"fit-file-writer": "tbsmark86/fit-file-writer#3eebe13",
"font-awesome": "4.7.0",
"geo-data-exchange": "alexcojocaru/geo-data-exchange#v2.0.0",
"geo-data-exchange": "alexcojocaru/geo-data-exchange#v2.2.0",
"i18next": "19.9.2",
"i18next-browser-languagedetector": "7.0.2",
"i18next-xhr-backend": "3.2.2",
@ -367,7 +367,8 @@
"icons/museum.svg",
"icons/spotting_scope.svg",
"icons/cabin.svg",
"icons/picnic_shelter.svg"
"icons/picnic_shelter.svg",
"icons/train.svg"
]
},
"@fortawesome/fontawesome-free": {

View file

@ -1397,10 +1397,10 @@
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe"
integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
"@maplibre/maplibre-gl-leaflet@0.0.19":
version "0.0.19"
resolved "https://registry.yarnpkg.com/@maplibre/maplibre-gl-leaflet/-/maplibre-gl-leaflet-0.0.19.tgz#adea2fe9890978c705f12a6274a6dc8b1467d02b"
integrity sha512-NwWqmE8Lmx8uMQS8sgHzGTz/CPfLBnbGns5BjXTmj459BUd7leCx3TVVhg04Pea4fzJeGaiyS2+KdWUVtKNuHg==
"@maplibre/maplibre-gl-leaflet@0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@maplibre/maplibre-gl-leaflet/-/maplibre-gl-leaflet-0.0.20.tgz#9b68bcb2226f300f3cf03865aa97647ca95f30ee"
integrity sha512-W36NFgRbhOic/Bv2dU4f6P3BE2QlhPbselQdf0snY4E36kjmhAl9RKEfAGDmfI1T5bUOmPmWzQDRnvEWqGc+jw==
"@mdn/browser-compat-data@^3.3.14":
version "3.3.14"
@ -5632,9 +5632,9 @@ gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
geo-data-exchange@alexcojocaru/geo-data-exchange#v2.0.0:
version "2.0.0"
resolved "https://codeload.github.com/alexcojocaru/geo-data-exchange/tar.gz/f3964028483ce194700f98c3d9c241818b54062b"
geo-data-exchange@alexcojocaru/geo-data-exchange#v2.2.0:
version "2.2.0"
resolved "https://codeload.github.com/alexcojocaru/geo-data-exchange/tar.gz/d6d517dee5e07e32ef948eecd7a151479a6d7938"
dependencies:
leaflet "^1.5.0"