Add prettier and reformat code
This commit is contained in:
parent
68eb00bae9
commit
970a34981f
37 changed files with 3459 additions and 1969 deletions
|
|
@ -1,18 +1,22 @@
|
|||
(function () {
|
||||
|
||||
var touchScreen = (function () {
|
||||
(function() {
|
||||
var touchScreen = (function() {
|
||||
var result = null;
|
||||
|
||||
|
||||
if ('maxTouchPoints' in navigator) {
|
||||
result = navigator.maxTouchPoints > 0;
|
||||
} else if (window.matchMedia && window.matchMedia('(any-pointer:coarse),(any-pointer:fine),(any-pointer:none)').matches) {
|
||||
result = window.matchMedia("(any-pointer:coarse)").matches;
|
||||
} else if (
|
||||
window.matchMedia &&
|
||||
window.matchMedia(
|
||||
'(any-pointer:coarse),(any-pointer:fine),(any-pointer:none)'
|
||||
).matches
|
||||
) {
|
||||
result = window.matchMedia('(any-pointer:coarse)').matches;
|
||||
} else if ('msMaxTouchPoints' in navigator) {
|
||||
result = navigator.msMaxTouchPoints > 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}()),
|
||||
})(),
|
||||
touchScreenDetectable = touchScreen !== null,
|
||||
touch = touchScreenDetectable ? touchScreen : L.Browser.touch;
|
||||
|
||||
|
|
@ -21,5 +25,4 @@
|
|||
touchScreenDetectable: touchScreenDetectable,
|
||||
touch: touch
|
||||
};
|
||||
|
||||
}());
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ BR.LayersConfig = L.Class.extend({
|
|||
defaultOverlays: BR.confLayers.defaultOverlays,
|
||||
legacyNameToIdMap: BR.confLayers.legacyNameToIdMap,
|
||||
|
||||
initialize: function (map) {
|
||||
initialize: function(map) {
|
||||
this._map = map;
|
||||
|
||||
this._addLeafletProvidersLayers();
|
||||
|
|
@ -13,7 +13,7 @@ BR.LayersConfig = L.Class.extend({
|
|||
|
||||
loadDefaultLayers: function() {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
var item = localStorage.getItem("map/defaultLayers");
|
||||
var item = localStorage.getItem('map/defaultLayers');
|
||||
if (item) {
|
||||
var defaultLayers = JSON.parse(item);
|
||||
this.defaultBaseLayers = defaultLayers.baseLayers;
|
||||
|
|
@ -22,17 +22,20 @@ BR.LayersConfig = L.Class.extend({
|
|||
}
|
||||
},
|
||||
|
||||
storeDefaultLayers: function (baseLayers, overlays) {
|
||||
storeDefaultLayers: function(baseLayers, overlays) {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
var defaultLayers = {
|
||||
baseLayers: baseLayers,
|
||||
overlays: overlays
|
||||
};
|
||||
localStorage.setItem("map/defaultLayers", JSON.stringify(defaultLayers));
|
||||
localStorage.setItem(
|
||||
'map/defaultLayers',
|
||||
JSON.stringify(defaultLayers)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_addLeafletProvidersLayers: function () {
|
||||
_addLeafletProvidersLayers: function() {
|
||||
var includeList = BR.confLayers.leafletProvidersIncludeList;
|
||||
|
||||
for (var i = 0; i < includeList.length; i++) {
|
||||
|
|
@ -44,13 +47,13 @@ BR.LayersConfig = L.Class.extend({
|
|||
name: id.replace('.', ' '),
|
||||
dataSource: 'leaflet-providers'
|
||||
},
|
||||
type: "Feature"
|
||||
type: 'Feature'
|
||||
};
|
||||
BR.layerIndex[id] = obj;
|
||||
}
|
||||
},
|
||||
|
||||
_customizeLayers: function () {
|
||||
_customizeLayers: function() {
|
||||
var propertyOverrides = BR.confLayers.getPropertyOverrides();
|
||||
|
||||
for (id in propertyOverrides) {
|
||||
|
|
@ -68,10 +71,11 @@ BR.LayersConfig = L.Class.extend({
|
|||
}
|
||||
}
|
||||
|
||||
BR.layerIndex['MtbMap'].geometry = BR.confLayers.europeGeofabrik;
|
||||
BR.layerIndex['1069'].geometry = BR.confLayers.europeGeofabrik;
|
||||
BR.layerIndex['MtbMap'].geometry = BR.confLayers.europeGeofabrik;
|
||||
BR.layerIndex['1069'].geometry = BR.confLayers.europeGeofabrik;
|
||||
|
||||
BR.layerIndex['OpenStreetMap.CH'].geometry = BR.confLayers.switzerlandPadded;
|
||||
BR.layerIndex['OpenStreetMap.CH'].geometry =
|
||||
BR.confLayers.switzerlandPadded;
|
||||
},
|
||||
|
||||
isDefaultLayer: function(id, overlay) {
|
||||
|
|
@ -111,7 +115,7 @@ BR.LayersConfig = L.Class.extend({
|
|||
|
||||
// own convention: key placeholder with prefix
|
||||
// e.g. ?api_key={keys_openrouteservice}
|
||||
getKeyName: function (url) {
|
||||
getKeyName: function(url) {
|
||||
var result = null;
|
||||
// L.Util.template only matches [\w_-]
|
||||
var prefix = 'keys_';
|
||||
|
|
@ -132,7 +136,7 @@ BR.LayersConfig = L.Class.extend({
|
|||
return result;
|
||||
},
|
||||
|
||||
createLayer: function (layerData) {
|
||||
createLayer: function(layerData) {
|
||||
var props = layerData.properties;
|
||||
var url = props.url;
|
||||
var layer;
|
||||
|
|
@ -167,7 +171,12 @@ BR.LayersConfig = L.Class.extend({
|
|||
if (attr.html) {
|
||||
result = attr.html;
|
||||
} else if (attr.url && attr.text) {
|
||||
result = '<a href="' + attr.url + '" target="_blank" rel="noopener">' + attr.text + '</a>';
|
||||
result =
|
||||
'<a href="' +
|
||||
attr.url +
|
||||
'" target="_blank" rel="noopener">' +
|
||||
attr.text +
|
||||
'</a>';
|
||||
} else if (attr.text) {
|
||||
result = attr.text;
|
||||
}
|
||||
|
|
@ -179,13 +188,20 @@ BR.LayersConfig = L.Class.extend({
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
var options = {
|
||||
maxZoom: this._map.getMaxZoom(),
|
||||
bounds: layerData.geometry && !props.worldTiles ? L.geoJson(layerData.geometry).getBounds() : null
|
||||
bounds:
|
||||
layerData.geometry && !props.worldTiles
|
||||
? L.geoJson(layerData.geometry).getBounds()
|
||||
: null
|
||||
};
|
||||
if (props.mapUrl) {
|
||||
options.mapLink = '<a target="_blank" href="' + props.mapUrl + '">' + (props.nameShort || props.name) + '</a>';
|
||||
options.mapLink =
|
||||
'<a target="_blank" href="' +
|
||||
props.mapUrl +
|
||||
'">' +
|
||||
(props.nameShort || props.name) +
|
||||
'</a>';
|
||||
}
|
||||
if (props.attribution) {
|
||||
options.attribution = props.attribution;
|
||||
|
|
@ -200,15 +216,17 @@ BR.LayersConfig = L.Class.extend({
|
|||
layer = L.tileLayer.provider(props.id);
|
||||
|
||||
var layerOptions = L.Util.extend(options, {
|
||||
maxNativeZoom: layer.options.maxZoom,
|
||||
maxNativeZoom: layer.options.maxZoom
|
||||
});
|
||||
L.setOptions(layer, layerOptions);
|
||||
|
||||
} else if (props.dataSource === 'LayersCollection') {
|
||||
layer = L.tileLayer(url, L.Util.extend(options, {
|
||||
minZoom: props.minZoom || 0,
|
||||
maxNativeZoom: props.maxZoom
|
||||
}));
|
||||
layer = L.tileLayer(
|
||||
url,
|
||||
L.Util.extend(options, {
|
||||
minZoom: props.minZoom || 0,
|
||||
maxNativeZoom: props.maxZoom
|
||||
})
|
||||
);
|
||||
if (props.subdomains) {
|
||||
layer.subdomains = props.subdomains;
|
||||
}
|
||||
|
|
@ -225,10 +243,13 @@ BR.LayersConfig = L.Class.extend({
|
|||
});
|
||||
|
||||
if (props.type && props.type === 'wms') {
|
||||
layer = L.tileLayer.wms(url, L.Util.extend(josmOptions, {
|
||||
layers: props.layers,
|
||||
format: props.format
|
||||
}));
|
||||
layer = L.tileLayer.wms(
|
||||
url,
|
||||
L.Util.extend(josmOptions, {
|
||||
layers: props.layers,
|
||||
format: props.format
|
||||
})
|
||||
);
|
||||
} else {
|
||||
layer = L.tileLayer(url, josmOptions);
|
||||
}
|
||||
|
|
@ -237,9 +258,9 @@ BR.LayersConfig = L.Class.extend({
|
|||
// Layer attribution here only as short link to original site,
|
||||
// to keep current position use placeholders: {zoom}/{lat}/{lon}
|
||||
// Copyright attribution in index.html #credits
|
||||
var getAttribution = function () {
|
||||
var getAttribution = function() {
|
||||
return this.options.mapLink;
|
||||
}
|
||||
};
|
||||
layer.getAttribution = getAttribution;
|
||||
|
||||
layer.id = props.id;
|
||||
|
|
@ -248,6 +269,6 @@ BR.LayersConfig = L.Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
BR.layersConfig = function (map) {
|
||||
return new BR.LayersConfig(map);
|
||||
BR.layersConfig = function(map) {
|
||||
return new BR.LayersConfig(map);
|
||||
};
|
||||
|
|
|
|||
80
js/Map.js
80
js/Map.js
|
|
@ -1,8 +1,6 @@
|
|||
BR.Map = {
|
||||
|
||||
initMap: function() {
|
||||
var map,
|
||||
layersControl;
|
||||
var map, layersControl;
|
||||
|
||||
BR.keys = BR.keys || {};
|
||||
|
||||
|
|
@ -14,23 +12,35 @@ BR.Map = {
|
|||
minZoom: 0,
|
||||
maxZoom: maxZoom
|
||||
});
|
||||
L.control.zoom({
|
||||
zoomInTitle: i18next.t('map.zoomInTitle'),
|
||||
zoomOutTitle: i18next.t('map.zoomOutTitle'),
|
||||
}).addTo(map);
|
||||
L.control
|
||||
.zoom({
|
||||
zoomInTitle: i18next.t('map.zoomInTitle'),
|
||||
zoomOutTitle: i18next.t('map.zoomOutTitle')
|
||||
})
|
||||
.addTo(map);
|
||||
if (!map.restoreView()) {
|
||||
map.setView([50.99, 9.86], 6);
|
||||
}
|
||||
|
||||
// two attribution lines by adding two controls, prevents ugly wrapping on
|
||||
// small screens, better separates static from layer-specific attribution
|
||||
var osmAttribution = $(map.getContainer()).outerWidth() >= 400 ? i18next.t('map.attribution-osm-long') : i18next.t('map.attribution-osm-short');
|
||||
var osmAttribution =
|
||||
$(map.getContainer()).outerWidth() >= 400
|
||||
? i18next.t('map.attribution-osm-long')
|
||||
: i18next.t('map.attribution-osm-short');
|
||||
map.attributionControl.setPrefix(
|
||||
'© <a target="_blank" href="https://www.openstreetmap.org/copyright">' + osmAttribution + '</a>' +
|
||||
' · <a href="" data-toggle="modal" data-target="#credits">' + i18next.t('map.copyright') + '</a>' +
|
||||
' · <a target="_blank" href="http://brouter.de/privacypolicy.html">' + i18next.t('map.privacy') + '</a>');
|
||||
'© <a target="_blank" href="https://www.openstreetmap.org/copyright">' +
|
||||
osmAttribution +
|
||||
'</a>' +
|
||||
' · <a href="" data-toggle="modal" data-target="#credits">' +
|
||||
i18next.t('map.copyright') +
|
||||
'</a>' +
|
||||
' · <a target="_blank" href="http://brouter.de/privacypolicy.html">' +
|
||||
i18next.t('map.privacy') +
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$('#credits').on('show.bs.modal', function (event) {
|
||||
$('#credits').on('show.bs.modal', function(event) {
|
||||
BR.Map._renderLayerCredits(layersControl._layers);
|
||||
});
|
||||
|
||||
|
|
@ -42,15 +52,22 @@ BR.Map = {
|
|||
var overlays = layersConfig.getOverlays();
|
||||
|
||||
if (BR.keys.bing) {
|
||||
baseLayers[i18next.t('map.layer.bing')] = new BR.BingLayer(BR.keys.bing);
|
||||
baseLayers[i18next.t('map.layer.bing')] = new BR.BingLayer(
|
||||
BR.keys.bing
|
||||
);
|
||||
}
|
||||
|
||||
if (BR.keys.digitalGlobe) {
|
||||
var recent = new L.tileLayer('https://{s}.tiles.mapbox.com/v4/digitalglobe.nal0g75k/{z}/{x}/{y}.png?access_token=' + BR.keys.digitalGlobe, {
|
||||
minZoom: 1,
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href=\"https://www.digitalglobe.com/platforms/mapsapi\">DigitalGlobe</a> (<a href=\"https://bit.ly/mapsapiview\">Terms of Use</a>)'
|
||||
});
|
||||
var recent = new L.tileLayer(
|
||||
'https://{s}.tiles.mapbox.com/v4/digitalglobe.nal0g75k/{z}/{x}/{y}.png?access_token=' +
|
||||
BR.keys.digitalGlobe,
|
||||
{
|
||||
minZoom: 1,
|
||||
maxZoom: 19,
|
||||
attribution:
|
||||
'© <a href="https://www.digitalglobe.com/platforms/mapsapi">DigitalGlobe</a> (<a href="https://bit.ly/mapsapiview">Terms of Use</a>)'
|
||||
}
|
||||
);
|
||||
baseLayers[i18next.t('map.layer.digitalglobe')] = recent;
|
||||
}
|
||||
|
||||
|
|
@ -69,17 +86,24 @@ BR.Map = {
|
|||
}
|
||||
}
|
||||
|
||||
layersControl = BR.layersTab(layersConfig, baseLayers, overlays).addTo(map);
|
||||
layersControl = BR.layersTab(layersConfig, baseLayers, overlays).addTo(
|
||||
map
|
||||
);
|
||||
|
||||
var secureContext = 'isSecureContext' in window ? isSecureContext : location.protocol === 'https:';
|
||||
var secureContext =
|
||||
'isSecureContext' in window
|
||||
? isSecureContext
|
||||
: location.protocol === 'https:';
|
||||
if (secureContext) {
|
||||
L.control.locate({
|
||||
strings: {
|
||||
title: i18next.t('map.locate-me')
|
||||
},
|
||||
icon: 'fa fa-location-arrow',
|
||||
iconLoading: 'fa fa-spinner fa-pulse',
|
||||
}).addTo(map);
|
||||
L.control
|
||||
.locate({
|
||||
strings: {
|
||||
title: i18next.t('map.locate-me')
|
||||
},
|
||||
icon: 'fa fa-location-arrow',
|
||||
iconLoading: 'fa fa-spinner fa-pulse'
|
||||
})
|
||||
.addTo(map);
|
||||
}
|
||||
|
||||
L.control.scale().addTo(map);
|
||||
|
|
@ -96,7 +120,7 @@ BR.Map = {
|
|||
};
|
||||
},
|
||||
|
||||
_renderLayerCredits: function (layers) {
|
||||
_renderLayerCredits: function(layers) {
|
||||
var dl = document.getElementById('credits-maps');
|
||||
var i, obj, dt, dd, attribution;
|
||||
|
||||
|
|
|
|||
12
js/Util.js
12
js/Util.js
|
|
@ -1,5 +1,4 @@
|
|||
BR.Util = {
|
||||
|
||||
get: function(url, cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
|
|
@ -16,7 +15,7 @@ BR.Util = {
|
|||
};
|
||||
try {
|
||||
xhr.send();
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
},
|
||||
|
|
@ -24,9 +23,9 @@ BR.Util = {
|
|||
getError: function(xhr) {
|
||||
var msg = i18next.t('warning.no-response');
|
||||
if (xhr.responseText) {
|
||||
msg = xhr.responseText;
|
||||
msg = xhr.responseText;
|
||||
} else if (xhr.status || xhr.statusText) {
|
||||
msg = xhr.status + ': ' + xhr.statusText;
|
||||
msg = xhr.status + ': ' + xhr.statusText;
|
||||
}
|
||||
return new Error(msg);
|
||||
},
|
||||
|
|
@ -46,9 +45,8 @@ BR.Util = {
|
|||
storage.setItem(x, x);
|
||||
storage.removeItem(x);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
BR.ControlLayers = L.Control.Layers.extend({
|
||||
|
||||
getActiveLayers: function () {
|
||||
getActiveLayers: function() {
|
||||
var result = [];
|
||||
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
var obj = this._layers[i];
|
||||
if (this._map.hasLayer(obj.layer)) {
|
||||
if (obj.overlay) {
|
||||
|
|
@ -17,7 +16,7 @@ BR.ControlLayers = L.Control.Layers.extend({
|
|||
return result;
|
||||
},
|
||||
|
||||
getActiveBaseLayer: function () {
|
||||
getActiveBaseLayer: function() {
|
||||
var activeLayers = this.getActiveLayers();
|
||||
for (var i = 0; i < activeLayers.length; i++) {
|
||||
var obj = activeLayers[i];
|
||||
|
|
@ -29,10 +28,10 @@ BR.ControlLayers = L.Control.Layers.extend({
|
|||
return null;
|
||||
},
|
||||
|
||||
removeActiveLayers: function () {
|
||||
removeActiveLayers: function() {
|
||||
var removed = [];
|
||||
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
var obj = this._layers[i];
|
||||
if (this._map.hasLayer(obj.layer)) {
|
||||
this._map.removeLayer(obj.layer);
|
||||
|
|
@ -43,7 +42,7 @@ BR.ControlLayers = L.Control.Layers.extend({
|
|||
return removed;
|
||||
},
|
||||
|
||||
getLayer: function (name) {
|
||||
getLayer: function(name) {
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
var obj = this._layers[i];
|
||||
if (obj.name === name) {
|
||||
|
|
@ -54,17 +53,17 @@ BR.ControlLayers = L.Control.Layers.extend({
|
|||
return null;
|
||||
},
|
||||
|
||||
getBaseLayers: function () {
|
||||
return this._layers.filter(function (obj) {
|
||||
getBaseLayers: function() {
|
||||
return this._layers.filter(function(obj) {
|
||||
return !obj.overlay;
|
||||
});
|
||||
},
|
||||
|
||||
activateLayer: function (layer) {
|
||||
activateLayer: function(layer) {
|
||||
this._map.addLayer(layer);
|
||||
},
|
||||
|
||||
activateFirstLayer: function () {
|
||||
activateFirstLayer: function() {
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
var obj = this._layers[i];
|
||||
if (!obj.overlay) {
|
||||
|
|
@ -74,26 +73,25 @@ BR.ControlLayers = L.Control.Layers.extend({
|
|||
}
|
||||
},
|
||||
|
||||
activateBaseLayerIndex: function (index) {
|
||||
activateBaseLayerIndex: function(index) {
|
||||
var baseLayers = this.getBaseLayers();
|
||||
var obj = baseLayers[index];
|
||||
|
||||
this.activateLayer(obj.layer);
|
||||
},
|
||||
|
||||
_addLayer: function (layer, name, overlay) {
|
||||
_addLayer: function(layer, name, overlay) {
|
||||
L.Control.Layers.prototype._addLayer.call(this, layer, name, overlay);
|
||||
|
||||
// override z-index assignment to fix that base layers added later
|
||||
// are on top of overlays; set all base layers to 0
|
||||
if (this.options.autoZIndex && layer.setZIndex) {
|
||||
if (this.options.autoZIndex && layer.setZIndex) {
|
||||
if (!overlay) {
|
||||
// undo increase in super method
|
||||
this._lastZIndex--;
|
||||
|
||||
layer.setZIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
BR.Download = L.Class.extend({
|
||||
update: function (urls) {
|
||||
update: function(urls) {
|
||||
if (urls) {
|
||||
['gpx', 'kml', 'geojson', 'csv'].forEach(function(e, i, a) {
|
||||
var a = L.DomUtil.get('dl-'+e);
|
||||
var a = L.DomUtil.get('dl-' + e);
|
||||
a.setAttribute('href', urls[e]);
|
||||
a.setAttribute('download', 'brouter.'+e);
|
||||
a.setAttribute('download', 'brouter.' + e);
|
||||
a.removeAttribute('disabled');
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
BR.Itinerary = L.Class.extend({
|
||||
|
||||
initialize: function () {
|
||||
initialize: function() {
|
||||
this._content = document.getElementById('itinerary');
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function (polyline, segments) {
|
||||
var i, j, iter, html = '';
|
||||
update: function(polyline, segments) {
|
||||
var i,
|
||||
j,
|
||||
iter,
|
||||
html = '';
|
||||
|
||||
html += '<pre class="flexgrow">';
|
||||
for (i = 0; segments && i < segments.length; i++)
|
||||
{
|
||||
for (i = 0; segments && i < segments.length; i++) {
|
||||
iter = segments[i].feature.iternity;
|
||||
for (j = 0; iter && j < iter.length; j++)
|
||||
{
|
||||
html += iter[j] + '\n';
|
||||
for (j = 0; iter && j < iter.length; j++) {
|
||||
html += iter[j] + '\n';
|
||||
}
|
||||
}
|
||||
html += '</pre>';
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
BR.Layers = L.Class.extend({
|
||||
|
||||
_loadLayers: function() {
|
||||
this._customLayers = {};
|
||||
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
var layers = JSON.parse(localStorage.getItem("map/customLayers"));
|
||||
var layers = JSON.parse(localStorage.getItem('map/customLayers'));
|
||||
for (a in layers) {
|
||||
this._addLayer(a, layers[a].layer, layers[a].isOverlay);
|
||||
}
|
||||
|
|
@ -14,24 +13,28 @@ BR.Layers = L.Class.extend({
|
|||
_loadTable: function() {
|
||||
var layersData = [];
|
||||
for (layer in this._customLayers) {
|
||||
layersData.push([layer, this._customLayers[layer].layer._url, this._customLayers[layer].isOverlay ? "Overlay" : "Layer"]);
|
||||
layersData.push([
|
||||
layer,
|
||||
this._customLayers[layer].layer._url,
|
||||
this._customLayers[layer].isOverlay ? 'Overlay' : 'Layer'
|
||||
]);
|
||||
}
|
||||
if (this._layersTable != null) {
|
||||
this._layersTable.destroy();
|
||||
}
|
||||
|
||||
this._layersTable = $('#custom_layers_table').DataTable({
|
||||
this._layersTable = $('#custom_layers_table').DataTable({
|
||||
data: layersData,
|
||||
info: false,
|
||||
searching: false,
|
||||
paging: false,
|
||||
language: {
|
||||
emptyTable: i18next.t("sidebar.layers.table.empty")
|
||||
emptyTable: i18next.t('sidebar.layers.table.empty')
|
||||
},
|
||||
columns: [
|
||||
{ title: i18next.t("sidebar.layers.table.name") },
|
||||
{ title: i18next.t("sidebar.layers.table.URL") },
|
||||
{ title: i18next.t("sidebar.layers.table.type") }
|
||||
{ title: i18next.t('sidebar.layers.table.name') },
|
||||
{ title: i18next.t('sidebar.layers.table.URL') },
|
||||
{ title: i18next.t('sidebar.layers.table.type') }
|
||||
]
|
||||
});
|
||||
},
|
||||
|
|
@ -39,22 +42,29 @@ BR.Layers = L.Class.extend({
|
|||
init: function(map, layersControl, baseLayers, overlays) {
|
||||
this._layersControl = layersControl;
|
||||
this._map = map;
|
||||
this._layers = {}
|
||||
for (var l in overlays)
|
||||
this._layers[l] = [overlays[l], true];
|
||||
for (var l in baseLayers)
|
||||
this._layers[l] = [baseLayers[l], false];
|
||||
this._layers = {};
|
||||
for (var l in overlays) this._layers[l] = [overlays[l], true];
|
||||
for (var l in baseLayers) this._layers[l] = [baseLayers[l], false];
|
||||
|
||||
L.DomUtil.get('custom_layers_add_base').onclick = L.bind(this._addBaseLayer, this);
|
||||
L.DomUtil.get('custom_layers_add_overlay').onclick = L.bind(this._addOverlay, this);
|
||||
L.DomUtil.get('custom_layers_remove').onclick = L.bind(this._remove, this);
|
||||
L.DomUtil.get('custom_layers_add_base').onclick = L.bind(
|
||||
this._addBaseLayer,
|
||||
this
|
||||
);
|
||||
L.DomUtil.get('custom_layers_add_overlay').onclick = L.bind(
|
||||
this._addOverlay,
|
||||
this
|
||||
);
|
||||
L.DomUtil.get('custom_layers_remove').onclick = L.bind(
|
||||
this._remove,
|
||||
this
|
||||
);
|
||||
|
||||
this._loadLayers();
|
||||
this._loadTable();
|
||||
|
||||
var table = this._layersTable;
|
||||
$('#custom_layers_table tbody').on( 'click', 'tr', function () {
|
||||
if ( $(this).hasClass('selected') ) {
|
||||
$('#custom_layers_table tbody').on('click', 'tr', function() {
|
||||
if ($(this).hasClass('selected')) {
|
||||
$(this).removeClass('selected');
|
||||
} else {
|
||||
table.$('tr.selected').removeClass('selected');
|
||||
|
|
@ -62,7 +72,7 @@ BR.Layers = L.Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
L.DomUtil.get('custom_layers_button').onclick = function () {
|
||||
L.DomUtil.get('custom_layers_button').onclick = function() {
|
||||
$('#custom_layers').modal();
|
||||
};
|
||||
},
|
||||
|
|
@ -74,7 +84,10 @@ BR.Layers = L.Class.extend({
|
|||
this._layersControl.removeLayer(this._customLayers[name].layer);
|
||||
this._map.removeLayer(this._customLayers[name].layer);
|
||||
delete this._customLayers[name];
|
||||
this._layersTable.row('.selected').remove().draw( false );
|
||||
this._layersTable
|
||||
.row('.selected')
|
||||
.remove()
|
||||
.draw(false);
|
||||
this._sync();
|
||||
}
|
||||
},
|
||||
|
|
@ -94,16 +107,17 @@ BR.Layers = L.Class.extend({
|
|||
},
|
||||
|
||||
_addLayer: function(layerName, layerUrl, isOverlay) {
|
||||
if (layerName in this._layers)
|
||||
return
|
||||
if (layerName in this._layers) return;
|
||||
|
||||
if (layerName in this._customLayers)
|
||||
return
|
||||
if (layerName in this._customLayers) return;
|
||||
|
||||
try {
|
||||
var layer = L.tileLayer(layerUrl);
|
||||
|
||||
this._customLayers[layerName] = {layer: layer, isOverlay: isOverlay};
|
||||
this._customLayers[layerName] = {
|
||||
layer: layer,
|
||||
isOverlay: isOverlay
|
||||
};
|
||||
|
||||
if (isOverlay) {
|
||||
this._layersControl.addOverlay(layer, layerName);
|
||||
|
|
@ -114,17 +128,20 @@ BR.Layers = L.Class.extend({
|
|||
this._sync();
|
||||
return layer;
|
||||
} catch (e) {
|
||||
console.warn("Oops:", e);
|
||||
return
|
||||
console.warn('Oops:', e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
localStorage.setItem("map/customLayers", JSON.stringify(this._customLayers, function(k, v) {
|
||||
// dont write Leaflet.Layer in localStorage; simply keep the URL
|
||||
return v._url || v;
|
||||
}));
|
||||
localStorage.setItem(
|
||||
'map/customLayers',
|
||||
JSON.stringify(this._customLayers, function(k, v) {
|
||||
// dont write Leaflet.Layer in localStorage; simply keep the URL
|
||||
return v._url || v;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,13 +3,18 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
previewBounds: null,
|
||||
saveLayers: [],
|
||||
|
||||
initialize: function (layersConfig, baseLayers, overlays, options) {
|
||||
L.Control.Layers.prototype.initialize.call(this, baseLayers, overlays, options);
|
||||
initialize: function(layersConfig, baseLayers, overlays, options) {
|
||||
L.Control.Layers.prototype.initialize.call(
|
||||
this,
|
||||
baseLayers,
|
||||
overlays,
|
||||
options
|
||||
);
|
||||
|
||||
this.layersConfig = layersConfig;
|
||||
},
|
||||
|
||||
addTo: function (map) {
|
||||
addTo: function(map) {
|
||||
this._map = map;
|
||||
this.onAdd(map);
|
||||
|
||||
|
|
@ -21,15 +26,15 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return this;
|
||||
},
|
||||
|
||||
initButtons: function () {
|
||||
var expandTree = function (e) {
|
||||
initButtons: function() {
|
||||
var expandTree = function(e) {
|
||||
this.jstree.open_all();
|
||||
};
|
||||
var collapseTree = function (e) {
|
||||
var collapseTree = function(e) {
|
||||
this.jstree.close_all();
|
||||
};
|
||||
|
||||
var toggleOptionalLayers = function (e) {
|
||||
var toggleOptionalLayers = function(e) {
|
||||
var button = L.DomUtil.get('optional_layers_button');
|
||||
var treeButtons = L.DomUtil.get('tree-button-group');
|
||||
var div = L.DomUtil.get('optional-layers-tree');
|
||||
|
|
@ -44,17 +49,23 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
};
|
||||
|
||||
L.DomUtil.get('expand_tree_button').onclick = L.bind(expandTree, this);
|
||||
L.DomUtil.get('collapse_tree_button').onclick = L.bind(collapseTree, this);
|
||||
L.DomUtil.get('collapse_tree_button').onclick = L.bind(
|
||||
collapseTree,
|
||||
this
|
||||
);
|
||||
|
||||
L.DomUtil.get('optional_layers_button').onclick = L.bind(toggleOptionalLayers, this);
|
||||
L.DomUtil.get('optional_layers_button').onclick = L.bind(
|
||||
toggleOptionalLayers,
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
initJsTree: function () {
|
||||
initJsTree: function() {
|
||||
var layerIndex = BR.layerIndex;
|
||||
var treeData = this.toJsTree(BR.confLayers.tree);
|
||||
var oldSelected = null;
|
||||
|
||||
var onSelectNode = function (e, data) {
|
||||
var onSelectNode = function(e, data) {
|
||||
var layerData = layerIndex[data.node.id];
|
||||
var selected = data.selected[0];
|
||||
|
||||
|
|
@ -66,12 +77,12 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
}
|
||||
};
|
||||
|
||||
var onDeselectNode = function (e, data) {
|
||||
var onDeselectNode = function(e, data) {
|
||||
this.hidePreview();
|
||||
oldSelected = null;
|
||||
};
|
||||
|
||||
var onCheckNode = function (e, data) {
|
||||
var onCheckNode = function(e, data) {
|
||||
var layerData = layerIndex[data.node.id];
|
||||
var layer = this.createLayer(layerData);
|
||||
var name = layerData.properties.name;
|
||||
|
|
@ -86,7 +97,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
this.storeDefaultLayers();
|
||||
};
|
||||
|
||||
var onUncheckNode = function (e, data) {
|
||||
var onUncheckNode = function(e, data) {
|
||||
var obj = this.getLayerById(data.node.id);
|
||||
if (!obj) return;
|
||||
|
||||
|
|
@ -107,28 +118,28 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
.on('deselect_node.jstree', L.bind(onDeselectNode, this))
|
||||
.on('check_node.jstree', L.bind(onCheckNode, this))
|
||||
.on('uncheck_node.jstree', L.bind(onUncheckNode, this))
|
||||
.on('ready.jstree', function (e, data) {
|
||||
.on('ready.jstree', function(e, data) {
|
||||
data.instance.open_all();
|
||||
})
|
||||
.jstree({
|
||||
plugins: [ 'checkbox' ],
|
||||
plugins: ['checkbox'],
|
||||
checkbox: {
|
||||
whole_node: false,
|
||||
tie_selection: false
|
||||
},
|
||||
core: {
|
||||
'multiple': false,
|
||||
'themes': {
|
||||
'icons': false,
|
||||
dots : false
|
||||
multiple: false,
|
||||
themes: {
|
||||
icons: false,
|
||||
dots: false
|
||||
},
|
||||
'data' : treeData
|
||||
data: treeData
|
||||
}
|
||||
});
|
||||
this.jstree = $('#optional-layers-tree').jstree(true);
|
||||
},
|
||||
|
||||
toJsTree: function (layerTree) {
|
||||
toJsTree: function(layerTree) {
|
||||
var data = {
|
||||
children: []
|
||||
};
|
||||
|
|
@ -136,11 +147,11 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
|
||||
function createRootNode(name) {
|
||||
var rootNode = {
|
||||
'text': i18next.t('sidebar.layers.category.' + name, name),
|
||||
'state': {
|
||||
'disabled': true
|
||||
text: i18next.t('sidebar.layers.category.' + name, name),
|
||||
state: {
|
||||
disabled: true
|
||||
},
|
||||
'children': []
|
||||
children: []
|
||||
};
|
||||
return rootNode;
|
||||
}
|
||||
|
|
@ -163,12 +174,15 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
var childNode = null;
|
||||
|
||||
// when key required only add if configured
|
||||
if (!keyObj || keyObj && BR.keys[keyObj.name]) {
|
||||
if (!keyObj || (keyObj && BR.keys[keyObj.name])) {
|
||||
childNode = {
|
||||
'id': id,
|
||||
'text': getText(props, parent),
|
||||
'state': {
|
||||
'checked': self.layersConfig.isDefaultLayer(id, props.overlay)
|
||||
id: id,
|
||||
text: getText(props, parent),
|
||||
state: {
|
||||
checked: self.layersConfig.isDefaultLayer(
|
||||
id,
|
||||
props.overlay
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -179,7 +193,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
function walkObject(obj) {
|
||||
for (name in obj) {
|
||||
var value = obj[name];
|
||||
var rootNode = createRootNode(name)
|
||||
var rootNode = createRootNode(name);
|
||||
|
||||
outTree.children.push(rootNode);
|
||||
walkTree(value, rootNode);
|
||||
|
|
@ -213,7 +227,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return data.children;
|
||||
},
|
||||
|
||||
storeDefaultLayers: function () {
|
||||
storeDefaultLayers: function() {
|
||||
var baseLayers = [];
|
||||
var overlays = [];
|
||||
|
||||
|
|
@ -233,7 +247,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
this.layersConfig.storeDefaultLayers(baseLayers, overlays);
|
||||
},
|
||||
|
||||
createLayer: function (layerData) {
|
||||
createLayer: function(layerData) {
|
||||
var layer = this.layersConfig.createLayer(layerData);
|
||||
var overlay = layerData.properties.overlay;
|
||||
|
||||
|
|
@ -243,7 +257,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return layer;
|
||||
},
|
||||
|
||||
getLayerById: function (id) {
|
||||
getLayerById: function(id) {
|
||||
for (var i = 0; i < this._layers.length; i++) {
|
||||
var obj = this._layers[i];
|
||||
if (obj.layer.id === id) {
|
||||
|
|
@ -254,7 +268,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return null;
|
||||
},
|
||||
|
||||
getLayerByLegacyName: function (legacyName) {
|
||||
getLayerByLegacyName: function(legacyName) {
|
||||
var obj = null;
|
||||
var id = this.layersConfig.legacyNameToIdMap[legacyName];
|
||||
|
||||
|
|
@ -265,7 +279,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return obj;
|
||||
},
|
||||
|
||||
activateDefaultBaseLayer: function () {
|
||||
activateDefaultBaseLayer: function() {
|
||||
var index = BR.conf.defaultBaseLayerIndex || 0;
|
||||
var activeBaseLayer = this.getActiveBaseLayer();
|
||||
if (!activeBaseLayer) {
|
||||
|
|
@ -273,12 +287,12 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
}
|
||||
},
|
||||
|
||||
saveRemoveActiveLayers: function () {
|
||||
this.saveLayers = this.removeActiveLayers();
|
||||
saveRemoveActiveLayers: function() {
|
||||
this.saveLayers = this.removeActiveLayers();
|
||||
},
|
||||
|
||||
restoreActiveLayers: function (overlaysOnly) {
|
||||
for (var i = 0; i < this.saveLayers.length; i++) {
|
||||
restoreActiveLayers: function(overlaysOnly) {
|
||||
for (var i = 0; i < this.saveLayers.length; i++) {
|
||||
var obj = this.saveLayers[i];
|
||||
|
||||
if (!overlaysOnly || (overlaysOnly && obj.overlay)) {
|
||||
|
|
@ -296,7 +310,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
this.saveLayers = [];
|
||||
},
|
||||
|
||||
removePreviewLayer: function () {
|
||||
removePreviewLayer: function() {
|
||||
if (this.previewLayer && this._map.hasLayer(this.previewLayer)) {
|
||||
this._map.removeLayer(this.previewLayer);
|
||||
this.previewLayer = null;
|
||||
|
|
@ -305,7 +319,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
return false;
|
||||
},
|
||||
|
||||
showPreviewBounds: function (layerData) {
|
||||
showPreviewBounds: function(layerData) {
|
||||
if (layerData.geometry) {
|
||||
this.previewBounds = L.geoJson(layerData.geometry, {
|
||||
// fill/mask outside of bounds polygon with Leaflet.snogylop
|
||||
|
|
@ -319,32 +333,35 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
}
|
||||
},
|
||||
|
||||
removePreviewBounds: function () {
|
||||
removePreviewBounds: function() {
|
||||
if (this.previewBounds && this._map.hasLayer(this.previewBounds)) {
|
||||
this._map.removeLayer(this.previewBounds);
|
||||
this.previewBounds = null;
|
||||
}
|
||||
},
|
||||
|
||||
deselectNode: function () {
|
||||
deselectNode: function() {
|
||||
var selected = this.jstree.get_selected();
|
||||
if (selected.length > 0) {
|
||||
this.jstree.deselect_node(selected[0]);
|
||||
}
|
||||
},
|
||||
|
||||
onBaselayerchange: function () {
|
||||
onBaselayerchange: function() {
|
||||
// execute after current input click handler,
|
||||
// otherwise added overlay checkbox state doesn't update
|
||||
setTimeout(L.Util.bind(function () {
|
||||
this.removePreviewBounds();
|
||||
this.removePreviewLayer();
|
||||
this.restoreActiveLayers(true);
|
||||
this.deselectNode();
|
||||
}, this), 0);
|
||||
setTimeout(
|
||||
L.Util.bind(function() {
|
||||
this.removePreviewBounds();
|
||||
this.removePreviewLayer();
|
||||
this.restoreActiveLayers(true);
|
||||
this.deselectNode();
|
||||
}, this),
|
||||
0
|
||||
);
|
||||
},
|
||||
|
||||
showPreview: function (layerData) {
|
||||
showPreview: function(layerData) {
|
||||
var layer = this.createLayer(layerData);
|
||||
this._map.addLayer(layer);
|
||||
this.removePreviewBounds();
|
||||
|
|
@ -357,7 +374,7 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
this.showPreviewBounds(layerData);
|
||||
},
|
||||
|
||||
hidePreview: function (layer) {
|
||||
hidePreview: function(layer) {
|
||||
this._map.off('baselayerchange', this.onBaselayerchange, this);
|
||||
this.removePreviewBounds();
|
||||
this.removePreviewLayer();
|
||||
|
|
@ -365,6 +382,6 @@ BR.LayersTab = BR.ControlLayers.extend({
|
|||
}
|
||||
});
|
||||
|
||||
BR.layersTab = function (baseLayers, overlays, options) {
|
||||
return new BR.LayersTab(baseLayers, overlays, options);
|
||||
BR.layersTab = function(baseLayers, overlays, options) {
|
||||
return new BR.LayersTab(baseLayers, overlays, options);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,45 +4,52 @@ BR.Message = L.Class.extend({
|
|||
// Bootstrap data-api's auto-initialization doesn't work in Controls because of stopPropagation
|
||||
alert: false
|
||||
},
|
||||
|
||||
initialize: function (id, options) {
|
||||
|
||||
initialize: function(id, options) {
|
||||
L.setOptions(this, options);
|
||||
this.id = id;
|
||||
},
|
||||
|
||||
_show: function (msg, type) {
|
||||
_show: function(msg, type) {
|
||||
var ele = L.DomUtil.get(this.id),
|
||||
iconClass = (type === 'warning') ? 'fa-exclamation-triangle' : 'fa-times-circle',
|
||||
alertClass = (type === 'warning') ? 'alert-warning' : 'alert-danger';
|
||||
iconClass =
|
||||
type === 'warning'
|
||||
? 'fa-exclamation-triangle'
|
||||
: 'fa-times-circle',
|
||||
alertClass = type === 'warning' ? 'alert-warning' : 'alert-danger';
|
||||
|
||||
L.DomEvent.disableClickPropagation(ele);
|
||||
|
||||
ele.innerHTML =
|
||||
'<div class="alert ' + alertClass + ' alert-dismissible fade in" role="alert">'
|
||||
+ ' <button type="button" class="close" data-dismiss="alert" aria-label="Close">'
|
||||
+ ' <span aria-hidden="true">×</span>'
|
||||
+ ' </button>'
|
||||
+ ' <span class="fa ' + iconClass + '" aria-hidden="true"/></span>'
|
||||
+ msg
|
||||
+ '</div>';
|
||||
'<div class="alert ' +
|
||||
alertClass +
|
||||
' alert-dismissible fade in" role="alert">' +
|
||||
' <button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
|
||||
' <span aria-hidden="true">×</span>' +
|
||||
' </button>' +
|
||||
' <span class="fa ' +
|
||||
iconClass +
|
||||
'" aria-hidden="true"/></span>' +
|
||||
msg +
|
||||
'</div>';
|
||||
|
||||
if (this.options.alert) {
|
||||
$('#' + this.id + ' .alert').alert();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
hide: function() {
|
||||
$('#' + this.id + ' .alert').alert('close');
|
||||
},
|
||||
|
||||
showError: function (err) {
|
||||
showError: function(err) {
|
||||
if (err == 'Error: target island detected for section 0\n') {
|
||||
err = i18next.t('warning.no-route-found');
|
||||
}
|
||||
this._show(err, 'error');
|
||||
},
|
||||
|
||||
showWarning: function (msg) {
|
||||
showWarning: function(msg) {
|
||||
this._show(msg, 'warning');
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
BR.OpacitySlider = L.Control.extend({
|
||||
options: {
|
||||
options: {
|
||||
position: 'topleft',
|
||||
callback: function(opacity) {}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
onAdd: function(map) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-bar control-slider'),
|
||||
input = $('<input id="slider" type="text"/>'),
|
||||
item = BR.Util.localStorageAvailable() ? localStorage.opacitySliderValue : null,
|
||||
item = BR.Util.localStorageAvailable()
|
||||
? localStorage.opacitySliderValue
|
||||
: null,
|
||||
value = item ? parseInt(item) : BR.conf.defaultOpacity * 100,
|
||||
minOpacity = (BR.conf.minOpacity || 0) * 100;
|
||||
|
||||
|
|
@ -24,41 +26,53 @@ BR.OpacitySlider = L.Control.extend({
|
|||
};
|
||||
var removeStopClickListeners = function() {
|
||||
document.removeEventListener('click', stopClickAfterSlide, true);
|
||||
document.removeEventListener('mousedown', removeStopClickListeners, true);
|
||||
document.removeEventListener(
|
||||
'mousedown',
|
||||
removeStopClickListeners,
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
$(container).html(input);
|
||||
$(container).attr('title', i18next.t('map.opacity-slider'));
|
||||
|
||||
input.slider({
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 1,
|
||||
value: value,
|
||||
orientation: 'vertical',
|
||||
reversed : true,
|
||||
selection: 'before', // inverted, serves as track style, see css
|
||||
tooltip: 'hide'
|
||||
}).on('slideStart', function (evt) {
|
||||
// dragging beyond slider control selects zoom control +/- text in Firefox
|
||||
L.DomUtil.disableTextSelection();
|
||||
}).on('slide slideStop', { self: this }, function (evt) {
|
||||
evt.data.self.options.callback(evt.value / 100);
|
||||
}).on('slideStop', function (evt) {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
localStorage.opacitySliderValue = evt.value;
|
||||
}
|
||||
|
||||
L.DomUtil.enableTextSelection();
|
||||
input
|
||||
.slider({
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 1,
|
||||
value: value,
|
||||
orientation: 'vertical',
|
||||
reversed: true,
|
||||
selection: 'before', // inverted, serves as track style, see css
|
||||
tooltip: 'hide'
|
||||
})
|
||||
.on('slideStart', function(evt) {
|
||||
// dragging beyond slider control selects zoom control +/- text in Firefox
|
||||
L.DomUtil.disableTextSelection();
|
||||
})
|
||||
.on('slide slideStop', { self: this }, function(evt) {
|
||||
evt.data.self.options.callback(evt.value / 100);
|
||||
})
|
||||
.on('slideStop', function(evt) {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
localStorage.opacitySliderValue = evt.value;
|
||||
}
|
||||
|
||||
// When dragging outside slider and over map, click event after mouseup
|
||||
// adds marker when active on Chromium. So disable click (not needed)
|
||||
// once after sliding.
|
||||
document.addEventListener('click', stopClickAfterSlide, true);
|
||||
// Firefox does not fire click event in this case, so make sure stop listener
|
||||
// is always removed on next mousedown.
|
||||
document.addEventListener('mousedown', removeStopClickListeners, true);
|
||||
});
|
||||
L.DomUtil.enableTextSelection();
|
||||
|
||||
// When dragging outside slider and over map, click event after mouseup
|
||||
// adds marker when active on Chromium. So disable click (not needed)
|
||||
// once after sliding.
|
||||
document.addEventListener('click', stopClickAfterSlide, true);
|
||||
// Firefox does not fire click event in this case, so make sure stop listener
|
||||
// is always removed on next mousedown.
|
||||
document.addEventListener(
|
||||
'mousedown',
|
||||
removeStopClickListeners,
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
this.options.callback(value / 100);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
BR.Profile = L.Evented.extend({
|
||||
cache: {},
|
||||
|
||||
initialize: function () {
|
||||
initialize: function() {
|
||||
var textArea = L.DomUtil.get('profile_upload');
|
||||
this.editor = CodeMirror.fromTextArea(textArea, {
|
||||
lineNumbers: true
|
||||
|
|
@ -19,7 +19,7 @@ BR.Profile = L.Evented.extend({
|
|||
var button = evt.target || evt.srcElement;
|
||||
|
||||
evt.preventDefault();
|
||||
this._setValue("");
|
||||
this._setValue('');
|
||||
|
||||
this.fire('clear');
|
||||
button.blur();
|
||||
|
|
@ -35,19 +35,30 @@ BR.Profile = L.Evented.extend({
|
|||
if (profileName && BR.conf.profilesUrl && (empty || clean)) {
|
||||
if (!(profileName in this.cache)) {
|
||||
profileUrl = BR.conf.profilesUrl + profileName + '.brf';
|
||||
BR.Util.get(profileUrl, L.bind(function(err, profileText) {
|
||||
if (err) {
|
||||
console.warn('Error getting profile from "' + profileUrl + '": ' + err);
|
||||
return;
|
||||
}
|
||||
BR.Util.get(
|
||||
profileUrl,
|
||||
L.bind(function(err, profileText) {
|
||||
if (err) {
|
||||
console.warn(
|
||||
'Error getting profile from "' +
|
||||
profileUrl +
|
||||
'": ' +
|
||||
err
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.cache[profileName] = profileText;
|
||||
this.cache[profileName] = profileText;
|
||||
|
||||
// don't set when option has changed while loading
|
||||
if (!this.profileName || this.profileName === profileName) {
|
||||
this._setValue(profileText);
|
||||
}
|
||||
}, this));
|
||||
// don't set when option has changed while loading
|
||||
if (
|
||||
!this.profileName ||
|
||||
this.profileName === profileName
|
||||
) {
|
||||
this._setValue(profileText);
|
||||
}
|
||||
}, this)
|
||||
);
|
||||
} else {
|
||||
this._setValue(this.cache[profileName]);
|
||||
}
|
||||
|
|
@ -72,7 +83,7 @@ BR.Profile = L.Evented.extend({
|
|||
|
||||
this.fire('update', {
|
||||
profileText: profile,
|
||||
callback: function () {
|
||||
callback: function() {
|
||||
$(button).button('reset');
|
||||
$(button).blur();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
BR.RoutingOptions = L.Evented.extend({
|
||||
|
||||
initialize: function () {
|
||||
$('#profile-alternative').on('changed.bs.select', this._getChangeHandler());
|
||||
initialize: function() {
|
||||
$('#profile-alternative').on(
|
||||
'changed.bs.select',
|
||||
this._getChangeHandler()
|
||||
);
|
||||
|
||||
// build option list from config
|
||||
var profiles = BR.conf.profiles;
|
||||
var profiles_list = L.DomUtil.get('profile');
|
||||
for (var i = 0; i < profiles.length; i++) {
|
||||
var option = document.createElement("option");
|
||||
var option = document.createElement('option');
|
||||
option.value = profiles[i];
|
||||
option.text = i18next.t("navbar.profile." + profiles[i]);
|
||||
option.text = i18next.t('navbar.profile.' + profiles[i]);
|
||||
profiles_list.appendChild(option);
|
||||
}
|
||||
// set default value, used as indicator for empty custom profile
|
||||
profiles_list.children[0].value = "Custom";
|
||||
// set default value, used as indicator for empty custom profile
|
||||
profiles_list.children[0].value = 'Custom';
|
||||
// <custom> profile is empty at start, select next one
|
||||
profiles_list.children[1].selected = true;
|
||||
},
|
||||
|
|
@ -21,19 +23,23 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
refreshUI: function() {
|
||||
// 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').find('option:disabled').each(function(index) {
|
||||
$(this).prop('disabled', false);
|
||||
});
|
||||
$('#profile-alternative').find('option:selected').each(function(index) {
|
||||
$(this).prop('disabled', true);
|
||||
});
|
||||
$('#profile-alternative')
|
||||
.find('option:disabled')
|
||||
.each(function(index) {
|
||||
$(this).prop('disabled', false);
|
||||
});
|
||||
$('#profile-alternative')
|
||||
.find('option:selected')
|
||||
.each(function(index) {
|
||||
$(this).prop('disabled', true);
|
||||
});
|
||||
|
||||
// disable custom option if it has no value yet (default value is "Custom")
|
||||
var custom = L.DomUtil.get('profile').children[0];
|
||||
if (custom.value === "Custom") {
|
||||
if (custom.value === 'Custom') {
|
||||
custom.disabled = true;
|
||||
}
|
||||
$('.selectpicker').selectpicker('refresh')
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
},
|
||||
|
||||
getOptions: function() {
|
||||
|
|
@ -49,8 +55,12 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
|
||||
setOptions: function(options) {
|
||||
var values = [
|
||||
options.profile ? options.profile : $('#profile option:selected').val(),
|
||||
options.alternative ? options.alternative : $('#alternative option:selected').val()
|
||||
options.profile
|
||||
? options.profile
|
||||
: $('#profile option:selected').val(),
|
||||
options.alternative
|
||||
? options.alternative
|
||||
: $('#alternative option:selected').val()
|
||||
];
|
||||
$('.selectpicker').selectpicker('val', values);
|
||||
this.refreshUI();
|
||||
|
|
@ -64,18 +74,19 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
},
|
||||
|
||||
setCustomProfile: function(profile, noUpdate) {
|
||||
var profiles_grp,
|
||||
option;
|
||||
var profiles_grp, option;
|
||||
|
||||
profiles_grp = L.DomUtil.get('profile');
|
||||
option = profiles_grp.children[0];
|
||||
option.value = profile || "Custom";
|
||||
option.value = profile || 'Custom';
|
||||
option.disabled = !profile;
|
||||
|
||||
if (profile) {
|
||||
$('#profile').find('option:selected').each(function(index) {
|
||||
$(this).prop('selected', false);
|
||||
});
|
||||
$('#profile')
|
||||
.find('option:selected')
|
||||
.each(function(index) {
|
||||
$(this).prop('selected', false);
|
||||
});
|
||||
} else if (option.selected) {
|
||||
// clear, select next in group when custom deselected
|
||||
profiles_grp.children[1].selected = true;
|
||||
|
|
@ -84,7 +95,7 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
option.selected = !!profile;
|
||||
|
||||
if (!noUpdate) {
|
||||
this.fire('update', {options: this.getOptions()});
|
||||
this.fire('update', { options: this.getOptions() });
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -93,7 +104,7 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
option = profiles_grp.children[0],
|
||||
profile = null;
|
||||
|
||||
if (option.value !== "Custom") {
|
||||
if (option.value !== 'Custom') {
|
||||
profile = option.value;
|
||||
}
|
||||
return profile;
|
||||
|
|
@ -101,7 +112,7 @@ BR.RoutingOptions = L.Evented.extend({
|
|||
|
||||
_getChangeHandler: function() {
|
||||
return L.bind(function(evt) {
|
||||
this.fire('update', {options: this.getOptions()});
|
||||
this.fire('update', { options: this.getOptions() });
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
BR.TrackMessages = L.Class.extend({
|
||||
|
||||
options: {
|
||||
edgeStyle: {
|
||||
color: 'yellow',
|
||||
|
|
@ -12,18 +11,18 @@ BR.TrackMessages = L.Class.extend({
|
|||
active: false,
|
||||
|
||||
columnOptions: {
|
||||
'Longitude': { visible: false },
|
||||
'Latitude': { visible: false },
|
||||
'Elevation': { title: 'elev.', className: 'dt-body-right' },
|
||||
'Distance': { title: 'dist.', className: 'dt-body-right' },
|
||||
'CostPerKm': { title: '$/km', className: 'dt-body-right' },
|
||||
'ElevCost': { title: 'elev$', className: 'dt-body-right' },
|
||||
'TurnCost': { title: 'turn$', className: 'dt-body-right' },
|
||||
'NodeCost': { title: 'node$', className: 'dt-body-right' },
|
||||
'InitialCost': { title: 'initial$', className: 'dt-body-right' }
|
||||
Longitude: { visible: false },
|
||||
Latitude: { visible: false },
|
||||
Elevation: { title: 'elev.', className: 'dt-body-right' },
|
||||
Distance: { title: 'dist.', className: 'dt-body-right' },
|
||||
CostPerKm: { title: '$/km', className: 'dt-body-right' },
|
||||
ElevCost: { title: 'elev$', className: 'dt-body-right' },
|
||||
TurnCost: { title: 'turn$', className: 'dt-body-right' },
|
||||
NodeCost: { title: 'node$', className: 'dt-body-right' },
|
||||
InitialCost: { title: 'initial$', className: 'dt-body-right' }
|
||||
},
|
||||
|
||||
initialize: function (map, options) {
|
||||
initialize: function(map, options) {
|
||||
L.setOptions(this, options);
|
||||
this._map = map;
|
||||
|
||||
|
|
@ -32,8 +31,11 @@ BR.TrackMessages = L.Class.extend({
|
|||
this.tableParent = table.parentElement;
|
||||
},
|
||||
|
||||
update: function (polyline, segments) {
|
||||
var i, messages, columns, headings,
|
||||
update: function(polyline, segments) {
|
||||
var i,
|
||||
messages,
|
||||
columns,
|
||||
headings,
|
||||
data = [];
|
||||
|
||||
if (!this.active) {
|
||||
|
|
@ -50,7 +52,7 @@ BR.TrackMessages = L.Class.extend({
|
|||
this._destroyTable();
|
||||
|
||||
if (data.length === 0) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
headings = messages[0];
|
||||
|
|
@ -65,14 +67,17 @@ BR.TrackMessages = L.Class.extend({
|
|||
info: false,
|
||||
// flexbox workaround: without scrollY height Firefox extends to content height
|
||||
// (^= minimum height with flexbox?)
|
||||
scrollY: 50,
|
||||
scrollY: 50,
|
||||
scrollX: true,
|
||||
order: []
|
||||
});
|
||||
|
||||
// highlight track segment (graph edge) on row hover
|
||||
this._setEdges(polyline, segments);
|
||||
$('#datatable tbody tr').hover(L.bind(this._handleHover, this), L.bind(this._handleHoverOut, this));
|
||||
$('#datatable tbody tr').hover(
|
||||
L.bind(this._handleHover, this),
|
||||
L.bind(this._handleHoverOut, this)
|
||||
);
|
||||
},
|
||||
|
||||
show: function() {
|
||||
|
|
@ -87,9 +92,11 @@ BR.TrackMessages = L.Class.extend({
|
|||
_destroyTable: function() {
|
||||
var ele;
|
||||
|
||||
if ($.fn.DataTable.isDataTable('#datatable') ) {
|
||||
if ($.fn.DataTable.isDataTable('#datatable')) {
|
||||
// destroy option too slow on update, really remove elements with destroy method
|
||||
$('#datatable').DataTable().destroy(true);
|
||||
$('#datatable')
|
||||
.DataTable()
|
||||
.destroy(true);
|
||||
|
||||
// recreate original table element, destroy removes all
|
||||
ele = document.createElement('table');
|
||||
|
|
@ -143,7 +150,14 @@ BR.TrackMessages = L.Class.extend({
|
|||
},
|
||||
|
||||
_setEdges: function(polyline, segments) {
|
||||
var messages, segLatLngs, length, si, mi, latLng, i, segIndex,
|
||||
var messages,
|
||||
segLatLngs,
|
||||
length,
|
||||
si,
|
||||
mi,
|
||||
latLng,
|
||||
i,
|
||||
segIndex,
|
||||
baseIndex = 0;
|
||||
|
||||
// track latLngs index for end node of edge
|
||||
|
|
@ -184,7 +198,10 @@ BR.TrackMessages = L.Class.extend({
|
|||
endIndex = this._edges[row.index()],
|
||||
edgeLatLngs = trackLatLngs.slice(startIndex, endIndex + 1);
|
||||
|
||||
this._selectedEdge = L.polyline(edgeLatLngs, this.options.edgeStyle).addTo(this._map);
|
||||
this._selectedEdge = L.polyline(
|
||||
edgeLatLngs,
|
||||
this.options.edgeStyle
|
||||
).addTo(this._map);
|
||||
},
|
||||
|
||||
_handleHoverOut: function(evt) {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,36 @@
|
|||
BR.TrackStats = L.Class.extend({
|
||||
update: function (polyline, segments) {
|
||||
update: function(polyline, segments) {
|
||||
var stats = this.calcStats(polyline, segments),
|
||||
length1 = L.Util.formatNum(stats.trackLength/1000,1),
|
||||
length3 = L.Util.formatNum(stats.trackLength/1000,3),
|
||||
meanCostFactor = stats.trackLength ? L.Util.formatNum(stats.cost / stats.trackLength, 2) : '',
|
||||
formattedTime = L.Util.formatNum(stats.totalTime / 60., 1),
|
||||
formattedEnergy = L.Util.formatNum(stats.totalEnergy / 3600000., 2),
|
||||
meanEnergy = stats.trackLength ? L.Util.formatNum(stats.totalEnergy / 36. / stats.trackLength, 2) : '';
|
||||
length1 = L.Util.formatNum(stats.trackLength / 1000, 1),
|
||||
length3 = L.Util.formatNum(stats.trackLength / 1000, 3),
|
||||
meanCostFactor = stats.trackLength
|
||||
? L.Util.formatNum(stats.cost / stats.trackLength, 2)
|
||||
: '',
|
||||
formattedTime = L.Util.formatNum(stats.totalTime / 60, 1),
|
||||
formattedEnergy = L.Util.formatNum(stats.totalEnergy / 3600000, 2),
|
||||
meanEnergy = stats.trackLength
|
||||
? L.Util.formatNum(
|
||||
stats.totalEnergy / 36 / stats.trackLength,
|
||||
2
|
||||
)
|
||||
: '';
|
||||
|
||||
$('#distance').html(length1);
|
||||
// alternative 3-digit format down to meters as tooltip
|
||||
$('#distance').attr('title', length3 + ' km');
|
||||
$('#ascend').html(stats.filteredAscend + ' (' + stats.plainAscend +')');
|
||||
$('#ascend').html(
|
||||
stats.filteredAscend + ' (' + stats.plainAscend + ')'
|
||||
);
|
||||
$('#cost').html(stats.cost + ' (' + meanCostFactor + ')');
|
||||
$('#totaltime').html(formattedTime);
|
||||
$('#totalenergy').html(formattedEnergy + ' (' + meanEnergy +')');
|
||||
$('#totalenergy').html(formattedEnergy + ' (' + meanEnergy + ')');
|
||||
|
||||
document.getElementById('totaltime').parentElement.parentElement.hidden = !stats.totalTime;
|
||||
document.getElementById('totalenergy').parentElement.parentElement.hidden = !stats.totalEnergy;
|
||||
document.getElementById(
|
||||
'totaltime'
|
||||
).parentElement.parentElement.hidden = !stats.totalTime;
|
||||
document.getElementById(
|
||||
'totalenergy'
|
||||
).parentElement.parentElement.hidden = !stats.totalEnergy;
|
||||
},
|
||||
|
||||
calcStats: function(polyline, segments) {
|
||||
|
|
|
|||
246
js/index.js
246
js/index.js
|
|
@ -5,14 +5,20 @@
|
|||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
var mapContext;
|
||||
|
||||
function verifyTouchStyle(mapContext) {
|
||||
// revert touch style (large icons) when touch screen detection is available and negative
|
||||
// see https://github.com/nrenner/brouter-web/issues/69
|
||||
if (L.Browser.touch && BR.Browser.touchScreenDetectable && !BR.Browser.touchScreen) {
|
||||
L.DomUtil.removeClass(mapContext.map.getContainer(), 'leaflet-touch');
|
||||
if (
|
||||
L.Browser.touch &&
|
||||
BR.Browser.touchScreenDetectable &&
|
||||
!BR.Browser.touchScreen
|
||||
) {
|
||||
L.DomUtil.removeClass(
|
||||
mapContext.map.getContainer(),
|
||||
'leaflet-touch'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,28 +58,31 @@
|
|||
router = L.bRouter(); //brouterCgi dummyRouter
|
||||
|
||||
drawButton = L.easyButton({
|
||||
states: [{
|
||||
stateName: 'deactivate-draw',
|
||||
icon: 'fa-pencil active',
|
||||
onClick: function (control) {
|
||||
routing.draw(false);
|
||||
control.state('activate-draw');
|
||||
states: [
|
||||
{
|
||||
stateName: 'deactivate-draw',
|
||||
icon: 'fa-pencil active',
|
||||
onClick: function(control) {
|
||||
routing.draw(false);
|
||||
control.state('activate-draw');
|
||||
},
|
||||
title: i18next.t('map.draw-route-stop')
|
||||
},
|
||||
title: i18next.t('map.draw-route-stop')
|
||||
}, {
|
||||
stateName: 'activate-draw',
|
||||
icon: 'fa-pencil',
|
||||
onClick: function (control) {
|
||||
routing.draw(true);
|
||||
control.state('deactivate-draw');
|
||||
},
|
||||
title: i18next.t('map.draw-route-start')
|
||||
}]
|
||||
{
|
||||
stateName: 'activate-draw',
|
||||
icon: 'fa-pencil',
|
||||
onClick: function(control) {
|
||||
routing.draw(true);
|
||||
control.state('deactivate-draw');
|
||||
},
|
||||
title: i18next.t('map.draw-route-start')
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
reverseRouteButton = L.easyButton(
|
||||
'fa-random',
|
||||
function () {
|
||||
function() {
|
||||
routing.reverse();
|
||||
},
|
||||
i18next.t('map.reverse-route')
|
||||
|
|
@ -81,15 +90,18 @@
|
|||
|
||||
deletePointButton = L.easyButton(
|
||||
'<span><i class="fa fa-caret-left"></i><i class="fa fa-map-marker" style="margin-left: 1px; color: gray;"></i></span>',
|
||||
function () {
|
||||
routing.removeWaypoint(routing.getLast(), function(err, data) {});
|
||||
function() {
|
||||
routing.removeWaypoint(routing.getLast(), function(
|
||||
err,
|
||||
data
|
||||
) {});
|
||||
},
|
||||
i18next.t('map.delete-last-point')
|
||||
);
|
||||
|
||||
deleteRouteButton = L.easyButton(
|
||||
'fa-trash-o',
|
||||
function () {
|
||||
function() {
|
||||
bootbox.prompt({
|
||||
size: 'small',
|
||||
title: i18next.t('map.delete-route'),
|
||||
|
|
@ -138,11 +150,11 @@
|
|||
profile.update(evt.options);
|
||||
});
|
||||
|
||||
BR.NogoAreas.MSG_BUTTON = i18next.t("map.nogo.draw");
|
||||
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t("map.nogo.cancel");
|
||||
BR.NogoAreas.MSG_CREATE = i18next.t("map.nogo.click-drag");
|
||||
BR.NogoAreas.MSG_DISABLED = i18next.t("map.nogo.edit");
|
||||
BR.NogoAreas.MSG_ENABLED = i18next.t("map.nogo.help");
|
||||
BR.NogoAreas.MSG_BUTTON = i18next.t('map.nogo.draw');
|
||||
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('map.nogo.cancel');
|
||||
BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag');
|
||||
BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit');
|
||||
BR.NogoAreas.MSG_ENABLED = i18next.t('map.nogo.help');
|
||||
nogos = new BR.NogoAreas();
|
||||
nogos.on('update', updateRoute);
|
||||
|
||||
|
|
@ -159,14 +171,19 @@
|
|||
profile.on('update', function(evt) {
|
||||
BR.message.hide();
|
||||
var profileId = routingOptions.getCustomProfile();
|
||||
router.uploadProfile(profileId, evt.profileText, function(err, profileId) {
|
||||
router.uploadProfile(profileId, evt.profileText, function(
|
||||
err,
|
||||
profileId
|
||||
) {
|
||||
if (!err) {
|
||||
routingOptions.setCustomProfile(profileId, true);
|
||||
updateRoute({
|
||||
options: routingOptions.getOptions()
|
||||
});
|
||||
if (!saveWarningShown) {
|
||||
profile.message.showWarning(i18next.t('warning.temporary-profile'));
|
||||
profile.message.showWarning(
|
||||
i18next.t('warning.temporary-profile')
|
||||
);
|
||||
saveWarningShown = true;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -197,7 +214,9 @@
|
|||
styles: BR.conf.routingStyles
|
||||
});
|
||||
|
||||
routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function(evt) {
|
||||
routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function(
|
||||
evt
|
||||
) {
|
||||
search.clear();
|
||||
onUpdate(evt && evt.err);
|
||||
});
|
||||
|
|
@ -240,16 +259,16 @@
|
|||
}
|
||||
|
||||
download.update(urls);
|
||||
};
|
||||
}
|
||||
|
||||
routing.addTo(map);
|
||||
elevation.addBelow(map);
|
||||
|
||||
|
||||
sidebar = BR.sidebar({
|
||||
defaultTabId: BR.conf.transit ? 'tab_itinerary' : 'tab_profile',
|
||||
listeningTabs: {
|
||||
'tab_profile': profile,
|
||||
'tab_data': trackMessages
|
||||
tab_profile: profile,
|
||||
tab_data: trackMessages
|
||||
}
|
||||
}).addTo(map);
|
||||
if (BR.conf.transit) {
|
||||
|
|
@ -257,16 +276,24 @@
|
|||
}
|
||||
|
||||
nogos.addTo(map);
|
||||
drawToolbar = L.easyBar([drawButton, reverseRouteButton, nogos.getButton(), deletePointButton, deleteRouteButton]).addTo(map);
|
||||
drawToolbar = L.easyBar([
|
||||
drawButton,
|
||||
reverseRouteButton,
|
||||
nogos.getButton(),
|
||||
deletePointButton,
|
||||
deleteRouteButton
|
||||
]).addTo(map);
|
||||
nogos.preventRoutePointOnCreate(routing);
|
||||
|
||||
if (BR.keys.strava) {
|
||||
BR.stravaSegments(map, layersControl);
|
||||
}
|
||||
|
||||
map.addControl(new BR.OpacitySlider({
|
||||
callback: L.bind(routing.setOpacity, routing)
|
||||
}));
|
||||
map.addControl(
|
||||
new BR.OpacitySlider({
|
||||
callback: L.bind(routing.setOpacity, routing)
|
||||
})
|
||||
);
|
||||
|
||||
// initial option settings (after controls are added and initialized with onAdd)
|
||||
router.setOptions(nogos.getOptions());
|
||||
|
|
@ -274,12 +301,11 @@
|
|||
profile.update(routingOptions.getOptions());
|
||||
|
||||
var onHashChangeCb = function(url) {
|
||||
var url2params = function (s) {
|
||||
var url2params = function(s) {
|
||||
s = s.replace(/;/g, '|');
|
||||
var p = {};
|
||||
var sep = '&';
|
||||
if (s.search('&') !== -1)
|
||||
sep = '&';
|
||||
if (s.search('&') !== -1) sep = '&';
|
||||
var params = s.split(sep);
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var tmp = params[i].split('=');
|
||||
|
|
@ -287,7 +313,7 @@
|
|||
p[tmp[0]] = decodeURIComponent(tmp[1]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
if (url == null) return;
|
||||
var opts = router.parseUrlParams(url2params(url));
|
||||
router.setOptions(opts);
|
||||
|
|
@ -313,10 +339,12 @@
|
|||
// do not initialize immediately
|
||||
urlHash = new L.Hash(null, null);
|
||||
urlHash.additionalCb = function() {
|
||||
var url = router.getUrl(routing.getWaypoints(), null).substr('brouter?'.length+1);
|
||||
url = url.replace(/\|/g, ';');
|
||||
return url.length > 0 ? '&' + url : null;
|
||||
};
|
||||
var url = router
|
||||
.getUrl(routing.getWaypoints(), null)
|
||||
.substr('brouter?'.length + 1);
|
||||
url = url.replace(/\|/g, ';');
|
||||
return url.length > 0 ? '&' + url : null;
|
||||
};
|
||||
urlHash.onHashChangeCb = onHashChangeCb;
|
||||
urlHash.onInvalidHashChangeCb = onInvalidHashChangeCb;
|
||||
urlHash.init(map, {
|
||||
|
|
@ -325,7 +353,7 @@
|
|||
|
||||
// activate configured default base layer or first if no hash,
|
||||
// only after hash init, by using the same delay
|
||||
setTimeout(function () {
|
||||
setTimeout(function() {
|
||||
layersControl.activateDefaultBaseLayer();
|
||||
}, urlHash.changeDefer);
|
||||
|
||||
|
|
@ -334,27 +362,30 @@
|
|||
// waypoint add, move, delete (but last)
|
||||
routing.on('routing:routeWaypointEnd', urlHash.onMapMove, urlHash);
|
||||
// delete last waypoint
|
||||
routing.on('waypoint:click', function (evt) {
|
||||
var r = evt.marker._routing;
|
||||
if (!r.prevMarker && !r.nextMarker) {
|
||||
urlHash.onMapMove();
|
||||
}
|
||||
}, urlHash);
|
||||
routing.on(
|
||||
'waypoint:click',
|
||||
function(evt) {
|
||||
var r = evt.marker._routing;
|
||||
if (!r.prevMarker && !r.nextMarker) {
|
||||
urlHash.onMapMove();
|
||||
}
|
||||
},
|
||||
urlHash
|
||||
);
|
||||
|
||||
$(window).resize(function () {
|
||||
$(window).resize(function() {
|
||||
elevation.addBelow(map);
|
||||
});
|
||||
|
||||
$('#elevation-chart').on('show.bs.collapse', function () {
|
||||
$('#elevation-chart').on('show.bs.collapse', function() {
|
||||
$('#elevation-btn').addClass('active');
|
||||
});
|
||||
$('#elevation-chart').on('hidden.bs.collapse', function () {
|
||||
$('#elevation-chart').on('hidden.bs.collapse', function() {
|
||||
$('#elevation-btn').removeClass('active');
|
||||
// we must fetch tiles that are located behind elevation-chart
|
||||
map._onResize();
|
||||
});
|
||||
|
||||
|
||||
var onHide = function() {
|
||||
if (this.id && BR.Util.localStorageAvailable()) {
|
||||
localStorage.removeItem(this.id);
|
||||
|
|
@ -366,33 +397,39 @@
|
|||
}
|
||||
};
|
||||
// on page load, we want to restore collapsible elements from previous usage
|
||||
$('.collapse').on('hidden.bs.collapse', onHide)
|
||||
.on('shown.bs.collapse', onShow)
|
||||
.each(function() {
|
||||
if (this.id && BR.Util.localStorageAvailable() && localStorage[this.id] === 'true') {
|
||||
$(this).collapse('show');
|
||||
}
|
||||
});
|
||||
$('.collapse')
|
||||
.on('hidden.bs.collapse', onHide)
|
||||
.on('shown.bs.collapse', onShow)
|
||||
.each(function() {
|
||||
if (
|
||||
this.id &&
|
||||
BR.Util.localStorageAvailable() &&
|
||||
localStorage[this.id] === 'true'
|
||||
) {
|
||||
$(this).collapse('show');
|
||||
}
|
||||
});
|
||||
|
||||
$('#submitNogos').on('click', function () {
|
||||
$('#submitNogos').on('click', function() {
|
||||
var geoJSONPromise;
|
||||
var nogoURL = $('#nogoURL').val();
|
||||
var nogoFile = $('#nogoFile')[0].files[0];
|
||||
if (nogoURL) {
|
||||
// TODO: Handle {{bbox}}
|
||||
geoJSONPromise = fetch(nogoURL).then(function (response) {
|
||||
geoJSONPromise = fetch(nogoURL).then(function(response) {
|
||||
response.json();
|
||||
});
|
||||
} else if (nogoFile) {
|
||||
geoJSONPromise = new Promise(function (resolve, reject) {
|
||||
geoJSONPromise = new Promise(function(resolve, reject) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
reader.onload = function() {
|
||||
resolve(reader.result);
|
||||
}
|
||||
};
|
||||
reader.readAsText(nogoFile);
|
||||
}).then(function (response) { return JSON.parse(response); });
|
||||
}
|
||||
else {
|
||||
}).then(function(response) {
|
||||
return JSON.parse(response);
|
||||
});
|
||||
} else {
|
||||
$('#nogoError').text('Error: Missing file or URL.');
|
||||
$('#nogoError').css('display', 'block');
|
||||
return false;
|
||||
|
|
@ -416,46 +453,54 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
geoJSONPromise.then(function (response) {
|
||||
geoJSONPromise.then(function(response) {
|
||||
// Iterate on features in order to discard features without geometry
|
||||
var cleanedGeoJSONFeatures = []
|
||||
turf.featureEach(response, function (feature) {
|
||||
var cleanedGeoJSONFeatures = [];
|
||||
turf.featureEach(response, function(feature) {
|
||||
if (turf.getGeom(feature)) {
|
||||
var maybeBufferedFeature = feature;
|
||||
// Eventually buffer GeoJSON
|
||||
if (nogoBuffer != 0) {
|
||||
maybeBufferedFeature = turf.buffer(
|
||||
maybeBufferedFeature, nogoBuffer, { units: 'meters' }
|
||||
maybeBufferedFeature,
|
||||
nogoBuffer,
|
||||
{ units: 'meters' }
|
||||
);
|
||||
}
|
||||
cleanedGeoJSONFeatures.push(maybeBufferedFeature);
|
||||
}
|
||||
});
|
||||
|
||||
var geoJSON = L.geoJson(turf.featureCollection(cleanedGeoJSONFeatures), {
|
||||
onEachFeature: function (feature, layer) {
|
||||
layer.options.nogoWeight = feature.properties.nogoWeight || nogoWeight;
|
||||
var geoJSON = L.geoJson(
|
||||
turf.featureCollection(cleanedGeoJSONFeatures),
|
||||
{
|
||||
onEachFeature: function(feature, layer) {
|
||||
layer.options.nogoWeight =
|
||||
feature.properties.nogoWeight || nogoWeight;
|
||||
}
|
||||
}
|
||||
});
|
||||
var nogosPoints = geoJSON.getLayers().filter(function (e) {
|
||||
);
|
||||
var nogosPoints = geoJSON.getLayers().filter(function(e) {
|
||||
return e.feature.geometry.type === 'Point';
|
||||
});
|
||||
nogosPoints = nogosPoints.map(function (item) {
|
||||
nogosPoints = nogosPoints.map(function(item) {
|
||||
var radius = item.feature.properties.radius || nogoRadius;
|
||||
if (radius > 0) {
|
||||
return L.circle(item.getLatLng(), { radius: radius });
|
||||
}
|
||||
return null;
|
||||
});
|
||||
nogosPoints = nogosPoints.filter(function (e) { return e; });
|
||||
nogosPoints = nogosPoints.filter(function(e) {
|
||||
return e;
|
||||
});
|
||||
nogos.setOptions({
|
||||
nogos: nogosPoints,
|
||||
polygons: geoJSON.getLayers().filter(function (e) {
|
||||
polygons: geoJSON.getLayers().filter(function(e) {
|
||||
return e.feature.geometry.type === 'Polygon';
|
||||
}),
|
||||
polylines: geoJSON.getLayers().filter(function (e) {
|
||||
polylines: geoJSON.getLayers().filter(function(e) {
|
||||
return e.feature.geometry.type === 'LineString';
|
||||
}),
|
||||
})
|
||||
});
|
||||
updateRoute({
|
||||
options: nogos.getOptions()
|
||||
|
|
@ -472,17 +517,20 @@
|
|||
i18next
|
||||
.use(window.i18nextXHRBackend)
|
||||
.use(window.i18nextBrowserLanguageDetector)
|
||||
.init({
|
||||
fallbackLng: 'en',
|
||||
backend: {
|
||||
loadPath: 'dist/locales/{{lng}}.json',
|
||||
}
|
||||
}, function(err, t) {
|
||||
jqueryI18next.init(i18next, $);
|
||||
$('html').localize();
|
||||
.init(
|
||||
{
|
||||
fallbackLng: 'en',
|
||||
backend: {
|
||||
loadPath: 'dist/locales/{{lng}}.json'
|
||||
}
|
||||
},
|
||||
function(err, t) {
|
||||
jqueryI18next.init(i18next, $);
|
||||
$('html').localize();
|
||||
|
||||
mapContext = BR.Map.initMap();
|
||||
verifyTouchStyle(mapContext);
|
||||
initApp(mapContext);
|
||||
});
|
||||
mapContext = BR.Map.initMap();
|
||||
verifyTouchStyle(mapContext);
|
||||
initApp(mapContext);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
BR.BingLayer = L.BingLayer.extend({
|
||||
options: {
|
||||
maxZoom: 19,
|
||||
attribution: '<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>'
|
||||
+ ' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)'
|
||||
attribution:
|
||||
'<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>' +
|
||||
' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)'
|
||||
},
|
||||
|
||||
initialize: function(key, options) {
|
||||
L.BingLayer.prototype.initialize.call(this, key, options);
|
||||
|
||||
this._logo = L.control({position: 'bottomleft'});
|
||||
this._logo.onAdd = function (map) {
|
||||
this._logo = L.control({ position: 'bottomleft' });
|
||||
this._logo.onAdd = function(map) {
|
||||
this._div = L.DomUtil.create('div', 'bing-logo');
|
||||
this._div.innerHTML = '<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">';
|
||||
this._div.innerHTML =
|
||||
'<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">';
|
||||
return this._div;
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,33 +1,47 @@
|
|||
BR.Elevation = L.Control.Elevation.extend({
|
||||
options: {
|
||||
width:$('#map').outerWidth(),
|
||||
width: $('#map').outerWidth(),
|
||||
margins: {
|
||||
top: 20,
|
||||
right: 30,
|
||||
bottom: 30,
|
||||
left: 60
|
||||
},
|
||||
theme: "steelblue-theme"
|
||||
theme: 'steelblue-theme'
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
|
||||
onAdd: function(map) {
|
||||
var container = L.Control.Elevation.prototype.onAdd.call(this, map);
|
||||
|
||||
// revert registering touch events when touch screen detection is available and negative
|
||||
// see https://github.com/MrMufflon/Leaflet.Elevation/issues/67
|
||||
if (L.Browser.touch && BR.Browser.touchScreenDetectable && !BR.Browser.touchScreen) {
|
||||
|
||||
this._background.on("touchmove.drag", null).
|
||||
on("touchstart.drag", null).
|
||||
on("touchstart.focus", null);
|
||||
L.DomEvent.off(this._container, 'touchend', this._dragEndHandler, this);
|
||||
|
||||
this._background.on("mousemove.focus", this._mousemoveHandler.bind(this)).
|
||||
on("mouseout.focus", this._mouseoutHandler.bind(this)).
|
||||
on("mousedown.drag", this._dragStartHandler.bind(this)).
|
||||
on("mousemove.drag", this._dragHandler.bind(this));
|
||||
L.DomEvent.on(this._container, 'mouseup', this._dragEndHandler, this);
|
||||
if (
|
||||
L.Browser.touch &&
|
||||
BR.Browser.touchScreenDetectable &&
|
||||
!BR.Browser.touchScreen
|
||||
) {
|
||||
this._background
|
||||
.on('touchmove.drag', null)
|
||||
.on('touchstart.drag', null)
|
||||
.on('touchstart.focus', null);
|
||||
L.DomEvent.off(
|
||||
this._container,
|
||||
'touchend',
|
||||
this._dragEndHandler,
|
||||
this
|
||||
);
|
||||
|
||||
this._background
|
||||
.on('mousemove.focus', this._mousemoveHandler.bind(this))
|
||||
.on('mouseout.focus', this._mouseoutHandler.bind(this))
|
||||
.on('mousedown.drag', this._dragStartHandler.bind(this))
|
||||
.on('mousemove.drag', this._dragHandler.bind(this));
|
||||
L.DomEvent.on(
|
||||
this._container,
|
||||
'mouseup',
|
||||
this._dragEndHandler,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
return container;
|
||||
|
|
@ -44,10 +58,13 @@ BR.Elevation = L.Control.Elevation.extend({
|
|||
|
||||
function setParent(el, newParent) {
|
||||
newParent.appendChild(el);
|
||||
}
|
||||
this.addTo(map);
|
||||
}
|
||||
this.addTo(map);
|
||||
// move elevation graph outside of the map
|
||||
setParent(this.getContainer(), document.getElementById('elevation-chart'));
|
||||
setParent(
|
||||
this.getContainer(),
|
||||
document.getElementById('elevation-chart')
|
||||
);
|
||||
},
|
||||
|
||||
update: function(track, layer) {
|
||||
|
|
@ -62,7 +79,7 @@ BR.Elevation = L.Control.Elevation.extend({
|
|||
if (track && track.getLatLngs().length > 0) {
|
||||
this.addData(track.toGeoJSON(), layer);
|
||||
|
||||
layer.on("mouseout", this._hidePositionMarker.bind(this));
|
||||
layer.on('mouseout', this._hidePositionMarker.bind(this));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ BR.NogoAreas = L.Control.extend({
|
|||
MSG_BUTTON_CANCEL: 'Cancel drawing no-go area',
|
||||
MSG_CREATE: 'Click and drag to draw circle',
|
||||
MSG_DISABLED: 'Click to edit',
|
||||
MSG_ENABLED: '□ = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing',
|
||||
MSG_ENABLED:
|
||||
'□ = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing',
|
||||
STATE_CREATE: 'no-go-create',
|
||||
STATE_CANCEL: 'cancel-no-go-create'
|
||||
},
|
||||
|
|
@ -19,17 +20,17 @@ BR.NogoAreas = L.Control.extend({
|
|||
},
|
||||
|
||||
editStyle: {
|
||||
color: '#fe57a1',
|
||||
opacity: 0.6,
|
||||
dashArray: '10, 10',
|
||||
fillOpacity: 0.1
|
||||
color: '#fe57a1',
|
||||
opacity: 0.6,
|
||||
dashArray: '10, 10',
|
||||
fillOpacity: 0.1
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
initialize: function() {
|
||||
this._wasRouteDrawing = false;
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
onAdd: function(map) {
|
||||
var self = this;
|
||||
|
||||
this.drawnItems = new L.FeatureGroup().addTo(map);
|
||||
|
|
@ -38,55 +39,77 @@ BR.NogoAreas = L.Control.extend({
|
|||
e.layer.toggleEdit();
|
||||
});
|
||||
|
||||
var editTools = this.editTools = map.editTools = new L.Editable(map, {
|
||||
var editTools = (this.editTools = map.editTools = new L.Editable(map, {
|
||||
circleEditorClass: BR.DeletableCircleEditor,
|
||||
// FeatureGroup instead of LayerGroup to propagate events to members
|
||||
editLayer: new L.FeatureGroup().addTo(map),
|
||||
featuresLayer: this.drawnItems
|
||||
});
|
||||
}));
|
||||
|
||||
this.button = L.easyButton({
|
||||
states: [{
|
||||
stateName: BR.NogoAreas.STATE_CREATE,
|
||||
icon: 'fa-ban',
|
||||
title: BR.NogoAreas.MSG_BUTTON,
|
||||
onClick: function (control) {
|
||||
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
|
||||
var opts = L.extend({radius: 0}, self.style);
|
||||
editTools.startCircle(null, opts);
|
||||
states: [
|
||||
{
|
||||
stateName: BR.NogoAreas.STATE_CREATE,
|
||||
icon: 'fa-ban',
|
||||
title: BR.NogoAreas.MSG_BUTTON,
|
||||
onClick: function(control) {
|
||||
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
|
||||
var opts = L.extend({ radius: 0 }, self.style);
|
||||
editTools.startCircle(null, opts);
|
||||
|
||||
control.state('cancel-no-go-create');
|
||||
control.state('cancel-no-go-create');
|
||||
}
|
||||
},
|
||||
{
|
||||
stateName: BR.NogoAreas.STATE_CANCEL,
|
||||
icon: 'fa-ban active',
|
||||
title: BR.NogoAreas.MSG_BUTTON_CANCEL,
|
||||
onClick: function(control) {
|
||||
editTools.stopDrawing();
|
||||
control.state('no-go-create');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
stateName: BR.NogoAreas.STATE_CANCEL,
|
||||
icon: 'fa-ban active',
|
||||
title: BR.NogoAreas.MSG_BUTTON_CANCEL,
|
||||
onClick: function (control) {
|
||||
editTools.stopDrawing();
|
||||
control.state('no-go-create');
|
||||
}
|
||||
}]
|
||||
]
|
||||
});
|
||||
|
||||
this.editTools.on('editable:drawing:end', function (e) {
|
||||
self.button.state(BR.NogoAreas.STATE_CREATE);
|
||||
this.editTools.on(
|
||||
'editable:drawing:end',
|
||||
function(e) {
|
||||
self.button.state(BR.NogoAreas.STATE_CREATE);
|
||||
|
||||
setTimeout(L.bind(function () {
|
||||
// turn editing off after create; async to still fire 'editable:vertex:dragend'
|
||||
e.layer.disableEdit();
|
||||
}, this), 0);
|
||||
}, this);
|
||||
setTimeout(
|
||||
L.bind(function() {
|
||||
// turn editing off after create; async to still fire 'editable:vertex:dragend'
|
||||
e.layer.disableEdit();
|
||||
}, this),
|
||||
0
|
||||
);
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
this.editTools.on('editable:vertex:dragend editable:deleted', function (e) {
|
||||
this._fireUpdate();
|
||||
}, this);
|
||||
this.editTools.on(
|
||||
'editable:vertex:dragend editable:deleted',
|
||||
function(e) {
|
||||
this._fireUpdate();
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
this.editTools.on('editable:enable', function (e) {
|
||||
e.layer.setStyle(this.editStyle);
|
||||
}, this);
|
||||
this.editTools.on('editable:disable', function (e) {
|
||||
e.layer.setStyle(this.style);
|
||||
}, this);
|
||||
this.editTools.on(
|
||||
'editable:enable',
|
||||
function(e) {
|
||||
e.layer.setStyle(this.editStyle);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.editTools.on(
|
||||
'editable:disable',
|
||||
function(e) {
|
||||
e.layer.setStyle(this.style);
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
this.tooltip = new BR.EditingTooltip(map, editTools, this.button);
|
||||
this.tooltip.enable();
|
||||
|
|
@ -97,28 +120,40 @@ BR.NogoAreas = L.Control.extend({
|
|||
|
||||
// prevent route waypoint added after circle create (map click after up)
|
||||
preventRoutePointOnCreate: function(routing) {
|
||||
this.editTools.on('editable:drawing:start', function (e) {
|
||||
this._wasRouteDrawing = routing.isDrawing();
|
||||
routing.draw(false);
|
||||
}, this);
|
||||
this.editTools.on(
|
||||
'editable:drawing:start',
|
||||
function(e) {
|
||||
this._wasRouteDrawing = routing.isDrawing();
|
||||
routing.draw(false);
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
// after create
|
||||
this.editTools.on('editable:drawing:end', function (e) {
|
||||
if (this._wasRouteDrawing) {
|
||||
setTimeout(function () {
|
||||
routing.draw(true);
|
||||
}, 0);
|
||||
}
|
||||
}, this);
|
||||
this.editTools.on(
|
||||
'editable:drawing:end',
|
||||
function(e) {
|
||||
if (this._wasRouteDrawing) {
|
||||
setTimeout(function() {
|
||||
routing.draw(true);
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
getOptions: function() {
|
||||
return {
|
||||
nogos: this.drawnItems.getLayers().filter(function (e) { return e instanceof L.Circle; }),
|
||||
polygons: this.drawnItems.getLayers().filter(function (e) { return e instanceof L.Polygon; }),
|
||||
polylines: this.drawnItems.getLayers().filter(function (e) {
|
||||
return (e instanceof L.Polyline) && !(e instanceof L.Polygon);
|
||||
nogos: this.drawnItems.getLayers().filter(function(e) {
|
||||
return e instanceof L.Circle;
|
||||
}),
|
||||
polygons: this.drawnItems.getLayers().filter(function(e) {
|
||||
return e instanceof L.Polygon;
|
||||
}),
|
||||
polylines: this.drawnItems.getLayers().filter(function(e) {
|
||||
return e instanceof L.Polyline && !(e instanceof L.Polygon);
|
||||
})
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -147,17 +182,17 @@ BR.NogoAreas = L.Control.extend({
|
|||
}
|
||||
},
|
||||
|
||||
_clear: function () {
|
||||
_clear: function() {
|
||||
this.drawnItems.clearLayers();
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
clear: function() {
|
||||
this._clear();
|
||||
this._fireUpdate();
|
||||
},
|
||||
|
||||
_fireUpdate: function () {
|
||||
this.fire('update', {options: this.getOptions()});
|
||||
_fireUpdate: function() {
|
||||
this.fire('update', { options: this.getOptions() });
|
||||
},
|
||||
|
||||
getFeatureGroup: function() {
|
||||
|
|
@ -175,27 +210,32 @@ BR.NogoAreas = L.Control.extend({
|
|||
|
||||
BR.NogoAreas.include(L.Evented.prototype);
|
||||
|
||||
|
||||
L.Editable.prototype.createVertexIcon = function (options) {
|
||||
return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
|
||||
L.Editable.prototype.createVertexIcon = function(options) {
|
||||
return BR.Browser.touch
|
||||
? new L.Editable.TouchVertexIcon(options)
|
||||
: new L.Editable.VertexIcon(options);
|
||||
};
|
||||
|
||||
|
||||
BR.EditingTooltip = L.Handler.extend({
|
||||
options: {
|
||||
closeTimeout: 2000
|
||||
},
|
||||
|
||||
initialize: function (map, editTools, button) {
|
||||
initialize: function(map, editTools, button) {
|
||||
this.map = map;
|
||||
this.editTools = editTools;
|
||||
this.button = button;
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
addHooks: function() {
|
||||
// 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);
|
||||
L.DomEvent.addListener(
|
||||
this.button.button,
|
||||
'click',
|
||||
this._addCreate,
|
||||
this
|
||||
);
|
||||
|
||||
this.editTools.featuresLayer.on('layeradd', this._bind, this);
|
||||
|
||||
|
|
@ -204,8 +244,13 @@ BR.EditingTooltip = L.Handler.extend({
|
|||
this.editTools.on('editable:disable', this._disable, this);
|
||||
},
|
||||
|
||||
removeHooks: function () {
|
||||
L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this);
|
||||
removeHooks: function() {
|
||||
L.DomEvent.removeListener(
|
||||
this.button.button,
|
||||
'click',
|
||||
this._addCreate,
|
||||
this
|
||||
);
|
||||
|
||||
this.editTools.featuresLayer.off('layeradd', this._bind, this);
|
||||
|
||||
|
|
@ -214,7 +259,7 @@ BR.EditingTooltip = L.Handler.extend({
|
|||
this.editTools.off('editable:disable', this._disable, this);
|
||||
},
|
||||
|
||||
_bind: function (e) {
|
||||
_bind: function(e) {
|
||||
// Position tooltip at bottom of circle, less distracting than
|
||||
// sticky with cursor or at center.
|
||||
|
||||
|
|
@ -226,18 +271,20 @@ BR.EditingTooltip = L.Handler.extend({
|
|||
|
||||
// Override to set position to south instead of center (circle latlng);
|
||||
// works better with zooming than updating offset to match radius
|
||||
layer.openTooltip = function (layer, latlng) {
|
||||
layer.openTooltip = function(layer, latlng) {
|
||||
if (!latlng && layer instanceof L.Layer) {
|
||||
latlng = L.latLng(
|
||||
layer.getBounds().getSouth(),
|
||||
0.5 * (layer.getBounds().getWest() + layer.getBounds().getEast())
|
||||
0.5 *
|
||||
(layer.getBounds().getWest() +
|
||||
layer.getBounds().getEast())
|
||||
);
|
||||
}
|
||||
L.Layer.prototype.openTooltip.call(this, layer, latlng);
|
||||
};
|
||||
},
|
||||
|
||||
_addCreate: function (e) {
|
||||
_addCreate: function(e) {
|
||||
// button cancel
|
||||
if (!this.editTools.drawing()) return;
|
||||
|
||||
|
|
@ -255,28 +302,32 @@ BR.EditingTooltip = L.Handler.extend({
|
|||
tooltip._tooltip = tooltip;
|
||||
|
||||
// simulate sticky feature (follow mouse) for map tooltip without layer
|
||||
var onOffMove = function (e) {
|
||||
var onOff = (e.type === 'tooltipclose') ? 'off' : 'on';
|
||||
var onOffMove = function(e) {
|
||||
var onOff = e.type === 'tooltipclose' ? 'off' : 'on';
|
||||
this._map[onOff]('mousemove', this._moveTooltip, this);
|
||||
}
|
||||
};
|
||||
this.map.on('tooltipopen', onOffMove, tooltip);
|
||||
this.map.on('tooltipclose', onOffMove, tooltip);
|
||||
|
||||
var onTooltipRemove = function (e) {
|
||||
var onTooltipRemove = function(e) {
|
||||
this.map.off('tooltipopen', onOffMove, e.tooltip);
|
||||
this.map.off('tooltipclose', onOffMove, e.tooltip);
|
||||
this.map.off('tooltipclose', onTooltipRemove, this);
|
||||
e.tooltip._tooltip = null;
|
||||
}
|
||||
};
|
||||
this.map.on('tooltipclose', onTooltipRemove, this);
|
||||
|
||||
tooltip.setTooltipContent(BR.NogoAreas.MSG_CREATE);
|
||||
this.map.openTooltip(tooltip, initialLatLng);
|
||||
|
||||
var closeTooltip = function () {
|
||||
var closeTooltip = function() {
|
||||
this.map.closeTooltip(tooltip);
|
||||
};
|
||||
this.editTools.once('editable:editing editable:drawing:cancel', closeTooltip, this);
|
||||
this.editTools.once(
|
||||
'editable:editing editable:drawing:cancel',
|
||||
closeTooltip,
|
||||
this
|
||||
);
|
||||
|
||||
if (BR.Browser.touch) {
|
||||
// can't move with cursor on touch devices, so show at start pos for a few seconds
|
||||
|
|
@ -285,51 +336,58 @@ BR.EditingTooltip = L.Handler.extend({
|
|||
},
|
||||
|
||||
_setCloseTimeout: function(layer) {
|
||||
var timeoutId = setTimeout(function () {
|
||||
layer.closeTooltip();
|
||||
var timeoutId = setTimeout(function() {
|
||||
layer.closeTooltip();
|
||||
}, this.options.closeTimeout);
|
||||
|
||||
// prevent timer to close tooltip that changed in the meantime
|
||||
layer.once('tooltipopen', function (e) {
|
||||
clearTimeout(timeoutId);
|
||||
layer.once('tooltipopen', function(e) {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
},
|
||||
|
||||
_postCreate: function () {
|
||||
_postCreate: function() {
|
||||
// editing is disabled by another handler, tooltip won't stay open before
|
||||
this.editTools.once('editable:disable', function (e) {
|
||||
|
||||
// show for a few seconds, as mouse often not hovering circle after create
|
||||
e.layer.openTooltip(e.layer);
|
||||
this._setCloseTimeout(e.layer);
|
||||
}, this);
|
||||
this.editTools.once(
|
||||
'editable:disable',
|
||||
function(e) {
|
||||
// show for a few seconds, as mouse often not hovering circle after create
|
||||
e.layer.openTooltip(e.layer);
|
||||
this._setCloseTimeout(e.layer);
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
_enable: function (e) {
|
||||
_enable: function(e) {
|
||||
e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED);
|
||||
|
||||
this.editTools.once('editable:editing', function(e) {
|
||||
e.layer.closeTooltip();
|
||||
}, this);
|
||||
this.editTools.once(
|
||||
'editable:editing',
|
||||
function(e) {
|
||||
e.layer.closeTooltip();
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
_disable: function (e) {
|
||||
_disable: function(e) {
|
||||
e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED);
|
||||
this._setCloseTimeout(e.layer);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
|
||||
|
||||
_computeDeleteLatLng: function () {
|
||||
_computeDeleteLatLng: function() {
|
||||
// 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),
|
||||
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: function() {
|
||||
this._deleteLatLng.update(this._computeDeleteLatLng());
|
||||
this._deleteLatLng.__vertex.update();
|
||||
},
|
||||
|
|
@ -350,15 +408,20 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
|
|||
this.fireAndForward('editable:deleted');
|
||||
},
|
||||
|
||||
initialize: function (map, feature, options) {
|
||||
L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options);
|
||||
initialize: function(map, feature, options) {
|
||||
L.Editable.CircleEditor.prototype.initialize.call(
|
||||
this,
|
||||
map,
|
||||
feature,
|
||||
options
|
||||
);
|
||||
this._deleteLatLng = this._computeDeleteLatLng();
|
||||
|
||||
// FeatureGroup instead of LayerGroup to propagate events to members
|
||||
this.editLayer = new L.FeatureGroup();
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
addHooks: function() {
|
||||
L.Editable.CircleEditor.prototype.addHooks.call(this);
|
||||
if (this.feature) {
|
||||
this._addDeleteMarker();
|
||||
|
|
@ -366,12 +429,12 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
|
|||
return this;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
reset: function() {
|
||||
L.Editable.CircleEditor.prototype.reset.call(this);
|
||||
this._addDeleteMarker();
|
||||
},
|
||||
|
||||
onDrawingMouseDown: function (e) {
|
||||
onDrawingMouseDown: function(e) {
|
||||
this._deleteLatLng.update(e.latlng);
|
||||
L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e);
|
||||
},
|
||||
|
|
@ -379,7 +442,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: function(e) {
|
||||
if (this.feature.getRadius() > 0) {
|
||||
this.commitDrawing(e);
|
||||
} else {
|
||||
|
|
@ -390,25 +453,24 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
|
|||
L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
|
||||
},
|
||||
|
||||
onVertexMarkerDrag: function (e) {
|
||||
onVertexMarkerDrag: function(e) {
|
||||
this._updateDeleteLatLng();
|
||||
L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
BR.DeleteMarker = L.Marker.extend({
|
||||
|
||||
options: {
|
||||
draggable: false,
|
||||
icon: L.divIcon({
|
||||
iconSize: BR.Browser.touch ? new L.Point(24, 24) : new L.Point(16, 16),
|
||||
iconSize: BR.Browser.touch
|
||||
? new L.Point(24, 24)
|
||||
: new L.Point(16, 16),
|
||||
className: 'leaflet-div-icon fa fa-trash-o nogo-delete-marker'
|
||||
})
|
||||
},
|
||||
|
||||
initialize: function (latlng, editor, options) {
|
||||
initialize: function(latlng, editor, options) {
|
||||
// derived from L.Editable.VertexMarker.initialize
|
||||
|
||||
// We don't use this._latlng, because on drag Leaflet replace it while
|
||||
|
|
@ -425,18 +487,18 @@ BR.DeleteMarker = L.Marker.extend({
|
|||
this.setZIndexOffset(editor.tools._lastZIndex);
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
onAdd: function(map) {
|
||||
L.Marker.prototype.onAdd.call(this, map);
|
||||
this.on('click', this.onClick);
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
onRemove: function(map) {
|
||||
delete this.latlng.__vertex;
|
||||
this.off('click', this.onClick);
|
||||
L.Marker.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
onClick: function (e) {
|
||||
onClick: function(e) {
|
||||
this.editor.delete();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
L.Routing.Draw.prototype._hideTrailer = function() {
|
||||
if (this._trailer.options.opacity !== 0.0) {
|
||||
this._trailer.setStyle({opacity: 0.0});
|
||||
}
|
||||
if (this._trailer.options.opacity !== 0.0) {
|
||||
this._trailer.setStyle({ opacity: 0.0 });
|
||||
}
|
||||
};
|
||||
|
||||
BR.Routing = L.Routing.extend({
|
||||
|
|
@ -20,7 +20,7 @@ BR.Routing = L.Routing.extend({
|
|||
zIndexOffset: -2000
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
onAdd: function(map) {
|
||||
this._segmentsCasing = new L.FeatureGroup().addTo(map);
|
||||
|
||||
var container = L.Routing.prototype.onAdd.call(this, map);
|
||||
|
|
@ -31,35 +31,50 @@ BR.Routing = L.Routing.extend({
|
|||
this._waypoints.on('layeradd', this._setMarkerOpacity, this);
|
||||
|
||||
// turn line mouse marker off while over waypoint marker
|
||||
this.on('waypoint:mouseover', function(e) {
|
||||
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
|
||||
if (this._dragging) { return; }
|
||||
this.on(
|
||||
'waypoint:mouseover',
|
||||
function(e) {
|
||||
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
|
||||
if (this._dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._mouseMarker.setOpacity(0.0);
|
||||
this._map.off('mousemove', this._segmentOnMousemove, this);
|
||||
this._suspended = true;
|
||||
}, this._edit);
|
||||
this._mouseMarker.setOpacity(0.0);
|
||||
this._map.off('mousemove', this._segmentOnMousemove, this);
|
||||
this._suspended = true;
|
||||
},
|
||||
this._edit
|
||||
);
|
||||
|
||||
this.on('waypoint:mouseout', function(e) {
|
||||
this._segmentOnMouseover(e);
|
||||
this._suspended = false;
|
||||
}, this._edit);
|
||||
this.on(
|
||||
'waypoint:mouseout',
|
||||
function(e) {
|
||||
this._segmentOnMouseover(e);
|
||||
this._suspended = false;
|
||||
},
|
||||
this._edit
|
||||
);
|
||||
|
||||
this._edit._mouseMarker.setIcon(L.divIcon({
|
||||
className: 'line-mouse-marker'
|
||||
,iconAnchor: [8, 8] // size/2 + border/2
|
||||
,iconSize: [16, 16]
|
||||
}));
|
||||
this._edit._mouseMarker.setIcon(
|
||||
L.divIcon({
|
||||
className: 'line-mouse-marker',
|
||||
iconAnchor: [8, 8], // size/2 + border/2
|
||||
iconSize: [16, 16]
|
||||
})
|
||||
);
|
||||
|
||||
// Forward mousemove event to snapped feature (for Leaflet.Elevation to
|
||||
// update indicator), see also L.Routing.Edit._segmentOnMousemove
|
||||
this._edit._mouseMarker.on('move', L.bind(function(e) {
|
||||
var latLng = e.latlng;
|
||||
if (latLng._feature) {
|
||||
this._mouseMarker._feature = latLng._feature;
|
||||
latLng._feature.fire('mousemove', e, true);
|
||||
}
|
||||
}, this._edit));
|
||||
this._edit._mouseMarker.on(
|
||||
'move',
|
||||
L.bind(function(e) {
|
||||
var latLng = e.latlng;
|
||||
if (latLng._feature) {
|
||||
this._mouseMarker._feature = latLng._feature;
|
||||
latLng._feature.fire('mousemove', e, true);
|
||||
}
|
||||
}, this._edit)
|
||||
);
|
||||
var mouseoutHandler = function(e) {
|
||||
if (this._mouseMarker._feature) {
|
||||
this._mouseMarker._feature.fire('mouseout', e, true);
|
||||
|
|
@ -79,12 +94,20 @@ BR.Routing = L.Routing.extend({
|
|||
|
||||
// intercept listener: only re-show draw trailer after marker hover
|
||||
// when edit is not active (i.e. wasn't also supended)
|
||||
this._parent.off('waypoint:mouseout' , this._catchWaypointEvent, this);
|
||||
this.on('waypoint:mouseout' , function(e) {
|
||||
if (!this._parent._edit._suspended) {
|
||||
this._catchWaypointEvent(e);
|
||||
}
|
||||
}, this);
|
||||
this._parent.off(
|
||||
'waypoint:mouseout',
|
||||
this._catchWaypointEvent,
|
||||
this
|
||||
);
|
||||
this.on(
|
||||
'waypoint:mouseout',
|
||||
function(e) {
|
||||
if (!this._parent._edit._suspended) {
|
||||
this._catchWaypointEvent(e);
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
});
|
||||
this._draw.on('disabled', function() {
|
||||
L.DomUtil.removeClass(map.getContainer(), 'routing-draw-enabled');
|
||||
|
|
@ -111,7 +134,12 @@ BR.Routing = L.Routing.extend({
|
|||
this._map.off('mouseout', hide, this);
|
||||
this._map.off('mouseover', show, this);
|
||||
L.DomEvent.off(this._map._controlContainer, 'mouseout', show, this);
|
||||
L.DomEvent.off(this._map._controlContainer, 'mouseover', hide, this);
|
||||
L.DomEvent.off(
|
||||
this._map._controlContainer,
|
||||
'mouseover',
|
||||
hide,
|
||||
this
|
||||
);
|
||||
});
|
||||
|
||||
// Call show after deleting last waypoint, but hide trailer.
|
||||
|
|
@ -119,191 +147,209 @@ BR.Routing = L.Routing.extend({
|
|||
// mouseout to show again never fires when deleted. Click handler
|
||||
// _onMouseClick aborts when hidden, so no waypoint can be added
|
||||
// although enabled.
|
||||
this.on('waypoint:click', function() {
|
||||
if (this._hidden && !this._parent._waypoints._first) {
|
||||
this._show();
|
||||
this._hideTrailer();
|
||||
}
|
||||
}, this._draw);
|
||||
this.on(
|
||||
'waypoint:click',
|
||||
function() {
|
||||
if (this._hidden && !this._parent._waypoints._first) {
|
||||
this._show();
|
||||
this._hideTrailer();
|
||||
}
|
||||
},
|
||||
this._draw
|
||||
);
|
||||
|
||||
// keys not working when map container does not have focus, use document instead
|
||||
L.DomEvent.removeListener(this._container, 'keyup', this._keyupListener);
|
||||
L.DomEvent.removeListener(
|
||||
this._container,
|
||||
'keyup',
|
||||
this._keyupListener
|
||||
);
|
||||
L.DomEvent.addListener(document, 'keyup', this._keyupListener, this);
|
||||
|
||||
// enable drawing mode
|
||||
this.draw(true);
|
||||
|
||||
return container;
|
||||
}
|
||||
},
|
||||
|
||||
,_addSegmentCasing: function(e) {
|
||||
var casing = L.polyline(e.layer.getLatLngs(), this.options.styles.trackCasing);
|
||||
this._segmentsCasing.addLayer(casing);
|
||||
e.layer._casing = casing;
|
||||
this._segments.bringToFront();
|
||||
}
|
||||
_addSegmentCasing: function(e) {
|
||||
var casing = L.polyline(
|
||||
e.layer.getLatLngs(),
|
||||
this.options.styles.trackCasing
|
||||
);
|
||||
this._segmentsCasing.addLayer(casing);
|
||||
e.layer._casing = casing;
|
||||
this._segments.bringToFront();
|
||||
},
|
||||
|
||||
,_removeSegmentCasing: function(e) {
|
||||
this._segmentsCasing.removeLayer(e.layer._casing);
|
||||
}
|
||||
_removeSegmentCasing: function(e) {
|
||||
this._segmentsCasing.removeLayer(e.layer._casing);
|
||||
},
|
||||
|
||||
,setOpacity: function(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.
|
||||
// SVG simple alpha compositing: Ca' = 1 - (1 - Ea) * (1 - Ca)
|
||||
// https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending
|
||||
var sourceOpacity = 1 - Math.sqrt(1 - opacity);
|
||||
setOpacity: function(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.
|
||||
// SVG simple alpha compositing: Ca' = 1 - (1 - Ea) * (1 - Ca)
|
||||
// https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending
|
||||
var sourceOpacity = 1 - Math.sqrt(1 - opacity);
|
||||
|
||||
this.options.styles.track.opacity = sourceOpacity;
|
||||
this.options.styles.trackCasing.opacity = sourceOpacity;
|
||||
this.options.icons.opacity = opacity;
|
||||
this.options.styles.track.opacity = sourceOpacity;
|
||||
this.options.styles.trackCasing.opacity = sourceOpacity;
|
||||
this.options.icons.opacity = opacity;
|
||||
|
||||
this._segments.setStyle({
|
||||
opacity: sourceOpacity
|
||||
});
|
||||
this._segmentsCasing.setStyle({
|
||||
opacity: sourceOpacity
|
||||
});
|
||||
this._waypoints.eachLayer(function(marker) {
|
||||
marker.setOpacity(opacity);
|
||||
});
|
||||
}
|
||||
|
||||
,_setMarkerOpacity: function(e) {
|
||||
e.layer.setOpacity(this.options.icons.opacity);
|
||||
}
|
||||
|
||||
,_removeMarkerEvents: function(marker) {
|
||||
marker.off('mouseover', this._fireWaypointEvent, this);
|
||||
marker.off('mouseout' , this._fireWaypointEvent, this);
|
||||
marker.off('dragstart', this._fireWaypointEvent, this);
|
||||
marker.off('dragend' , this._fireWaypointEvent, this);
|
||||
marker.off('drag' , this._fireWaypointEvent, this);
|
||||
marker.off('click' , this._fireWaypointEvent, this);
|
||||
}
|
||||
|
||||
,clear: function() {
|
||||
var drawEnabled = this._draw._enabled;
|
||||
var current = this._waypoints._first;
|
||||
|
||||
this.draw(false);
|
||||
|
||||
if (current === null) { return; }
|
||||
this._removeMarkerEvents(current);
|
||||
while (current._routing.nextMarker) {
|
||||
var marker = current._routing.nextMarker;
|
||||
this._removeMarkerEvents(marker);
|
||||
current = marker;
|
||||
};
|
||||
|
||||
this._waypoints._first = null;
|
||||
this._waypoints._last = null;
|
||||
this._waypoints.clearLayers();
|
||||
this._segments.clearLayers();
|
||||
|
||||
if (drawEnabled) {
|
||||
this.draw(true);
|
||||
}
|
||||
}
|
||||
|
||||
,setWaypoints: function(latLngs, cb) {
|
||||
var i;
|
||||
var callbackCount = 0;
|
||||
var firstErr;
|
||||
var $this = this;
|
||||
|
||||
var callback = function(err, data) {
|
||||
callbackCount++;
|
||||
firstErr = firstErr || err;
|
||||
if (callbackCount >= latLngs.length) {
|
||||
$this.fire('routing:setWaypointsEnd', { err: firstErr });
|
||||
if (cb) {
|
||||
cb(firstErr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.fire('routing:setWaypointsStart');
|
||||
for (i = 0; latLngs && i < latLngs.length; i++) {
|
||||
this.addWaypoint(latLngs[i], this._waypoints._last, null, callback);
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
var latLngs = [];
|
||||
|
||||
this._eachSegment(function(m1, m2, line) {
|
||||
// omit if null (still calculating) or error
|
||||
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
|
||||
if (line && line.feature) {
|
||||
latLngs = latLngs.concat(line.getLatLngs());
|
||||
}
|
||||
});
|
||||
|
||||
return L.polyline(latLngs);
|
||||
}
|
||||
|
||||
,_routeSegment: function(m1, m2, cb) {
|
||||
var loadingTrailer;
|
||||
|
||||
// change segment color before request to indicate recalculation (mark old)
|
||||
if (m1 && m1._routing.nextLine !== null) {
|
||||
m1._routing.nextLine.setStyle({color: 'dimgray' });
|
||||
}
|
||||
|
||||
// animate dashed trailer as loading indicator
|
||||
if (m1 && m2) {
|
||||
loadingTrailer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], {
|
||||
color: this.options.styles.track.color,
|
||||
opacity: this.options.styles.trailer.opacity,
|
||||
dashArray: [10, 10],
|
||||
className: 'loading-trailer'
|
||||
this._segments.setStyle({
|
||||
opacity: sourceOpacity
|
||||
});
|
||||
loadingTrailer.addTo(this._map);
|
||||
}
|
||||
this._segmentsCasing.setStyle({
|
||||
opacity: sourceOpacity
|
||||
});
|
||||
this._waypoints.eachLayer(function(marker) {
|
||||
marker.setOpacity(opacity);
|
||||
});
|
||||
},
|
||||
|
||||
L.Routing.prototype._routeSegment.call(this, m1, m2, L.bind(function(err, data) {
|
||||
if (loadingTrailer) {
|
||||
this._map.removeLayer(loadingTrailer);
|
||||
_setMarkerOpacity: function(e) {
|
||||
e.layer.setOpacity(this.options.icons.opacity);
|
||||
},
|
||||
|
||||
_removeMarkerEvents: function(marker) {
|
||||
marker.off('mouseover', this._fireWaypointEvent, this);
|
||||
marker.off('mouseout', this._fireWaypointEvent, this);
|
||||
marker.off('dragstart', this._fireWaypointEvent, this);
|
||||
marker.off('dragend', this._fireWaypointEvent, this);
|
||||
marker.off('drag', this._fireWaypointEvent, this);
|
||||
marker.off('click', this._fireWaypointEvent, this);
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
var drawEnabled = this._draw._enabled;
|
||||
var current = this._waypoints._first;
|
||||
|
||||
this.draw(false);
|
||||
|
||||
if (current === null) {
|
||||
return;
|
||||
}
|
||||
this._removeMarkerEvents(current);
|
||||
while (current._routing.nextMarker) {
|
||||
var marker = current._routing.nextMarker;
|
||||
this._removeMarkerEvents(marker);
|
||||
current = marker;
|
||||
}
|
||||
cb(err, data);
|
||||
}, this));
|
||||
}
|
||||
|
||||
,getSegments: function() {
|
||||
var segments = [];
|
||||
this._waypoints._first = null;
|
||||
this._waypoints._last = null;
|
||||
this._waypoints.clearLayers();
|
||||
this._segments.clearLayers();
|
||||
|
||||
this._eachSegment(function(m1, m2, line) {
|
||||
// omit if null (still calculating) or error
|
||||
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
|
||||
if (line && line.feature) {
|
||||
segments.push(line);
|
||||
}
|
||||
});
|
||||
if (drawEnabled) {
|
||||
this.draw(true);
|
||||
}
|
||||
},
|
||||
|
||||
return segments;
|
||||
}
|
||||
setWaypoints: function(latLngs, cb) {
|
||||
var i;
|
||||
var callbackCount = 0;
|
||||
var firstErr;
|
||||
var $this = this;
|
||||
|
||||
// add 'esc' to disable drawing
|
||||
,_keyupListener: function (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this._draw.disable();
|
||||
} else {
|
||||
L.Routing.prototype._keyupListener.call(this, e);
|
||||
var callback = function(err, data) {
|
||||
callbackCount++;
|
||||
firstErr = firstErr || err;
|
||||
if (callbackCount >= latLngs.length) {
|
||||
$this.fire('routing:setWaypointsEnd', { err: firstErr });
|
||||
if (cb) {
|
||||
cb(firstErr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.fire('routing:setWaypointsStart');
|
||||
for (i = 0; latLngs && i < latLngs.length; i++) {
|
||||
this.addWaypoint(latLngs[i], this._waypoints._last, null, callback);
|
||||
}
|
||||
},
|
||||
|
||||
// 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() {
|
||||
var latLngs = [];
|
||||
|
||||
this._eachSegment(function(m1, m2, line) {
|
||||
// omit if null (still calculating) or error
|
||||
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
|
||||
if (line && line.feature) {
|
||||
latLngs = latLngs.concat(line.getLatLngs());
|
||||
}
|
||||
});
|
||||
|
||||
return L.polyline(latLngs);
|
||||
},
|
||||
|
||||
_routeSegment: function(m1, m2, cb) {
|
||||
var loadingTrailer;
|
||||
|
||||
// change segment color before request to indicate recalculation (mark old)
|
||||
if (m1 && m1._routing.nextLine !== null) {
|
||||
m1._routing.nextLine.setStyle({ color: 'dimgray' });
|
||||
}
|
||||
|
||||
// animate dashed trailer as loading indicator
|
||||
if (m1 && m2) {
|
||||
loadingTrailer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], {
|
||||
color: this.options.styles.track.color,
|
||||
opacity: this.options.styles.trailer.opacity,
|
||||
dashArray: [10, 10],
|
||||
className: 'loading-trailer'
|
||||
});
|
||||
loadingTrailer.addTo(this._map);
|
||||
}
|
||||
|
||||
L.Routing.prototype._routeSegment.call(
|
||||
this,
|
||||
m1,
|
||||
m2,
|
||||
L.bind(function(err, data) {
|
||||
if (loadingTrailer) {
|
||||
this._map.removeLayer(loadingTrailer);
|
||||
}
|
||||
cb(err, data);
|
||||
}, this)
|
||||
);
|
||||
},
|
||||
|
||||
getSegments: function() {
|
||||
var segments = [];
|
||||
|
||||
this._eachSegment(function(m1, m2, line) {
|
||||
// omit if null (still calculating) or error
|
||||
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
|
||||
if (line && line.feature) {
|
||||
segments.push(line);
|
||||
}
|
||||
});
|
||||
|
||||
return segments;
|
||||
},
|
||||
|
||||
// add 'esc' to disable drawing
|
||||
_keyupListener: function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
this._draw.disable();
|
||||
} else {
|
||||
L.Routing.prototype._keyupListener.call(this, e);
|
||||
}
|
||||
},
|
||||
|
||||
isDrawing: function() {
|
||||
return this._draw._enabled;
|
||||
},
|
||||
|
||||
reverse: function() {
|
||||
var waypoints = this.getWaypoints();
|
||||
waypoints.reverse();
|
||||
this.clear();
|
||||
this.setWaypoints(waypoints);
|
||||
}
|
||||
}
|
||||
|
||||
,isDrawing: function () {
|
||||
return this._draw._enabled;
|
||||
}
|
||||
|
||||
,reverse: function() {
|
||||
var waypoints = this.getWaypoints();
|
||||
waypoints.reverse();
|
||||
this.clear();
|
||||
this.setWaypoints(waypoints);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
|
|||
|
||||
options: {
|
||||
position: 'right',
|
||||
container: 'sidebar',
|
||||
container: 'sidebar',
|
||||
tabContainer: 'sidebarTabs',
|
||||
autopan: false,
|
||||
defaultTabId: '',
|
||||
|
|
@ -13,26 +13,34 @@ BR.Sidebar = L.Control.Sidebar.extend({
|
|||
listeningTabs: {}
|
||||
},
|
||||
|
||||
initialize: function (id, options) {
|
||||
initialize: function(id, options) {
|
||||
L.Control.Sidebar.prototype.initialize.call(this, id, options);
|
||||
|
||||
this.oldTab = null;
|
||||
},
|
||||
|
||||
addTo: function (map) {
|
||||
addTo: function(map) {
|
||||
L.Control.Sidebar.prototype.addTo.call(this, map);
|
||||
|
||||
this.on('content', this._notifyOnContent, this);
|
||||
this.on('closing', this._notifyOnClose, this);
|
||||
this.on('toggleExpand', this._notifyOnResize, this);
|
||||
|
||||
this.on('closing', function () {
|
||||
this._map.getContainer().focus();
|
||||
}, this);
|
||||
this.on(
|
||||
'closing',
|
||||
function() {
|
||||
this._map.getContainer().focus();
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
this._rememberTabState();
|
||||
|
||||
if (L.Browser.touch && BR.Browser.touchScreenDetectable && !BR.Browser.touchScreen) {
|
||||
if (
|
||||
L.Browser.touch &&
|
||||
BR.Browser.touchScreenDetectable &&
|
||||
!BR.Browser.touchScreen
|
||||
) {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-touch');
|
||||
L.DomUtil.removeClass(this._tabContainer, 'leaflet-touch');
|
||||
}
|
||||
|
|
@ -47,12 +55,12 @@ BR.Sidebar = L.Control.Sidebar.extend({
|
|||
return this;
|
||||
},
|
||||
|
||||
_rememberTabState: function () {
|
||||
_rememberTabState: function() {
|
||||
if (BR.Util.localStorageAvailable()) {
|
||||
this.on('content closing', this._storeActiveTab, this);
|
||||
|
||||
var tabId = localStorage.getItem(this.storageId);
|
||||
|
||||
|
||||
// 'true': legacy value for toggling old sidebar
|
||||
if (tabId === 'true') {
|
||||
tabId = this.options.defaultTabId;
|
||||
|
|
@ -66,42 +74,42 @@ BR.Sidebar = L.Control.Sidebar.extend({
|
|||
}
|
||||
},
|
||||
|
||||
_notifyShow: function (tab) {
|
||||
_notifyShow: function(tab) {
|
||||
if (tab && tab.show) {
|
||||
tab.show();
|
||||
}
|
||||
},
|
||||
|
||||
_notifyHide: function (tab) {
|
||||
_notifyHide: function(tab) {
|
||||
if (tab && tab.hide) {
|
||||
tab.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_notifyOnContent: function (e) {
|
||||
_notifyOnContent: function(e) {
|
||||
var tab = this.options.listeningTabs[e.id];
|
||||
this._notifyHide(this.oldTab);
|
||||
this._notifyShow(tab);
|
||||
this.oldTab = tab;
|
||||
},
|
||||
|
||||
_notifyOnClose: function (e) {
|
||||
|
||||
_notifyOnClose: function(e) {
|
||||
this._notifyHide(this.oldTab);
|
||||
this.oldTab = null;
|
||||
},
|
||||
|
||||
_notifyOnResize: function (e) {
|
||||
|
||||
_notifyOnResize: function(e) {
|
||||
var tab = this.oldTab;
|
||||
if (tab && tab.onResize) {
|
||||
tab.onResize();
|
||||
}
|
||||
},
|
||||
|
||||
_storeActiveTab: function (e) {
|
||||
_storeActiveTab: function(e) {
|
||||
localStorage.setItem(this.storageId, e.id || '');
|
||||
}
|
||||
});
|
||||
|
||||
BR.sidebar = function (divId, options) {
|
||||
BR.sidebar = function(divId, options) {
|
||||
return new BR.Sidebar(divId, options);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
(function(window) {
|
||||
var HAS_HASHCHANGE = (function() {
|
||||
var doc_mode = window.documentMode;
|
||||
return ('onhashchange' in window) &&
|
||||
(doc_mode === undefined || doc_mode > 7);
|
||||
return (
|
||||
'onhashchange' in window && (doc_mode === undefined || doc_mode > 7)
|
||||
);
|
||||
})();
|
||||
|
||||
L.Hash = function(map, options) {
|
||||
|
|
@ -14,17 +15,17 @@
|
|||
};
|
||||
|
||||
L.Hash.parseHash = function(hash) {
|
||||
if(hash.indexOf('#map=') === 0) {
|
||||
if (hash.indexOf('#map=') === 0) {
|
||||
hash = hash.substr(5);
|
||||
}
|
||||
var args = hash.split(/\&(.+)/);
|
||||
var mapsArgs = args[0].split("/");
|
||||
var mapsArgs = args[0].split('/');
|
||||
if (mapsArgs.length == 4) {
|
||||
var zoom = parseInt(mapsArgs[0], 10),
|
||||
lat = parseFloat(mapsArgs[1]),
|
||||
lon = parseFloat(mapsArgs[2]),
|
||||
layers = this.parseLayers(mapsArgs[3]),
|
||||
additional = args[1];
|
||||
lat = parseFloat(mapsArgs[1]),
|
||||
lon = parseFloat(mapsArgs[2]),
|
||||
layers = this.parseLayers(mapsArgs[3]),
|
||||
additional = args[1];
|
||||
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
@ -40,7 +41,7 @@
|
|||
}
|
||||
};
|
||||
|
||||
L.Hash.formatHash = function(map) {
|
||||
(L.Hash.formatHash = function(map) {
|
||||
var center = map.getCenter(),
|
||||
zoom = map.getZoom(),
|
||||
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
|
||||
|
|
@ -52,7 +53,7 @@
|
|||
center.lng.toFixed(precision),
|
||||
layers
|
||||
];
|
||||
url = "#map=" + params.join("/");
|
||||
url = '#map=' + params.join('/');
|
||||
if (this.additionalCb != null) {
|
||||
var additional = this.additionalCb();
|
||||
if (additional != null) {
|
||||
|
|
@ -60,232 +61,261 @@
|
|||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
}),
|
||||
(L.Hash.prototype = {
|
||||
options: {
|
||||
layerSeparator: ','
|
||||
},
|
||||
map: null,
|
||||
lastHash: null,
|
||||
|
||||
L.Hash.prototype = {
|
||||
options: {
|
||||
layerSeparator: ','
|
||||
},
|
||||
map: null,
|
||||
lastHash: null,
|
||||
parseHash: L.Hash.parseHash,
|
||||
formatHash: L.Hash.formatHash,
|
||||
|
||||
parseHash: L.Hash.parseHash,
|
||||
formatHash: L.Hash.formatHash,
|
||||
init: function(map, options) {
|
||||
this.map = map;
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
init: function(map, options) {
|
||||
this.map = map;
|
||||
L.Util.setOptions(this, options);
|
||||
// reset the hash
|
||||
this.lastHash = null;
|
||||
this.onHashChange();
|
||||
|
||||
// reset the hash
|
||||
this.lastHash = null;
|
||||
this.onHashChange();
|
||||
if (!this.isListening) {
|
||||
this.startListening();
|
||||
}
|
||||
},
|
||||
|
||||
if (!this.isListening) {
|
||||
this.startListening();
|
||||
}
|
||||
},
|
||||
_parseLayers: function(layersParam, layerSeparator) {
|
||||
var layers = layersParam.split(layerSeparator).map(
|
||||
L.bind(function(layerEncoded) {
|
||||
var obj = null;
|
||||
var layerString = decodeURIComponent(layerEncoded);
|
||||
|
||||
_parseLayers: function (layersParam, layerSeparator) {
|
||||
var layers = layersParam.split(layerSeparator).map(L.bind(function (layerEncoded) {
|
||||
var obj = null;
|
||||
var layerString = decodeURIComponent(layerEncoded);
|
||||
if (layerString) {
|
||||
obj = this._getLayerFromString(layerString);
|
||||
}
|
||||
|
||||
if (layerString) {
|
||||
obj = this._getLayerFromString(layerString);
|
||||
return obj;
|
||||
}, this)
|
||||
);
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
parseLayers: function(layersParam) {
|
||||
var countFoundLayers = function(count, obj) {
|
||||
if (obj) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
var layers = this._parseLayers(
|
||||
layersParam,
|
||||
this.options.layerSeparator
|
||||
);
|
||||
var found = layers.reduce(countFoundLayers, 0);
|
||||
|
||||
if (found < layers.length) {
|
||||
// legacy support for name instead of id and '-' layer separator
|
||||
var layersLegacy = this._parseLayers(layersParam, '-');
|
||||
var foundLegacy = layersLegacy.reduce(countFoundLayers, 0);
|
||||
|
||||
if (foundLegacy > found) {
|
||||
layers = layersLegacy;
|
||||
}
|
||||
}
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
activateLayers: function(layers) {
|
||||
var layersControl = this.options.layersControl;
|
||||
var added = false;
|
||||
|
||||
layersControl.removeActiveLayers();
|
||||
|
||||
layers.forEach(
|
||||
L.bind(function(obj, index, array) {
|
||||
if (obj) {
|
||||
layersControl.activateLayer(obj.layer);
|
||||
if (obj && !obj.overlay) {
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
}, this)
|
||||
);
|
||||
|
||||
if (!added) {
|
||||
// if we couldn't add layers (removed or invalid name), add the default one
|
||||
layersControl.activateDefaultBaseLayer();
|
||||
}
|
||||
},
|
||||
|
||||
formatLayers: function() {
|
||||
var objList = this.options.layersControl.getActiveLayers();
|
||||
var layerList = objList.map(
|
||||
L.bind(function(obj) {
|
||||
return encodeURIComponent(this._toLayerString(obj));
|
||||
}, this)
|
||||
);
|
||||
|
||||
return layerList.join(this.options.layerSeparator);
|
||||
},
|
||||
|
||||
_toLayerString: function(obj) {
|
||||
return obj.layer.id ? obj.layer.id : obj.name;
|
||||
},
|
||||
|
||||
_getLayerFromString: function(layerString) {
|
||||
var layersControl = this.options.layersControl;
|
||||
var obj = layersControl.getLayerById(layerString);
|
||||
|
||||
if (!obj) {
|
||||
// fallback to name for custom and config layers
|
||||
obj = layersControl.getLayer(layerString);
|
||||
|
||||
if (!obj) {
|
||||
// legacy layer name support
|
||||
obj = layersControl.getLayerByLegacyName(layerString);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}, this));
|
||||
},
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
parseLayers: function (layersParam) {
|
||||
var countFoundLayers = function (count, obj) {
|
||||
if (obj) {
|
||||
count++;
|
||||
removeFrom: function(map) {
|
||||
if (this.changeTimeout) {
|
||||
clearTimeout(this.changeTimeout);
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
var layers = this._parseLayers(layersParam, this.options.layerSeparator);
|
||||
var found = layers.reduce(countFoundLayers, 0);
|
||||
|
||||
if (found < layers.length) {
|
||||
// legacy support for name instead of id and '-' layer separator
|
||||
var layersLegacy = this._parseLayers(layersParam, '-');
|
||||
var foundLegacy = layersLegacy.reduce(countFoundLayers, 0);
|
||||
|
||||
if (foundLegacy > found) {
|
||||
layers = layersLegacy;
|
||||
if (this.isListening) {
|
||||
this.stopListening();
|
||||
}
|
||||
}
|
||||
|
||||
return layers;
|
||||
},
|
||||
this.map = null;
|
||||
},
|
||||
|
||||
activateLayers: function (layers) {
|
||||
var layersControl = this.options.layersControl;
|
||||
var added = false;
|
||||
onMapMove: function() {
|
||||
// bail if we're moving the map (updating from a hash),
|
||||
// or if the map is not yet loaded
|
||||
|
||||
layersControl.removeActiveLayers();
|
||||
if (this.movingMap || !this.map._loaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
layers.forEach(L.bind(function(obj, index, array) {
|
||||
if (obj) {
|
||||
layersControl.activateLayer(obj.layer);
|
||||
if (obj && !obj.overlay) {
|
||||
added = true;
|
||||
var hash = this.formatHash(this.map);
|
||||
if (this.lastHash != hash) {
|
||||
location.replace(hash);
|
||||
this.lastHash = hash;
|
||||
}
|
||||
},
|
||||
|
||||
movingMap: false,
|
||||
update: function() {
|
||||
var hash = location.hash;
|
||||
if (hash === this.lastHash) {
|
||||
return;
|
||||
}
|
||||
var parsed = this.parseHash(hash);
|
||||
if (!parsed) {
|
||||
// migration from old hash style to new one
|
||||
if (this.onInvalidHashChangeCb != null) {
|
||||
var newHash = this.onInvalidHashChangeCb(hash);
|
||||
if (newHash != null && newHash != hash) {
|
||||
parsed = this.parseHash(newHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this));
|
||||
|
||||
if (!added) {
|
||||
// if we couldn't add layers (removed or invalid name), add the default one
|
||||
layersControl.activateDefaultBaseLayer();
|
||||
}
|
||||
},
|
||||
if (parsed) {
|
||||
this.movingMap = true;
|
||||
|
||||
formatLayers: function () {
|
||||
var objList = this.options.layersControl.getActiveLayers();
|
||||
var layerList = objList.map(L.bind(function (obj) {
|
||||
return encodeURIComponent(this._toLayerString(obj));
|
||||
}, this));
|
||||
this.map.setView(parsed.center, parsed.zoom);
|
||||
|
||||
return layerList.join(this.options.layerSeparator)
|
||||
},
|
||||
this.activateLayers(parsed.layers);
|
||||
|
||||
_toLayerString: function (obj) {
|
||||
return obj.layer.id ? obj.layer.id : obj.name;
|
||||
},
|
||||
if (this.onHashChangeCb != null) {
|
||||
this.onHashChangeCb(parsed.additional);
|
||||
}
|
||||
|
||||
_getLayerFromString: function (layerString) {
|
||||
var layersControl = this.options.layersControl;
|
||||
var obj = layersControl.getLayerById(layerString);
|
||||
|
||||
if (!obj) {
|
||||
// fallback to name for custom and config layers
|
||||
obj = layersControl.getLayer(layerString);
|
||||
|
||||
if (!obj) {
|
||||
// legacy layer name support
|
||||
obj = layersControl.getLayerByLegacyName(layerString);
|
||||
this.movingMap = false;
|
||||
} else {
|
||||
this.onMapMove(this.map);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
return obj;
|
||||
},
|
||||
// defer hash change updates every 100ms
|
||||
changeDefer: 100,
|
||||
changeTimeout: null,
|
||||
onHashChange: function() {
|
||||
// throttle calls to update() so that they only happen every
|
||||
// `changeDefer` ms
|
||||
if (!this.changeTimeout) {
|
||||
var that = this;
|
||||
this.changeTimeout = setTimeout(function() {
|
||||
that.update();
|
||||
that.changeTimeout = null;
|
||||
}, this.changeDefer);
|
||||
}
|
||||
},
|
||||
|
||||
removeFrom: function(map) {
|
||||
if (this.changeTimeout) {
|
||||
clearTimeout(this.changeTimeout);
|
||||
}
|
||||
isListening: false,
|
||||
hashChangeInterval: null,
|
||||
startListening: function() {
|
||||
this.map.on(
|
||||
'moveend layeradd layerremove',
|
||||
this.onMapMove,
|
||||
this
|
||||
);
|
||||
|
||||
if (this.isListening) {
|
||||
this.stopListening();
|
||||
}
|
||||
if (HAS_HASHCHANGE) {
|
||||
L.DomEvent.addListener(
|
||||
window,
|
||||
'hashchange',
|
||||
this.onHashChange
|
||||
);
|
||||
} else {
|
||||
clearInterval(this.hashChangeInterval);
|
||||
this.hashChangeInterval = setInterval(
|
||||
this.onHashChange,
|
||||
50
|
||||
);
|
||||
}
|
||||
this.isListening = true;
|
||||
},
|
||||
|
||||
this.map = null;
|
||||
},
|
||||
stopListening: function() {
|
||||
this.map.off(
|
||||
'moveend layeradd layerremove',
|
||||
this.onMapMove,
|
||||
this
|
||||
);
|
||||
|
||||
onMapMove: function() {
|
||||
// bail if we're moving the map (updating from a hash),
|
||||
// or if the map is not yet loaded
|
||||
if (HAS_HASHCHANGE) {
|
||||
L.DomEvent.removeListener(
|
||||
window,
|
||||
'hashchange',
|
||||
this.onHashChange
|
||||
);
|
||||
} else {
|
||||
clearInterval(this.hashChangeInterval);
|
||||
}
|
||||
this.isListening = false;
|
||||
},
|
||||
|
||||
if (this.movingMap || !this.map._loaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var hash = this.formatHash(this.map);
|
||||
if (this.lastHash != hash) {
|
||||
location.replace(hash);
|
||||
this.lastHash = hash;
|
||||
}
|
||||
},
|
||||
|
||||
movingMap: false,
|
||||
update: function() {
|
||||
var hash = location.hash;
|
||||
if (hash === this.lastHash) {
|
||||
return;
|
||||
}
|
||||
var parsed = this.parseHash(hash);
|
||||
if (!parsed) {
|
||||
// migration from old hash style to new one
|
||||
if (this.onInvalidHashChangeCb != null) {
|
||||
var newHash = this.onInvalidHashChangeCb(hash);
|
||||
if (newHash != null && newHash != hash) {
|
||||
parsed = this.parseHash(newHash);
|
||||
_keyByValue: function(obj, value) {
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
if (obj[key] === value) {
|
||||
return key;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed) {
|
||||
this.movingMap = true;
|
||||
|
||||
this.map.setView(parsed.center, parsed.zoom);
|
||||
|
||||
this.activateLayers(parsed.layers);
|
||||
|
||||
if (this.onHashChangeCb != null) {
|
||||
this.onHashChangeCb(parsed.additional);
|
||||
}
|
||||
|
||||
this.movingMap = false;
|
||||
} else {
|
||||
this.onMapMove(this.map);
|
||||
}
|
||||
},
|
||||
|
||||
// defer hash change updates every 100ms
|
||||
changeDefer: 100,
|
||||
changeTimeout: null,
|
||||
onHashChange: function() {
|
||||
// throttle calls to update() so that they only happen every
|
||||
// `changeDefer` ms
|
||||
if (!this.changeTimeout) {
|
||||
var that = this;
|
||||
this.changeTimeout = setTimeout(function() {
|
||||
that.update();
|
||||
that.changeTimeout = null;
|
||||
}, this.changeDefer);
|
||||
}
|
||||
},
|
||||
|
||||
isListening: false,
|
||||
hashChangeInterval: null,
|
||||
startListening: function() {
|
||||
this.map.on("moveend layeradd layerremove", this.onMapMove, this);
|
||||
|
||||
if (HAS_HASHCHANGE) {
|
||||
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
|
||||
} else {
|
||||
clearInterval(this.hashChangeInterval);
|
||||
this.hashChangeInterval = setInterval(this.onHashChange, 50);
|
||||
}
|
||||
this.isListening = true;
|
||||
},
|
||||
|
||||
stopListening: function() {
|
||||
this.map.off("moveend layeradd layerremove", this.onMapMove, this);
|
||||
|
||||
if (HAS_HASHCHANGE) {
|
||||
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
|
||||
} else {
|
||||
clearInterval(this.hashChangeInterval);
|
||||
}
|
||||
this.isListening = false;
|
||||
},
|
||||
|
||||
_keyByValue: function(obj, value) {
|
||||
for(var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
if (obj[key] === value) {
|
||||
return key;
|
||||
} else { return null; };
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
L.hash = function(map, options) {
|
||||
return new L.Hash(map, options);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,26 @@
|
|||
BR.stravaSegments = function (map, layersControl) {
|
||||
const stravaControl = L.control.stravaSegments({
|
||||
runningTitle: i18next.t('map.strava-running'),
|
||||
bikingTitle: i18next.t('map.strava-biking'),
|
||||
loadingTitle: i18next.t('map.loading'),
|
||||
stravaToken: BR.keys.strava
|
||||
})
|
||||
.addTo(map);
|
||||
layersControl.addOverlay(stravaControl.stravaLayer, i18next.t('map.layer.strava-segments'));
|
||||
BR.stravaSegments = function(map, layersControl) {
|
||||
const stravaControl = L.control
|
||||
.stravaSegments({
|
||||
runningTitle: i18next.t('map.strava-running'),
|
||||
bikingTitle: i18next.t('map.strava-biking'),
|
||||
loadingTitle: i18next.t('map.loading'),
|
||||
stravaToken: BR.keys.strava
|
||||
})
|
||||
.addTo(map);
|
||||
layersControl.addOverlay(
|
||||
stravaControl.stravaLayer,
|
||||
i18next.t('map.layer.strava-segments')
|
||||
);
|
||||
stravaControl.onError = function(err) {
|
||||
BR.message.showError(i18next.t('warning.strava-error', {error: err && err.message ? err.message : err}));
|
||||
}
|
||||
BR.message.showError(
|
||||
i18next.t('warning.strava-error', {
|
||||
error: err && err.message ? err.message : err
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
// hide strava buttons when layer is inactive
|
||||
var toggleStravaControl = function () {
|
||||
var toggleStravaControl = function() {
|
||||
var stravaBar = stravaControl.runningButton.button.parentElement;
|
||||
stravaBar.hidden = !stravaBar.hidden;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ L.BRouter = L.Class.extend({
|
|||
statics: {
|
||||
// NOTE: the routing API used here is not public!
|
||||
// /brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml
|
||||
URL_TEMPLATE: '/brouter?lonlats={lonlats}&nogos={nogos}&polylines={polylines}&polygons={polygons}&profile={profile}&alternativeidx={alternativeidx}&format={format}',
|
||||
URL_TEMPLATE:
|
||||
'/brouter?lonlats={lonlats}&nogos={nogos}&polylines={polylines}&polygons={polygons}&profile={profile}&alternativeidx={alternativeidx}&format={format}',
|
||||
URL_PROFILE_UPLOAD: BR.conf.host + '/brouter/profile',
|
||||
PRECISION: 6,
|
||||
NUMBER_SEPARATOR: ',',
|
||||
|
|
@ -10,18 +11,20 @@ L.BRouter = L.Class.extend({
|
|||
ABORTED_ERROR: 'aborted'
|
||||
},
|
||||
|
||||
options: {
|
||||
},
|
||||
options: {},
|
||||
|
||||
initialize: function (options) {
|
||||
initialize: function(options) {
|
||||
L.setOptions(this, options);
|
||||
|
||||
this.queue = async.queue(L.bind(function (task, callback) {
|
||||
this.getRoute(task.segment, callback);
|
||||
}, this), 1);
|
||||
this.queue = async.queue(
|
||||
L.bind(function(task, callback) {
|
||||
this.getRoute(task.segment, callback);
|
||||
}, this),
|
||||
1
|
||||
);
|
||||
|
||||
// patch to call callbacks on kill for cleanup (loadingTrailer)
|
||||
this.queue.kill = function () {
|
||||
this.queue.kill = function() {
|
||||
var aborted = this.tasks;
|
||||
this.drain = null;
|
||||
this.tasks = [];
|
||||
|
|
@ -41,17 +44,29 @@ L.BRouter = L.Class.extend({
|
|||
if (this._getLonLatsString(latLngs) != null)
|
||||
params.lonlats = this._getLonLatsString(latLngs);
|
||||
|
||||
if (this.options.nogos && this._getNogosString(this.options.nogos).length > 0)
|
||||
if (
|
||||
this.options.nogos &&
|
||||
this._getNogosString(this.options.nogos).length > 0
|
||||
)
|
||||
params.nogos = this._getNogosString(this.options.nogos);
|
||||
|
||||
if (this.options.polylines && this._getNogosPolylinesString(this.options.polylines).length > 0)
|
||||
params.polylines = this._getNogosPolylinesString(this.options.polylines);
|
||||
if (
|
||||
this.options.polylines &&
|
||||
this._getNogosPolylinesString(this.options.polylines).length > 0
|
||||
)
|
||||
params.polylines = this._getNogosPolylinesString(
|
||||
this.options.polylines
|
||||
);
|
||||
|
||||
if (this.options.polygons && this._getNogosPolygonsString(this.options.polygons).length > 0)
|
||||
params.polygons = this._getNogosPolygonsString(this.options.polygons);
|
||||
if (
|
||||
this.options.polygons &&
|
||||
this._getNogosPolygonsString(this.options.polygons).length > 0
|
||||
)
|
||||
params.polygons = this._getNogosPolygonsString(
|
||||
this.options.polygons
|
||||
);
|
||||
|
||||
if (this.options.profile != null)
|
||||
params.profile = this.options.profile;
|
||||
if (this.options.profile != null) params.profile = this.options.profile;
|
||||
|
||||
params.alternativeidx = this.options.alternative;
|
||||
|
||||
|
|
@ -59,13 +74,14 @@ L.BRouter = L.Class.extend({
|
|||
params.format = format;
|
||||
} else {
|
||||
// do not put values in URL if this is the default value (format===null)
|
||||
if (params.profile === BR.conf.profiles[0])
|
||||
delete params.profile;
|
||||
if (params.alternativeidx == 0)
|
||||
delete params.alternativeidx;
|
||||
if (params.profile === BR.conf.profiles[0]) delete params.profile;
|
||||
if (params.alternativeidx == 0) delete params.alternativeidx;
|
||||
|
||||
// don't add custom profile, as these are only stored temporarily
|
||||
if (params.profile && params.profile.substring(0, 7) === 'custom_') {
|
||||
if (
|
||||
params.profile &&
|
||||
params.profile.substring(0, 7) === 'custom_'
|
||||
) {
|
||||
delete params.profile;
|
||||
}
|
||||
}
|
||||
|
|
@ -99,7 +115,7 @@ L.BRouter = L.Class.extend({
|
|||
getUrl: function(latLngs, format) {
|
||||
var urlParams = this.getUrlParams(latLngs, format);
|
||||
|
||||
var args = []
|
||||
var args = [];
|
||||
if (urlParams.lonlats != null && urlParams.lonlats.length > 0)
|
||||
args.push(L.Util.template('lonlats={lonlats}', urlParams));
|
||||
if (urlParams.nogos != null)
|
||||
|
|
@ -111,13 +127,17 @@ L.BRouter = L.Class.extend({
|
|||
if (urlParams.profile != null)
|
||||
args.push(L.Util.template('profile={profile}', urlParams));
|
||||
if (urlParams.alternativeidx != null)
|
||||
args.push(L.Util.template('alternativeidx={alternativeidx}', urlParams));
|
||||
args.push(
|
||||
L.Util.template('alternativeidx={alternativeidx}', urlParams)
|
||||
);
|
||||
if (urlParams.format != null)
|
||||
args.push(L.Util.template('format={format}', urlParams));
|
||||
|
||||
var prepend_host = (format != null);
|
||||
var prepend_host = format != null;
|
||||
|
||||
return (prepend_host ? BR.conf.host : '') + '/brouter?' + args.join('&');
|
||||
return (
|
||||
(prepend_host ? BR.conf.host : '') + '/brouter?' + args.join('&')
|
||||
);
|
||||
},
|
||||
|
||||
getRoute: function(latLngs, cb) {
|
||||
|
|
@ -130,21 +150,27 @@ L.BRouter = L.Class.extend({
|
|||
|
||||
xhr.open('GET', url, true);
|
||||
xhr.onload = L.bind(this._handleRouteResponse, this, xhr, cb);
|
||||
xhr.onerror = L.bind(function(xhr, cb) {
|
||||
cb(BR.Util.getError(xhr));
|
||||
}, this, xhr, cb);
|
||||
xhr.onerror = L.bind(
|
||||
function(xhr, cb) {
|
||||
cb(BR.Util.getError(xhr));
|
||||
},
|
||||
this,
|
||||
xhr,
|
||||
cb
|
||||
);
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
_handleRouteResponse: function(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') {
|
||||
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'
|
||||
) {
|
||||
// leaflet.spin
|
||||
//gpxLayer.fire('data:loaded');
|
||||
|
||||
|
|
@ -153,7 +179,7 @@ L.BRouter = L.Class.extend({
|
|||
layer = L.geoJSON(geojson).getLayers()[0];
|
||||
|
||||
return cb(null, layer);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
console.error(e, xhr.responseText);
|
||||
return cb(e);
|
||||
}
|
||||
|
|
@ -168,7 +194,7 @@ L.BRouter = L.Class.extend({
|
|||
|
||||
uploadProfile: function(profileId, profileText, cb) {
|
||||
var url = L.BRouter.URL_PROFILE_UPLOAD;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
// reuse existing profile file
|
||||
if (profileId) {
|
||||
|
|
@ -179,7 +205,7 @@ L.BRouter = L.Class.extend({
|
|||
xhr.onload = L.bind(this._handleProfileResponse, this, xhr, cb);
|
||||
xhr.onerror = function(evt) {
|
||||
var xhr = this;
|
||||
cb(i18next.t('warning.upload-error', {error: xhr.statusText}));
|
||||
cb(i18next.t('warning.upload-error', { error: xhr.statusText }));
|
||||
};
|
||||
|
||||
// send profile text only, as text/plain;charset=UTF-8
|
||||
|
|
@ -189,7 +215,11 @@ L.BRouter = L.Class.extend({
|
|||
_handleProfileResponse: function(xhr, cb) {
|
||||
var response;
|
||||
|
||||
if (xhr.status === 200 && xhr.responseText && xhr.responseText.length > 0) {
|
||||
if (
|
||||
xhr.status === 200 &&
|
||||
xhr.responseText &&
|
||||
xhr.responseText.length > 0
|
||||
) {
|
||||
response = JSON.parse(xhr.responseText);
|
||||
cb(response.error, response.profileid);
|
||||
} else {
|
||||
|
|
@ -201,7 +231,7 @@ L.BRouter = L.Class.extend({
|
|||
var s = '';
|
||||
for (var i = 0; i < latLngs.length; i++) {
|
||||
s += this._formatLatLng(latLngs[i]);
|
||||
if (i < (latLngs.length - 1)) {
|
||||
if (i < latLngs.length - 1) {
|
||||
s += L.BRouter.GROUP_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
|
@ -235,11 +265,14 @@ L.BRouter = L.Class.extend({
|
|||
s += L.BRouter.NUMBER_SEPARATOR;
|
||||
s += Math.round(circle.getRadius());
|
||||
// -1 is default nogo exclusion, it should not be passed as a URL parameter.
|
||||
if (circle.options.nogoWeight !== null && circle.options.nogoWeight !== -1) {
|
||||
if (
|
||||
circle.options.nogoWeight !== null &&
|
||||
circle.options.nogoWeight !== -1
|
||||
) {
|
||||
s += L.BRouter.NUMBER_SEPARATOR;
|
||||
s += circle.options.nogoWeight;
|
||||
}
|
||||
if (i < (nogos.length - 1)) {
|
||||
if (i < nogos.length - 1) {
|
||||
s += L.BRouter.GROUP_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
|
@ -262,7 +295,7 @@ L.BRouter = L.Class.extend({
|
|||
// TODO refactor: pass simple obj, create circle in NogoAreas; use shapeOptions of instance
|
||||
// [lat,lng],radius
|
||||
// Parse as a nogo circle
|
||||
var nogoOptions = {radius: numbers[2]};
|
||||
var nogoOptions = { radius: numbers[2] };
|
||||
if (numbers.length > 3) {
|
||||
nogoOptions.nogoWeight = numbers[3];
|
||||
}
|
||||
|
|
@ -284,11 +317,14 @@ L.BRouter = L.Class.extend({
|
|||
s += this._formatLatLng(vertices[j]);
|
||||
}
|
||||
// -1 is default nogo exclusion, it should not be passed as a URL parameter.
|
||||
if (polyline.options.nogoWeight !== null && polyline.options.nogoWeight !== -1) {
|
||||
if (
|
||||
polyline.options.nogoWeight !== null &&
|
||||
polyline.options.nogoWeight !== -1
|
||||
) {
|
||||
s += L.BRouter.NUMBER_SEPARATOR;
|
||||
s += polyline.options.nogoWeight;
|
||||
}
|
||||
if (i < (nogos.length - 1)) {
|
||||
if (i < nogos.length - 1) {
|
||||
s += L.BRouter.GROUP_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
|
@ -302,14 +338,11 @@ L.BRouter = L.Class.extend({
|
|||
nogos = [];
|
||||
|
||||
groups = s.split(L.BRouter.GROUP_SEPARATOR);
|
||||
for (var i = 0; i < groups.length; i++)
|
||||
{
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
numbers = groups[i].split(L.BRouter.NUMBER_SEPARATOR);
|
||||
if (numbers.length > 1)
|
||||
{
|
||||
if (numbers.length > 1) {
|
||||
latlngs = [];
|
||||
for (var j = 0; j < numbers.length - 1;)
|
||||
{
|
||||
for (var j = 0; j < numbers.length - 1; ) {
|
||||
var lng = Number.parseFloat(numbers[j++]);
|
||||
var lat = Number.parseFloat(numbers[j++]);
|
||||
latlngs.push([lat, lng]);
|
||||
|
|
@ -336,11 +369,14 @@ L.BRouter = L.Class.extend({
|
|||
s += this._formatLatLng(vertices[j]);
|
||||
}
|
||||
// -1 is default nogo exclusion, it should not be passed as a URL parameter.
|
||||
if (polygon.options.nogoWeight !== null && polygon.options.nogoWeight !== -1) {
|
||||
if (
|
||||
polygon.options.nogoWeight !== null &&
|
||||
polygon.options.nogoWeight !== -1
|
||||
) {
|
||||
s += L.BRouter.NUMBER_SEPARATOR;
|
||||
s += polygon.options.nogoWeight;
|
||||
}
|
||||
if (i < (nogos.length - 1)) {
|
||||
if (i < nogos.length - 1) {
|
||||
s += L.BRouter.GROUP_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
|
@ -354,14 +390,11 @@ L.BRouter = L.Class.extend({
|
|||
nogos = [];
|
||||
|
||||
groups = s.split(L.BRouter.GROUP_SEPARATOR);
|
||||
for (var i = 0; i < groups.length; i++)
|
||||
{
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
numbers = groups[i].split(L.BRouter.NUMBER_SEPARATOR);
|
||||
if (numbers.length > 1)
|
||||
{
|
||||
if (numbers.length > 1) {
|
||||
latlngs = [];
|
||||
for (var j = 0; j < numbers.length - 1;)
|
||||
{
|
||||
for (var j = 0; j < numbers.length - 1; ) {
|
||||
var lng = Number.parseFloat(numbers[j++]);
|
||||
var lat = Number.parseFloat(numbers[j++]);
|
||||
latlngs.push([lat, lng]);
|
||||
|
|
@ -386,6 +419,6 @@ L.BRouter = L.Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
L.bRouter = function (options) {
|
||||
L.bRouter = function(options) {
|
||||
return new L.BRouter(options);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
var brouterCgi = (function() {
|
||||
// http://h2096617.stratoserver.net/cgi-bin/brouter.sh?coords=13.404681_52.520185_13.340278_52.512356_trekking_0
|
||||
//var URL_TEMPLATE = '/cgi-bin/proxy.cgi?url=' + 'http://h2096617.stratoserver.net/cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
||||
var URL_TEMPLATE = '/proxy.php?url=' + 'cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
||||
var URL_TEMPLATE =
|
||||
'/proxy.php?url=' +
|
||||
'cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
|
||||
var PRECISION = 6;
|
||||
|
||||
function getUrl(polyline) {
|
||||
|
|
@ -21,9 +23,8 @@ var brouterCgi = (function() {
|
|||
//return 'test/test.gpx';
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
getUrl: getUrl
|
||||
}
|
||||
|
||||
})();
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue