Merge remote-tracking branch 'upstream/master' into heightgraph-transpiled

This commit is contained in:
alexcojocaru 2020-12-21 21:23:04 -08:00
commit 3c1f5d0d6d
62 changed files with 4486 additions and 3554 deletions

View file

@ -2,3 +2,6 @@ language: node_js
node_js: node_js:
- lts/* - lts/*
cache: yarn cache: yarn
script:
- yarn test
- yarn lint

View file

@ -1,5 +1,11 @@
# BRouter-Web Changelog # BRouter-Web Changelog
## 0.14.0 (2020-12-04)
### New Features [fr]
- [French users only] New button to add 20km allowed zone - by [@bagage](https://github.com/bagage) ([#347](https://github.com/nrenner/brouter-web/pull/347), [#350](https://github.com/nrenner/brouter-web/pull/350), [#352](https://github.com/nrenner/brouter-web/pull/352))
## 0.13.0 (2020-08-04) ## 0.13.0 (2020-08-04)
See also [milestone 0.13.0](https://github.com/nrenner/brouter-web/milestone/14?closed=1) See also [milestone 0.13.0](https://github.com/nrenner/brouter-web/milestone/14?closed=1)

View file

@ -1,4 +1,4 @@
(function() { (function () {
var hostname = window.location.hostname; var hostname = window.location.hostname;
var origin = window.location.protocol + '//' + hostname + (window.location.port ? ':' + window.location.port : ''); var origin = window.location.protocol + '//' + hostname + (window.location.port ? ':' + window.location.port : '');
@ -54,7 +54,7 @@
'vm-forum-velomobil-schnell', 'vm-forum-velomobil-schnell',
'fastbike-lowtraffic', 'fastbike-lowtraffic',
'fastbike-asia-pacific', 'fastbike-asia-pacific',
'hiking-beta' 'hiking-beta',
]; ];
// Removes default base layers when 'true'. Useful for only having custom layers (see below). // Removes default base layers when 'true'. Useful for only having custom layers (see below).
@ -84,22 +84,22 @@
weight: 5, weight: 5,
dashArray: [10, 10], dashArray: [10, 10],
opacity: 0.6, opacity: 0.6,
color: 'magenta' color: 'magenta',
}, },
track: { track: {
weight: 5, weight: 5,
color: 'magenta', color: 'magenta',
opacity: BR.conf.defaultOpacity opacity: BR.conf.defaultOpacity,
}, },
trackCasing: { trackCasing: {
weight: 8, weight: 8,
color: 'white', color: 'white',
// assumed to be same as track, see setOpacity // assumed to be same as track, see setOpacity
opacity: BR.conf.defaultOpacity opacity: BR.conf.defaultOpacity,
}, },
nodata: { nodata: {
color: 'darkred' color: 'darkred',
} },
}; };
BR.conf.markerColors = { BR.conf.markerColors = {
@ -107,7 +107,7 @@
poi: '#436978', poi: '#436978',
start: '#72b026', start: '#72b026',
via: '#38aadd', via: '#38aadd',
stop: '#d63e2a' stop: '#d63e2a',
}; };
// transit (intermodal routing) demo config // transit (intermodal routing) demo config
@ -121,7 +121,7 @@
'fastbike', 'fastbike',
'shortest', 'shortest',
'moped', 'moped',
'car-test' 'car-test',
]; ];
} }

View file

@ -197,6 +197,12 @@ input#trackname:focus:invalid {
.pois-draw-enabled { .pois-draw-enabled {
cursor: cell; cursor: cell;
} }
.circlego-draw-enabled {
cursor: pointer;
}
.circlego-outside {
cursor: not-allowed;
}
#map { #map {
/* center error message horizontally */ /* center error message horizontally */

View file

@ -34,16 +34,15 @@ var debug = false;
var paths = { var paths = {
// see overrides in package.json // see overrides in package.json
scriptsConfig: mainNpmFiles().filter(f => RegExp('url-search-params/.*\\.js', 'i').test(f)), scriptsConfig: mainNpmFiles().filter((f) => RegExp('url-search-params/.*\\.js', 'i').test(f)),
scripts: [ scripts: [
'node_modules/jquery/dist/jquery.js', 'node_modules/jquery/dist/jquery.js',
'node_modules/tether/dist/js/tether.js',
'node_modules/async/lib/async.js', 'node_modules/async/lib/async.js',
'node_modules/leaflet/dist/leaflet-src.js' 'node_modules/leaflet/dist/leaflet-src.js',
] ]
.concat( .concat(
mainNpmFiles().filter( mainNpmFiles().filter(
f => (f) =>
RegExp('.*\\.js', 'i').test(f) && RegExp('.*\\.js', 'i').test(f) &&
!RegExp('.*\\.min\\.js', 'i').test(f) && !RegExp('.*\\.min\\.js', 'i').test(f) &&
!RegExp('url-search-params/.*\\.js', 'i').test(f) !RegExp('url-search-params/.*\\.js', 'i').test(f)
@ -58,13 +57,13 @@ var paths = {
'js/util/*.js', 'js/util/*.js',
'js/plugin/*.js', 'js/plugin/*.js',
'js/control/*.js', 'js/control/*.js',
'js/index.js' 'js/index.js',
]), ]),
styles: mainNpmFiles() styles: mainNpmFiles()
.filter(f => RegExp('.*\\.css', 'i').test(f) && !RegExp('.*\\.min\\.css', 'i').test(f)) .filter((f) => RegExp('.*\\.css', 'i').test(f) && !RegExp('.*\\.min\\.css', 'i').test(f))
.concat('css/*.css'), .concat('css/*.css'),
images: mainNpmFiles().filter(f => RegExp('.*.+(png|gif|svg)', 'i').test(f)), images: mainNpmFiles().filter((f) => RegExp('.*.+(png|gif|svg)', 'i').test(f)),
fonts: mainNpmFiles().filter(f => RegExp('font-awesome/fonts/.*', 'i').test(f)), fonts: mainNpmFiles().filter((f) => RegExp('font-awesome/fonts/.*', 'i').test(f)),
locales: 'locales/*.json', locales: 'locales/*.json',
layers: 'layers/**/*.geojson', layers: 'layers/**/*.geojson',
layersDestName: 'layers.js', layersDestName: 'layers.js',
@ -72,25 +71,25 @@ var paths = {
'layers/config/config.js', 'layers/config/config.js',
'layers/config/tree.js', 'layers/config/tree.js',
'layers/config/overrides.js', 'layers/config/overrides.js',
'layers/config/geometry.js' 'layers/config/geometry.js',
], ],
layersConfigDestName: 'layersConf.js', layersConfigDestName: 'layersConf.js',
zip: ['dist/**', 'index.html', 'config.template.js', 'keys.template.js'], zip: ['dist/**', 'index.html', 'config.template.js', 'keys.template.js'],
dest: 'dist', dest: 'dist',
destName: 'brouter-web' destName: 'brouter-web',
}; };
gulp.task('clean', function(cb) { gulp.task('clean', function (cb) {
del(paths.dest + '/**/*', cb); del(paths.dest + '/**/*', cb);
}); });
// libs that require loading before config.js // libs that require loading before config.js
gulp.task('scripts_config', function() { gulp.task('scripts_config', function () {
// just copy for now // just copy for now
return gulp.src(paths.scriptsConfig).pipe(gulp.dest(paths.dest)); return gulp.src(paths.scriptsConfig).pipe(gulp.dest(paths.dest));
}); });
gulp.task('scripts', function() { gulp.task('scripts', function () {
if (debug) gutil.log(gutil.colors.yellow('Running in Debug mode')); if (debug) gutil.log(gutil.colors.yellow('Running in Debug mode'));
else gutil.log(gutil.colors.green('Running in Release mode')); else gutil.log(gutil.colors.green('Running in Release mode'));
@ -106,14 +105,14 @@ gulp.task('scripts', function() {
}); });
// separate, fallback task for debugging (switch manually in index.html) // separate, fallback task for debugging (switch manually in index.html)
gulp.task('concat', function() { gulp.task('concat', function () {
return gulp return gulp
.src(paths.scripts) .src(paths.scripts)
.pipe(concat(paths.destName + '.src.js')) .pipe(concat(paths.destName + '.src.js'))
.pipe(gulp.dest(paths.dest)); .pipe(gulp.dest(paths.dest));
}); });
gulp.task('styles', function() { gulp.task('styles', function () {
return gulp return gulp
.src(paths.styles) .src(paths.styles)
.pipe( .pipe(
@ -129,40 +128,40 @@ gulp.task('styles', function() {
} }
return distUrl; return distUrl;
} },
}) })
) )
.pipe(concat(paths.destName + '.css')) .pipe(concat(paths.destName + '.css'))
.pipe( .pipe(
cleanCSS({ cleanCSS({
rebase: false rebase: false,
}) })
) )
.pipe(postcss([autoprefixer({ remove: false })])) .pipe(postcss([autoprefixer({ remove: false })]))
.pipe(gulp.dest(paths.dest)); .pipe(gulp.dest(paths.dest));
}); });
gulp.task('images', function() { gulp.task('images', function () {
return gulp.src(paths.images).pipe(gulp.dest(paths.dest + '/images')); return gulp.src(paths.images).pipe(gulp.dest(paths.dest + '/images'));
}); });
gulp.task('fonts', function() { gulp.task('fonts', function () {
return gulp.src(paths.fonts).pipe(gulp.dest(paths.dest + '/fonts')); return gulp.src(paths.fonts).pipe(gulp.dest(paths.dest + '/fonts'));
}); });
gulp.task('locales', function() { gulp.task('locales', function () {
return gulp.src(paths.locales).pipe(gulp.dest(paths.dest + '/locales')); return gulp.src(paths.locales).pipe(gulp.dest(paths.dest + '/locales'));
}); });
gulp.task('reload', function(done) { gulp.task('reload', function (done) {
server.reload(); server.reload();
done(); done();
}); });
gulp.task('watch', function() { gulp.task('watch', function () {
debug = true; debug = true;
var watcher = gulp.watch(paths.scripts, gulp.series('scripts', 'reload')); var watcher = gulp.watch(paths.scripts, gulp.series('scripts', 'reload'));
watcher.on('change', function(event) { watcher.on('change', function (event) {
if (event.type === 'deleted') { if (event.type === 'deleted') {
delete cached.caches.scripts[event.path]; delete cached.caches.scripts[event.path];
remember.forget('scripts', event.path); remember.forget('scripts', event.path);
@ -171,35 +170,26 @@ gulp.task('watch', function() {
gulp.watch(paths.locales, gulp.series('locales', 'reload')); gulp.watch(paths.locales, gulp.series('locales', 'reload'));
gulp.watch(paths.styles, gulp.series('styles', 'reload')); gulp.watch(paths.styles, gulp.series('styles', 'reload'));
gulp.watch(paths.layersConfig, gulp.series('layers_config', 'reload')); gulp.watch(paths.layersConfig, gulp.series('layers_config', 'reload'));
gulp.watch( gulp.watch(['./index.html'].concat(paths.images).concat(paths.fonts).concat(paths.locales), gulp.series('reload'));
['./index.html']
.concat(paths.images)
.concat(paths.fonts)
.concat(paths.locales),
gulp.series('reload')
);
}); });
// Print paths to console, for manually debugging the gulp build // Print paths to console, for manually debugging the gulp build
// (comment out corresponding line of paths to print) // (comment out corresponding line of paths to print)
gulp.task('log', function() { gulp.task('log', function () {
// var src = paths.scripts // var src = paths.scripts
// var src = paths.styles // var src = paths.styles
// var src = paths.images // var src = paths.images
// var src = paths.locales // var src = paths.locales
var src = paths.scripts var src = paths.scripts.concat(paths.styles).concat(paths.images).concat(paths.locales);
.concat(paths.styles)
.concat(paths.images)
.concat(paths.locales);
return gulp.src(src).pipe(gulpDebug()); return gulp.src(src).pipe(gulpDebug());
}); });
gulp.task('inject', function() { gulp.task('inject', function () {
var target = gulp.src('index.html'); var target = gulp.src('index.html');
var sources = gulp.src(paths.scripts.concat(paths.styles), { var sources = gulp.src(paths.scripts.concat(paths.styles), {
base: '.', base: '.',
read: false read: false,
}); });
return target.pipe(inject(sources, { relative: true })).pipe(gulp.dest('.')); return target.pipe(inject(sources, { relative: true })).pipe(gulp.dest('.'));
@ -209,7 +199,7 @@ var pkg = require('./package.json');
var nextVersion; var nextVersion;
var ghToken; var ghToken;
gulp.task('release:init', function(cb) { gulp.task('release:init', function (cb) {
var tag = gutil.env.tag; var tag = gutil.env.tag;
if (!tag) { if (!tag) {
return cb(new Error('--tag is required')); return cb(new Error('--tag is required'));
@ -227,7 +217,7 @@ gulp.task('release:init', function(cb) {
nextVersion = semver.inc(pkg.version, tag); nextVersion = semver.inc(pkg.version, tag);
git.status({ args: '--porcelain', quiet: true }, function(err, stdout) { git.status({ args: '--porcelain', quiet: true }, function (err, stdout) {
if (err) return cb(err); if (err) return cb(err);
if (stdout.length > 0) { if (stdout.length > 0) {
return cb(new Error('Repository is not clean. Please commit or stash your pending modification')); return cb(new Error('Repository is not clean. Please commit or stash your pending modification'));
@ -237,7 +227,7 @@ gulp.task('release:init', function(cb) {
}); });
}); });
gulp.task('bump:json', function() { gulp.task('bump:json', function () {
gutil.log(gutil.colors.green('Bump to ' + nextVersion)); gutil.log(gutil.colors.green('Bump to ' + nextVersion));
return gulp return gulp
.src(['./package.json']) .src(['./package.json'])
@ -245,7 +235,7 @@ gulp.task('bump:json', function() {
.pipe(gulp.dest('./')); .pipe(gulp.dest('./'));
}); });
gulp.task('bump:html', function() { gulp.task('bump:html', function () {
return gulp return gulp
.src('./index.html') .src('./index.html')
.pipe(replace(/<sup class="version">(.*)<\/sup>/, '<sup class="version">' + nextVersion + '</sup>')) .pipe(replace(/<sup class="version">(.*)<\/sup>/, '<sup class="version">' + nextVersion + '</sup>'))
@ -254,19 +244,19 @@ gulp.task('bump:html', function() {
gulp.task('bump', gulp.series('bump:json', 'bump:html')); gulp.task('bump', gulp.series('bump:json', 'bump:html'));
gulp.task('release:commit', function() { gulp.task('release:commit', function () {
return gulp.src(['./index.html', './package.json']).pipe(git.commit('release: ' + nextVersion)); return gulp.src(['./index.html', './package.json']).pipe(git.commit('release: ' + nextVersion));
}); });
gulp.task('release:tag', function(cb) { gulp.task('release:tag', function (cb) {
return git.tag(nextVersion, '', cb); return git.tag(nextVersion, '', cb);
}); });
gulp.task('release:push', function(cb) { gulp.task('release:push', function (cb) {
git.push('origin', 'master', { args: '--tags' }, cb); git.push('origin', 'master', { args: '--tags' }, cb);
}); });
gulp.task('i18next', function() { gulp.task('i18next', function () {
return gulp return gulp
.src(['index.html', 'locales/keys.js', 'layers/config/overrides.js', 'js/**/*.js']) .src(['index.html', 'locales/keys.js', 'layers/config/overrides.js', 'js/**/*.js'])
.pipe(sort()) .pipe(sort())
@ -280,29 +270,26 @@ gulp.task('i18next', function() {
loadPath: 'locales/{{lng}}.json', loadPath: 'locales/{{lng}}.json',
// the destination path is relative to your `gulp.dest()` path // the destination path is relative to your `gulp.dest()` path
savePath: 'locales/{{lng}}.json' savePath: 'locales/{{lng}}.json',
} },
}) })
) )
.pipe(gulp.dest('.')); .pipe(gulp.dest('.'));
}); });
gulp.task('layers_config', function() { gulp.task('layers_config', function () {
return gulp return gulp.src(paths.layersConfig).pipe(concat(paths.layersConfigDestName)).pipe(gulp.dest(paths.dest));
.src(paths.layersConfig)
.pipe(concat(paths.layersConfigDestName))
.pipe(gulp.dest(paths.dest));
}); });
// Bundles layer files. To download and extract run "yarn layers" // Bundles layer files. To download and extract run "yarn layers"
gulp.task('layers', function() { gulp.task('layers', function () {
return ( return (
gulp gulp
.src(paths.layers) .src(paths.layers)
// Workaround to get file extension removed from the dictionary key // Workaround to get file extension removed from the dictionary key
.pipe(rename({ extname: '.json' })) .pipe(rename({ extname: '.json' }))
.pipe( .pipe(
jsonConcat(paths.layersDestName, function(data) { jsonConcat(paths.layersDestName, function (data) {
var header = var header =
'// Licensed under the MIT License (https://github.com/nrenner/brouter-web#license + Credits and Licenses),\n' + '// Licensed under the MIT License (https://github.com/nrenner/brouter-web#license + Credits and Licenses),\n' +
'// except JOSM imagery database (dataSource=JOSM) is licensed under Creative Commons (CC-BY-SA),\n' + '// except JOSM imagery database (dataSource=JOSM) is licensed under Creative Commons (CC-BY-SA),\n' +
@ -321,7 +308,7 @@ gulp.task(
gulp.task( gulp.task(
'debug', 'debug',
gulp.series(function(cb) { gulp.series(function (cb) {
debug = true; debug = true;
cb(); cb();
}, 'default') }, 'default')
@ -329,28 +316,28 @@ gulp.task(
gulp.task( gulp.task(
'serve', 'serve',
gulp.series('debug', function(cb) { gulp.series('debug', function (cb) {
server.init({ server.init({
server: { server: {
baseDir: './' baseDir: './',
}, },
open: false open: false,
}); });
cb(); cb();
}) })
); );
gulp.task('release:zip', function() { gulp.task('release:zip', function () {
gutil.log(gutil.colors.green('Build brouter-web.' + nextVersion + '.zip')); gutil.log(gutil.colors.green('Build brouter-web.' + nextVersion + '.zip'));
return gulp return gulp
.src(paths.zip, { .src(paths.zip, {
base: '.' base: '.',
}) })
.pipe(zip('brouter-web.' + nextVersion + '.zip')) .pipe(zip('brouter-web.' + nextVersion + '.zip'))
.pipe(gulp.dest('.')); .pipe(gulp.dest('.'));
}); });
gulp.task('release:zip_standalone', function() { gulp.task('release:zip_standalone', function () {
var version = pkg.version; var version = pkg.version;
var destName = 'brouter-web-standalone.' + version + '.zip'; var destName = 'brouter-web-standalone.' + version + '.zip';
@ -358,10 +345,10 @@ gulp.task('release:zip_standalone', function() {
var brouterWeb = gulp var brouterWeb = gulp
.src(paths.zip, { .src(paths.zip, {
base: '.' base: '.',
}) })
.pipe( .pipe(
rename(function(path) { rename(function (path) {
path.dirname = 'brouter-web/' + path.dirname; path.dirname = 'brouter-web/' + path.dirname;
}) })
); );
@ -372,14 +359,14 @@ gulp.task('release:zip_standalone', function() {
.src( .src(
[ [
'misc/readmes/profile_developers_guide.txt', 'misc/readmes/profile_developers_guide.txt',
'brouter-server/target/brouter-server-*-jar-with-dependencies.jar' 'brouter-server/target/brouter-server-*-jar-with-dependencies.jar',
], ],
{ {
cwd: path.join(process.cwd(), '../brouter') cwd: path.join(process.cwd(), '../brouter'),
} }
) )
.pipe( .pipe(
rename(function(path) { rename(function (path) {
if (path.basename.startsWith('brouter-server-')) { if (path.basename.startsWith('brouter-server-')) {
path.basename = 'brouter'; path.basename = 'brouter';
} }
@ -392,30 +379,28 @@ gulp.task('release:zip_standalone', function() {
'!profiles2/all.brf', '!profiles2/all.brf',
'!profiles2/car-eco-suspect_scan.brf', '!profiles2/car-eco-suspect_scan.brf',
'!profiles2/car-traffic_analysis.brf', '!profiles2/car-traffic_analysis.brf',
'!profiles2/softaccess.brf' '!profiles2/softaccess.brf',
], ],
{ {
cwd: path.join(process.cwd(), '../brouter/misc/'), cwd: path.join(process.cwd(), '../brouter/misc/'),
base: '../brouter/misc/' base: '../brouter/misc/',
} }
); );
var serverScripts = gulp.src(['standalone/**'], { var serverScripts = gulp.src(['standalone/**'], {
cwd: path.join(process.cwd(), '../brouter/misc/scripts/'), cwd: path.join(process.cwd(), '../brouter/misc/scripts/'),
base: '../brouter/misc/scripts/' base: '../brouter/misc/scripts/',
}); });
return merge(brouterWeb, root, serverRoot, serverProfiles, serverScripts) return merge(brouterWeb, root, serverRoot, serverProfiles, serverScripts).pipe(zip(destName)).pipe(gulp.dest('.'));
.pipe(zip(destName))
.pipe(gulp.dest('.'));
}); });
gulp.task('release:publish', function() { gulp.task('release:publish', function () {
return gulp.src('./brouter-web.' + nextVersion + '.zip').pipe( return gulp.src('./brouter-web.' + nextVersion + '.zip').pipe(
release({ release({
tag: nextVersion, tag: nextVersion,
token: ghToken, token: ghToken,
manifest: pkg manifest: pkg,
}) })
); );
}); });

2253
index.html

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
(function() { (function () {
var touchScreen = (function() { var touchScreen = (function () {
var result = null; var result = null;
if ('maxTouchPoints' in navigator) { if ('maxTouchPoints' in navigator) {
@ -21,6 +21,6 @@
BR.Browser = { BR.Browser = {
touchScreen: touchScreen, touchScreen: touchScreen,
touchScreenDetectable: touchScreenDetectable, touchScreenDetectable: touchScreenDetectable,
touch: touch touch: touch,
}; };
})(); })();

View file

@ -5,7 +5,7 @@ BR.LayersConfig = L.Class.extend({
// hardcoded, built-in layers with an id set (for URL hash) // hardcoded, built-in layers with an id set (for URL hash)
builtInLayers: ['route-quality'], builtInLayers: ['route-quality'],
initialize: function(map) { initialize: function (map) {
this._map = map; this._map = map;
this._addLeafletProvidersLayers(); this._addLeafletProvidersLayers();
@ -14,7 +14,7 @@ BR.LayersConfig = L.Class.extend({
this._addLanguageDefaultLayer(); this._addLanguageDefaultLayer();
}, },
loadDefaultLayers: function() { loadDefaultLayers: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
var item = localStorage.getItem('map/defaultLayers'); var item = localStorage.getItem('map/defaultLayers');
if (item) { if (item) {
@ -25,17 +25,17 @@ BR.LayersConfig = L.Class.extend({
} }
}, },
storeDefaultLayers: function(baseLayers, overlays) { storeDefaultLayers: function (baseLayers, overlays) {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
var defaultLayers = { var defaultLayers = {
baseLayers: baseLayers, baseLayers: baseLayers,
overlays: overlays 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; var includeList = BR.confLayers.leafletProvidersIncludeList;
for (var i = 0; i < includeList.length; i++) { for (var i = 0; i < includeList.length; i++) {
@ -45,15 +45,15 @@ BR.LayersConfig = L.Class.extend({
properties: { properties: {
id: id, id: id,
name: id.replace('.', ' '), name: id.replace('.', ' '),
dataSource: 'leaflet-providers' dataSource: 'leaflet-providers',
}, },
type: 'Feature' type: 'Feature',
}; };
BR.layerIndex[id] = obj; BR.layerIndex[id] = obj;
} }
}, },
_customizeLayers: function() { _customizeLayers: function () {
var propertyOverrides = BR.confLayers.getPropertyOverrides(); var propertyOverrides = BR.confLayers.getPropertyOverrides();
for (id in propertyOverrides) { for (id in propertyOverrides) {
@ -79,7 +79,7 @@ BR.LayersConfig = L.Class.extend({
BR.layerIndex['1017'].geometry = BR.confLayers.osmapaPl; BR.layerIndex['1017'].geometry = BR.confLayers.osmapaPl;
}, },
_addLanguageDefaultLayer: function() { _addLanguageDefaultLayer: function () {
// language code -> layer id // language code -> layer id
var languageLayersMap = {}; var languageLayersMap = {};
var i; var i;
@ -107,7 +107,7 @@ BR.LayersConfig = L.Class.extend({
} }
}, },
isDefaultLayer: function(id, overlay) { isDefaultLayer: function (id, overlay) {
var result = false; var result = false;
if (overlay) { if (overlay) {
result = this.defaultOverlays.indexOf(id) > -1; result = this.defaultOverlays.indexOf(id) > -1;
@ -117,15 +117,15 @@ BR.LayersConfig = L.Class.extend({
return result; return result;
}, },
getBaseLayers: function() { getBaseLayers: function () {
return this._getLayers(this.defaultBaseLayers); return this._getLayers(this.defaultBaseLayers);
}, },
getOverlays: function() { getOverlays: function () {
return this._getLayers(this.defaultOverlays); return this._getLayers(this.defaultOverlays);
}, },
_getLayers: function(ids) { _getLayers: function (ids) {
var layers = {}; var layers = {};
for (var i = 0; i < ids.length; i++) { for (var i = 0; i < ids.length; i++) {
@ -148,7 +148,7 @@ BR.LayersConfig = L.Class.extend({
// own convention: key placeholder with prefix // own convention: key placeholder with prefix
// e.g. ?api_key={keys_openrouteservice} // e.g. ?api_key={keys_openrouteservice}
getKeyName: function(url) { getKeyName: function (url) {
var result = null; var result = null;
// L.Util.template only matches [\w_-] // L.Util.template only matches [\w_-]
var prefix = 'keys_'; var prefix = 'keys_';
@ -162,14 +162,14 @@ BR.LayersConfig = L.Class.extend({
name = found[1]; name = found[1];
result = { result = {
name: name, name: name,
urlVar: prefix + name urlVar: prefix + name,
}; };
} }
return result; return result;
}, },
createLayer: function(layerData) { createLayer: function (layerData) {
var props = layerData.properties; var props = layerData.properties;
var url = props.url; var url = props.url;
var layer; var layer;
@ -218,7 +218,7 @@ BR.LayersConfig = L.Class.extend({
var options = { var options = {
maxZoom: this._map.getMaxZoom(), 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) { if (props.mapUrl) {
options.mapLink = options.mapLink =
@ -237,7 +237,7 @@ BR.LayersConfig = L.Class.extend({
layer = L.tileLayer.provider(props.id); layer = L.tileLayer.provider(props.id);
var layerOptions = L.Util.extend(options, { var layerOptions = L.Util.extend(options, {
maxNativeZoom: layer.options.maxZoom maxNativeZoom: layer.options.maxZoom,
}); });
L.setOptions(layer, layerOptions); L.setOptions(layer, layerOptions);
} else if (props.dataSource === 'LayersCollection') { } else if (props.dataSource === 'LayersCollection') {
@ -245,7 +245,7 @@ BR.LayersConfig = L.Class.extend({
url, url,
L.Util.extend(options, { L.Util.extend(options, {
minZoom: props.minZoom || 0, minZoom: props.minZoom || 0,
maxNativeZoom: props.maxZoom maxNativeZoom: props.maxZoom,
}) })
); );
if (props.subdomains) { if (props.subdomains) {
@ -260,7 +260,7 @@ BR.LayersConfig = L.Class.extend({
minZoom: props.min_zoom || 0, minZoom: props.min_zoom || 0,
maxNativeZoom: props.max_zoom, maxNativeZoom: props.max_zoom,
subdomains: getSubdomains(josmUrl), subdomains: getSubdomains(josmUrl),
attribution: convertAttributionJosm(props) attribution: convertAttributionJosm(props),
}); });
if (props.type && props.type === 'wms') { if (props.type && props.type === 'wms') {
@ -268,7 +268,7 @@ BR.LayersConfig = L.Class.extend({
url, url,
L.Util.extend(josmOptions, { L.Util.extend(josmOptions, {
layers: props.layers, layers: props.layers,
format: props.format format: props.format,
}) })
); );
} else { } else {
@ -279,7 +279,7 @@ BR.LayersConfig = L.Class.extend({
// Layer attribution here only as short link to original site, // Layer attribution here only as short link to original site,
// to keep current position use placeholders: {zoom}/{lat}/{lon} // to keep current position use placeholders: {zoom}/{lat}/{lon}
// Copyright attribution in index.html #credits // Copyright attribution in index.html #credits
var getAttribution = function() { var getAttribution = function () {
return this.options.mapLink; return this.options.mapLink;
}; };
layer.getAttribution = getAttribution; layer.getAttribution = getAttribution;
@ -287,9 +287,9 @@ BR.LayersConfig = L.Class.extend({
layer.id = props.id; layer.id = props.id;
return layer; return layer;
} },
}); });
BR.layersConfig = function(map) { BR.layersConfig = function (map) {
return new BR.LayersConfig(map); return new BR.LayersConfig(map);
}; };

View file

@ -1,11 +1,11 @@
BR.Map = { BR.Map = {
initMap: function() { initMap: function () {
var map, layersControl; var map, layersControl;
L.setOptions(this, { L.setOptions(this, {
shortcut: { shortcut: {
locate: 76 // char code for 'l' locate: 76, // char code for 'l'
} },
}); });
BR.keys = BR.keys || {}; BR.keys = BR.keys || {};
@ -18,14 +18,14 @@ BR.Map = {
minZoom: 0, minZoom: 0,
maxZoom: maxZoom, maxZoom: maxZoom,
// fix for route drag on mobile (#285), until next Leaflet version released (> 1.6.0) // fix for route drag on mobile (#285), until next Leaflet version released (> 1.6.0)
tap: false tap: false,
}); });
if (BR.Util.getResponsiveBreakpoint() >= '3md') { if (BR.Util.getResponsiveBreakpoint() >= '3md') {
L.control L.control
.zoom({ .zoom({
zoomInTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomInTitle)', key: '+' }), zoomInTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomInTitle)', key: '+' }),
zoomOutTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomOutTitle)', key: '-' }) zoomOutTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomOutTitle)', key: '-' }),
}) })
.addTo(map); .addTo(map);
} }
@ -54,7 +54,7 @@ BR.Map = {
'</a>' '</a>'
); );
$('#credits').on('show.bs.modal', function(event) { $('#credits').on('show.bs.modal', function (event) {
BR.Map._renderLayerCredits(layersControl._layers); BR.Map._renderLayerCredits(layersControl._layers);
}); });
@ -77,7 +77,7 @@ BR.Map = {
minZoom: 1, minZoom: 1,
maxZoom: 19, maxZoom: 19,
attribution: attribution:
'&copy; <a href="https://www.digitalglobe.com/platforms/mapsapi">DigitalGlobe</a> (<a href="https://bit.ly/mapsapiview">Terms of Use</a>)' '&copy; <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; baseLayers[i18next.t('map.layer.digitalglobe')] = recent;
@ -105,16 +105,16 @@ BR.Map = {
var locationControl = L.control var locationControl = L.control
.locate({ .locate({
strings: { strings: {
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.locate-me)', key: 'L' }) title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.locate-me)', key: 'L' }),
}, },
icon: 'fa fa-location-arrow', icon: 'fa fa-location-arrow',
iconLoading: 'fa fa-spinner fa-pulse' iconLoading: 'fa fa-spinner fa-pulse',
}) })
.addTo(map); .addTo(map);
L.DomEvent.addListener( L.DomEvent.addListener(
document, document,
'keydown', 'keydown',
function(e) { function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.locate) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.locate) {
locationControl.start(); locationControl.start();
} }
@ -133,11 +133,11 @@ BR.Map = {
return { return {
map: map, map: map,
layersControl: layersControl layersControl: layersControl,
}; };
}, },
_renderLayerCredits: function(layers) { _renderLayerCredits: function (layers) {
var dl = document.getElementById('credits-maps'); var dl = document.getElementById('credits-maps');
var i, obj, dt, dd, attribution; var i, obj, dt, dd, attribution;
@ -157,5 +157,5 @@ BR.Map = {
dl.appendChild(dd); dl.appendChild(dd);
} }
} }
} },
}; };

View file

@ -1,16 +1,16 @@
BR.Util = { BR.Util = {
get: function(url, cb) { get: function (url, cb) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); xhr.open('GET', url, true);
xhr.onload = function() { xhr.onload = function () {
if ((xhr.status === 200 || xhr.status === 0) && xhr.responseText) { if ((xhr.status === 200 || xhr.status === 0) && xhr.responseText) {
cb(null, xhr.responseText); cb(null, xhr.responseText);
} else { } else {
cb(BR.Util.getError(xhr)); cb(BR.Util.getError(xhr));
} }
}; };
xhr.onerror = function() { xhr.onerror = function () {
cb(BR.Util.getError(xhr)); cb(BR.Util.getError(xhr));
}; };
try { try {
@ -20,7 +20,7 @@ BR.Util = {
} }
}, },
getError: function(xhr) { getError: function (xhr) {
var msg = i18next.t('warning.no-response'); var msg = i18next.t('warning.no-response');
if (xhr.responseText) { if (xhr.responseText) {
msg = xhr.responseText; msg = xhr.responseText;
@ -38,7 +38,7 @@ BR.Util = {
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Testing_for_support_vs_availability // https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Testing_for_support_vs_availability
// by Mozilla Contributors, with modifications; // by Mozilla Contributors, with modifications;
// Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/ // Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/
localStorageAvailable: function() { localStorageAvailable: function () {
try { try {
var storage = window.localStorage, var storage = window.localStorage,
x = '__storage_test__'; x = '__storage_test__';
@ -51,7 +51,7 @@ BR.Util = {
}, },
// see https://stackoverflow.com/a/37141090/1906123 // see https://stackoverflow.com/a/37141090/1906123
getResponsiveBreakpoint: function() { getResponsiveBreakpoint: function () {
var envs = { '1xs': 'd-none', '2sm': 'd-sm-none', '3md': 'd-md-none', '4lg': 'd-lg-none', '5xl': 'd-xl-none' }; var envs = { '1xs': 'd-none', '2sm': 'd-sm-none', '3md': 'd-md-none', '4lg': 'd-lg-none', '5xl': 'd-xl-none' };
var env = ''; var env = '';
@ -69,7 +69,7 @@ BR.Util = {
return env; return env;
}, },
keyboardShortcutsAllowed: function(keyEvent) { keyboardShortcutsAllowed: function (keyEvent) {
// Skip auto-repeating key events // Skip auto-repeating key events
if (keyEvent.repeat) { if (keyEvent.repeat) {
return false; return false;
@ -102,9 +102,9 @@ BR.Util = {
// this method must only be used to sanitize for textContent. // this method must only be used to sanitize for textContent.
// do NOT use it to sanitize any attribute, // do NOT use it to sanitize any attribute,
// see https://web.archive.org/web/20121208091505/http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/ // see https://web.archive.org/web/20121208091505/http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/
sanitizeHTMLContent: function(str) { sanitizeHTMLContent: function (str) {
var temp = document.createElement('div'); var temp = document.createElement('div');
temp.textContent = str; temp.textContent = str;
return temp.innerHTML; return temp.innerHTML;
} },
}; };

View file

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

View file

@ -3,11 +3,11 @@ BR.Export = L.Class.extend({
options: { options: {
shortcut: { shortcut: {
export: 88 // char code for 'x' export: 88, // char code for 'x'
} },
}, },
initialize: function(router, pois) { initialize: function (router, pois) {
this.router = router; this.router = router;
this.pois = pois; this.pois = pois;
this.exportButton = $('#exportButton'); this.exportButton = $('#exportButton');
@ -31,7 +31,7 @@ BR.Export = L.Class.extend({
this.update([]); this.update([]);
}, },
update: function(latLngs) { update: function (latLngs) {
this.latLngs = latLngs; this.latLngs = latLngs;
if (latLngs.length < 2) { if (latLngs.length < 2) {
@ -41,13 +41,13 @@ BR.Export = L.Class.extend({
} }
}, },
_export: function(e) { _export: function (e) {
var exportForm = document.forms['export']; var exportForm = document.forms['export'];
var format = exportForm['format'].value || $('#export-format input:radio:checked').val(); var format = exportForm['format'].value || $('#export-format input:radio:checked').val();
var name = encodeURIComponent(exportForm['trackname'].value); var name = encodeURIComponent(exportForm['trackname'].value);
var includeWaypoints = exportForm['include-waypoints'].checked; var includeWaypoints = exportForm['include-waypoints'].checked;
var uri = this.router.getUrl(this.latLngs, this.pois.getMarkers(), format, name, includeWaypoints); var uri = this.router.getUrl(this.latLngs, this.pois.getMarkers(), null, format, name, includeWaypoints);
e.preventDefault(); e.preventDefault();
@ -58,7 +58,7 @@ BR.Export = L.Class.extend({
link.dispatchEvent(evt); link.dispatchEvent(evt);
}, },
_validationMessage: function() { _validationMessage: function () {
var trackname = this.trackname; var trackname = this.trackname;
var replaceRegex = new RegExp('[^' + this.tracknameAllowedChars + ']', 'g'); var replaceRegex = new RegExp('[^' + this.tracknameAllowedChars + ']', 'g');
@ -71,14 +71,14 @@ BR.Export = L.Class.extend({
} }
}, },
_generateTrackname: function() { _generateTrackname: function () {
var trackname = this.trackname; var trackname = this.trackname;
this._getCityAtPosition( this._getCityAtPosition(
this.latLngs[0], this.latLngs[0],
L.bind(function(from) { L.bind(function (from) {
this._getCityAtPosition( this._getCityAtPosition(
this.latLngs[this.latLngs.length - 1], this.latLngs[this.latLngs.length - 1],
L.bind(function(to) { L.bind(function (to) {
var distance = document.getElementById('distance').innerHTML; var distance = document.getElementById('distance').innerHTML;
if (this.tracknameAllowedChars) { if (this.tracknameAllowedChars) {
distance = distance.replace(',', '.'); // temp. fix (#202) distance = distance.replace(',', '.'); // temp. fix (#202)
@ -88,13 +88,13 @@ BR.Export = L.Class.extend({
} else if (from === to) { } else if (from === to) {
trackname.value = i18next.t('export.route-loop', { trackname.value = i18next.t('export.route-loop', {
from: from, from: from,
distance: distance distance: distance,
}); });
} else { } else {
trackname.value = i18next.t('export.route-from-to', { trackname.value = i18next.t('export.route-from-to', {
from: from, from: from,
to: to, to: to,
distance: distance distance: distance,
}); });
} }
@ -109,14 +109,14 @@ BR.Export = L.Class.extend({
); );
}, },
_getCityAtPosition: function(lonlat, cb) { _getCityAtPosition: function (lonlat, cb) {
var url = L.Util.template( var url = L.Util.template(
'https://nominatim.openstreetmap.org/reverse?lon={lng}&lat={lat}&format=json', 'https://nominatim.openstreetmap.org/reverse?lon={lng}&lat={lat}&format=json',
lonlat lonlat
); );
BR.Util.get( BR.Util.get(
url, url,
L.bind(function(err, response) { L.bind(function (err, response) {
try { try {
var addr = JSON.parse(response).address; var addr = JSON.parse(response).address;
cb(addr.village || addr.town || addr.hamlet || addr.city_district || addr.city); cb(addr.village || addr.town || addr.hamlet || addr.city_district || addr.city);
@ -128,7 +128,7 @@ BR.Export = L.Class.extend({
); );
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if ( if (
BR.Util.keyboardShortcutsAllowed(e) && BR.Util.keyboardShortcutsAllowed(e) &&
e.keyCode === this.options.shortcut.export && e.keyCode === this.options.shortcut.export &&
@ -137,9 +137,9 @@ BR.Export = L.Class.extend({
this._generateTrackname(); this._generateTrackname();
$('#export').modal('show'); $('#export').modal('show');
} }
} },
}); });
BR.export = function() { BR.export = function () {
return new BR.Export(); return new BR.Export();
}; };

View file

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

View file

@ -1,5 +1,5 @@
BR.Layers = L.Class.extend({ BR.Layers = L.Class.extend({
_loadLayers: function() { _loadLayers: function () {
this._customLayers = {}; this._customLayers = {};
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
@ -10,13 +10,13 @@ BR.Layers = L.Class.extend({
} }
}, },
_loadTable: function() { _loadTable: function () {
var layersData = []; var layersData = [];
for (layer in this._customLayers) { for (layer in this._customLayers) {
layersData.push([ layersData.push([
layer, layer,
this._customLayers[layer].layer._url, this._customLayers[layer].layer._url,
this._customLayers[layer].isOverlay ? 'Overlay' : 'Layer' this._customLayers[layer].isOverlay ? 'Overlay' : 'Layer',
]); ]);
} }
if (this._layersTable != null) { if (this._layersTable != null) {
@ -29,17 +29,17 @@ BR.Layers = L.Class.extend({
searching: false, searching: false,
paging: false, paging: false,
language: { language: {
emptyTable: i18next.t('sidebar.layers.table.empty') emptyTable: i18next.t('sidebar.layers.table.empty'),
}, },
columns: [ columns: [
{ title: i18next.t('sidebar.layers.table.name') }, { title: i18next.t('sidebar.layers.table.name') },
{ title: i18next.t('sidebar.layers.table.URL') }, { title: i18next.t('sidebar.layers.table.URL') },
{ title: i18next.t('sidebar.layers.table.type') } { title: i18next.t('sidebar.layers.table.type') },
] ],
}); });
}, },
init: function(map, layersControl, baseLayers, overlays) { init: function (map, layersControl, baseLayers, overlays) {
this._layersControl = layersControl; this._layersControl = layersControl;
this._map = map; this._map = map;
this._layers = {}; this._layers = {};
@ -54,7 +54,7 @@ BR.Layers = L.Class.extend({
this._loadTable(); this._loadTable();
var table = this._layersTable; var table = this._layersTable;
$('#custom_layers_table tbody').on('click', 'tr', function() { $('#custom_layers_table tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) { if ($(this).hasClass('selected')) {
$(this).removeClass('selected'); $(this).removeClass('selected');
} else { } else {
@ -63,40 +63,37 @@ BR.Layers = L.Class.extend({
} }
}); });
L.DomUtil.get('custom_layers_button').onclick = function() { L.DomUtil.get('custom_layers_button').onclick = function () {
$('#custom_layers').modal(); $('#custom_layers').modal();
}; };
}, },
_remove: function(evt) { _remove: function (evt) {
var row = this._layersTable.row('.selected').data(); var row = this._layersTable.row('.selected').data();
if (row != null) { if (row != null) {
var name = row[0]; var name = row[0];
this._layersControl.removeLayer(this._customLayers[name].layer); this._layersControl.removeLayer(this._customLayers[name].layer);
this._map.removeLayer(this._customLayers[name].layer); this._map.removeLayer(this._customLayers[name].layer);
delete this._customLayers[name]; delete this._customLayers[name];
this._layersTable this._layersTable.row('.selected').remove().draw(false);
.row('.selected')
.remove()
.draw(false);
this._sync(); this._sync();
} }
}, },
_addFromInput: function(isOverlay) { _addFromInput: function (isOverlay) {
var layer_name = L.DomUtil.get('layer_name').value; var layer_name = L.DomUtil.get('layer_name').value;
var layer_url = L.DomUtil.get('layer_url').value; var layer_url = L.DomUtil.get('layer_url').value;
if (layer_name.length > 0 && layer_url.length > 0) this._addLayer(layer_name, layer_url, isOverlay); if (layer_name.length > 0 && layer_url.length > 0) this._addLayer(layer_name, layer_url, isOverlay);
}, },
_addBaseLayer: function(evt) { _addBaseLayer: function (evt) {
this._addFromInput(false); this._addFromInput(false);
}, },
_addOverlay: function(evt) { _addOverlay: function (evt) {
this._addFromInput(true); this._addFromInput(true);
}, },
_addLayer: function(layerName, layerUrl, isOverlay) { _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;
@ -106,7 +103,7 @@ BR.Layers = L.Class.extend({
this._customLayers[layerName] = { this._customLayers[layerName] = {
layer: layer, layer: layer,
isOverlay: isOverlay isOverlay: isOverlay,
}; };
if (isOverlay) { if (isOverlay) {
@ -123,15 +120,15 @@ BR.Layers = L.Class.extend({
} }
}, },
_sync: function() { _sync: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
localStorage.setItem( localStorage.setItem(
'map/customLayers', 'map/customLayers',
JSON.stringify(this._customLayers, function(k, v) { JSON.stringify(this._customLayers, function (k, v) {
// dont write Leaflet.Layer in localStorage; simply keep the URL // dont write Leaflet.Layer in localStorage; simply keep the URL
return v._url || v; return v._url || v;
}) })
); );
} }
} },
}); });

View file

@ -3,13 +3,13 @@ BR.LayersTab = BR.ControlLayers.extend({
previewBounds: null, previewBounds: null,
saveLayers: [], saveLayers: [],
initialize: function(layersConfig, baseLayers, overlays, options) { initialize: function (layersConfig, baseLayers, overlays, options) {
L.Control.Layers.prototype.initialize.call(this, baseLayers, overlays, options); L.Control.Layers.prototype.initialize.call(this, baseLayers, overlays, options);
this.layersConfig = layersConfig; this.layersConfig = layersConfig;
}, },
addTo: function(map) { addTo: function (map) {
this._map = map; this._map = map;
this.onAdd(map); this.onAdd(map);
@ -22,19 +22,19 @@ BR.LayersTab = BR.ControlLayers.extend({
return this; return this;
}, },
onAdd: function(map) { onAdd: function (map) {
BR.ControlLayers.prototype.onAdd.call(this, map); BR.ControlLayers.prototype.onAdd.call(this, map);
map.on('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this); map.on('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this);
}, },
onRemove: function(map) { onRemove: function (map) {
BR.ControlLayers.prototype.onRemove.call(this, map); BR.ControlLayers.prototype.onRemove.call(this, map);
map.off('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this); map.off('baselayerchange overlayadd overlayremove', this.storeActiveLayers, this);
}, },
initOpacitySlider: function(map) { initOpacitySlider: function (map) {
var self = this; var self = this;
var overlayOpacitySlider = new BR.OpacitySlider({ var overlayOpacitySlider = new BR.OpacitySlider({
id: 'overlay', id: 'overlay',
@ -42,7 +42,7 @@ BR.LayersTab = BR.ControlLayers.extend({
orientation: 'horizontal', orientation: 'horizontal',
defaultValue: 1, defaultValue: 1,
title: i18next.t('layers.opacity-slider'), title: i18next.t('layers.opacity-slider'),
callback: function(opacity) { callback: function (opacity) {
for (var i = 0; i < self._layers.length; i++) { for (var i = 0; i < self._layers.length; i++) {
if (!self._layers[i].overlay || !map.hasLayer(self._layers[i].layer)) { if (!self._layers[i].overlay || !map.hasLayer(self._layers[i].layer)) {
continue; continue;
@ -53,20 +53,20 @@ BR.LayersTab = BR.ControlLayers.extend({
self._layers[i].layer.setStyle({ opacity: opacity }); self._layers[i].layer.setStyle({ opacity: opacity });
} }
} }
} },
}); });
L.DomUtil.get('leaflet-control-layers-overlays-opacity-slider').appendChild(overlayOpacitySlider.getElement()); L.DomUtil.get('leaflet-control-layers-overlays-opacity-slider').appendChild(overlayOpacitySlider.getElement());
}, },
initButtons: function() { initButtons: function () {
var expandTree = function(e) { var expandTree = function (e) {
this.jstree.open_all(); this.jstree.open_all();
}; };
var collapseTree = function(e) { var collapseTree = function (e) {
this.jstree.close_all(); this.jstree.close_all();
}; };
var toggleOptionalLayers = function(e) { var toggleOptionalLayers = function (e) {
var button = L.DomUtil.get('optional_layers_button'); var button = L.DomUtil.get('optional_layers_button');
var treeButtons = L.DomUtil.get('tree-button-group'); var treeButtons = L.DomUtil.get('tree-button-group');
var div = L.DomUtil.get('optional-layers'); var div = L.DomUtil.get('optional-layers');
@ -86,12 +86,12 @@ BR.LayersTab = BR.ControlLayers.extend({
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 layerIndex = BR.layerIndex;
var treeData = this.toJsTree(BR.confLayers.tree); var treeData = this.toJsTree(BR.confLayers.tree);
var oldSelected = null; var oldSelected = null;
var onSelectNode = function(e, data) { var onSelectNode = function (e, data) {
var layerData = layerIndex[data.node.id]; var layerData = layerIndex[data.node.id];
var selected = data.selected[0]; var selected = data.selected[0];
@ -103,12 +103,12 @@ BR.LayersTab = BR.ControlLayers.extend({
} }
}; };
var onDeselectNode = function(e, data) { var onDeselectNode = function (e, data) {
this.hidePreview(); this.hidePreview();
oldSelected = null; oldSelected = null;
}; };
var onCheckNode = function(e, data) { var onCheckNode = function (e, data) {
var layerData = layerIndex[data.node.id]; var layerData = layerIndex[data.node.id];
var layer = this.createLayer(layerData); var layer = this.createLayer(layerData);
var name = layerData.properties.name; var name = layerData.properties.name;
@ -124,12 +124,12 @@ BR.LayersTab = BR.ControlLayers.extend({
var ele = document.getElementById(data.node.a_attr.id); var ele = document.getElementById(data.node.a_attr.id);
ele.classList.add('added'); ele.classList.add('added');
setTimeout(function() { setTimeout(function () {
ele.classList.remove('added'); ele.classList.remove('added');
}, 1000); }, 1000);
}; };
var onUncheckNode = function(e, data) { var onUncheckNode = function (e, data) {
var obj = this.getLayerById(data.node.id); var obj = this.getLayerById(data.node.id);
if (!obj) return; if (!obj) return;
@ -146,7 +146,7 @@ BR.LayersTab = BR.ControlLayers.extend({
var ele = document.getElementById(data.node.a_attr.id); var ele = document.getElementById(data.node.a_attr.id);
ele.classList.add('removed'); ele.classList.add('removed');
setTimeout(function() { setTimeout(function () {
ele.classList.remove('removed'); ele.classList.remove('removed');
}, 1000); }, 1000);
}; };
@ -156,30 +156,30 @@ BR.LayersTab = BR.ControlLayers.extend({
.on('deselect_node.jstree', L.bind(onDeselectNode, this)) .on('deselect_node.jstree', L.bind(onDeselectNode, this))
.on('check_node.jstree', L.bind(onCheckNode, this)) .on('check_node.jstree', L.bind(onCheckNode, this))
.on('uncheck_node.jstree', L.bind(onUncheckNode, 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(); data.instance.open_all();
}) })
.jstree({ .jstree({
plugins: ['checkbox'], plugins: ['checkbox'],
checkbox: { checkbox: {
whole_node: false, whole_node: false,
tie_selection: false tie_selection: false,
}, },
core: { core: {
multiple: false, multiple: false,
themes: { themes: {
icons: false, icons: false,
dots: false dots: false,
}, },
data: treeData data: treeData,
} },
}); });
this.jstree = $('#optional-layers-tree').jstree(true); this.jstree = $('#optional-layers-tree').jstree(true);
}, },
toJsTree: function(layerTree) { toJsTree: function (layerTree) {
var data = { var data = {
children: [] children: [],
}; };
var self = this; var self = this;
@ -187,9 +187,9 @@ BR.LayersTab = BR.ControlLayers.extend({
var rootNode = { var rootNode = {
text: i18next.t('sidebar.layers.category.' + name, name), text: i18next.t('sidebar.layers.category.' + name, name),
state: { state: {
disabled: true disabled: true,
}, },
children: [] children: [],
}; };
return rootNode; return rootNode;
} }
@ -217,8 +217,8 @@ BR.LayersTab = BR.ControlLayers.extend({
id: id, id: id,
text: getText(props, parent), text: getText(props, parent),
state: { state: {
checked: self.layersConfig.isDefaultLayer(id, props.overlay) checked: self.layersConfig.isDefaultLayer(id, props.overlay),
} },
}; };
} }
return childNode; return childNode;
@ -262,7 +262,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return data.children; return data.children;
}, },
storeDefaultLayers: function() { storeDefaultLayers: function () {
var baseLayers = []; var baseLayers = [];
var overlays = []; var overlays = [];
@ -284,7 +284,7 @@ BR.LayersTab = BR.ControlLayers.extend({
this.layersConfig.storeDefaultLayers(baseLayers, overlays); this.layersConfig.storeDefaultLayers(baseLayers, overlays);
}, },
createLayer: function(layerData) { createLayer: function (layerData) {
var layer = this.layersConfig.createLayer(layerData); var layer = this.layersConfig.createLayer(layerData);
var overlay = layerData.properties.overlay; var overlay = layerData.properties.overlay;
@ -294,7 +294,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return layer; return layer;
}, },
getLayerById: function(id) { getLayerById: function (id) {
for (var i = 0; i < this._layers.length; i++) { for (var i = 0; i < this._layers.length; i++) {
var obj = this._layers[i]; var obj = this._layers[i];
if (obj.layer.id === id) { if (obj.layer.id === id) {
@ -305,7 +305,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return null; return null;
}, },
getLayerByLegacyName: function(legacyName) { getLayerByLegacyName: function (legacyName) {
var obj = null; var obj = null;
var id = this.layersConfig.legacyNameToIdMap[legacyName]; var id = this.layersConfig.legacyNameToIdMap[legacyName];
@ -316,7 +316,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return obj; return obj;
}, },
activateDefaultBaseLayer: function() { activateDefaultBaseLayer: function () {
var index = BR.conf.defaultBaseLayerIndex || 0; var index = BR.conf.defaultBaseLayerIndex || 0;
var activeBaseLayer = this.getActiveBaseLayer(); var activeBaseLayer = this.getActiveBaseLayer();
if (!activeBaseLayer) { if (!activeBaseLayer) {
@ -324,11 +324,11 @@ BR.LayersTab = BR.ControlLayers.extend({
} }
}, },
saveRemoveActiveLayers: function() { saveRemoveActiveLayers: function () {
this.saveLayers = this.removeActiveLayers(); this.saveLayers = this.removeActiveLayers();
}, },
restoreActiveLayers: function(overlaysOnly) { restoreActiveLayers: function (overlaysOnly) {
for (var i = 0; i < this.saveLayers.length; i++) { for (var i = 0; i < this.saveLayers.length; i++) {
var obj = this.saveLayers[i]; var obj = this.saveLayers[i];
@ -345,7 +345,7 @@ BR.LayersTab = BR.ControlLayers.extend({
this.saveLayers = []; this.saveLayers = [];
}, },
removePreviewLayer: function() { removePreviewLayer: function () {
if (this.previewLayer && this._map.hasLayer(this.previewLayer)) { if (this.previewLayer && this._map.hasLayer(this.previewLayer)) {
this._map.removeLayer(this.previewLayer); this._map.removeLayer(this.previewLayer);
this.previewLayer = null; this.previewLayer = null;
@ -354,7 +354,7 @@ BR.LayersTab = BR.ControlLayers.extend({
return false; return false;
}, },
showPreviewBounds: function(layerData) { showPreviewBounds: function (layerData) {
if (layerData.geometry) { if (layerData.geometry) {
this.previewBounds = L.geoJson(layerData.geometry, { this.previewBounds = L.geoJson(layerData.geometry, {
// fill/mask outside of bounds polygon with Leaflet.snogylop // fill/mask outside of bounds polygon with Leaflet.snogylop
@ -363,30 +363,30 @@ BR.LayersTab = BR.ControlLayers.extend({
renderer: L.svg({ padding: 1 }), renderer: L.svg({ padding: 1 }),
color: '#333', color: '#333',
fillOpacity: 0.4, fillOpacity: 0.4,
weight: 2 weight: 2,
}).addTo(this._map); }).addTo(this._map);
} }
}, },
removePreviewBounds: function() { removePreviewBounds: function () {
if (this.previewBounds && this._map.hasLayer(this.previewBounds)) { if (this.previewBounds && this._map.hasLayer(this.previewBounds)) {
this._map.removeLayer(this.previewBounds); this._map.removeLayer(this.previewBounds);
this.previewBounds = null; this.previewBounds = null;
} }
}, },
deselectNode: function() { deselectNode: function () {
var selected = this.jstree.get_selected(); var selected = this.jstree.get_selected();
if (selected.length > 0) { if (selected.length > 0) {
this.jstree.deselect_node(selected[0]); this.jstree.deselect_node(selected[0]);
} }
}, },
onBaselayerchange: function() { onBaselayerchange: function () {
// execute after current input click handler, // execute after current input click handler,
// otherwise added overlay checkbox state doesn't update // otherwise added overlay checkbox state doesn't update
setTimeout( setTimeout(
L.Util.bind(function() { L.Util.bind(function () {
this.removePreviewBounds(); this.removePreviewBounds();
this.removePreviewLayer(); this.removePreviewLayer();
this.restoreActiveLayers(true); this.restoreActiveLayers(true);
@ -396,7 +396,7 @@ BR.LayersTab = BR.ControlLayers.extend({
); );
}, },
showPreview: function(layerData) { showPreview: function (layerData) {
var layer = this.createLayer(layerData); var layer = this.createLayer(layerData);
this._map.addLayer(layer); this._map.addLayer(layer);
this.removePreviewBounds(); this.removePreviewBounds();
@ -411,7 +411,7 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('preview').hidden = false; L.DomUtil.get('preview').hidden = false;
}, },
hidePreview: function(layer) { hidePreview: function (layer) {
this._map.off('baselayerchange', this.onBaselayerchange, this); this._map.off('baselayerchange', this.onBaselayerchange, this);
this.removePreviewBounds(); this.removePreviewBounds();
this.removePreviewLayer(); this.removePreviewLayer();
@ -420,11 +420,11 @@ BR.LayersTab = BR.ControlLayers.extend({
L.DomUtil.get('preview').hidden = true; L.DomUtil.get('preview').hidden = true;
}, },
toLayerString: function(obj) { toLayerString: function (obj) {
return obj.layer.id ? obj.layer.id : obj.name; return obj.layer.id ? obj.layer.id : obj.name;
}, },
getLayerFromString: function(layerString) { getLayerFromString: function (layerString) {
var obj = this.getLayerById(layerString); var obj = this.getLayerById(layerString);
if (!obj) { if (!obj) {
@ -440,11 +440,11 @@ BR.LayersTab = BR.ControlLayers.extend({
return obj; return obj;
}, },
storeActiveLayers: function() { storeActiveLayers: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
var objList = this.getActiveLayers(); var objList = this.getActiveLayers();
var idList = objList.map( var idList = objList.map(
L.bind(function(obj) { L.bind(function (obj) {
return this.toLayerString(obj); return this.toLayerString(obj);
}, this) }, this)
); );
@ -454,7 +454,7 @@ BR.LayersTab = BR.ControlLayers.extend({
} }
}, },
loadActiveLayers: function() { loadActiveLayers: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
var item = localStorage.getItem('map/activeLayers'); var item = localStorage.getItem('map/activeLayers');
@ -471,9 +471,9 @@ BR.LayersTab = BR.ControlLayers.extend({
} }
} }
} }
} },
}); });
BR.layersTab = function(baseLayers, overlays, options) { BR.layersTab = function (baseLayers, overlays, options) {
return new BR.LayersTab(baseLayers, overlays, options); return new BR.LayersTab(baseLayers, overlays, options);
}; };

View file

@ -2,15 +2,15 @@ BR.Message = L.Class.extend({
options: { options: {
// true to manually attach click event to close button, // true to manually attach click event to close button,
// Bootstrap data-api's auto-initialization doesn't work in Controls because of stopPropagation // Bootstrap data-api's auto-initialization doesn't work in Controls because of stopPropagation
alert: false alert: false,
}, },
initialize: function(id, options) { initialize: function (id, options) {
L.setOptions(this, options); L.setOptions(this, options);
this.id = id; this.id = id;
}, },
_show: function(msg, type) { _show: function (msg, type) {
var ele = L.DomUtil.get(this.id), var ele = L.DomUtil.get(this.id),
iconClass = type === 'warning' ? 'fa-exclamation-triangle' : 'fa-times-circle', iconClass = type === 'warning' ? 'fa-exclamation-triangle' : 'fa-times-circle',
alertClass = type === 'warning' ? 'alert-warning' : 'alert-danger'; alertClass = type === 'warning' ? 'alert-warning' : 'alert-danger';
@ -35,20 +35,30 @@ BR.Message = L.Class.extend({
} }
}, },
hide: function() { hide: function () {
$('#' + this.id + ' .alert').alert('close'); $('#' + this.id + ' .alert').alert('close');
}, },
showError: function(err) { showError: function (err) {
if (err == 'Error: target island detected for section 0\n') { if (err && err.message) err = err.message;
if (err == 'target island detected for section 0\n') {
err = i18next.t('warning.no-route-found');
} else if (err == 'no track found at pass=0\n') {
err = i18next.t('warning.no-route-found');
} else if (err == 'to-position not mapped in existing datafile\n') {
err = i18next.t('warning.invalid-route-to');
} else if (err == 'from-position not mapped in existing datafile\n') {
err = i18next.t('warning.invalid-route-from');
} else if (err && err.startsWith('null description for: ')) {
err = i18next.t('warning.no-route-found'); err = i18next.t('warning.no-route-found');
} }
this._show(err, 'error'); this._show(err, 'error');
}, },
showWarning: function(msg) { showWarning: function (msg) {
this._show(msg, 'warning'); this._show(msg, 'warning');
} },
}); });
// static instance as global control // static instance as global control

View file

@ -5,10 +5,10 @@ BR.OpacitySlider = L.Class.extend({
orientation: 'vertical', orientation: 'vertical',
defaultValue: BR.conf.defaultOpacity, defaultValue: BR.conf.defaultOpacity,
title: '', title: '',
callback: function(opacity) {} callback: function (opacity) {},
}, },
initialize: function(options) { initialize: function (options) {
L.setOptions(this, options); L.setOptions(this, options);
var input = (this.input = $('<input id="slider-' + this.options.id + '" type="text"/>')), var input = (this.input = $('<input id="slider-' + this.options.id + '" type="text"/>')),
@ -30,12 +30,12 @@ BR.OpacitySlider = L.Class.extend({
orientation: this.options.orientation, orientation: this.options.orientation,
reversed: this.options.reversed, reversed: this.options.reversed,
selection: this.options.reversed ? 'before' : 'after', // inverted, serves as track style, see css selection: this.options.reversed ? 'before' : 'after', // inverted, serves as track style, see css
tooltip: 'hide' tooltip: 'hide',
}) })
.on('slide slideStop', { self: this }, function(evt) { .on('slide slideStop', { self: this }, function (evt) {
evt.data.self.options.callback(evt.value / 100); evt.data.self.options.callback(evt.value / 100);
}) })
.on('slideStop', { self: this }, function(evt) { .on('slideStop', { self: this }, function (evt) {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
localStorage['opacitySliderValue' + evt.data.self.options.id] = evt.value; localStorage['opacitySliderValue' + evt.data.self.options.id] = evt.value;
} }
@ -51,19 +51,19 @@ BR.OpacitySlider = L.Class.extend({
} }
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) {
this.options.callback(0); this.options.callback(0);
} }
}, },
_keyupListener: function(e) { _keyupListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.muteKeyCode) {
this.options.callback(this.input.val() / 100); this.options.callback(this.input.val() / 100);
} }
}, },
getElement: function() { getElement: function () {
return this.input.slider('getElement'); return this.input.slider('getElement');
} },
}); });

View file

@ -1,9 +1,9 @@
BR.OpacitySliderControl = L.Control.extend({ BR.OpacitySliderControl = L.Control.extend({
options: { options: {
position: 'topleft' position: 'topleft',
}, },
onAdd: function(map) { onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-bar control-slider'); var container = L.DomUtil.create('div', 'leaflet-bar control-slider');
// prevent also dragging map in Chrome // prevent also dragging map in Chrome
@ -21,22 +21,22 @@ BR.OpacitySliderControl = L.Control.extend({
var slider = new BR.OpacitySlider(this.options); var slider = new BR.OpacitySlider(this.options);
container.appendChild(slider.getElement()); container.appendChild(slider.getElement());
var stopClickAfterSlide = function(evt) { var stopClickAfterSlide = function (evt) {
L.DomEvent.stop(evt); L.DomEvent.stop(evt);
removeStopClickListeners(); removeStopClickListeners();
}; };
var removeStopClickListeners = function() { var removeStopClickListeners = function () {
document.removeEventListener('click', stopClickAfterSlide, true); document.removeEventListener('click', stopClickAfterSlide, true);
document.removeEventListener('mousedown', removeStopClickListeners, true); document.removeEventListener('mousedown', removeStopClickListeners, true);
}; };
slider.input slider.input
.on('slideStart', function(evt) { .on('slideStart', function (evt) {
// dragging beyond slider control selects zoom control +/- text in Firefox // dragging beyond slider control selects zoom control +/- text in Firefox
L.DomUtil.disableTextSelection(); L.DomUtil.disableTextSelection();
}) })
.on('slideStop', { self: this }, function(evt) { .on('slideStop', { self: this }, function (evt) {
L.DomUtil.enableTextSelection(); L.DomUtil.enableTextSelection();
// When dragging outside slider and over map, click event after mouseup // When dragging outside slider and over map, click event after mouseup
@ -49,5 +49,5 @@ BR.OpacitySliderControl = L.Control.extend({
}); });
return container; return container;
} },
}); });

View file

@ -2,15 +2,15 @@ BR.Profile = L.Evented.extend({
cache: {}, cache: {},
saveWarningShown: false, saveWarningShown: false,
initialize: function() { initialize: function () {
var textArea = L.DomUtil.get('profile_upload'); var textArea = L.DomUtil.get('profile_upload');
this.editor = CodeMirror.fromTextArea(textArea, { this.editor = CodeMirror.fromTextArea(textArea, {
lineNumbers: true lineNumbers: true,
}); });
$('#profileEditorTabs a[data-toggle="tab"]').on( $('#profileEditorTabs a[data-toggle="tab"]').on(
'shown.bs.tab', 'shown.bs.tab',
L.bind(function(e) { L.bind(function (e) {
this._activateSecondaryTab(); this._activateSecondaryTab();
}, this) }, this)
); );
@ -22,11 +22,11 @@ BR.Profile = L.Evented.extend({
this.pinned = L.DomUtil.get('profile-pinned'); this.pinned = L.DomUtil.get('profile-pinned');
this.message = new BR.Message('profile_message', { this.message = new BR.Message('profile_message', {
alert: true alert: true,
}); });
}, },
clear: function(evt) { clear: function (evt) {
var button = evt.target || evt.srcElement; var button = evt.target || evt.srcElement;
evt.preventDefault(); evt.preventDefault();
@ -38,7 +38,7 @@ BR.Profile = L.Evented.extend({
button.blur(); button.blur();
}, },
update: function(options) { update: function (options) {
var profileName = options.profile, var profileName = options.profile,
profileUrl, profileUrl,
empty = !this.editor.getValue(), empty = !this.editor.getValue(),
@ -53,7 +53,7 @@ BR.Profile = L.Evented.extend({
profileUrl = BR.conf.profilesUrl + profileName + '.brf'; profileUrl = BR.conf.profilesUrl + profileName + '.brf';
BR.Util.get( BR.Util.get(
profileUrl, profileUrl,
L.bind(function(err, profileText) { L.bind(function (err, profileText) {
if (err) { if (err) {
console.warn('Error getting profile from "' + profileUrl + '": ' + err); console.warn('Error getting profile from "' + profileUrl + '": ' + err);
return; return;
@ -82,15 +82,15 @@ BR.Profile = L.Evented.extend({
} }
}, },
show: function() { show: function () {
this.editor.refresh(); this.editor.refresh();
}, },
onResize: function() { onResize: function () {
this.editor.refresh(); this.editor.refresh();
}, },
_upload: function(evt) { _upload: function (evt) {
var button = evt.target || evt.srcElement, var button = evt.target || evt.srcElement,
profile = this.editor.getValue(); profile = this.editor.getValue();
@ -99,7 +99,7 @@ BR.Profile = L.Evented.extend({
this.fire('update', { this.fire('update', {
profileText: profile, profileText: profile,
callback: L.bind(function(err, profileId, profileText) { callback: L.bind(function (err, profileId, profileText) {
$(button).blur(); $(button).blur();
if (!err) { if (!err) {
this.profileName = profileId; this.profileName = profileId;
@ -110,12 +110,12 @@ BR.Profile = L.Evented.extend({
this.saveWarningShown = true; this.saveWarningShown = true;
} }
} }
}, this) }, this),
}); });
}, },
_buildCustomProfile: function(profileText) { _buildCustomProfile: function (profileText) {
document.querySelectorAll('#profile_params input, #profile_params select').forEach(function(input) { document.querySelectorAll('#profile_params input, #profile_params select').forEach(function (input) {
var name = input.name; var name = input.name;
var value; var value;
if (input.type == 'checkbox') { if (input.type == 'checkbox') {
@ -129,28 +129,28 @@ BR.Profile = L.Evented.extend({
name + name +
'\\s*=?\\s*)([\\w.]*)(\\s*#\\s*%(.*)%\\s*(\\|\\s*(.*)\\s*\\|\\s*(.*)\\s*)?[\\r\\n])' '\\s*=?\\s*)([\\w.]*)(\\s*#\\s*%(.*)%\\s*(\\|\\s*(.*)\\s*\\|\\s*(.*)\\s*)?[\\r\\n])'
); );
profileText = profileText.replace(re, function(match, p1, p2, p3) { profileText = profileText.replace(re, function (match, p1, p2, p3) {
return p1 + value + p3; return p1 + value + p3;
}); });
}); });
return profileText; return profileText;
}, },
_save: function(evt) { _save: function (evt) {
var profileText = this._buildCustomProfile(this.editor.getValue()); var profileText = this._buildCustomProfile(this.editor.getValue());
var that = this; var that = this;
this.fire('update', { this.fire('update', {
profileText: profileText, profileText: profileText,
callback: function(err, profileId, profileText) { callback: function (err, profileId, profileText) {
if (!err) { if (!err) {
that.profileName = profileId; that.profileName = profileId;
that.cache[profileId] = profileText; that.cache[profileId] = profileText;
} }
} },
}); });
}, },
_setValue: function(profileText) { _setValue: function (profileText) {
profileText = profileText || ''; profileText = profileText || '';
var clean = this.editor.isClean(); var clean = this.editor.isClean();
@ -169,12 +169,12 @@ BR.Profile = L.Evented.extend({
} }
}, },
_buildParamsForm: function(profileText) { _buildParamsForm: function (profileText) {
if (!profileText) return; if (!profileText) return;
// Otherwise, create user friendly form // Otherwise, create user friendly form
var params = {}; var params = {};
var global = profileText.split('---context:').filter(function(e) { var global = profileText.split('---context:').filter(function (e) {
return e.startsWith('global'); return e.startsWith('global');
}); });
if (global && global.length > 0) { if (global && global.length > 0) {
@ -183,7 +183,7 @@ BR.Profile = L.Evented.extend({
// Comment is mandatory // Comment is mandatory
var assignRegex = /assign\s*(\w*)\s*=?\s*([\w\.]*)\s*#\s*%(.*)%\s*(\|\s*(.*)\s*\|\s*(.*)\s*)?$/; var assignRegex = /assign\s*(\w*)\s*=?\s*([\w\.]*)\s*#\s*%(.*)%\s*(\|\s*(.*)\s*\|\s*(.*)\s*)?$/;
global.forEach(function(item) { global.forEach(function (item) {
var match = item.match(assignRegex); var match = item.match(assignRegex);
var value; var value;
if (match) { if (match) {
@ -198,7 +198,7 @@ BR.Profile = L.Evented.extend({
paramType paramType
.slice(1, -1) .slice(1, -1)
.split(',') .split(',')
.forEach(function(option) { .forEach(function (option) {
var splitOption = option.split('='); var splitOption = option.split('=');
var value = (splitOption[0] || '').replace(/^\s+|\s+$/g, ''); var value = (splitOption[0] || '').replace(/^\s+|\s+$/g, '');
var description = (splitOption[1] || '').replace(/^\s+|\s+$/g, ''); var description = (splitOption[1] || '').replace(/^\s+|\s+$/g, '');
@ -230,7 +230,7 @@ BR.Profile = L.Evented.extend({
description: description, description: description,
type: paramType, type: paramType,
value: value, value: value,
possible_values: paramValues possible_values: paramValues,
}; };
} }
}); });
@ -242,7 +242,7 @@ BR.Profile = L.Evented.extend({
paramsSection.append(i18next.t('sidebar.profile.no_easy_configuration_warning')); paramsSection.append(i18next.t('sidebar.profile.no_easy_configuration_warning'));
} }
Object.keys(params).forEach(function(param) { Object.keys(params).forEach(function (param) {
var div = document.createElement('div'); var div = document.createElement('div');
var label = document.createElement('label'); var label = document.createElement('label');
@ -257,7 +257,7 @@ BR.Profile = L.Evented.extend({
label.htmlFor = select.id = 'customize-profile-' + paramName; label.htmlFor = select.id = 'customize-profile-' + paramName;
var paramValues = params[param].possible_values; var paramValues = params[param].possible_values;
Object.keys(paramValues).forEach(function(paramValue) { Object.keys(paramValues).forEach(function (paramValue) {
var option = document.createElement('option'); var option = document.createElement('option');
option.value = paramValue; option.value = paramValue;
if (paramValue == params[param].value) { if (paramValue == params[param].value) {
@ -308,11 +308,11 @@ BR.Profile = L.Evented.extend({
}); });
}, },
_isParamsFormActive: function() { _isParamsFormActive: function () {
return L.DomUtil.get('profile_params_container').classList.contains('active'); return L.DomUtil.get('profile_params_container').classList.contains('active');
}, },
_activateSecondaryTab: function() { _activateSecondaryTab: function () {
var profileText = this.editor.getValue(); var profileText = this.editor.getValue();
if (this._isParamsFormActive()) { if (this._isParamsFormActive()) {
@ -320,5 +320,5 @@ BR.Profile = L.Evented.extend({
} else { } else {
this._setValue(this._buildCustomProfile(profileText)); this._setValue(this._buildCustomProfile(profileText));
} }
} },
}); });

View file

@ -1,11 +1,11 @@
BR.RoutingOptions = L.Evented.extend({ BR.RoutingOptions = L.Evented.extend({
options: { options: {
shortcut: { shortcut: {
switch: 71 // char code for 'g' switch: 71, // char code for 'g'
} },
}, },
initialize: function() { initialize: function () {
$('#profile-alternative').on('changed.bs.select', this._getChangeHandler()); $('#profile-alternative').on('changed.bs.select', this._getChangeHandler());
// build option list from config // build option list from config
@ -25,17 +25,17 @@ BR.RoutingOptions = L.Evented.extend({
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this); L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
}, },
refreshUI: function() { refreshUI: function () {
// we do not allow to select more than one profile and/or alternative at a time // we do not allow to select more than one profile and/or alternative at a time
// so we disable the current selected items // so we disable the current selected items
$('#profile-alternative') $('#profile-alternative')
.find('option:disabled') .find('option:disabled')
.each(function(index) { .each(function (index) {
$(this).prop('disabled', false); $(this).prop('disabled', false);
}); });
$('#profile-alternative') $('#profile-alternative')
.find('option:selected') .find('option:selected')
.each(function(index) { .each(function (index) {
$(this).prop('disabled', true); $(this).prop('disabled', true);
}); });
@ -51,21 +51,21 @@ BR.RoutingOptions = L.Evented.extend({
button.title = button.title + i18next.t('navbar.profile-tooltip', { key: 'G' }); button.title = button.title + i18next.t('navbar.profile-tooltip', { key: 'G' });
}, },
getOptions: function() { getOptions: function () {
var profile = $('#profile option:selected'), var profile = $('#profile option:selected'),
alternative = $('#alternative option:selected'); alternative = $('#alternative option:selected');
this.refreshUI(); this.refreshUI();
return { return {
profile: profile.val(), profile: profile.val(),
alternative: alternative.val() alternative: alternative.val(),
}; };
}, },
setOptions: function(options) { setOptions: function (options) {
var values = [ var values = [
options.profile ? options.profile : $('#profile option:selected').val(), options.profile ? options.profile : $('#profile option:selected').val(),
options.alternative ? options.alternative : $('#alternative option:selected').val() options.alternative ? options.alternative : $('#alternative option:selected').val(),
]; ];
$('.selectpicker').selectpicker('val', values); $('.selectpicker').selectpicker('val', values);
this.refreshUI(); this.refreshUI();
@ -76,7 +76,7 @@ BR.RoutingOptions = L.Evented.extend({
} }
}, },
setCustomProfile: function(profile, noUpdate) { setCustomProfile: function (profile, noUpdate) {
var profiles_grp, option; var profiles_grp, option;
profiles_grp = L.DomUtil.get('profile'); profiles_grp = L.DomUtil.get('profile');
@ -87,7 +87,7 @@ BR.RoutingOptions = L.Evented.extend({
if (profile) { if (profile) {
$('#profile') $('#profile')
.find('option:selected') .find('option:selected')
.each(function(index) { .each(function (index) {
$(this).prop('selected', false); $(this).prop('selected', false);
}); });
} else if (option.selected) { } else if (option.selected) {
@ -102,7 +102,7 @@ BR.RoutingOptions = L.Evented.extend({
} }
}, },
getCustomProfile: function() { getCustomProfile: function () {
var profiles_grp = L.DomUtil.get('profile'), var profiles_grp = L.DomUtil.get('profile'),
option = profiles_grp.children[0], option = profiles_grp.children[0],
profile = null; profile = null;
@ -113,17 +113,17 @@ BR.RoutingOptions = L.Evented.extend({
return profile; return profile;
}, },
_getChangeHandler: function() { _getChangeHandler: function () {
return L.bind(function(evt) { return L.bind(function (evt) {
this.fire('update', { options: this.getOptions() }); this.fire('update', { options: this.getOptions() });
}, this); }, this);
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.switch) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.switch) {
if (!$('#profile-alternative-form .dropdown').hasClass('show')) { if (!$('#profile-alternative-form .dropdown').hasClass('show')) {
$('#profile-alternative-form button').click(); $('#profile-alternative-form button').click();
} }
} }
} },
}); });

View file

@ -20,8 +20,8 @@ BR.TrackAnalysis = L.Class.extend({
opacity: 0.8, opacity: 0.8,
weight: 8, weight: 8,
// show above quality coding (pane defined in RoutingPathQuality.js) // show above quality coding (pane defined in RoutingPathQuality.js)
pane: 'routingQualityPane' pane: 'routingQualityPane',
} },
}, },
/** /**
@ -35,7 +35,7 @@ BR.TrackAnalysis = L.Class.extend({
* @param {Map} map * @param {Map} map
* @param {object} options * @param {object} options
*/ */
initialize: function(map, options) { initialize: function (map, options) {
this.map = map; this.map = map;
L.setOptions(this, options); L.setOptions(this, options);
}, },
@ -60,7 +60,7 @@ BR.TrackAnalysis = L.Class.extend({
/** /**
* Called by BR.Sidebar when tab is activated * Called by BR.Sidebar when tab is activated
*/ */
show: function() { show: function () {
this.active = true; this.active = true;
this.options.requestUpdate(this); this.options.requestUpdate(this);
}, },
@ -68,7 +68,7 @@ BR.TrackAnalysis = L.Class.extend({
/** /**
* Called by BR.Sidebar when tab is deactivated * Called by BR.Sidebar when tab is deactivated
*/ */
hide: function() { hide: function () {
this.active = false; this.active = false;
}, },
@ -84,7 +84,7 @@ BR.TrackAnalysis = L.Class.extend({
* @param {Polyline} polyline * @param {Polyline} polyline
* @param {Array} segments * @param {Array} segments
*/ */
update: function(polyline, segments) { update: function (polyline, segments) {
if (!this.active) { if (!this.active) {
return; return;
} }
@ -121,11 +121,11 @@ BR.TrackAnalysis = L.Class.extend({
* @param segments * @param segments
* @returns {Object} * @returns {Object}
*/ */
calcStats: function(polyline, segments) { calcStats: function (polyline, segments) {
var analysis = { var analysis = {
highway: {}, highway: {},
surface: {}, surface: {},
smoothness: {} smoothness: {},
}; };
this.totalRouteDistance = 0.0; this.totalRouteDistance = 0.0;
@ -158,7 +158,7 @@ BR.TrackAnalysis = L.Class.extend({
), ),
name: wayTagParts[1], name: wayTagParts[1],
subtype: trackType, subtype: trackType,
distance: 0.0 distance: 0.0,
}; };
} }
analysis.highway[highwayType].distance += parseFloat( analysis.highway[highwayType].distance += parseFloat(
@ -175,7 +175,7 @@ BR.TrackAnalysis = L.Class.extend({
), ),
name: wayTagParts[1], name: wayTagParts[1],
subtype: '', subtype: '',
distance: 0.0 distance: 0.0,
}; };
} }
analysis[wayTagParts[0]][wayTagParts[1]].distance += parseFloat( analysis[wayTagParts[0]][wayTagParts[1]].distance += parseFloat(
@ -198,7 +198,7 @@ BR.TrackAnalysis = L.Class.extend({
* *
* @returns {Object} * @returns {Object}
*/ */
sortAnalysisData: function(analysis) { sortAnalysisData: function (analysis) {
var analysisSortable = {}; var analysisSortable = {};
var result = {}; var result = {};
@ -217,7 +217,7 @@ BR.TrackAnalysis = L.Class.extend({
analysisSortable[type].push(analysis[type][name]); analysisSortable[type].push(analysis[type][name]);
} }
analysisSortable[type].sort(function(a, b) { analysisSortable[type].sort(function (a, b) {
return b.distance - a.distance; return b.distance - a.distance;
}); });
@ -236,7 +236,7 @@ BR.TrackAnalysis = L.Class.extend({
* @param {string[]} wayTags * @param {string[]} wayTags
* @returns {string} * @returns {string}
*/ */
getTrackType: function(wayTags) { getTrackType: function (wayTags) {
for (var i = 0; i < wayTags.length; i++) { for (var i = 0; i < wayTags.length; i++) {
var wayTagParts = wayTags[i].split('='); var wayTagParts = wayTags[i].split('=');
if (wayTagParts[0] === 'tracktype') { if (wayTagParts[0] === 'tracktype') {
@ -250,7 +250,7 @@ BR.TrackAnalysis = L.Class.extend({
/** /**
* @param {Object} analysis * @param {Object} analysis
*/ */
render: function(analysis) { render: function (analysis) {
var $content = $('#track_statistics'); var $content = $('#track_statistics');
$content.html(''); $content.html('');
@ -275,7 +275,7 @@ BR.TrackAnalysis = L.Class.extend({
* @param {Array} data * @param {Array} data
* @returns {jQuery} * @returns {jQuery}
*/ */
renderTable: function(type, data) { renderTable: function (type, data) {
var index; var index;
var $table = $( var $table = $(
'<table data-type="' + type + '" class="mini cell-border stripe dataTable track-analysis-table"></table>' '<table data-type="' + type + '" class="mini cell-border stripe dataTable track-analysis-table"></table>'
@ -366,11 +366,11 @@ BR.TrackAnalysis = L.Class.extend({
* @param {number} meters * @param {number} meters
* @returns {string} * @returns {string}
*/ */
formatDistance: function(meters) { formatDistance: function (meters) {
return (meters / 1000).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); return (meters / 1000).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}, },
handleHover: function(event) { handleHover: function (event) {
var $tableRow = $(event.currentTarget); var $tableRow = $(event.currentTarget);
var $table = $tableRow.parents('table').first(); var $table = $tableRow.parents('table').first();
var dataType = $table.data('type'); var dataType = $table.data('type');
@ -382,15 +382,13 @@ BR.TrackAnalysis = L.Class.extend({
this.highlightedSegments = L.layerGroup(polylinesForDataType).addTo(this.map); this.highlightedSegments = L.layerGroup(polylinesForDataType).addTo(this.map);
}, },
handleHoverOut: function() { handleHoverOut: function () {
this.map.removeLayer(this.highlightedSegments); this.map.removeLayer(this.highlightedSegments);
}, },
toggleSelected: function(event) { toggleSelected: function (event) {
var tableRow = event.currentTarget; var tableRow = event.currentTarget;
var $table = $(tableRow) var $table = $(tableRow).parents('table').first();
.parents('table')
.first();
var dataType = $table.data('type'); var dataType = $table.data('type');
var dataName = $(tableRow).data('name'); var dataName = $(tableRow).data('name');
var trackType = $(tableRow).data('subtype'); var trackType = $(tableRow).data('subtype');
@ -426,7 +424,7 @@ BR.TrackAnalysis = L.Class.extend({
* *
* @returns {Polyline[]} * @returns {Polyline[]}
*/ */
getPolylinesForDataType: function(dataType, dataName, trackType) { getPolylinesForDataType: function (dataType, dataName, trackType) {
var polylines = []; var polylines = [];
var trackLatLngs = this.trackPolyline.getLatLngs(); var trackLatLngs = this.trackPolyline.getLatLngs();
@ -461,7 +459,7 @@ BR.TrackAnalysis = L.Class.extend({
* *
* @returns {boolean} * @returns {boolean}
*/ */
wayTagsMatchesData: function(wayTags, dataType, dataName, trackType) { wayTagsMatchesData: function (wayTags, dataType, dataName, trackType) {
var parsed = this.parseWayTags(wayTags); var parsed = this.parseWayTags(wayTags);
switch (dataType) { switch (dataType) {
@ -502,7 +500,7 @@ BR.TrackAnalysis = L.Class.extend({
* *
* @returns {object} * @returns {object}
*/ */
parseWayTags: function(wayTags) { parseWayTags: function (wayTags) {
var result = {}; var result = {};
var wayTagPairs = wayTags.feature.wayTags.split(' '); var wayTagPairs = wayTags.feature.wayTags.split(' ');
@ -512,5 +510,5 @@ BR.TrackAnalysis = L.Class.extend({
} }
return result; return result;
} },
}); });

View file

@ -5,10 +5,10 @@ BR.TrackMessages = L.Class.extend({
opacity: 0.8, opacity: 0.8,
weight: 8, weight: 8,
// show above quality coding (pane defined in RoutingPathQuality.js) // show above quality coding (pane defined in RoutingPathQuality.js)
pane: 'routingQualityPane' pane: 'routingQualityPane',
}, },
// center hovered edge (way segment) on map // center hovered edge (way segment) on map
syncMap: true syncMap: true,
}, },
// true when tab is shown, false when hidden // true when tab is shown, false when hidden
@ -23,7 +23,7 @@ BR.TrackMessages = L.Class.extend({
ElevCost: { title: 'elev$', className: 'dt-body-right' }, ElevCost: { title: 'elev$', className: 'dt-body-right' },
TurnCost: { title: 'turn$', className: 'dt-body-right' }, TurnCost: { title: 'turn$', className: 'dt-body-right' },
NodeCost: { title: 'node$', className: 'dt-body-right' }, NodeCost: { title: 'node$', className: 'dt-body-right' },
InitialCost: { title: 'initial$', className: 'dt-body-right' } InitialCost: { title: 'initial$', className: 'dt-body-right' },
}, },
/** /**
@ -36,7 +36,7 @@ BR.TrackMessages = L.Class.extend({
*/ */
trackPolyline: null, trackPolyline: null,
initialize: function(map, options) { initialize: function (map, options) {
L.setOptions(this, options); L.setOptions(this, options);
this._map = map; this._map = map;
@ -48,7 +48,7 @@ BR.TrackMessages = L.Class.extend({
L.DomEvent.on(syncButton, 'click', this._toggleSyncMap, this); L.DomEvent.on(syncButton, 'click', this._toggleSyncMap, this);
}, },
update: function(polyline, segments) { update: function (polyline, segments) {
var i, var i,
messages, messages,
columns, columns,
@ -89,7 +89,7 @@ BR.TrackMessages = L.Class.extend({
// (^= minimum height with flexbox?) // (^= minimum height with flexbox?)
scrollY: 50, scrollY: 50,
scrollX: true, scrollX: true,
order: [] order: [],
}); });
// highlight track segment (graph edge) on row hover // highlight track segment (graph edge) on row hover
@ -98,23 +98,21 @@ BR.TrackMessages = L.Class.extend({
$('#datatable tbody').on('click', 'tr', L.bind(this._toggleSelected, this)); $('#datatable tbody').on('click', 'tr', L.bind(this._toggleSelected, this));
}, },
show: function() { show: function () {
this.active = true; this.active = true;
this.options.requestUpdate(this); this.options.requestUpdate(this);
}, },
hide: function() { hide: function () {
this.active = false; this.active = false;
}, },
_destroyTable: function() { _destroyTable: function () {
var ele; var ele;
if ($.fn.DataTable.isDataTable('#datatable')) { if ($.fn.DataTable.isDataTable('#datatable')) {
// destroy option too slow on update, really remove elements with destroy method // destroy option too slow on update, really remove elements with destroy method
$('#datatable') $('#datatable').DataTable().destroy(true);
.DataTable()
.destroy(true);
// recreate original table element, destroy removes all // recreate original table element, destroy removes all
ele = document.createElement('table'); ele = document.createElement('table');
@ -126,7 +124,7 @@ BR.TrackMessages = L.Class.extend({
return ele || document.getElementById('datatable'); return ele || document.getElementById('datatable');
}, },
_getColumns: function(headings, data) { _getColumns: function (headings, data) {
var columns = [], var columns = [],
defaultOptions, defaultOptions,
options, options,
@ -135,7 +133,7 @@ BR.TrackMessages = L.Class.extend({
for (k = 0; k < headings.length; k++) { for (k = 0; k < headings.length; k++) {
defaultOptions = { defaultOptions = {
title: headings[k], title: headings[k],
visible: !emptyColumns[k] visible: !emptyColumns[k],
}; };
options = L.extend(defaultOptions, this.columnOptions[headings[k]]); options = L.extend(defaultOptions, this.columnOptions[headings[k]]);
columns.push(options); columns.push(options);
@ -143,7 +141,7 @@ BR.TrackMessages = L.Class.extend({
return columns; return columns;
}, },
_getEmptyColumns: function(data) { _getEmptyColumns: function (data) {
var empty = new Array(data[0].length), var empty = new Array(data[0].length),
i; i;
@ -151,8 +149,8 @@ BR.TrackMessages = L.Class.extend({
empty[i] = true; empty[i] = true;
} }
data.forEach(function(row) { data.forEach(function (row) {
row.forEach(function(val, i) { row.forEach(function (val, i) {
empty[i] = empty[i] && !val; empty[i] = empty[i] && !val;
}); });
}); });
@ -160,7 +158,7 @@ BR.TrackMessages = L.Class.extend({
return empty; return empty;
}, },
_getRowEdge: function(tr) { _getRowEdge: function (tr) {
var row = this._table.row($(tr)), var row = this._table.row($(tr)),
trackLatLngs = this.trackPolyline.getLatLngs(), trackLatLngs = this.trackPolyline.getLatLngs(),
startIndex = row.index() > 0 ? this.trackEdges.edges[row.index() - 1] : 0, startIndex = row.index() > 0 ? this.trackEdges.edges[row.index() - 1] : 0,
@ -170,7 +168,7 @@ BR.TrackMessages = L.Class.extend({
return L.polyline(edgeLatLngs, this.options.edgeStyle); return L.polyline(edgeLatLngs, this.options.edgeStyle);
}, },
_handleHover: function(evt) { _handleHover: function (evt) {
var tr = evt.currentTarget; var tr = evt.currentTarget;
this._hoveredEdge = this._getRowEdge(tr).addTo(this._map); this._hoveredEdge = this._getRowEdge(tr).addTo(this._map);
@ -179,12 +177,12 @@ BR.TrackMessages = L.Class.extend({
} }
}, },
_handleHoverOut: function(evt) { _handleHoverOut: function (evt) {
this._map.removeLayer(this._hoveredEdge); this._map.removeLayer(this._hoveredEdge);
this._hoveredEdge = null; this._hoveredEdge = null;
}, },
_toggleSelected: function(evt) { _toggleSelected: function (evt) {
var tr = evt.currentTarget; var tr = evt.currentTarget;
if (tr.classList.toggle('selected')) { if (tr.classList.toggle('selected')) {
@ -205,10 +203,10 @@ BR.TrackMessages = L.Class.extend({
} }
}, },
_toggleSyncMap: function(evt) { _toggleSyncMap: function (evt) {
var button = evt.currentTarget; var button = evt.currentTarget;
button.classList.toggle('active'); button.classList.toggle('active');
this.options.syncMap = !this.options.syncMap; this.options.syncMap = !this.options.syncMap;
} },
}); });

View file

@ -1,5 +1,5 @@
BR.TrackStats = L.Class.extend({ BR.TrackStats = L.Class.extend({
update: function(polyline, segments) { update: function (polyline, segments) {
if (segments.length == 0) { if (segments.length == 0) {
$('#stats-container').hide(); $('#stats-container').hide();
$('#stats-info').show(); $('#stats-info').show();
@ -12,7 +12,7 @@ BR.TrackStats = L.Class.extend({
var stats = this.calcStats(polyline, segments), var stats = this.calcStats(polyline, segments),
length1 = L.Util.formatNum(stats.trackLength / 1000, 1).toLocaleString(), length1 = L.Util.formatNum(stats.trackLength / 1000, 1).toLocaleString(),
length3 = L.Util.formatNum(stats.trackLength / 1000, 3).toLocaleString(undefined, { length3 = L.Util.formatNum(stats.trackLength / 1000, 3).toLocaleString(undefined, {
minimumFractionDigits: 3 minimumFractionDigits: 3,
}), }),
formattedAscend = stats.filteredAscend.toLocaleString(), formattedAscend = stats.filteredAscend.toLocaleString(),
formattedPlainAscend = stats.plainAscend.toLocaleString(), formattedPlainAscend = stats.plainAscend.toLocaleString(),
@ -39,14 +39,14 @@ BR.TrackStats = L.Class.extend({
$('#meanenergy').html(meanEnergy); $('#meanenergy').html(meanEnergy);
}, },
calcStats: function(polyline, segments) { calcStats: function (polyline, segments) {
var stats = { var stats = {
trackLength: 0, trackLength: 0,
filteredAscend: 0, filteredAscend: 0,
plainAscend: 0, plainAscend: 0,
totalTime: 0, totalTime: 0,
totalEnergy: 0, totalEnergy: 0,
cost: 0 cost: 0,
}; };
var i, props; var i, props;
@ -61,5 +61,5 @@ BR.TrackStats = L.Class.extend({
} }
return stats; return stats;
} },
}); });

View file

@ -4,7 +4,7 @@
Licensed under the MIT license. Licensed under the MIT license.
*/ */
(function() { (function () {
var mapContext; var mapContext;
function verifyTouchStyle(mapContext) { function verifyTouchStyle(mapContext) {
@ -34,6 +34,7 @@
drawButton, drawButton,
deleteRouteButton, deleteRouteButton,
pois, pois,
circlego,
urlHash; urlHash;
// By default bootstrap-select use glyphicons // By default bootstrap-select use glyphicons
@ -41,14 +42,14 @@
iconBase: 'fa', iconBase: 'fa',
tickIcon: 'fa-check', tickIcon: 'fa-check',
// don't overlap with footer // don't overlap with footer
windowPadding: [0, 0, 40, 0] windowPadding: [0, 0, 40, 0],
}); });
search = new BR.Search(); search = new BR.Search();
map.addControl(search); map.addControl(search);
$('#map .leaflet-control-geocoder > button')[0].title = i18next.t('keyboard.generic-shortcut', { $('#map .leaflet-control-geocoder > button')[0].title = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.geocoder)', action: '$t(map.geocoder)',
key: 'F' key: 'F',
}); });
router = L.bRouter(); //brouterCgi dummyRouter router = L.bRouter(); //brouterCgi dummyRouter
@ -58,55 +59,67 @@
{ {
stateName: 'deactivate-draw', stateName: 'deactivate-draw',
icon: 'fa-pencil active', icon: 'fa-pencil active',
onClick: function(control) { onClick: function (control) {
routing.draw(false); routing.draw(false);
control.state('activate-draw'); control.state('activate-draw');
}, },
title: i18next.t('keyboard.generic-shortcut', { title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-route-stop)', action: '$t(map.draw-route-stop)',
key: '$t(keyboard.escape)' key: '$t(keyboard.escape)',
}) }),
}, },
{ {
stateName: 'activate-draw', stateName: 'activate-draw',
icon: 'fa-pencil', icon: 'fa-pencil',
onClick: function(control) { onClick: function (control) {
routing.draw(true); routing.draw(true);
control.state('deactivate-draw'); control.state('deactivate-draw');
}, },
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-route-start)', key: 'D' }) title: i18next.t('keyboard.generic-shortcut', {
} action: '$t(map.draw-route-start)',
] key: 'D',
}),
},
],
}); });
var reverseRouteButton = L.easyButton( var reverseRouteButton = L.easyButton(
'fa-random', 'fa-random',
function() { function () {
routing.reverse(); routing.reverse();
}, },
i18next.t('keyboard.generic-shortcut', { action: '$t(map.reverse-route)', key: 'R' }) i18next.t('keyboard.generic-shortcut', {
action: '$t(map.reverse-route)',
key: 'R',
})
); );
var deletePointButton = L.easyButton( var 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>', '<span><i class="fa fa-caret-left"></i><i class="fa fa-map-marker" style="margin-left: 1px; color: gray;"></i></span>',
function() { function () {
routing.deleteLastPoint(); routing.deleteLastPoint();
}, },
i18next.t('keyboard.generic-shortcut', { action: '$t(map.delete-last-point)', key: 'Z' }) i18next.t('keyboard.generic-shortcut', {
action: '$t(map.delete-last-point)',
key: 'Z',
})
); );
deleteRouteButton = L.easyButton( deleteRouteButton = L.easyButton(
'fa-trash-o', 'fa-trash-o',
function() { function () {
clearRoute(); clearRoute();
}, },
i18next.t('keyboard.generic-shortcut', { action: '$t(map.clear-route)', key: '$t(keyboard.backspace)' }) i18next.t('keyboard.generic-shortcut', {
action: '$t(map.clear-route)',
key: '$t(keyboard.backspace)',
})
); );
L.DomEvent.addListener( L.DomEvent.addListener(
document, document,
'keydown', 'keydown',
function(e) { function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && !$('.modal.show').length) { if (BR.Util.keyboardShortcutsAllowed(e) && !$('.modal.show').length) {
if (e.keyCode === 8) { if (e.keyCode === 8) {
// char code for 'backspace' // char code for 'backspace'
@ -128,19 +141,19 @@
inputOptions: [ inputOptions: [
{ {
text: i18next.t('map.delete-route'), text: i18next.t('map.delete-route'),
value: 'route' value: 'route',
}, },
{ {
text: i18next.t('map.delete-nogo-areas'), text: i18next.t('map.delete-nogo-areas'),
value: 'nogo' value: 'nogo',
}, },
{ {
text: i18next.t('map.delete-pois'), text: i18next.t('map.delete-pois'),
value: 'pois' value: 'pois',
} },
], ],
value: ['route'], value: ['route'],
callback: function(result) { callback: function (result) {
if (result !== null) { if (result !== null) {
if (result.indexOf('route') !== -1) { if (result.indexOf('route') !== -1) {
routing.clear(); routing.clear();
@ -154,7 +167,7 @@
onUpdate(); onUpdate();
urlHash.onMapMove(); urlHash.onMapMove();
} }
} },
}); });
} }
@ -177,14 +190,17 @@
routingOptions = new BR.RoutingOptions(); routingOptions = new BR.RoutingOptions();
routingOptions.on('update', updateRoute); routingOptions.on('update', updateRoute);
routingOptions.on('update', function(evt) { routingOptions.on('update', function (evt) {
profile.update(evt.options); profile.update(evt.options);
}); });
BR.NogoAreas.MSG_BUTTON = i18next.t('keyboard.generic-shortcut', { action: '$t(map.nogo.draw)', key: 'N' }); BR.NogoAreas.MSG_BUTTON = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.nogo.draw)',
key: 'N',
});
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('keyboard.generic-shortcut', { BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.nogo.cancel)', action: '$t(map.nogo.cancel)',
key: '$t(keyboard.escape)' key: '$t(keyboard.escape)',
}); });
BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag'); BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag');
BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit'); BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit');
@ -202,14 +218,14 @@
elevation = new BR.Heightgraph(); elevation = new BR.Heightgraph();
profile = new BR.Profile(); profile = new BR.Profile();
profile.on('update', function(evt) { profile.on('update', function (evt) {
BR.message.hide(); BR.message.hide();
var profileId = routingOptions.getCustomProfile(); var profileId = routingOptions.getCustomProfile();
router.uploadProfile(profileId, evt.profileText, function(err, profileId) { router.uploadProfile(profileId, evt.profileText, function (err, profileId) {
if (!err) { if (!err) {
routingOptions.setCustomProfile(profileId, true); routingOptions.setCustomProfile(profileId, true);
updateRoute({ updateRoute({
options: routingOptions.getOptions() options: routingOptions.getOptions(),
}); });
} else { } else {
profile.message.showError(err); profile.message.showError(err);
@ -224,40 +240,38 @@
} }
}); });
}); });
profile.on('clear', function(evt) { profile.on('clear', function (evt) {
profile.message.hide(); profile.message.hide();
routingOptions.setCustomProfile(null); routingOptions.setCustomProfile(null);
}); });
trackMessages = new BR.TrackMessages(map, { trackMessages = new BR.TrackMessages(map, {
requestUpdate: requestUpdate requestUpdate: requestUpdate,
}); });
trackAnalysis = new BR.TrackAnalysis(map, { trackAnalysis = new BR.TrackAnalysis(map, {
requestUpdate: requestUpdate requestUpdate: requestUpdate,
}); });
routingPathQuality = new BR.RoutingPathQuality(map, layersControl); routingPathQuality = new BR.RoutingPathQuality(map, layersControl);
routing = new BR.Routing({ routing = new BR.Routing({
routing: { routing: {
router: L.bind(router.getRouteSegment, router) router: L.bind(router.getRouteSegment, router),
}, },
styles: BR.conf.routingStyles styles: BR.conf.routingStyles,
}); });
pois = new BR.PoiMarkers({ pois = new BR.PoiMarkers(routing);
routing: routing
});
exportRoute = new BR.Export(router, pois); exportRoute = new BR.Export(router, pois);
routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function(evt) { routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function (evt) {
search.clear(); search.clear();
onUpdate(evt && evt.err); onUpdate(evt && evt.err);
}); });
map.on('routing:draw-start', function() { map.on('routing:draw-start', function () {
drawButton.state('deactivate-draw'); drawButton.state('deactivate-draw');
}); });
map.on('routing:draw-end', function() { map.on('routing:draw-end', function () {
drawButton.state('activate-draw'); drawButton.state('activate-draw');
}); });
@ -298,15 +312,34 @@
listeningTabs: { listeningTabs: {
tab_profile: profile, tab_profile: profile,
tab_data: trackMessages, tab_data: trackMessages,
tab_analysis: trackAnalysis tab_analysis: trackAnalysis,
} },
}).addTo(map); }).addTo(map);
if (BR.conf.transit) { if (BR.conf.transit) {
sidebar.showPanel('tab_itinerary'); sidebar.showPanel('tab_itinerary');
} }
nogos.addTo(map); nogos.addTo(map);
L.easyBar([drawButton, reverseRouteButton, nogos.getButton(), deletePointButton, deleteRouteButton]).addTo(map);
var circlegoRadius = null;
var lang = i18next.languages.length && i18next.languages[0];
if (lang.startsWith('fr')) {
circlegoRadius = 20000;
}
if (circlegoRadius != null) {
circlego = new BR.CircleGoArea(routing, nogos, pois);
circlego.options.radius = circlegoRadius;
pois.circlego = circlego;
circlego.addTo(map);
}
var buttons = [drawButton, reverseRouteButton, nogos.getButton()];
if (circlegoRadius) buttons.push(circlego.getButton());
buttons.push(deletePointButton, deleteRouteButton);
L.easyBar(buttons).addTo(map);
nogos.preventRoutePointOnCreate(routing); nogos.preventRoutePointOnCreate(routing);
if (BR.keys.strava) { if (BR.keys.strava) {
@ -323,9 +356,12 @@
map.addControl( map.addControl(
new BR.OpacitySliderControl({ new BR.OpacitySliderControl({
id: 'route', id: 'route',
title: i18next.t('map.opacity-slider-shortcut', { action: '$t(map.opacity-slider)', key: 'M' }), title: i18next.t('map.opacity-slider-shortcut', {
action: '$t(map.opacity-slider)',
key: 'M',
}),
muteKeyCode: 77, // m muteKeyCode: 77, // m
callback: L.bind(routing.setOpacity, routing) callback: L.bind(routing.setOpacity, routing),
}) })
); );
@ -340,8 +376,8 @@
layersControl.loadActiveLayers(); layersControl.loadActiveLayers();
} }
var onHashChangeCb = function(url) { var onHashChangeCb = function (url) {
var url2params = function(s) { var url2params = function (s) {
s = s.replace(/;/g, '|'); s = s.replace(/;/g, '|');
var p = {}; var p = {};
var sep = '&'; var sep = '&';
@ -367,13 +403,16 @@
routing.clear(); routing.clear();
routing.setWaypoints(opts.lonlats); routing.setWaypoints(opts.lonlats);
} }
if (opts.pois) { if (opts.pois) {
pois.setMarkers(opts.pois); pois.setMarkers(opts.pois);
} }
if (circlego && opts.circlego) {
circlego.options.radius = opts.circlego[2];
circlego.setCircle([opts.circlego[0], opts.circlego[1]], opts.polylines != null);
}
}; };
var onInvalidHashChangeCb = function(params) { var onInvalidHashChangeCb = function (params) {
params = params.replace('zoom=', 'map='); params = params.replace('zoom=', 'map=');
params = params.replace('&lat=', '/'); params = params.replace('&lat=', '/');
params = params.replace('&lon=', '/'); params = params.replace('&lon=', '/');
@ -384,8 +423,10 @@
// do not initialize immediately // do not initialize immediately
urlHash = new L.Hash(null, null); urlHash = new L.Hash(null, null);
// this callback is used to append anything in URL after L.Hash wrote #map=zoom/lat/lng/layer // this callback is used to append anything in URL after L.Hash wrote #map=zoom/lat/lng/layer
urlHash.additionalCb = function() { urlHash.additionalCb = function () {
var url = router.getUrl(routing.getWaypoints(), pois.getMarkers(), null).substr('brouter?'.length + 1); var url = router
.getUrl(routing.getWaypoints(), pois.getMarkers(), circlego ? circlego.getCircle() : null, null)
.substr('brouter?'.length + 1);
// by default brouter use | as separator. To make URL more human-readable, we remplace them with ; for users // by default brouter use | as separator. To make URL more human-readable, we remplace them with ; for users
url = url.replace(/\|/g, ';'); url = url.replace(/\|/g, ';');
@ -395,12 +436,12 @@
urlHash.onHashChangeCb = onHashChangeCb; urlHash.onHashChangeCb = onHashChangeCb;
urlHash.onInvalidHashChangeCb = onInvalidHashChangeCb; urlHash.onInvalidHashChangeCb = onInvalidHashChangeCb;
urlHash.init(map, { urlHash.init(map, {
layersControl: layersControl layersControl: layersControl,
}); });
// activate configured default base layer or first if no hash, // activate configured default base layer or first if no hash,
// only after hash init, by using the same delay // only after hash init, by using the same delay
setTimeout(function() { setTimeout(function () {
layersControl.activateDefaultBaseLayer(); layersControl.activateDefaultBaseLayer();
}, urlHash.changeDefer); }, urlHash.changeDefer);
@ -412,7 +453,7 @@
// delete last waypoint // delete last waypoint
routing.on( routing.on(
'waypoint:click', 'waypoint:click',
function(evt) { function (evt) {
var r = evt.marker._routing; var r = evt.marker._routing;
if (!r.prevMarker && !r.nextMarker) { if (!r.prevMarker && !r.nextMarker) {
urlHash.onMapMove(); urlHash.onMapMove();
@ -422,7 +463,7 @@
); );
} }
i18next.on('languageChanged', function(detectedLanguage) { i18next.on('languageChanged', function (detectedLanguage) {
// detected + fallbacks, e.g. ["de-DE", "de", "en"] // detected + fallbacks, e.g. ["de-DE", "de", "en"]
for (i = 0; i < i18next.languages.length; i++) { for (i = 0; i < i18next.languages.length; i++) {
var language = i18next.languages[i]; var language = i18next.languages[i];
@ -445,14 +486,14 @@
{ {
fallbackLng: 'en', fallbackLng: 'en',
backend: { backend: {
loadPath: 'dist/locales/{{lng}}.json' loadPath: 'dist/locales/{{lng}}.json',
} },
}, },
function(err, t) { function (err, t) {
jqueryI18next.init(i18next, $, { useOptionsAttr: true }); jqueryI18next.init(i18next, $, { useOptionsAttr: true });
$('html').localize(); $('html').localize();
$('#aboutLinks').localize({ $('#aboutLinks').localize({
privacyPolicyUrl: BR.conf.privacyPolicyUrl || 'https://brouter.de/privacypolicy.html' privacyPolicyUrl: BR.conf.privacyPolicyUrl || 'https://brouter.de/privacypolicy.html',
}); });
mapContext = BR.Map.initMap(); mapContext = BR.Map.initMap();

View file

@ -3,14 +3,14 @@ BR.BingLayer = L.BingLayer.extend({
maxZoom: 19, maxZoom: 19,
attribution: attribution:
'<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>' + '<a target="_blank" href="https://www.bing.com/maps/">Bing Maps</a>' +
' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)' ' (<a target="_blank" href="https://go.microsoft.com/?linkid=9710837">TOU</a>)',
}, },
initialize: function(key, options) { initialize: function (key, options) {
L.BingLayer.prototype.initialize.call(this, key, options); L.BingLayer.prototype.initialize.call(this, key, options);
this._logo = L.control({ position: 'bottomleft' }); this._logo = L.control({ position: 'bottomleft' });
this._logo.onAdd = function(map) { this._logo.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'bing-logo'); this._div = L.DomUtil.create('div', 'bing-logo');
this._div.innerHTML = this._div.innerHTML =
'<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">'; '<img src="https://www.microsoft.com/maps/images/branding/Bing%20logo%20white_50px-19px.png">';
@ -18,13 +18,13 @@ BR.BingLayer = L.BingLayer.extend({
}; };
}, },
onAdd: function(map) { onAdd: function (map) {
L.BingLayer.prototype.onAdd.call(this, map); L.BingLayer.prototype.onAdd.call(this, map);
map.addControl(this._logo); map.addControl(this._logo);
}, },
onRemove: function(map) { onRemove: function (map) {
L.BingLayer.prototype.onRemove.call(this, map); L.BingLayer.prototype.onRemove.call(this, map);
map.removeControl(this._logo); map.removeControl(this._logo);
} },
}); });

248
js/plugin/CircleGoArea.js Normal file
View file

@ -0,0 +1,248 @@
BR.CircleGoArea = L.Control.extend({
circleLayer: null,
outsideAreaRenderer: L.svg({ padding: 1 }),
options: {
radius: 1000, // in meters
shortcut: {
draw: {
enable: 73, // char code for 'i'
disable: 27, // char code for 'ESC'
},
},
},
initialize: function (routing, nogos, pois) {
this.routing = routing;
this.nogos = nogos;
this.pois = pois;
},
onAdd: function (map) {
var self = this;
this.map = map;
this.circleLayer = L.layerGroup([]).addTo(map);
var radiusKm = (this.options.radius / 1000).toFixed();
this.drawButton = L.easyButton({
states: [
{
stateName: 'activate-circlego',
icon: 'fa-circle-o',
onClick: function () {
self.draw(true);
},
title: i18next.t('keyboard.generic-shortcut', {
action: i18next.t('map.draw-circlego-start', { radius: radiusKm }),
key: 'I',
}),
},
{
stateName: 'deactivate-circlego',
icon: 'fa-circle-o active',
onClick: function () {
self.draw(false);
},
title: i18next.t('keyboard.generic-shortcut', {
action: i18next.t('map.draw-circlego-stop', { radius: radiusKm }),
key: '$t(keyboard.escape)',
}),
},
],
});
map.on('routing:draw-start', function () {
self.draw(false);
});
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
var container = new L.DomUtil.create('div');
return container;
},
draw: function (enable) {
this.drawButton.state(enable ? 'deactivate-circlego' : 'activate-circlego');
if (enable) {
this.routing.draw(false);
this.pois.draw(false);
this.map.on('click', this.onMapClick, this);
L.DomUtil.addClass(this.map.getContainer(), 'circlego-draw-enabled');
} else {
this.map.off('click', this.onMapClick, this);
L.DomUtil.removeClass(this.map.getContainer(), 'circlego-draw-enabled');
}
},
_keydownListener: function (e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) {
return;
}
if (e.keyCode === this.options.shortcut.draw.disable) {
this.draw(false);
} else if (e.keyCode === this.options.shortcut.draw.enable) {
this.draw(true);
}
},
setNogoCircle: function (center) {
if (center) {
var polygon = this.circleToPolygon(center, this.options.radius);
var geoJson = JSON.stringify(polygon);
$('#nogoJSON').val(geoJson);
$('#nogoBuffer').val(0);
this.nogos.uploadNogos();
var polygonClone = JSON.parse(geoJson);
this.setOutsideArea(polygonClone);
} else {
this.nogos.clear();
this.map.removeLayer(this.outsideArea);
}
},
setOutsideArea: function (polygon) {
var inner = polygon.features[0].geometry.coordinates.concat(polygon.features[1].geometry.coordinates);
var world = [
[180, 90],
[-180, 90],
[-180, -90],
[180, -90],
[180, 90],
];
polygon.features[0].geometry.coordinates = [world, inner];
polygon.features[0].geometry.type = 'Polygon';
polygon.features.pop();
if (this.outsideArea) {
this.map.removeLayer(this.outsideArea);
}
this.outsideArea = L.geoJson(polygon, {
renderer: this.outsideAreaRenderer,
style: function (feature) {
return {
weight: 2,
color: 'black',
opacity: 0.4,
fillColor: 'black',
fillOpacity: 0.4,
className: 'circlego-outside',
};
},
})
.on('click', L.DomEvent.stop)
.addTo(this.map);
},
onMapClick: function (e) {
this.setCircle([e.latlng.lng, e.latlng.lat], false);
},
setCircle: function (center, skipNogo) {
var self = this;
var icon = L.VectorMarkers.icon({
icon: 'home',
markerColor: BR.conf.markerColors.circlego,
});
var marker = L.marker([center[1], center[0]], { icon: icon, draggable: true, name: name })
.on('dragend', function (e) {
self.setNogoCircle([e.target.getLatLng().lng, e.target.getLatLng().lat]);
})
.on('click', function () {
var drawing = self.drawButton.state() == 'deactivate-circlego';
if (drawing) {
self.circleLayer.removeLayer(marker);
self.setNogoCircle(undefined);
}
});
this.clear();
marker.addTo(this.circleLayer);
if (!skipNogo) {
this.setNogoCircle(center);
} else {
var polygon = this.circleToPolygon(center, this.options.radius);
this.setOutsideArea(polygon);
}
this.draw(false);
},
clear: function () {
this.circleLayer.clearLayers();
},
getButton: function () {
return this.drawButton;
},
getCircle: function () {
var circle = this.circleLayer.getLayers().map(function (it) {
return it.getLatLng();
});
if (circle && circle.length) {
return [circle[0].lng.toFixed(6), circle[0].lat.toFixed(6), this.options.radius].join(',');
} else {
return null;
}
},
toRadians: function (angleInDegrees) {
return (angleInDegrees * Math.PI) / 180;
},
toDegrees: function (angleInRadians) {
return (angleInRadians * 180) / Math.PI;
},
offset: function (c1, distance, bearing) {
var lon1 = this.toRadians(c1[0]);
var lat1 = this.toRadians(c1[1]);
var dByR = distance / 6378137; // distance divided by 6378137 (radius of the earth) wgs84
var lat = Math.asin(Math.sin(lat1) * Math.cos(dByR) + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));
var lon =
lon1 +
Math.atan2(
Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat)
);
return [this.toDegrees(lon), this.toDegrees(lat)];
},
circleToPolygon: function (center, radius, numberOfSegments) {
var n = numberOfSegments ? numberOfSegments : 32;
var inner = [];
for (var i = 0; i < n; ++i) {
inner.push(this.offset(center, radius, (2 * Math.PI * -i) / n));
}
inner.push(inner[0]);
/* hack: it seems there is a bug when using a single closed ring line,
cf. https://github.com/nrenner/brouter-web/issues/349#issue-755514458
so instead we use 2 half rings to ensure we properly close the area */
return {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: inner.slice(n / 2 - 1),
},
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: inner.slice(0, n / 2 + 1),
},
},
],
};
},
});
BR.CircleGoArea.include(L.Evented.prototype);

View file

@ -1,4 +1,4 @@
BR.Heightgraph = function(map, layersControl, routing, pois) { BR.Heightgraph = function (map, layersControl, routing, pois) {
Heightgraph = L.Control.Heightgraph.extend({ Heightgraph = L.Control.Heightgraph.extend({
options: { options: {
width: $('#map').outerWidth(), width: $('#map').outerWidth(),
@ -6,64 +6,64 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
top: 15, top: 15,
right: 30, right: 30,
bottom: 30, bottom: 30,
left: 70 left: 70,
}, },
expandControls: false, expandControls: false,
mappings: { mappings: {
gradient: { gradient: {
'-5': { '-5': {
text: '- 16%+', text: '- 16%+',
color: '#028306' color: '#028306',
}, },
'-4': { '-4': {
text: '- 10-15%', text: '- 10-15%',
color: '#2AA12E' color: '#2AA12E',
}, },
'-3': { '-3': {
text: '- 7-9%', text: '- 7-9%',
color: '#53BF56' color: '#53BF56',
}, },
'-2': { '-2': {
text: '- 4-6%', text: '- 4-6%',
color: '#7BDD7E' color: '#7BDD7E',
}, },
'-1': { '-1': {
text: '- 1-3%', text: '- 1-3%',
color: '#A4FBA6' color: '#A4FBA6',
}, },
'0': { 0: {
text: '0%', text: '0%',
color: '#ffcc99' color: '#ffcc99',
}, },
'1': { 1: {
text: '1-3%', text: '1-3%',
color: '#F29898' color: '#F29898',
}, },
'2': { 2: {
text: '4-6%', text: '4-6%',
color: '#E07575' color: '#E07575',
}, },
'3': { 3: {
text: '7-9%', text: '7-9%',
color: '#CF5352' color: '#CF5352',
}, },
'4': { 4: {
text: '10-15%', text: '10-15%',
color: '#BE312F' color: '#BE312F',
}, },
'5': { 5: {
text: '16%+', text: '16%+',
color: '#AD0F0C' color: '#AD0F0C',
} },
} },
}, },
// extra options // extra options
shortcut: { shortcut: {
toggle: 69 // char code for 'e' toggle: 69, // char code for 'e'
} },
}, },
addBelow: function(map) { addBelow: function (map) {
// waiting for https://github.com/MrMufflon/Leaflet.Elevation/pull/66 // waiting for https://github.com/MrMufflon/Leaflet.Elevation/pull/66
// this.width($('#map').outerWidth()); // this.width($('#map').outerWidth());
this.options.width = $('#content').outerWidth(); this.options.width = $('#content').outerWidth();
@ -89,12 +89,12 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
var self = this; var self = this;
var container = $('#elevation-chart'); var container = $('#elevation-chart');
$(window).resize(function() { $(window).resize(function () {
// avoid useless computations if the chart is not visible // avoid useless computations if the chart is not visible
if (container.is(':visible')) { if (container.is(':visible')) {
self.resize({ self.resize({
width: container.width(), width: container.width(),
height: container.height() height: container.height(),
}); });
} }
}); });
@ -103,10 +103,10 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
// The resize must be called after the animation (i.e. 'shown.bs.collapse') // The resize must be called after the animation (i.e. 'shown.bs.collapse')
// and cannot be called before the animation (i.e. 'show.bs.collapse'), // and cannot be called before the animation (i.e. 'show.bs.collapse'),
// for the container has the old width pre animation and new width post animation. // for the container has the old width pre animation and new width post animation.
container.on('shown.bs.collapse', function() { container.on('shown.bs.collapse', function () {
self.resize({ self.resize({
width: container.width(), width: container.width(),
height: container.height() height: container.height(),
}); });
}); });
@ -114,9 +114,9 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
this.update(); this.update();
}, },
initCollapse: function(map) { initCollapse: function (map) {
var self = this; var self = this;
var onHide = function() { var onHide = function () {
$('#elevation-btn').removeClass('active'); $('#elevation-btn').removeClass('active');
// we must fetch tiles that are located behind elevation-chart // we must fetch tiles that are located behind elevation-chart
map._onResize(); map._onResize();
@ -125,7 +125,7 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
localStorage.removeItem(this.id); localStorage.removeItem(this.id);
} }
}; };
var onShow = function() { var onShow = function () {
$('#elevation-btn').addClass('active'); $('#elevation-btn').addClass('active');
if (this.id && BR.Util.localStorageAvailable()) { if (this.id && BR.Util.localStorageAvailable()) {
@ -136,20 +136,20 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
$('#elevation-chart') $('#elevation-chart')
.on('hidden.bs.collapse', onHide) .on('hidden.bs.collapse', onHide)
.on('shown.bs.collapse', onShow) .on('shown.bs.collapse', onShow)
.each(function() { .each(function () {
if (this.id && BR.Util.localStorageAvailable() && localStorage[this.id] === 'true') { if (this.id && BR.Util.localStorageAvailable() && localStorage[this.id] === 'true') {
self.shouldRestoreChart = true; self.shouldRestoreChart = true;
} }
}); });
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggle) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggle) {
$('#elevation-btn').click(); $('#elevation-btn').click();
} }
}, },
update: function(track, layer) { update: function (track, layer) {
// bring height indicator to front, because of track casing in BR.Routing // bring height indicator to front, because of track casing in BR.Routing
if (this._mouseHeightFocus) { if (this._mouseHeightFocus) {
var g = this._mouseHeightFocus._groups[0][0].parentNode; var g = this._mouseHeightFocus._groups[0][0].parentNode;
@ -186,7 +186,7 @@ BR.Heightgraph = function(map, layersControl, routing, pois) {
} }
$('#elevation-chart').collapse('hide'); $('#elevation-chart').collapse('hide');
} }
} },
}); });
var heightgraphControl = new Heightgraph(); var heightgraphControl = new Heightgraph();

View file

@ -3,9 +3,9 @@ BR.NogoAreas = L.Control.extend({
shortcut: { shortcut: {
draw: { draw: {
enable: 78, // char code for 'n' enable: 78, // char code for 'n'
disable: 27 // char code for 'ESC' disable: 27, // char code for 'ESC'
} },
} },
}, },
statics: { statics: {
@ -16,7 +16,7 @@ BR.NogoAreas = L.Control.extend({
MSG_ENABLED: MSG_ENABLED:
'&square; = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing', '&square; = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click nogo to quit editing',
STATE_CREATE: 'no-go-create', STATE_CREATE: 'no-go-create',
STATE_CANCEL: 'cancel-no-go-create' STATE_CANCEL: 'cancel-no-go-create',
}, },
style: { style: {
@ -25,27 +25,27 @@ BR.NogoAreas = L.Control.extend({
opacity: 0.5, opacity: 0.5,
fillColor: null, //same as color by default fillColor: null, //same as color by default
fillOpacity: 0.2, fillOpacity: 0.2,
dashArray: null dashArray: null,
}, },
editStyle: { editStyle: {
color: '#fe57a1', color: '#fe57a1',
opacity: 0.6, opacity: 0.6,
dashArray: '10, 10', dashArray: '10, 10',
fillOpacity: 0.1 fillOpacity: 0.1,
}, },
initialize: function() { initialize: function () {
this._wasRouteDrawing = false; this._wasRouteDrawing = false;
}, },
onAdd: function(map) { onAdd: function (map) {
var self = this; var self = this;
$('#submitNogos').on('click', L.bind(this.uploadNogos, this)); $('#submitNogos').on('click', L.bind(this.uploadNogos, this));
this.drawnItems = new L.FeatureGroup().addTo(map); this.drawnItems = new L.FeatureGroup().addTo(map);
this.drawnItems.on('click', function(e) { this.drawnItems.on('click', function (e) {
L.DomEvent.stop(e); L.DomEvent.stop(e);
e.layer.toggleEdit(); e.layer.toggleEdit();
}); });
@ -54,10 +54,10 @@ BR.NogoAreas = L.Control.extend({
circleEditorClass: BR.DeletableCircleEditor, circleEditorClass: BR.DeletableCircleEditor,
// FeatureGroup instead of LayerGroup to propagate events to members // FeatureGroup instead of LayerGroup to propagate events to members
editLayer: new L.FeatureGroup().addTo(map), editLayer: new L.FeatureGroup().addTo(map),
featuresLayer: this.drawnItems featuresLayer: this.drawnItems,
})); }));
this.startDrawing = function(control) { this.startDrawing = function (control) {
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp // initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
var opts = L.extend({ radius: 0 }, self.style); var opts = L.extend({ radius: 0 }, self.style);
editTools.startCircle(null, opts); editTools.startCircle(null, opts);
@ -65,7 +65,7 @@ BR.NogoAreas = L.Control.extend({
control.state('cancel-no-go-create'); control.state('cancel-no-go-create');
}; };
this.stopDrawing = function(control) { this.stopDrawing = function (control) {
editTools.stopDrawing(); editTools.stopDrawing();
control.state('no-go-create'); control.state('no-go-create');
}; };
@ -76,15 +76,15 @@ BR.NogoAreas = L.Control.extend({
stateName: BR.NogoAreas.STATE_CREATE, stateName: BR.NogoAreas.STATE_CREATE,
icon: 'fa-ban', icon: 'fa-ban',
title: BR.NogoAreas.MSG_BUTTON, title: BR.NogoAreas.MSG_BUTTON,
onClick: this.startDrawing onClick: this.startDrawing,
}, },
{ {
stateName: BR.NogoAreas.STATE_CANCEL, stateName: BR.NogoAreas.STATE_CANCEL,
icon: 'fa-ban active', icon: 'fa-ban active',
title: BR.NogoAreas.MSG_BUTTON_CANCEL, title: BR.NogoAreas.MSG_BUTTON_CANCEL,
onClick: this.stopDrawing onClick: this.stopDrawing,
} },
] ],
}); });
// prevent instant re-activate when turning off button by both Pointer and Click // prevent instant re-activate when turning off button by both Pointer and Click
@ -95,11 +95,11 @@ BR.NogoAreas = L.Control.extend({
this.editTools.on( this.editTools.on(
'editable:drawing:end', 'editable:drawing:end',
function(e) { function (e) {
self.button.state(BR.NogoAreas.STATE_CREATE); self.button.state(BR.NogoAreas.STATE_CREATE);
setTimeout( setTimeout(
L.bind(function() { L.bind(function () {
// turn editing off after create; async to still fire 'editable:vertex:dragend' // turn editing off after create; async to still fire 'editable:vertex:dragend'
e.layer.disableEdit(); e.layer.disableEdit();
}, this), }, this),
@ -111,7 +111,7 @@ BR.NogoAreas = L.Control.extend({
this.editTools.on( this.editTools.on(
'editable:vertex:dragend editable:deleted', 'editable:vertex:dragend editable:deleted',
function(e) { function (e) {
this._fireUpdate(); this._fireUpdate();
}, },
this this
@ -119,14 +119,14 @@ BR.NogoAreas = L.Control.extend({
this.editTools.on( this.editTools.on(
'editable:enable', 'editable:enable',
function(e) { function (e) {
e.layer.setStyle(this.editStyle); e.layer.setStyle(this.editStyle);
}, },
this this
); );
this.editTools.on( this.editTools.on(
'editable:disable', 'editable:disable',
function(e) { function (e) {
e.layer.setStyle(this.style); e.layer.setStyle(this.style);
}, },
this this
@ -139,7 +139,7 @@ BR.NogoAreas = L.Control.extend({
return L.DomUtil.create('div'); return L.DomUtil.create('div');
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) { if (!BR.Util.keyboardShortcutsAllowed(e)) {
return; return;
} }
@ -153,34 +153,38 @@ BR.NogoAreas = L.Control.extend({
} }
}, },
displayUploadError: function(message) { displayUploadError: function (message) {
$('#nogoError').text(message ? message : ''); $('#nogoError').text(message ? message : '');
$('#nogoError').css('display', message ? 'block' : 'none'); $('#nogoError').css('display', message ? 'block' : 'none');
}, },
uploadNogos: function() { uploadNogos: function () {
var self = this; var self = this;
var geoJSONPromise; var geoJSONPromise;
var nogoJSON = $('#nogoJSON').val(); //hidden
var nogoURL = $('#nogoURL').val(); var nogoURL = $('#nogoURL').val();
var nogoFile = $('#nogoFile')[0].files[0]; var nogoFile = $('#nogoFile')[0].files[0];
if (nogoURL) { if (nogoJSON) {
geoJSONPromise = Promise.resolve(JSON.parse(nogoJSON));
$('#nogoJSON').val(undefined);
} else if (nogoURL) {
// TODO: Handle {{bbox}} // TODO: Handle {{bbox}}
geoJSONPromise = fetch(nogoURL).then(function(response) { geoJSONPromise = fetch(nogoURL).then(function (response) {
response.json(); response.json();
}); });
} else if (nogoFile) { } else if (nogoFile) {
geoJSONPromise = new Promise(function(resolve, reject) { geoJSONPromise = new Promise(function (resolve, reject) {
var reader = new FileReader(); var reader = new FileReader();
reader.onload = function() { reader.onload = function () {
resolve(reader.result); resolve(reader.result);
}; };
reader.onerror = function() { reader.onerror = function () {
self.displayUploadError('Could not load file: ' + reader.error.message); self.displayUploadError('Could not load file: ' + reader.error.message);
}; };
reader.readAsText(nogoFile); reader.readAsText(nogoFile);
}).then(function(response) { }).then(function (response) {
return JSON.parse(response); return JSON.parse(response);
}); });
} else { } else {
@ -207,10 +211,10 @@ BR.NogoAreas = L.Control.extend({
return false; return false;
} }
geoJSONPromise.then(function(response) { geoJSONPromise.then(function (response) {
// Iterate on features in order to discard features without geometry // Iterate on features in order to discard features without geometry
var cleanedGeoJSONFeatures = []; var cleanedGeoJSONFeatures = [];
turf.flattenEach(response, function(feature) { turf.flattenEach(response, function (feature) {
if (turf.getGeom(feature)) { if (turf.getGeom(feature)) {
var maybeBufferedFeature = feature; var maybeBufferedFeature = feature;
// Eventually buffer GeoJSON // Eventually buffer GeoJSON
@ -227,31 +231,31 @@ BR.NogoAreas = L.Control.extend({
} }
var geoJSON = L.geoJson(turf.featureCollection(cleanedGeoJSONFeatures), { var geoJSON = L.geoJson(turf.featureCollection(cleanedGeoJSONFeatures), {
onEachFeature: function(feature, layer) { onEachFeature: function (feature, layer) {
layer.options.nogoWeight = feature.properties.nogoWeight || nogoWeight; 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'; return e.feature.geometry.type === 'Point';
}); });
nogosPoints = nogosPoints.map(function(item) { nogosPoints = nogosPoints.map(function (item) {
var radius = item.feature.properties.radius || nogoRadius; var radius = item.feature.properties.radius || nogoRadius;
if (radius > 0) { if (radius > 0) {
return L.circle(item.getLatLng(), { radius: radius }); return L.circle(item.getLatLng(), { radius: radius });
} }
return null; return null;
}); });
nogosPoints = nogosPoints.filter(function(e) { nogosPoints = nogosPoints.filter(function (e) {
return e; return e;
}); });
self.setOptions({ self.setOptions({
nogos: nogosPoints, nogos: nogosPoints,
polygons: geoJSON.getLayers().filter(function(e) { polygons: geoJSON.getLayers().filter(function (e) {
return e.feature.geometry.type === 'Polygon'; return e.feature.geometry.type === 'Polygon';
}), }),
polylines: geoJSON.getLayers().filter(function(e) { polylines: geoJSON.getLayers().filter(function (e) {
return e.feature.geometry.type === 'LineString'; return e.feature.geometry.type === 'LineString';
}) }),
}); });
self._fireUpdate(); self._fireUpdate();
self.displayUploadError(undefined); self.displayUploadError(undefined);
@ -261,10 +265,10 @@ BR.NogoAreas = L.Control.extend({
}, },
// prevent route waypoint added after circle create (map click after up) // prevent route waypoint added after circle create (map click after up)
preventRoutePointOnCreate: function(routing) { preventRoutePointOnCreate: function (routing) {
this.editTools.on( this.editTools.on(
'editable:drawing:start', 'editable:drawing:start',
function(e) { function (e) {
this._wasRouteDrawing = routing.isDrawing(); this._wasRouteDrawing = routing.isDrawing();
routing.draw(false); routing.draw(false);
}, },
@ -274,9 +278,9 @@ BR.NogoAreas = L.Control.extend({
// after create // after create
this.editTools.on( this.editTools.on(
'editable:drawing:end', 'editable:drawing:end',
function(e) { function (e) {
if (this._wasRouteDrawing) { if (this._wasRouteDrawing) {
setTimeout(function() { setTimeout(function () {
routing.draw(true); routing.draw(true);
}, 0); }, 0);
} }
@ -285,21 +289,21 @@ BR.NogoAreas = L.Control.extend({
); );
}, },
getOptions: function() { getOptions: function () {
return { return {
nogos: this.drawnItems.getLayers().filter(function(e) { nogos: this.drawnItems.getLayers().filter(function (e) {
return e instanceof L.Circle; return e instanceof L.Circle;
}), }),
polygons: this.drawnItems.getLayers().filter(function(e) { polygons: this.drawnItems.getLayers().filter(function (e) {
return e instanceof L.Polygon; return e instanceof L.Polygon;
}), }),
polylines: this.drawnItems.getLayers().filter(function(e) { polylines: this.drawnItems.getLayers().filter(function (e) {
return e instanceof L.Polyline && !(e instanceof L.Polygon); return e instanceof L.Polyline && !(e instanceof L.Polygon);
}) }),
}; };
}, },
setOptions: function(options) { setOptions: function (options) {
var nogos = options.nogos; var nogos = options.nogos;
var polylines = options.polylines; var polylines = options.polylines;
var polygons = options.polygons; var polygons = options.polygons;
@ -324,30 +328,30 @@ BR.NogoAreas = L.Control.extend({
} }
}, },
_clear: function() { _clear: function () {
this.drawnItems.clearLayers(); this.drawnItems.clearLayers();
}, },
clear: function() { clear: function () {
this._clear(); this._clear();
this._fireUpdate(); this._fireUpdate();
}, },
_fireUpdate: function() { _fireUpdate: function () {
this.fire('update', { options: this.getOptions() }); this.fire('update', { options: this.getOptions() });
}, },
getFeatureGroup: function() { getFeatureGroup: function () {
return this.drawnItems; return this.drawnItems;
}, },
getEditGroup: function() { getEditGroup: function () {
return this.editTools.editLayer; return this.editTools.editLayer;
}, },
getButton: function() { getButton: function () {
return this.button; return this.button;
} },
}); });
BR.NogoAreas.include(L.Evented.prototype); BR.NogoAreas.include(L.Evented.prototype);
@ -359,7 +363,7 @@ BR.Editable = L.Editable.extend({
// Also, we generally disable the Tap handler in the map options for route dragging, // Also, we generally disable the Tap handler in the map options for route dragging,
// see Map.js, so we always need to enable for drawing. // see Map.js, so we always need to enable for drawing.
initialize: function(map, options) { initialize: function (map, options) {
L.Editable.prototype.initialize.call(this, map, options); L.Editable.prototype.initialize.call(this, map, options);
if (!this.map.tap) { if (!this.map.tap) {
@ -368,7 +372,7 @@ BR.Editable = L.Editable.extend({
} }
}, },
registerForDrawing: function(editor) { registerForDrawing: function (editor) {
this._tapEnabled = this.map.tap.enabled(); this._tapEnabled = this.map.tap.enabled();
if (!this._tapEnabled) { if (!this._tapEnabled) {
this.map.tap.enable(); this.map.tap.enable();
@ -377,7 +381,7 @@ BR.Editable = L.Editable.extend({
L.Editable.prototype.registerForDrawing.call(this, editor); L.Editable.prototype.registerForDrawing.call(this, editor);
}, },
unregisterForDrawing: function(editor) { unregisterForDrawing: function (editor) {
if (!this._tapEnabled) { if (!this._tapEnabled) {
this.map.tap.disable(); this.map.tap.disable();
} }
@ -385,23 +389,23 @@ BR.Editable = L.Editable.extend({
L.Editable.prototype.unregisterForDrawing.call(this, editor); L.Editable.prototype.unregisterForDrawing.call(this, editor);
}, },
createVertexIcon: function(options) { createVertexIcon: function (options) {
return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options); return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
} },
}); });
BR.EditingTooltip = L.Handler.extend({ BR.EditingTooltip = L.Handler.extend({
options: { options: {
closeTimeout: 2000 closeTimeout: 2000,
}, },
initialize: function(map, editTools, button) { initialize: function (map, editTools, button) {
this.map = map; this.map = map;
this.editTools = editTools; this.editTools = editTools;
this.button = button; this.button = button;
}, },
addHooks: function() { addHooks: function () {
// hack: listen to EasyButton click (instead of editable:drawing:start), // hack: listen to EasyButton click (instead of editable:drawing:start),
// to get mouse position from event for initial tooltip location // 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);
@ -413,7 +417,7 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.on('editable:disable', this._disable, this); this.editTools.on('editable:disable', this._disable, this);
}, },
removeHooks: function() { removeHooks: function () {
L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this); L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this);
this.editTools.featuresLayer.off('layeradd', this._bind, this); this.editTools.featuresLayer.off('layeradd', this._bind, this);
@ -423,19 +427,19 @@ BR.EditingTooltip = L.Handler.extend({
this.editTools.off('editable:disable', this._disable, this); this.editTools.off('editable:disable', this._disable, this);
}, },
_bind: function(e) { _bind: function (e) {
// Position tooltip at bottom of circle, less distracting than // Position tooltip at bottom of circle, less distracting than
// sticky with cursor or at center. // sticky with cursor or at center.
var layer = e.layer; var layer = e.layer;
layer.bindTooltip(BR.NogoAreas.MSG_DISABLED, { layer.bindTooltip(BR.NogoAreas.MSG_DISABLED, {
direction: 'bottom', direction: 'bottom',
className: 'editing-tooltip' className: 'editing-tooltip',
}); });
// Override to set position to south instead of center (circle latlng); // Override to set position to south instead of center (circle latlng);
// works better with zooming than updating offset to match radius // 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) { if (!latlng && layer instanceof L.Layer) {
latlng = L.latLng( latlng = L.latLng(
layer.getBounds().getSouth(), layer.getBounds().getSouth(),
@ -446,7 +450,7 @@ BR.EditingTooltip = L.Handler.extend({
}; };
}, },
_addCreate: function(e) { _addCreate: function (e) {
// button cancel // button cancel
if (!this.editTools.drawing()) return; if (!this.editTools.drawing()) return;
@ -457,21 +461,21 @@ BR.EditingTooltip = L.Handler.extend({
// offset wrong with 'auto' when switching direction // offset wrong with 'auto' when switching direction
direction: 'right', direction: 'right',
offset: L.point(5, 28), offset: L.point(5, 28),
className: 'editing-tooltip-create' className: 'editing-tooltip-create',
}); });
// self-reference hack for _moveTooltip, as tooltip is not bound to layer // self-reference hack for _moveTooltip, as tooltip is not bound to layer
tooltip._tooltip = tooltip; tooltip._tooltip = tooltip;
// simulate sticky feature (follow mouse) for map tooltip without layer // simulate sticky feature (follow mouse) for map tooltip without layer
var onOffMove = function(e) { var onOffMove = function (e) {
var onOff = e.type === 'tooltipclose' ? 'off' : 'on'; var onOff = e.type === 'tooltipclose' ? 'off' : 'on';
this._map[onOff]('mousemove', this._moveTooltip, this); this._map[onOff]('mousemove', this._moveTooltip, this);
}; };
this.map.on('tooltipopen', onOffMove, tooltip); this.map.on('tooltipopen', onOffMove, tooltip);
this.map.on('tooltipclose', 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('tooltipopen', onOffMove, e.tooltip);
this.map.off('tooltipclose', onOffMove, e.tooltip); this.map.off('tooltipclose', onOffMove, e.tooltip);
this.map.off('tooltipclose', onTooltipRemove, this); this.map.off('tooltipclose', onTooltipRemove, this);
@ -482,7 +486,7 @@ BR.EditingTooltip = L.Handler.extend({
tooltip.setTooltipContent(BR.NogoAreas.MSG_CREATE); tooltip.setTooltipContent(BR.NogoAreas.MSG_CREATE);
this.map.openTooltip(tooltip, initialLatLng); this.map.openTooltip(tooltip, initialLatLng);
var closeTooltip = function() { var closeTooltip = function () {
this.map.closeTooltip(tooltip); this.map.closeTooltip(tooltip);
}; };
this.editTools.once('editable:editing editable:drawing:cancel', closeTooltip, this); this.editTools.once('editable:editing editable:drawing:cancel', closeTooltip, this);
@ -493,22 +497,22 @@ BR.EditingTooltip = L.Handler.extend({
} }
}, },
_setCloseTimeout: function(layer) { _setCloseTimeout: function (layer) {
var timeoutId = setTimeout(function() { var timeoutId = setTimeout(function () {
layer.closeTooltip(); layer.closeTooltip();
}, this.options.closeTimeout); }, this.options.closeTimeout);
// prevent timer to close tooltip that changed in the meantime // prevent timer to close tooltip that changed in the meantime
layer.once('tooltipopen', function(e) { layer.once('tooltipopen', function (e) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
}); });
}, },
_postCreate: function() { _postCreate: function () {
// editing is disabled by another handler, tooltip won't stay open before // editing is disabled by another handler, tooltip won't stay open before
this.editTools.once( this.editTools.once(
'editable:disable', 'editable:disable',
function(e) { function (e) {
// show for a few seconds, as mouse often not hovering circle after create // show for a few seconds, as mouse often not hovering circle after create
e.layer.openTooltip(e.layer); e.layer.openTooltip(e.layer);
this._setCloseTimeout(e.layer); this._setCloseTimeout(e.layer);
@ -517,54 +521,54 @@ BR.EditingTooltip = L.Handler.extend({
); );
}, },
_enable: function(e) { _enable: function (e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED); e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED);
this.editTools.once( this.editTools.once(
'editable:editing', 'editable:editing',
function(e) { function (e) {
e.layer.closeTooltip(); e.layer.closeTooltip();
}, },
this this
); );
}, },
_disable: function(e) { _disable: function (e) {
e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED); e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED);
this._setCloseTimeout(e.layer); this._setCloseTimeout(e.layer);
} },
}); });
BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
_computeDeleteLatLng: function() { _computeDeleteLatLng: function () {
// While circle is not added to the map, _radius is not set. // 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); point = this.map.project(this.feature._latlng);
return this.map.unproject([point.x - delta, point.y - delta]); return this.map.unproject([point.x - delta, point.y - delta]);
}, },
_updateDeleteLatLng: function() { _updateDeleteLatLng: function () {
this._deleteLatLng.update(this._computeDeleteLatLng()); this._deleteLatLng.update(this._computeDeleteLatLng());
this._deleteLatLng.__vertex.update(); this._deleteLatLng.__vertex.update();
}, },
_addDeleteMarker: function() { _addDeleteMarker: function () {
if (!this.enabled()) return; if (!this.enabled()) return;
this._deleteLatLng = this._computeDeleteLatLng(); this._deleteLatLng = this._computeDeleteLatLng();
return new BR.DeleteMarker(this._deleteLatLng, this); return new BR.DeleteMarker(this._deleteLatLng, this);
}, },
_delete: function() { _delete: function () {
this.disable(); this.disable();
this.tools.featuresLayer.removeLayer(this.feature); this.tools.featuresLayer.removeLayer(this.feature);
}, },
delete: function() { delete: function () {
this._delete(); this._delete();
this.fireAndForward('editable:deleted'); this.fireAndForward('editable:deleted');
}, },
initialize: function(map, feature, options) { initialize: function (map, feature, options) {
L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options); L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options);
this._deleteLatLng = this._computeDeleteLatLng(); this._deleteLatLng = this._computeDeleteLatLng();
@ -572,7 +576,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
this.editLayer = new L.FeatureGroup(); this.editLayer = new L.FeatureGroup();
}, },
addHooks: function() { addHooks: function () {
L.Editable.CircleEditor.prototype.addHooks.call(this); L.Editable.CircleEditor.prototype.addHooks.call(this);
if (this.feature) { if (this.feature) {
this._addDeleteMarker(); this._addDeleteMarker();
@ -580,12 +584,12 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
return this; return this;
}, },
reset: function() { reset: function () {
L.Editable.CircleEditor.prototype.reset.call(this); L.Editable.CircleEditor.prototype.reset.call(this);
this._addDeleteMarker(); this._addDeleteMarker();
}, },
onDrawingMouseDown: function(e) { onDrawingMouseDown: function (e) {
this._deleteLatLng.update(e.latlng); this._deleteLatLng.update(e.latlng);
L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e); L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e);
}, },
@ -593,7 +597,7 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
// override to cancel/remove created circle when added by click instead of drag, because: // override to cancel/remove created circle when added by click instead of drag, because:
// - without resize, edit handles stacked on top of each other // - without resize, edit handles stacked on top of each other
// - makes event handling more complicated (editable:vertex:dragend not called) // - makes event handling more complicated (editable:vertex:dragend not called)
onDrawingMouseUp: function(e) { onDrawingMouseUp: function (e) {
if (this.feature.getRadius() > 0) { if (this.feature.getRadius() > 0) {
this.commitDrawing(e); this.commitDrawing(e);
} else { } else {
@ -604,10 +608,10 @@ BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e); L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
}, },
onVertexMarkerDrag: function(e) { onVertexMarkerDrag: function (e) {
this._updateDeleteLatLng(); this._updateDeleteLatLng();
L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e); L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e);
} },
}); });
BR.DeleteMarker = L.Marker.extend({ BR.DeleteMarker = L.Marker.extend({
@ -615,11 +619,11 @@ BR.DeleteMarker = L.Marker.extend({
draggable: false, draggable: false,
icon: L.divIcon({ 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' 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 // derived from L.Editable.VertexMarker.initialize
// We don't use this._latlng, because on drag Leaflet replace it while // We don't use this._latlng, because on drag Leaflet replace it while
@ -636,18 +640,18 @@ BR.DeleteMarker = L.Marker.extend({
this.setZIndexOffset(editor.tools._lastZIndex); this.setZIndexOffset(editor.tools._lastZIndex);
}, },
onAdd: function(map) { onAdd: function (map) {
L.Marker.prototype.onAdd.call(this, map); L.Marker.prototype.onAdd.call(this, map);
this.on('click', this.onClick); this.on('click', this.onClick);
}, },
onRemove: function(map) { onRemove: function (map) {
delete this.latlng.__vertex; delete this.latlng.__vertex;
this.off('click', this.onClick); this.off('click', this.onClick);
L.Marker.prototype.onRemove.call(this, map); L.Marker.prototype.onRemove.call(this, map);
}, },
onClick: function(e) { onClick: function (e) {
this.editor.delete(); this.editor.delete();
} },
}); });

View file

@ -1,17 +1,21 @@
BR.PoiMarkers = L.Control.extend({ BR.PoiMarkers = L.Control.extend({
markersLayer: null, markersLayer: null,
circlego: null,
options: { options: {
routing: null,
shortcut: { shortcut: {
draw: { draw: {
enable: 80, // char code for 'p' enable: 80, // char code for 'p'
disable: 27 // char code for 'ESC' disable: 27, // char code for 'ESC'
} },
} },
},
initialize: function (routing) {
this.routing = routing;
this.circlego = null;
}, },
onAdd: function(map) { onAdd: function (map) {
var self = this; var self = this;
this.map = map; this.map = map;
@ -22,26 +26,26 @@ BR.PoiMarkers = L.Control.extend({
{ {
stateName: 'activate-poi', stateName: 'activate-poi',
icon: 'fa-hand-o-right', icon: 'fa-hand-o-right',
onClick: function() { onClick: function () {
self.draw(true); self.draw(true);
}, },
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-poi-start)', key: 'P' }) title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-poi-start)', key: 'P' }),
}, },
{ {
stateName: 'deactivate-poi', stateName: 'deactivate-poi',
icon: 'fa-hand-o-right active', icon: 'fa-hand-o-right active',
onClick: function() { onClick: function () {
self.draw(false); self.draw(false);
}, },
title: i18next.t('keyboard.generic-shortcut', { title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-poi-stop)', action: '$t(map.draw-poi-stop)',
key: '$t(keyboard.escape)' key: '$t(keyboard.escape)',
}) }),
} },
] ],
}).addTo(map); }).addTo(map);
map.on('routing:draw-start', function() { map.on('routing:draw-start', function () {
self.draw(false); self.draw(false);
}); });
@ -51,10 +55,11 @@ BR.PoiMarkers = L.Control.extend({
return container; return container;
}, },
draw: function(enable) { draw: function (enable) {
this.drawButton.state(enable ? 'deactivate-poi' : 'activate-poi'); this.drawButton.state(enable ? 'deactivate-poi' : 'activate-poi');
if (enable) { if (enable) {
this.options.routing.draw(false); this.routing.draw(false);
if (this.circlego) this.circlego.draw(false);
this.map.on('click', this.onMapClick, this); this.map.on('click', this.onMapClick, this);
L.DomUtil.addClass(this.map.getContainer(), 'pois-draw-enabled'); L.DomUtil.addClass(this.map.getContainer(), 'pois-draw-enabled');
} else { } else {
@ -63,7 +68,7 @@ BR.PoiMarkers = L.Control.extend({
} }
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) { if (!BR.Util.keyboardShortcutsAllowed(e)) {
return; return;
} }
@ -74,22 +79,22 @@ BR.PoiMarkers = L.Control.extend({
} }
}, },
onMapClick: function(e) { onMapClick: function (e) {
var self = this; var self = this;
bootbox.prompt({ bootbox.prompt({
title: i18next.t('map.enter-poi-name'), title: i18next.t('map.enter-poi-name'),
callback: function(result) { callback: function (result) {
if (result !== null) { if (result !== null) {
self.addMarker(e.latlng, result); self.addMarker(e.latlng, result);
} }
} },
}); });
}, },
addMarker: function(latlng, name) { addMarker: function (latlng, name) {
var icon = L.VectorMarkers.icon({ var icon = L.VectorMarkers.icon({
icon: 'star', icon: 'star',
markerColor: BR.conf.markerColors.poi markerColor: BR.conf.markerColors.poi,
}); });
var content = BR.Util.sanitizeHTMLContent(name) + '<br>'; var content = BR.Util.sanitizeHTMLContent(name) + '<br>';
@ -98,11 +103,11 @@ BR.PoiMarkers = L.Control.extend({
var self = this; var self = this;
var marker = L.marker(latlng, { icon: icon, draggable: true, name: name }) var marker = L.marker(latlng, { icon: icon, draggable: true, name: name })
.bindPopup(content) .bindPopup(content)
.on('dragend', function() { .on('dragend', function () {
self.fire('update'); self.fire('update');
}) })
.on('popupopen', function() { .on('popupopen', function () {
$('#remove-poi-marker').on('click', function(e) { $('#remove-poi-marker').on('click', function (e) {
self.markersLayer.removeLayer(marker); self.markersLayer.removeLayer(marker);
e.preventDefault(); e.preventDefault();
self.fire('update'); self.fire('update');
@ -111,11 +116,11 @@ BR.PoiMarkers = L.Control.extend({
.addTo(this.markersLayer); .addTo(this.markersLayer);
}, },
clear: function() { clear: function () {
this.markersLayer.clearLayers(); this.markersLayer.clearLayers();
}, },
setMarkers: function(latLngNames) { setMarkers: function (latLngNames) {
this.clear(); this.clear();
if (!latLngNames) return; if (!latLngNames) return;
@ -126,14 +131,14 @@ BR.PoiMarkers = L.Control.extend({
} }
}, },
getMarkers: function() { getMarkers: function () {
return this.markersLayer.getLayers().map(function(it) { return this.markersLayer.getLayers().map(function (it) {
return { return {
latlng: it._latlng, latlng: it.getLatLng(),
name: it.options.name name: it.options.name,
}; };
}); });
} },
}); });
BR.PoiMarkers.include(L.Evented.prototype); BR.PoiMarkers.include(L.Evented.prototype);

View file

@ -1,395 +1,393 @@
BR.routeLoader = function(map, layersControl, routing, pois) { BR.routeLoader = function (map, layersControl, routing, pois) {
RouteLoader = L.Control.extend({ RouteLoader = L.Control.extend({
_layerName: 'Tracklayer', _layerName: 'Tracklayer',
_trackLayer: undefined, _trackLayer: undefined,
_bounds: undefined, _bounds: undefined,
_testLayer: L.layerGroup().addTo(map), _testLayer: L.layerGroup().addTo(map),
_trackPoints: [], _trackPoints: [],
_maxTrackPoints: 200, _maxTrackPoints: 200,
_closeCanceled: true, _closeCanceled: true,
_currentGeoJSON: {}, _currentGeoJSON: {},
_options: { _options: {
format: undefined, format: undefined,
showTrackLayer: true, showTrackLayer: true,
showPointAsPoi: true, showPointAsPoi: true,
simplifyTolerance: -1, simplifyTolerance: -1,
isTestMode: false, isTestMode: false,
simplifyLastKnownGood: 0.001 simplifyLastKnownGood: 0.001,
}, },
setDialogDraggable: function(jqDlgHeader) { setDialogDraggable: function (jqDlgHeader) {
jqDlgHeader.on('mousedown', function(mousedownEvt) { jqDlgHeader.on('mousedown', function (mousedownEvt) {
var $draggable = $(this); var $draggable = $(this);
var x = mousedownEvt.pageX - $draggable.offset().left, var x = mousedownEvt.pageX - $draggable.offset().left,
y = mousedownEvt.pageY - $draggable.offset().top; y = mousedownEvt.pageY - $draggable.offset().top;
$('body').on('mousemove.draggable', function(mousemoveEvt) { $('body').on('mousemove.draggable', function (mousemoveEvt) {
$draggable.closest('.modal-dialog').offset({ $draggable.closest('.modal-dialog').offset({
left: mousemoveEvt.pageX - x, left: mousemoveEvt.pageX - x,
top: mousemoveEvt.pageY - y top: mousemoveEvt.pageY - y,
}); });
}); });
$('body').one('mouseup', function() { $('body').one('mouseup', function () {
$('body').off('mousemove.draggable'); $('body').off('mousemove.draggable');
}); });
$draggable.closest('.modal').one('bs.modal.hide', function() { $draggable.closest('.modal').one('bs.modal.hide', function () {
$('body').off('mousemove.draggable'); $('body').off('mousemove.draggable');
}); });
}); });
}, },
getSimplifiedCoords: function(tolerance) { getSimplifiedCoords: function (tolerance) {
var simplifiedLine = turf.simplify(this._trackPoints.geometry, { var simplifiedLine = turf.simplify(this._trackPoints.geometry, {
tolerance: tolerance, tolerance: tolerance,
highQuality: true highQuality: true,
}); });
return simplifiedLine.coordinates; return simplifiedLine.coordinates;
}, },
refreshTestLayer: function() { refreshTestLayer: function () {
this.onBusyChanged(true); this.onBusyChanged(true);
this._testLayer.clearLayers(); this._testLayer.clearLayers();
var simplifiedLatLngs = L.GeoJSON.coordsToLatLngs( var simplifiedLatLngs = L.GeoJSON.coordsToLatLngs(
this.getSimplifiedCoords(this._options.simplifyTolerance) this.getSimplifiedCoords(this._options.simplifyTolerance)
); );
if (simplifiedLatLngs.length > this._maxTrackPoints) { if (simplifiedLatLngs.length > this._maxTrackPoints) {
this.onBusyChanged(false); this.onBusyChanged(false);
return false; return false;
} }
for (var i = 0; i < simplifiedLatLngs.length; i++) { for (var i = 0; i < simplifiedLatLngs.length; i++) {
this._testLayer.addLayer( this._testLayer.addLayer(
L.circleMarker(simplifiedLatLngs[i], { L.circleMarker(simplifiedLatLngs[i], {
radius: 6, radius: 6,
fill: false, fill: false,
color: '#FF0000' color: '#FF0000',
}) })
); );
} }
this.onBusyChanged(false); this.onBusyChanged(false);
return true; return true;
}, },
cleanup: function(e) { cleanup: function (e) {
this._testLayer.clearLayers(); this._testLayer.clearLayers();
if ( if (
this._trackLayer && this._trackLayer &&
map.hasLayer(this._trackLayer) && map.hasLayer(this._trackLayer) &&
(!this._options.showTrackLayer || this._closeCanceled) (!this._options.showTrackLayer || this._closeCanceled)
) { ) {
map.removeLayer(this._trackLayer); map.removeLayer(this._trackLayer);
layersControl.removeLayer(this._trackLayer); layersControl.removeLayer(this._trackLayer);
this._trackLayer = undefined; this._trackLayer = undefined;
} }
(this._bounds = undefined), (this._trackPoints = []); (this._bounds = undefined), (this._trackPoints = []);
this._currentGeoJSON = {}; this._currentGeoJSON = {};
this._options = { this._options = {
ext: 'gpx', ext: 'gpx',
showTrackLayer: true, showTrackLayer: true,
showPointAsPoi: true, showPointAsPoi: true,
simplifyTolerance: -1, simplifyTolerance: -1,
isTestMode: false, isTestMode: false,
simplifyLastKnownGood: 0.001 simplifyLastKnownGood: 0.001,
}; };
}, },
setSliderRange: function() { setSliderRange: function () {
$slider = $('#simplify_tolerance'); $slider = $('#simplify_tolerance');
$slider.prop('min', -500); $slider.prop('min', -500);
var guessedTolerance = this.guessSimplifyTolerance(this._trackPoints); var guessedTolerance = this.guessSimplifyTolerance(this._trackPoints);
var guessedLength = this.getSimplifiedCoords(guessedTolerance).length; var guessedLength = this.getSimplifiedCoords(guessedTolerance).length;
if (guessedLength > this._maxTrackPoints) { if (guessedLength > this._maxTrackPoints) {
this._maxTrackPoints = guessedLength; this._maxTrackPoints = guessedLength;
$slider.prop('min', 0); $slider.prop('min', 0);
} }
$slider.data('lastknowngood', 0); $slider.data('lastknowngood', 0);
$slider.data('guess', guessedTolerance.toFixed(20)); $slider.data('guess', guessedTolerance.toFixed(20));
$slider.val(0); $slider.val(0);
this._options.simplifyTolerance = guessedTolerance; this._options.simplifyTolerance = guessedTolerance;
this.refreshTestLayer(); this.refreshTestLayer();
}, },
onToleranceSlider: function(e) { onToleranceSlider: function (e) {
var guess = parseFloat($(e.target).data('guess')); var guess = parseFloat($(e.target).data('guess'));
var f = parseFloat(e.target.value); var f = parseFloat(e.target.value);
var frac = parseFloat($(e.target).prop('max')); var frac = parseFloat($(e.target).prop('max'));
if (f > guess) if (f > guess)
this._options.simplifyTolerance = guess + Math.pow(f, 2) * (guess / (Math.pow(frac, 2) / 10)); this._options.simplifyTolerance = guess + Math.pow(f, 2) * (guess / (Math.pow(frac, 2) / 10));
else this._options.simplifyTolerance = Math.abs(guess + Math.pow(f, 3) * (guess / Math.pow(frac, 3))); else this._options.simplifyTolerance = Math.abs(guess + Math.pow(f, 3) * (guess / Math.pow(frac, 3)));
if (!this.refreshTestLayer()) { if (!this.refreshTestLayer()) {
var iterate = this.findLowestTolerance( var iterate = this.findLowestTolerance(
parseInt(e.target.value), parseInt(e.target.value),
parseInt($(e.target).data('lastknowngood')), parseInt($(e.target).data('lastknowngood')),
guess, guess,
frac frac
); );
$(e.target).prop('min', iterate); $(e.target).prop('min', iterate);
$(e.target).data('lastknowngood', iterate); $(e.target).data('lastknowngood', iterate);
e.target.value = $(e.target).data('lastknowngood'); e.target.value = $(e.target).data('lastknowngood');
this._options.simplifyTolerance = this._options.simplifyLastKnownGood = Math.abs( this._options.simplifyTolerance = this._options.simplifyLastKnownGood = Math.abs(
guess + Math.pow(iterate, 3) * (guess / Math.pow(frac, 3)) guess + Math.pow(iterate, 3) * (guess / Math.pow(frac, 3))
); );
this.refreshTestLayer(); this.refreshTestLayer();
} else { } else {
this._options.simplifyLastKnownGood = this._options.simplifyTolerance; this._options.simplifyLastKnownGood = this._options.simplifyTolerance;
$(e.target).data('lastknowngood', e.target.value); $(e.target).data('lastknowngood', e.target.value);
} }
}, },
findLowestTolerance: function(min, max, guess, frac) { findLowestTolerance: function (min, max, guess, frac) {
if (Math.abs(max - min) <= 2) return max; if (Math.abs(max - min) <= 2) return max;
var meridian = Math.round((max + min) / 2); var meridian = Math.round((max + min) / 2);
var tolerance = Math.abs(guess + Math.pow(meridian, 3) * (guess / Math.pow(frac, 3))); var tolerance = Math.abs(guess + Math.pow(meridian, 3) * (guess / Math.pow(frac, 3)));
var simplifiedCoords = this.getSimplifiedCoords(tolerance); var simplifiedCoords = this.getSimplifiedCoords(tolerance);
if (simplifiedCoords.length > this._maxTrackPoints) if (simplifiedCoords.length > this._maxTrackPoints)
return this.findLowestTolerance(meridian, max, guess, frac); return this.findLowestTolerance(meridian, max, guess, frac);
else return this.findLowestTolerance(min, meridian, guess, frac); else return this.findLowestTolerance(min, meridian, guess, frac);
}, },
onBusyChanged: function(isBusy) { onBusyChanged: function (isBusy) {
if (typeof isBusy === undefined) { if (typeof isBusy === undefined) {
isBusy = false; isBusy = false;
} }
if (isBusy === true) $('#loadedittrackdlg #msg_busy').removeClass('invisible'); if (isBusy === true) $('#loadedittrackdlg #msg_busy').removeClass('invisible');
else $('#loadedittrackdlg #msg_busy').addClass('invisible'); else $('#loadedittrackdlg #msg_busy').addClass('invisible');
}, },
onManualCollapse: function(e) { onManualCollapse: function (e) {
//workaround for starting with closed collapse //workaround for starting with closed collapse
if ($('#loadedittrackdlg').is(':hidden')) return; if ($('#loadedittrackdlg').is(':hidden')) return;
this._options.isTestMode = $(e.target).hasClass('show'); this._options.isTestMode = $(e.target).hasClass('show');
if (this._options.isTestMode) { if (this._options.isTestMode) {
this.once('file:loaded', this.setSliderRange, this); this.once('file:loaded', this.setSliderRange, this);
this.convertTrackLocal(); this.convertTrackLocal();
} else this.cleanup(); } else this.cleanup();
}, },
onAdd: function(map) { onAdd: function (map) {
$('#loadedittrackdlg').on( $('#loadedittrackdlg').on(
'hidden.bs.modal', 'hidden.bs.modal',
function(e) { function (e) {
this.cleanup(); this.cleanup();
}.bind(this) }.bind(this)
); );
$('#loadedittrackdlg').on( $('#loadedittrackdlg').on(
'show.bs.modal', 'show.bs.modal',
function(e) { function (e) {
$('#manual_collapse').collapse('hide'); $('#manual_collapse').collapse('hide');
this._closeCanceled = true; this._closeCanceled = true;
}.bind(this) }.bind(this)
); );
L.DomUtil.get('submitLoadEditTrack').onclick = L.bind(function() { L.DomUtil.get('submitLoadEditTrack').onclick = L.bind(function () {
this._closeCanceled = false; this._closeCanceled = false;
this.onBusyChanged(true); this.onBusyChanged(true);
if (this._testLayer.getLayers().length > 0) { if (this._testLayer.getLayers().length > 0) {
this._testLayer.clearLayers(); this._testLayer.clearLayers();
setTimeout( setTimeout(
function() { function () {
this.addRoutingPoints(); this.addRoutingPoints();
this.onBusyChanged(false); this.onBusyChanged(false);
$('#loadedittrackdlg').modal('hide'); $('#loadedittrackdlg').modal('hide');
}.bind(this), }.bind(this),
0 0
); );
} else } else
setTimeout( setTimeout(
function() { function () {
this.convertTrackLocal(); this.convertTrackLocal();
$('#loadedittrackdlg').modal('hide'); $('#loadedittrackdlg').modal('hide');
}.bind(this), }.bind(this),
0 0
); );
}, this); }, this);
L.DomUtil.get('simplify_tolerance').oninput = L.bind(this.onToleranceSlider, this); L.DomUtil.get('simplify_tolerance').oninput = L.bind(this.onToleranceSlider, this);
L.DomUtil.get('loadedittrackFile').onchange = L.bind(this.onFileChanged, this); L.DomUtil.get('loadedittrackFile').onchange = L.bind(this.onFileChanged, this);
this.onFileChanged({ target: L.DomUtil.get('loadedittrackFile') }); this.onFileChanged({ target: L.DomUtil.get('loadedittrackFile') });
this.setDialogDraggable($('#loadedittrackdlg .modal-header')); this.setDialogDraggable($('#loadedittrackdlg .modal-header'));
$('#manual_collapse').collapse('hide'); $('#manual_collapse').collapse('hide');
$('#manual_collapse').on( $('#manual_collapse').on(
'hidden.bs.collapse shown.bs.collapse', 'hidden.bs.collapse shown.bs.collapse',
function(e) { function (e) {
this.onManualCollapse(e); this.onManualCollapse(e);
}.bind(this) }.bind(this)
); );
// dummy, no own representation, delegating to EasyButton // dummy, no own representation, delegating to EasyButton
var dummy = L.DomUtil.create('div'); var dummy = L.DomUtil.create('div');
dummy.hidden = true; dummy.hidden = true;
return dummy; return dummy;
}, },
onRemove: function(map) { onRemove: function (map) {
// Nothing to do here // Nothing to do here
}, },
onFileChanged: function(e) { onFileChanged: function (e) {
if (!e.target.files[0]) return; if (!e.target.files[0]) return;
$(e.target) $(e.target).next('label').text(e.target.files[0].name);
.next('label') var testmode = this._options.isTestMode;
.text(e.target.files[0].name); this.cleanup();
var testmode = this._options.isTestMode; this._options.isTestMode = testmode;
this.cleanup(); if (this._options.isTestMode) {
this._options.isTestMode = testmode; this.once('file:loaded', this.setSliderRange, this);
if (this._options.isTestMode) { this.convertTrackLocal();
this.once('file:loaded', this.setSliderRange, this); }
this.convertTrackLocal(); },
}
}, setLayerNameFromGeojson: function (geoJSON) {
if (geoJSON.type == 'Feature' && geoJSON.properties && geoJSON.properties.name) {
setLayerNameFromGeojson: function(geoJSON) { this._layerName = geoJSON.properties.name;
if (geoJSON.type == 'Feature' && geoJSON.properties && geoJSON.properties.name) { return;
this._layerName = geoJSON.properties.name; }
return;
} if (geoJSON.type == 'FeatureCollection') {
for (var i = 0; i < geoJSON.features.length; i++) {
if (geoJSON.type == 'FeatureCollection') { if (geoJSON.features[i].properties && geoJSON.features[i].properties.name) {
for (var i = 0; i < geoJSON.features.length; i++) { this._layerName = geoJSON.features[i].properties.name;
if (geoJSON.features[i].properties && geoJSON.features[i].properties.name) { return;
this._layerName = geoJSON.features[i].properties.name; }
return; }
} }
} },
}
}, getOptions: function () {
this._options.showTrackLayer = $('#cb_showtracklayer')[0].checked;
getOptions: function() { this._options.showPointAsPoi = $('#cb_showpois')[0].checked;
this._options.showTrackLayer = $('#cb_showtracklayer')[0].checked;
this._options.showPointAsPoi = $('#cb_showpois')[0].checked; this._options.simplifyTolerance = -1;
this._bounds = undefined;
this._options.simplifyTolerance = -1; },
this._bounds = undefined;
}, convertTrackLocal: function () {
if ($('#loadedittrackFile')[0].files.length == 0) return;
convertTrackLocal: function() { this.onBusyChanged(true);
if ($('#loadedittrackFile')[0].files.length == 0) return;
this.onBusyChanged(true); this.getOptions();
this.getOptions(); var trackFile = $('#loadedittrackFile')[0].files[0];
this._layerName = trackFile.name.replace(/\.[^\.]*$/, '');
var trackFile = $('#loadedittrackFile')[0].files[0];
this._layerName = trackFile.name.replace(/\.[^\.]*$/, ''); if (!this._options.format) this._options.format = trackFile.name.split('.').pop();
if (!this._options.format) this._options.format = trackFile.name.split('.').pop(); var reader = new FileReader();
var reader = new FileReader(); reader.onload = L.bind(this.processFile, this);
reader.readAsText(trackFile);
reader.onload = L.bind(this.processFile, this); },
reader.readAsText(trackFile);
}, addTrackOverlay: function (geoJSON) {
this._trackLayer = L.geoJSON(geoJSON, BR.Track.getGeoJsonOptions(layersControl)).addTo(map);
addTrackOverlay: function(geoJSON) {
this._trackLayer = L.geoJSON(geoJSON, BR.Track.getGeoJsonOptions(layersControl)).addTo(map); layersControl.addOverlay(this._trackLayer, BR.Util.sanitizeHTMLContent(this._layerName));
layersControl.addOverlay(this._trackLayer, BR.Util.sanitizeHTMLContent(this._layerName)); this._bounds = this._trackLayer.getBounds();
this._bounds = this._trackLayer.getBounds(); if (this._bounds) map.fitBounds(this._bounds);
},
if (this._bounds) map.fitBounds(this._bounds);
}, getLineStringsFromGeoJSON: function (geoJSON) {
var allLinePoints = [];
getLineStringsFromGeoJSON: function(geoJSON) { var flat = turf.flatten(geoJSON);
var allLinePoints = []; turf.featureEach(flat, function (feature, idx) {
var flat = turf.flatten(geoJSON); if (turf.getType(feature) == 'LineString') {
turf.featureEach(flat, function(feature, idx) { feature = turf.cleanCoords(feature);
if (turf.getType(feature) == 'LineString') { var lPoints = turf.coordAll(feature);
feature = turf.cleanCoords(feature); allLinePoints = allLinePoints.concat(lPoints);
var lPoints = turf.coordAll(feature); }
allLinePoints = allLinePoints.concat(lPoints); });
}
}); var linesGeoJSON = turf.lineString(allLinePoints);
linesGeoJSON.length = allLinePoints.length;
var linesGeoJSON = turf.lineString(allLinePoints); return linesGeoJSON;
linesGeoJSON.length = allLinePoints.length; },
return linesGeoJSON;
}, guessSimplifyTolerance: function (trackPoints) {
var tolerance = trackPoints.length / 1000000;
guessSimplifyTolerance: function(trackPoints) { if (tolerance > 0.8) tolerance = 0.8;
var tolerance = trackPoints.length / 1000000; return tolerance;
if (tolerance > 0.8) tolerance = 0.8; },
return tolerance;
}, addRoutingPoints: function (geoJSON) {
if (this._options.simplifyTolerance < 0)
addRoutingPoints: function(geoJSON) { this._options.simplifyTolerance = this.guessSimplifyTolerance(this._trackPoints);
if (this._options.simplifyTolerance < 0)
this._options.simplifyTolerance = this.guessSimplifyTolerance(this._trackPoints); var routingPoints = [];
var simplifiedLatLngs = L.GeoJSON.coordsToLatLngs(
var routingPoints = []; this.getSimplifiedCoords(this._options.simplifyTolerance)
var simplifiedLatLngs = L.GeoJSON.coordsToLatLngs( );
this.getSimplifiedCoords(this._options.simplifyTolerance)
); for (var i = 0; i < simplifiedLatLngs.length; i++) {
routingPoints.push(simplifiedLatLngs[i]);
for (var i = 0; i < simplifiedLatLngs.length; i++) { }
routingPoints.push(simplifiedLatLngs[i]);
} if (routingPoints.length > 0) {
routing.setWaypoints(routingPoints, function (event) {
if (routingPoints.length > 0) { if (!event) return;
routing.setWaypoints(routingPoints, function(event) { var err = event.error;
if (!event) return; BR.message.showError(
var err = event.error; i18next.t('warning.tracks-load-error', {
BR.message.showError( error: err && err.message ? err.message : err,
i18next.t('warning.tracks-load-error', { })
error: err && err.message ? err.message : err );
}) });
);
}); if (!this._bounds) this._bounds = L.latLngBounds(routingPoints);
}
if (!this._bounds) this._bounds = L.latLngBounds(routingPoints);
} if (!this._bounds) map.fitBounds(this._bounds);
if (!this._bounds) map.fitBounds(this._bounds); if (this._options.showPointAsPoi) {
BR.Track.addPoiMarkers(pois, this._currentGeoJSON);
if (this._options.showPointAsPoi) { }
BR.Track.addPoiMarkers(pois, this._currentGeoJSON); },
}
}, processFile: function (e) {
var res = e.target.result;
processFile: function(e) { var geoJSON = null;
var res = e.target.result; switch (this._options.format) {
var geoJSON = null; case 'kml':
switch (this._options.format) { case 'gpx':
case 'kml': var xml = new DOMParser().parseFromString(res, 'text/xml');
case 'gpx': geoJSON = toGeoJSON[this._options.format](xml);
var xml = new DOMParser().parseFromString(res, 'text/xml'); break;
geoJSON = toGeoJSON[this._options.format](xml);
break; default:
geoJSON = JSON.parse(res);
default: break;
geoJSON = JSON.parse(res); }
break;
} this._currentGeoJSON = geoJSON;
this.setLayerNameFromGeojson(geoJSON);
this._currentGeoJSON = geoJSON;
this.setLayerNameFromGeojson(geoJSON); this._trackPoints = this.getLineStringsFromGeoJSON(geoJSON);
var length = turf.length(this._trackPoints, { units: 'kilometers' });
this._trackPoints = this.getLineStringsFromGeoJSON(geoJSON); this._maxTrackPoints = Math.min(length * Math.max(-0.14 * length + 10, 1), 200);
var length = turf.length(this._trackPoints, { units: 'kilometers' }); this.fire('file:loaded');
this._maxTrackPoints = Math.min(length * Math.max(-0.14 * length + 10, 1), 200);
this.fire('file:loaded'); if (this._options.showTrackLayer || this._options.isTestMode) this.addTrackOverlay(geoJSON);
if (this._options.showTrackLayer || this._options.isTestMode) this.addTrackOverlay(geoJSON); if (!this._options.isTestMode) this.addRoutingPoints();
if (!this._options.isTestMode) this.addRoutingPoints(); this.onBusyChanged(false);
},
this.onBusyChanged(false); });
}
}); RouteLoader.include(L.Evented.prototype);
RouteLoader.include(L.Evented.prototype); var routeLoaderControl = new RouteLoader();
routeLoaderControl.addTo(map);
var routeLoaderControl = new RouteLoader();
routeLoaderControl.addTo(map); return routeLoaderControl;
};
return routeLoaderControl;
};

View file

@ -1,4 +1,4 @@
L.Routing.Draw.prototype._hideTrailer = function() { L.Routing.Draw.prototype._hideTrailer = function () {
if (this._trailer.options.opacity !== 0.0) { if (this._trailer.options.opacity !== 0.0) {
this._trailer.setStyle({ opacity: 0.0 }); this._trailer.setStyle({ opacity: 0.0 });
} }
@ -12,7 +12,7 @@ BR.Routing = L.Routing.extend({
normal: L.VectorMarkers.icon({ icon: 'circle', markerColor: BR.conf.markerColors.via }), normal: L.VectorMarkers.icon({ icon: 'circle', markerColor: BR.conf.markerColors.via }),
end: L.VectorMarkers.icon({ icon: 'stop', markerColor: BR.conf.markerColors.stop }), end: L.VectorMarkers.icon({ icon: 'stop', markerColor: BR.conf.markerColors.stop }),
draw: false, draw: false,
opacity: 1 opacity: 1,
}, },
snapping: null, snapping: null,
zIndexOffset: -2000, zIndexOffset: -2000,
@ -20,21 +20,21 @@ BR.Routing = L.Routing.extend({
// width as base number, multiplied by number of digits + one for padding // width as base number, multiplied by number of digits + one for padding
iconSize: [6, 18], iconSize: [6, 18],
offset: 5000, offset: 5000,
textFunction: function(distance) { textFunction: function (distance) {
return distance / 1000; return distance / 1000;
} },
}, },
shortcut: { shortcut: {
draw: { draw: {
enable: 68, // char code for 'd' enable: 68, // char code for 'd'
disable: 27 // char code for 'ESC' disable: 27, // char code for 'ESC'
}, },
reverse: 82, // char code for 'r' reverse: 82, // char code for 'r'
deleteLastPoint: 90 // char code for 'z' deleteLastPoint: 90, // char code for 'z'
} },
}, },
onAdd: function(map) { onAdd: function (map) {
this._segmentsCasing = new L.FeatureGroup().addTo(map); this._segmentsCasing = new L.FeatureGroup().addTo(map);
this._loadingTrailerGroup = new L.FeatureGroup().addTo(map); this._loadingTrailerGroup = new L.FeatureGroup().addTo(map);
@ -45,18 +45,18 @@ BR.Routing = L.Routing.extend({
this._waypoints.on('layeradd', this._setMarkerOpacity, this); this._waypoints.on('layeradd', this._setMarkerOpacity, this);
this.on('routing:routeWaypointStart routing:rerouteAllSegmentsStart', function(evt) { this.on('routing:routeWaypointStart routing:rerouteAllSegmentsStart', function (evt) {
this._removeDistanceMarkers(); this._removeDistanceMarkers();
}); });
this.on('routing:routeWaypointEnd routing:setWaypointsEnd routing:rerouteAllSegmentsEnd', function(evt) { this.on('routing:routeWaypointEnd routing:setWaypointsEnd routing:rerouteAllSegmentsEnd', function (evt) {
this._updateDistanceMarkers(evt); this._updateDistanceMarkers(evt);
}); });
// turn line mouse marker off while over waypoint marker // turn line mouse marker off while over waypoint marker
this.on( this.on(
'waypoint:mouseover', 'waypoint:mouseover',
function(e) { function (e) {
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw) // L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
if (this._dragging) { if (this._dragging) {
return; return;
@ -71,7 +71,7 @@ BR.Routing = L.Routing.extend({
this.on( this.on(
'waypoint:mouseout', 'waypoint:mouseout',
function(e) { function (e) {
this._segmentOnMouseover(e); this._segmentOnMouseover(e);
this._suspended = false; this._suspended = false;
}, },
@ -82,7 +82,7 @@ BR.Routing = L.Routing.extend({
L.divIcon({ L.divIcon({
className: 'line-mouse-marker', className: 'line-mouse-marker',
iconAnchor: [8, 8], // size/2 + border/2 iconAnchor: [8, 8], // size/2 + border/2
iconSize: [16, 16] iconSize: [16, 16],
}) })
); );
@ -90,7 +90,7 @@ BR.Routing = L.Routing.extend({
// update indicator), see also L.Routing.Edit._segmentOnMousemove // update indicator), see also L.Routing.Edit._segmentOnMousemove
this._edit._mouseMarker.on( this._edit._mouseMarker.on(
'move', 'move',
L.bind(function(e) { L.bind(function (e) {
var latLng = e.latlng; var latLng = e.latlng;
if (latLng._feature) { if (latLng._feature) {
this._mouseMarker._feature = latLng._feature; this._mouseMarker._feature = latLng._feature;
@ -98,7 +98,7 @@ BR.Routing = L.Routing.extend({
} }
}, this._edit) }, this._edit)
); );
var mouseoutHandler = function(e) { var mouseoutHandler = function (e) {
if (this._mouseMarker._feature) { if (this._mouseMarker._feature) {
this._mouseMarker._feature.fire('mouseout', e, true); this._mouseMarker._feature.fire('mouseout', e, true);
this._mouseMarker._feature = null; this._mouseMarker._feature = null;
@ -108,7 +108,7 @@ BR.Routing = L.Routing.extend({
this._edit._mouseMarker.on('dragstart', mouseoutHandler, this._edit); this._edit._mouseMarker.on('dragstart', mouseoutHandler, this._edit);
this.on('waypoint:mouseover', mouseoutHandler, this._edit); this.on('waypoint:mouseover', mouseoutHandler, this._edit);
this._draw.on('enabled', function() { this._draw.on('enabled', function () {
// crosshair cursor // crosshair cursor
L.DomUtil.addClass(map.getContainer(), 'routing-draw-enabled'); L.DomUtil.addClass(map.getContainer(), 'routing-draw-enabled');
@ -120,7 +120,7 @@ BR.Routing = L.Routing.extend({
this._parent.off('waypoint:mouseout', this._catchWaypointEvent, this); this._parent.off('waypoint:mouseout', this._catchWaypointEvent, this);
this.on( this.on(
'waypoint:mouseout', 'waypoint:mouseout',
function(e) { function (e) {
if (!this._parent._edit._suspended) { if (!this._parent._edit._suspended) {
this._catchWaypointEvent(e); this._catchWaypointEvent(e);
} }
@ -128,7 +128,7 @@ BR.Routing = L.Routing.extend({
this this
); );
}); });
this._draw.on('disabled', function() { this._draw.on('disabled', function () {
L.DomUtil.removeClass(map.getContainer(), 'routing-draw-enabled'); L.DomUtil.removeClass(map.getContainer(), 'routing-draw-enabled');
}); });
@ -143,13 +143,13 @@ BR.Routing = L.Routing.extend({
this._hide(); this._hide();
} }
} }
this._draw.on('enabled', function() { this._draw.on('enabled', function () {
this._map.on('mouseout', hide, this); this._map.on('mouseout', hide, this);
this._map.on('mouseover', show, this); this._map.on('mouseover', show, this);
L.DomEvent.on(this._map._controlContainer, 'mouseout', show, this); L.DomEvent.on(this._map._controlContainer, 'mouseout', show, this);
L.DomEvent.on(this._map._controlContainer, 'mouseover', hide, this); L.DomEvent.on(this._map._controlContainer, 'mouseover', hide, this);
}); });
this._draw.on('disabled', function() { this._draw.on('disabled', function () {
this._map.off('mouseout', hide, this); this._map.off('mouseout', hide, this);
this._map.off('mouseover', show, this); this._map.off('mouseover', show, this);
L.DomEvent.off(this._map._controlContainer, 'mouseout', show, this); L.DomEvent.off(this._map._controlContainer, 'mouseout', show, this);
@ -163,7 +163,7 @@ BR.Routing = L.Routing.extend({
// although enabled. // although enabled.
this.on( this.on(
'waypoint:click', 'waypoint:click',
function() { function () {
if (this._hidden && !this._parent._waypoints._first) { if (this._hidden && !this._parent._waypoints._first) {
this._show(); this._show();
this._hideTrailer(); this._hideTrailer();
@ -181,18 +181,18 @@ BR.Routing = L.Routing.extend({
return container; return container;
}, },
_addSegmentCasing: function(e) { _addSegmentCasing: function (e) {
var casing = L.polyline(e.layer.getLatLngs(), this.options.styles.trackCasing); var casing = L.polyline(e.layer.getLatLngs(), this.options.styles.trackCasing);
this._segmentsCasing.addLayer(casing); this._segmentsCasing.addLayer(casing);
e.layer._casing = casing; e.layer._casing = casing;
this._segments.bringToFront(); this._segments.bringToFront();
}, },
_removeSegmentCasing: function(e) { _removeSegmentCasing: function (e) {
this._segmentsCasing.removeLayer(e.layer._casing); this._segmentsCasing.removeLayer(e.layer._casing);
}, },
setOpacity: function(opacity) { setOpacity: function (opacity) {
// Due to the second Polyline layer for casing, the combined opacity is less // 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 // 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. // inverted formula is used to get the same result as with a single layer.
@ -205,12 +205,12 @@ BR.Routing = L.Routing.extend({
this.options.icons.opacity = opacity; this.options.icons.opacity = opacity;
this._segments.setStyle({ this._segments.setStyle({
opacity: sourceOpacity opacity: sourceOpacity,
}); });
this._segmentsCasing.setStyle({ this._segmentsCasing.setStyle({
opacity: sourceOpacity opacity: sourceOpacity,
}); });
this._waypoints.eachLayer(function(marker) { this._waypoints.eachLayer(function (marker) {
marker.setOpacity(opacity); marker.setOpacity(opacity);
}); });
@ -219,11 +219,11 @@ BR.Routing = L.Routing.extend({
} }
}, },
_setMarkerOpacity: function(e) { _setMarkerOpacity: function (e) {
e.layer.setOpacity(this.options.icons.opacity); e.layer.setOpacity(this.options.icons.opacity);
}, },
_removeMarkerEvents: function(marker) { _removeMarkerEvents: function (marker) {
marker.off('mouseover', this._fireWaypointEvent, this); marker.off('mouseover', this._fireWaypointEvent, this);
marker.off('mouseout', this._fireWaypointEvent, this); marker.off('mouseout', this._fireWaypointEvent, this);
marker.off('dragstart', this._fireWaypointEvent, this); marker.off('dragstart', this._fireWaypointEvent, this);
@ -232,7 +232,7 @@ BR.Routing = L.Routing.extend({
marker.off('click', this._fireWaypointEvent, this); marker.off('click', this._fireWaypointEvent, this);
}, },
clear: function() { clear: function () {
var drawEnabled = this._draw._enabled; var drawEnabled = this._draw._enabled;
var current = this._waypoints._first; var current = this._waypoints._first;
@ -259,13 +259,13 @@ BR.Routing = L.Routing.extend({
} }
}, },
setWaypoints: function(latLngs, cb) { setWaypoints: function (latLngs, cb) {
var i; var i;
var callbackCount = 0; var callbackCount = 0;
var firstErr; var firstErr;
var $this = this; var $this = this;
var callback = function(err, data) { var callback = function (err, data) {
callbackCount++; callbackCount++;
firstErr = firstErr || err; firstErr = firstErr || err;
if (callbackCount >= latLngs.length) { if (callbackCount >= latLngs.length) {
@ -299,10 +299,10 @@ BR.Routing = L.Routing.extend({
// patch to fix error when line is null or error line // patch to fix error when line is null or error line
// (when called while still segments to calculate, e.g. permalink or fast drawing) // (when called while still segments to calculate, e.g. permalink or fast drawing)
toPolyline: function() { toPolyline: function () {
var latLngs = []; var latLngs = [];
this._eachSegment(function(m1, m2, line) { this._eachSegment(function (m1, m2, line) {
// omit if null (still calculating) or error // omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line // NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) { if (line && line.feature) {
@ -313,7 +313,7 @@ BR.Routing = L.Routing.extend({
return L.polyline(latLngs); return L.polyline(latLngs);
}, },
_routeSegment: function(m1, m2, cb) { _routeSegment: function (m1, m2, cb) {
var loadingTrailer; var loadingTrailer;
// change segment color before request to indicate recalculation (mark old) // change segment color before request to indicate recalculation (mark old)
@ -327,7 +327,7 @@ BR.Routing = L.Routing.extend({
color: this.options.styles.track.color, color: this.options.styles.track.color,
opacity: this.options.styles.trailer.opacity, opacity: this.options.styles.trailer.opacity,
dashArray: [10, 10], dashArray: [10, 10],
className: 'loading-trailer' className: 'loading-trailer',
}); });
this._loadingTrailerGroup.addLayer(loadingTrailer); this._loadingTrailerGroup.addLayer(loadingTrailer);
} }
@ -336,7 +336,7 @@ BR.Routing = L.Routing.extend({
this, this,
m1, m1,
m2, m2,
L.bind(function(err, data) { L.bind(function (err, data) {
if (loadingTrailer) { if (loadingTrailer) {
this._loadingTrailerGroup.removeLayer(loadingTrailer); this._loadingTrailerGroup.removeLayer(loadingTrailer);
} }
@ -345,10 +345,10 @@ BR.Routing = L.Routing.extend({
); );
}, },
getSegments: function() { getSegments: function () {
var segments = []; var segments = [];
this._eachSegment(function(m1, m2, line) { this._eachSegment(function (m1, m2, line) {
// omit if null (still calculating) or error // omit if null (still calculating) or error
// NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line // NOTE: feature check specific to BRouter GeoJSON response, workaround to detect error line
if (line && line.feature) { if (line && line.feature) {
@ -359,7 +359,7 @@ BR.Routing = L.Routing.extend({
return segments; return segments;
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) { if (!BR.Util.keyboardShortcutsAllowed(e)) {
return; return;
} }
@ -374,7 +374,7 @@ BR.Routing = L.Routing.extend({
} }
}, },
_keyupListener: function(e) { _keyupListener: function (e) {
// Prevent Leaflet from triggering drawing a second time on keyup, // Prevent Leaflet from triggering drawing a second time on keyup,
// since this is already done in _keydownListener // since this is already done in _keydownListener
if (e.keyCode === this.options.shortcut.draw.enable) { if (e.keyCode === this.options.shortcut.draw.enable) {
@ -382,30 +382,30 @@ BR.Routing = L.Routing.extend({
} }
}, },
isDrawing: function() { isDrawing: function () {
return this._draw._enabled; return this._draw._enabled;
}, },
reverse: function() { reverse: function () {
var waypoints = this.getWaypoints(); var waypoints = this.getWaypoints();
waypoints.reverse(); waypoints.reverse();
this.clear(); this.clear();
this.setWaypoints(waypoints); this.setWaypoints(waypoints);
}, },
deleteLastPoint: function() { deleteLastPoint: function () {
if ((lastPoint = this.getLast())) { if ((lastPoint = this.getLast())) {
this.removeWaypoint(lastPoint, function(err, data) {}); this.removeWaypoint(lastPoint, function (err, data) {});
} }
}, },
_removeDistanceMarkers: function() { _removeDistanceMarkers: function () {
if (this._map && this._distanceMarkers) { if (this._map && this._distanceMarkers) {
this._map.removeLayer(this._distanceMarkers); this._map.removeLayer(this._distanceMarkers);
} }
}, },
_updateDistanceMarkers: function(e) { _updateDistanceMarkers: function (e) {
this._removeDistanceMarkers(); this._removeDistanceMarkers();
if (this._map) { if (this._map) {
@ -413,5 +413,5 @@ BR.Routing = L.Routing.extend({
this._distanceMarkers = new L.DistanceMarkers(this.toPolyline(), this._map, distanceMarkersOpts); this._distanceMarkers = new L.DistanceMarkers(this.toPolyline(), this._map, distanceMarkersOpts);
this._map.addLayer(this._distanceMarkers); this._map.addLayer(this._distanceMarkers);
} }
} },
}); });

View file

@ -2,11 +2,11 @@ BR.RoutingPathQuality = L.Control.extend({
options: { options: {
shortcut: { shortcut: {
toggle: 67, // char code for 'c' toggle: 67, // char code for 'c'
muteKeyCode: 77 // char code for 'm' muteKeyCode: 77, // char code for 'm'
} },
}, },
initialize: function(map, layersControl, options) { initialize: function (map, layersControl, options) {
L.setOptions(this, options); L.setOptions(this, options);
// hotline uses canvas and cannot be moved in front of the svg, so we create another pane // hotline uses canvas and cannot be moved in front of the svg, so we create another pane
@ -32,20 +32,20 @@ BR.RoutingPathQuality = L.Control.extend({
0.25: '#00ffff', // cyan 0.25: '#00ffff', // cyan
0.5: '#00ff00', // green 0.5: '#00ff00', // green
0.75: '#ffff00', // yellow 0.75: '#ffff00', // yellow
1.0: '#ff0000' // red 1.0: '#ff0000', // red
}, },
outlineColor: 'dimgray', outlineColor: 'dimgray',
renderer: renderer renderer: renderer,
}, },
valueFunction: function(latLng, prevLatLng) { valueFunction: function (latLng, prevLatLng) {
var deltaAltitude = latLng.alt - prevLatLng.alt, // in m var deltaAltitude = latLng.alt - prevLatLng.alt, // in m
distance = prevLatLng.distanceTo(latLng); // in m distance = prevLatLng.distanceTo(latLng); // in m
if (distance === 0) { if (distance === 0) {
return 0; return 0;
} }
return (Math.atan(deltaAltitude / distance) * 180) / Math.PI; return (Math.atan(deltaAltitude / distance) * 180) / Math.PI;
} },
}) }),
}, },
altitude: { altitude: {
title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-altitude)', key: 'C' }), title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-altitude)', key: 'C' }),
@ -53,12 +53,12 @@ BR.RoutingPathQuality = L.Control.extend({
provider: new HotLineQualityProvider({ provider: new HotLineQualityProvider({
hotlineOptions: { hotlineOptions: {
outlineColor: 'dimgray', outlineColor: 'dimgray',
renderer: renderer renderer: renderer,
}, },
valueFunction: function(latLng) { valueFunction: function (latLng) {
return latLng.alt; return latLng.alt;
} },
}) }),
}, },
cost: { cost: {
title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-cost)', key: 'C' }), title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-cost)', key: 'C' }),
@ -66,9 +66,9 @@ BR.RoutingPathQuality = L.Control.extend({
provider: new HotLineQualityProvider({ provider: new HotLineQualityProvider({
hotlineOptions: { hotlineOptions: {
outlineColor: 'dimgray', outlineColor: 'dimgray',
renderer: renderer renderer: renderer,
}, },
valueFunction: function(latLng) { valueFunction: function (latLng) {
var feature = latLng.feature; var feature = latLng.feature;
var cost = feature.cost.perKm; var cost = feature.cost.perKm;
var distance = feature.distance / 1000; // in km var distance = feature.distance / 1000; // in km
@ -78,9 +78,9 @@ BR.RoutingPathQuality = L.Control.extend({
distance; distance;
} }
return cost; return cost;
} },
}) }),
} },
}; };
this._initialProvider = this.options.initialProvider || 'incline'; this._initialProvider = this.options.initialProvider || 'incline';
this.selectedProvider = this._initialProvider; this.selectedProvider = this._initialProvider;
@ -89,12 +89,12 @@ BR.RoutingPathQuality = L.Control.extend({
this._muted = false; this._muted = false;
}, },
onAdd: function(map) { onAdd: function (map) {
this._map = map; this._map = map;
map.on( map.on(
'overlayadd', 'overlayadd',
function(evt) { function (evt) {
if (evt.layer === this._routingSegments) { if (evt.layer === this._routingSegments) {
this._activate(this.routingPathButton); this._activate(this.routingPathButton);
} }
@ -103,7 +103,7 @@ BR.RoutingPathQuality = L.Control.extend({
); );
map.on( map.on(
'overlayremove', 'overlayremove',
function(evt) { function (evt) {
if (evt.layer === this._routingSegments) { if (evt.layer === this._routingSegments) {
this._deactivate(this.routingPathButton); this._deactivate(this.routingPathButton);
} }
@ -123,8 +123,8 @@ BR.RoutingPathQuality = L.Control.extend({
stateName: keys[i], stateName: keys[i],
icon: provider.icon, icon: provider.icon,
title: provider.title, title: provider.title,
onClick: L.bind(function(state) { onClick: L.bind(function (state) {
return L.bind(function(btn) { return L.bind(function (btn) {
if (this._active) { if (this._active) {
btn.state(state); btn.state(state);
this.setProvider(state); this.setProvider(state);
@ -138,7 +138,7 @@ BR.RoutingPathQuality = L.Control.extend({
this._activate(btn); this._activate(btn);
} }
}, this); }, this);
}, this)(nextState) }, this)(nextState),
}); });
} }
@ -148,42 +148,42 @@ BR.RoutingPathQuality = L.Control.extend({
} }
this.routingPathButton = new L.easyButton({ this.routingPathButton = new L.easyButton({
states: states states: states,
}).addTo(map); }).addTo(map);
return new L.DomUtil.create('div'); return new L.DomUtil.create('div');
}, },
_activate: function(btn) { _activate: function (btn) {
this._active = true; this._active = true;
this._getIcon(btn).classList.add('active'); this._getIcon(btn).classList.add('active');
this._routingSegments.addTo(this._map); this._routingSegments.addTo(this._map);
}, },
_deactivate: function(btn) { _deactivate: function (btn) {
this._active = false; this._active = false;
this._getIcon(btn).classList.remove('active'); this._getIcon(btn).classList.remove('active');
this._map.removeLayer(this._routingSegments); this._map.removeLayer(this._routingSegments);
}, },
_getIcon: function(btn) { _getIcon: function (btn) {
return btn.button.firstChild.firstChild; return btn.button.firstChild.firstChild;
}, },
update: function(track, layer) { update: function (track, layer) {
var segments = []; var segments = [];
layer.eachLayer(function(layer) { layer.eachLayer(function (layer) {
segments.push(layer); segments.push(layer);
}); });
this.segments = segments; this.segments = segments;
this._update(this.segments); this._update(this.segments);
}, },
setProvider: function(provider) { setProvider: function (provider) {
this.selectedProvider = provider; this.selectedProvider = provider;
this._update(this.segments); this._update(this.segments);
}, },
_update: function(segments) { _update: function (segments) {
this._routingSegments.clearLayers(); this._routingSegments.clearLayers();
var layers = this.providers[this.selectedProvider].provider.computeLayers(segments); var layers = this.providers[this.selectedProvider].provider.computeLayers(segments);
if (layers) { if (layers) {
@ -193,7 +193,7 @@ BR.RoutingPathQuality = L.Control.extend({
} }
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (!BR.Util.keyboardShortcutsAllowed(e)) { if (!BR.Util.keyboardShortcutsAllowed(e)) {
return; return;
} }
@ -206,21 +206,21 @@ BR.RoutingPathQuality = L.Control.extend({
} }
}, },
_keyupListener: function(e) { _keyupListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && this._muted && e.keyCode === this.options.shortcut.muteKeyCode) { if (BR.Util.keyboardShortcutsAllowed(e) && this._muted && e.keyCode === this.options.shortcut.muteKeyCode) {
this._muted = false; this._muted = false;
this._activate(this.routingPathButton); this._activate(this.routingPathButton);
} }
} },
}); });
var HotLineQualityProvider = L.Class.extend({ var HotLineQualityProvider = L.Class.extend({
initialize: function(options) { initialize: function (options) {
this.hotlineOptions = options.hotlineOptions; this.hotlineOptions = options.hotlineOptions;
this.valueFunction = options.valueFunction; this.valueFunction = options.valueFunction;
}, },
computeLayers: function(segments) { computeLayers: function (segments) {
var layers = []; var layers = [];
if (segments) { if (segments) {
var segmentLatLngs = []; var segmentLatLngs = [];
@ -250,7 +250,7 @@ var HotLineQualityProvider = L.Class.extend({
return layers; return layers;
}, },
_computeLatLngVals: function(segment) { _computeLatLngVals: function (segment) {
var latLngVals = [], var latLngVals = [],
segmentLatLngs = segment.getLatLngs(), segmentLatLngs = segment.getLatLngs(),
segmentLength = segmentLatLngs.length; segmentLength = segmentLatLngs.length;
@ -268,11 +268,11 @@ var HotLineQualityProvider = L.Class.extend({
return latLngVals; return latLngVals;
}, },
_convertToArray: function(latLng, val) { _convertToArray: function (latLng, val) {
return [latLng.lat, latLng.lng, val]; return [latLng.lat, latLng.lng, val];
}, },
_calcMinMaxValues: function(lines) { _calcMinMaxValues: function (lines) {
var min = lines[0][2], var min = lines[0][2],
max = min; max = min;
for (var i = 1; lines && i < lines.length; i++) { for (var i = 1; lines && i < lines.length; i++) {
@ -285,7 +285,7 @@ var HotLineQualityProvider = L.Class.extend({
} }
return { return {
min: min, min: min,
max: max max: max,
}; };
} },
}); });

View file

@ -2,30 +2,30 @@ BR.Search = L.Control.Geocoder.extend({
options: { options: {
geocoder: new L.Control.Geocoder.LatLng({ geocoder: new L.Control.Geocoder.LatLng({
next: new L.Control.Geocoder.Nominatim({ next: new L.Control.Geocoder.Nominatim({
serviceUrl: 'https://nominatim.openstreetmap.org/' serviceUrl: 'https://nominatim.openstreetmap.org/',
}), }),
sizeInMeters: 800 sizeInMeters: 800,
}), }),
position: 'topleft', position: 'topleft',
shortcut: { shortcut: {
search: 70 // char code for 'f' search: 70, // char code for 'f'
} },
}, },
initialize: function(options) { initialize: function (options) {
L.Control.Geocoder.prototype.initialize.call(this, options); L.Control.Geocoder.prototype.initialize.call(this, options);
L.setOptions(this, { L.setOptions(this, {
// i18next.t will only return 'undefined' if it is called in a static context // i18next.t will only return 'undefined' if it is called in a static context
// (e.g. when added directly to "options:" above), so we have to call it here // (e.g. when added directly to "options:" above), so we have to call it here
placeholder: i18next.t('map.geocoder-placeholder') placeholder: i18next.t('map.geocoder-placeholder'),
}); });
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this); L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
}, },
markGeocode: function(result) { markGeocode: function (result) {
this._map.fitBounds(result.geocode.bbox, { this._map.fitBounds(result.geocode.bbox, {
maxZoom: 17 maxZoom: 17,
}); });
this.clear(); this.clear();
@ -33,22 +33,22 @@ BR.Search = L.Control.Geocoder.extend({
interactive: false, interactive: false,
color: 'red', color: 'red',
opacity: 1, opacity: 1,
weight: 3 weight: 3,
}).addTo(this._map); }).addTo(this._map);
return this; return this;
}, },
clear: function() { clear: function () {
if (this._geocodeMarker) { if (this._geocodeMarker) {
this._map.removeLayer(this._geocodeMarker); this._map.removeLayer(this._geocodeMarker);
} }
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.search) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.search) {
$('#map .leaflet-control-geocoder')[0].dispatchEvent(new MouseEvent('mousedown')); $('#map .leaflet-control-geocoder')[0].dispatchEvent(new MouseEvent('mousedown'));
e.preventDefault(); e.preventDefault();
} }
} },
}); });

View file

@ -9,15 +9,15 @@ BR.Sidebar = L.Control.Sidebar.extend({
defaultTabId: '', defaultTabId: '',
shortcut: { shortcut: {
toggleTabs: 84 // char code for 't' toggleTabs: 84, // char code for 't'
}, },
// Tabs to be notified when shown or hidden // Tabs to be notified when shown or hidden
// (tab div id -> object implementing show/hide methods) // (tab div id -> object implementing show/hide methods)
listeningTabs: {} listeningTabs: {},
}, },
initialize: function(id, options) { initialize: function (id, options) {
L.Control.Sidebar.prototype.initialize.call(this, id, options); L.Control.Sidebar.prototype.initialize.call(this, id, options);
this.oldTab = null; this.oldTab = null;
@ -25,7 +25,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
L.DomEvent.addListener(document, 'keydown', this._keydownListener, this); L.DomEvent.addListener(document, 'keydown', this._keydownListener, this);
}, },
addTo: function(map) { addTo: function (map) {
L.Control.Sidebar.prototype.addTo.call(this, map); L.Control.Sidebar.prototype.addTo.call(this, map);
this.on('content', this._notifyOnContent, this); this.on('content', this._notifyOnContent, this);
@ -34,7 +34,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
this.on( this.on(
'closing', 'closing',
function() { function () {
this._map.getContainer().focus(); this._map.getContainer().focus();
}, },
this this
@ -43,7 +43,7 @@ BR.Sidebar = L.Control.Sidebar.extend({
this.recentTab = this.options.defaultTabId; this.recentTab = this.options.defaultTabId;
this.on( this.on(
'content', 'content',
function(tab) { function (tab) {
this.recentTab = tab.id; this.recentTab = tab.id;
}, },
this this
@ -59,14 +59,14 @@ BR.Sidebar = L.Control.Sidebar.extend({
return this; return this;
}, },
showPanel: function(id) { showPanel: function (id) {
var tab = this._getTab(id); var tab = this._getTab(id);
tab.hidden = false; tab.hidden = false;
return this; return this;
}, },
_rememberTabState: function() { _rememberTabState: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
this.on('content closing', this._storeActiveTab, this); this.on('content closing', this._storeActiveTab, this);
@ -85,42 +85,42 @@ BR.Sidebar = L.Control.Sidebar.extend({
} }
}, },
_notifyShow: function(tab) { _notifyShow: function (tab) {
if (tab && tab.show) { if (tab && tab.show) {
tab.show(); tab.show();
} }
}, },
_notifyHide: function(tab) { _notifyHide: function (tab) {
if (tab && tab.hide) { if (tab && tab.hide) {
tab.hide(); tab.hide();
} }
}, },
_notifyOnContent: function(e) { _notifyOnContent: function (e) {
var tab = this.options.listeningTabs[e.id]; var tab = this.options.listeningTabs[e.id];
this._notifyHide(this.oldTab); this._notifyHide(this.oldTab);
this._notifyShow(tab); this._notifyShow(tab);
this.oldTab = tab; this.oldTab = tab;
}, },
_notifyOnClose: function(e) { _notifyOnClose: function (e) {
this._notifyHide(this.oldTab); this._notifyHide(this.oldTab);
this.oldTab = null; this.oldTab = null;
}, },
_notifyOnResize: function(e) { _notifyOnResize: function (e) {
var tab = this.oldTab; var tab = this.oldTab;
if (tab && tab.onResize) { if (tab && tab.onResize) {
tab.onResize(); tab.onResize();
} }
}, },
_storeActiveTab: function(e) { _storeActiveTab: function (e) {
localStorage.setItem(this.storageId, e.id || ''); localStorage.setItem(this.storageId, e.id || '');
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleTabs) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleTabs) {
if ($('#sidebarTabs > ul > li[class=active]').length) { if ($('#sidebarTabs > ul > li[class=active]').length) {
// sidebar is currently open, close current tab // sidebar is currently open, close current tab
@ -142,9 +142,9 @@ BR.Sidebar = L.Control.Sidebar.extend({
this.open(nextTab.attr('href').slice(1)); this.open(nextTab.attr('href').slice(1));
} }
} }
} },
}); });
BR.sidebar = function(divId, options) { BR.sidebar = function (divId, options) {
return new BR.Sidebar(divId, options); return new BR.Sidebar(divId, options);
}; };

View file

@ -1,6 +1,6 @@
BR.tracksLoader = function(map, layersControl, routing, pois) { BR.tracksLoader = function (map, layersControl, routing, pois) {
// proxy to L.geoJSON factory function, to get hold of raw GeoJSON object // proxy to L.geoJSON factory function, to get hold of raw GeoJSON object
var createGeoJsonLayer = function(geojson, options) { var createGeoJsonLayer = function (geojson, options) {
BR.Track.addPoiMarkers(pois, geojson); BR.Track.addPoiMarkers(pois, geojson);
return L.geoJSON(geojson, options); return L.geoJSON(geojson, options);
@ -15,11 +15,11 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
// File size limit in kb (default: 1024) ? // File size limit in kb (default: 1024) ?
fileSizeLimit: 1024, fileSizeLimit: 1024,
shortcut: { shortcut: {
open: 79 // char code for 'o' open: 79, // char code for 'o'
} },
}, },
_initContainer: function() { _initContainer: function () {
var thisLoader = this.loader; var thisLoader = this.loader;
var fileInput; var fileInput;
@ -40,7 +40,7 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
// Load on file change // Load on file change
fileInput.addEventListener( fileInput.addEventListener(
'change', 'change',
function() { function () {
thisLoader.loadMultiple(this.files); thisLoader.loadMultiple(this.files);
// reset so that the user can upload the same file again if they want to // reset so that the user can upload the same file again if they want to
this.value = ''; this.value = '';
@ -50,7 +50,7 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
var link = L.DomUtil.get('navbarLoadTracks'); var link = L.DomUtil.get('navbarLoadTracks');
L.DomEvent.disableClickPropagation(link); L.DomEvent.disableClickPropagation(link);
L.DomEvent.on(link, 'click', function(e) { L.DomEvent.on(link, 'click', function (e) {
fileInput.click(); fileInput.click();
e.preventDefault(); e.preventDefault();
}); });
@ -60,7 +60,7 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
return dummy; return dummy;
}, },
_keydownListener: function(e) { _keydownListener: function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.open) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.open) {
if (e.shiftKey) { if (e.shiftKey) {
$('#loadNogos').modal('show'); $('#loadNogos').modal('show');
@ -68,12 +68,12 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
$('#navbarLoadTracks')[0].click(); $('#navbarLoadTracks')[0].click();
} }
} }
} },
}); });
var tracksLoaderControl = new TracksLoader(); var tracksLoaderControl = new TracksLoader();
tracksLoaderControl.addTo(map); tracksLoaderControl.addTo(map);
tracksLoaderControl.loader.on('data:loaded', function(event) { tracksLoaderControl.loader.on('data:loaded', function (event) {
var eventLayer = event.layer, var eventLayer = event.layer,
routingMarkers = []; routingMarkers = [];
/* disabled for now, see issue #254 /* disabled for now, see issue #254
@ -101,11 +101,11 @@ BR.tracksLoader = function(map, layersControl, routing, pois) {
eventLayer.addTo(map); eventLayer.addTo(map);
}); });
tracksLoaderControl.loader.on('data:error', function(event) { tracksLoaderControl.loader.on('data:error', function (event) {
var err = event.error; var err = event.error;
BR.message.showError( BR.message.showError(
i18next.t('warning.tracks-load-error', { i18next.t('warning.tracks-load-error', {
error: err && err.message ? err.message : err error: err && err.message ? err.message : err,
}) })
); );
console.error(err); console.error(err);

View file

@ -24,7 +24,7 @@
*/ */
L.DistanceMarkers = L.LayerGroup.extend({ L.DistanceMarkers = L.LayerGroup.extend({
initialize: function(line, map, options) { initialize: function (line, map, options) {
options = options || {}; options = options || {};
var offset = options.offset || 1000; var offset = options.offset || 1000;
var showAll = Math.min(map.getMaxZoom(), options.showAll || 12); var showAll = Math.min(map.getMaxZoom(), options.showAll || 12);
@ -32,7 +32,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
var iconSize = options.iconSize !== undefined ? options.iconSize : [12, 12]; var iconSize = options.iconSize !== undefined ? options.iconSize : [12, 12];
var textFunction = var textFunction =
options.textFunction || options.textFunction ||
function(distance, i) { function (distance, i) {
return i; return i;
}; };
@ -81,7 +81,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
var currentZoomLevel = 0; var currentZoomLevel = 0;
var markerLayer = this; var markerLayer = this;
var updateMarkerVisibility = function() { var updateMarkerVisibility = function () {
var oldZoom = currentZoomLevel; var oldZoom = currentZoomLevel;
var newZoom = (currentZoomLevel = map.getZoom()); var newZoom = (currentZoomLevel = map.getZoom());
@ -106,20 +106,20 @@ L.DistanceMarkers = L.LayerGroup.extend({
updateMarkerVisibility(); updateMarkerVisibility();
}, },
setOpacity: function(opacity) { setOpacity: function (opacity) {
var i, var i,
keys = Object.keys(this._zoomLayers), keys = Object.keys(this._zoomLayers),
l = keys.length; l = keys.length;
for (i = 0; i < l; ++i) { for (i = 0; i < l; ++i) {
var zoomLayer = this._zoomLayers[keys[i]]; var zoomLayer = this._zoomLayers[keys[i]];
zoomLayer.eachLayer(function(layer) { zoomLayer.eachLayer(function (layer) {
layer.setOpacity(opacity); layer.setOpacity(opacity);
}); });
} }
}, },
_minimumZoomLevelForItem: function(item, showAllLevel) { _minimumZoomLevelForItem: function (item, showAllLevel) {
var zoom = showAllLevel, var zoom = showAllLevel,
i = item; i = item;
while (i > 0 && i % 2 === 0) { while (i > 0 && i % 2 === 0) {
@ -127,5 +127,5 @@ L.DistanceMarkers = L.LayerGroup.extend({
i = Math.floor(i / 2); i = Math.floor(i / 2);
} }
return zoom; return zoom;
} },
}); });

View file

@ -1,10 +1,10 @@
(function(window) { (function (window) {
var HAS_HASHCHANGE = (function() { var HAS_HASHCHANGE = (function () {
var doc_mode = window.documentMode; 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) { L.Hash = function (map, options) {
this.onHashChange = L.Util.bind(this.onHashChange, this); this.onHashChange = L.Util.bind(this.onHashChange, this);
if (map) { if (map) {
@ -12,7 +12,7 @@
} }
}; };
L.Hash.parseHash = function(hash) { L.Hash.parseHash = function (hash) {
if (hash.indexOf('#map=') === 0) { if (hash.indexOf('#map=') === 0) {
hash = hash.substr(5); hash = hash.substr(5);
} }
@ -31,7 +31,7 @@
center: new L.LatLng(lat, lon), center: new L.LatLng(lat, lon),
zoom: zoom, zoom: zoom,
layers: layers, layers: layers,
additional: additional additional: additional,
}; };
} }
} else { } else {
@ -39,7 +39,7 @@
} }
}; };
(L.Hash.formatHash = function(map) { (L.Hash.formatHash = function (map) {
var center = map.getCenter(), var center = map.getCenter(),
zoom = map.getZoom(), zoom = map.getZoom(),
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)), precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
@ -57,7 +57,7 @@
}), }),
(L.Hash.prototype = { (L.Hash.prototype = {
options: { options: {
layerSeparator: ',' layerSeparator: ',',
}, },
map: null, map: null,
lastHash: null, lastHash: null,
@ -65,7 +65,7 @@
parseHash: L.Hash.parseHash, parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash, formatHash: L.Hash.formatHash,
init: function(map, options) { init: function (map, options) {
this.map = map; this.map = map;
L.Util.setOptions(this, options); L.Util.setOptions(this, options);
@ -78,9 +78,9 @@
} }
}, },
_parseLayers: function(layersParam, layerSeparator) { _parseLayers: function (layersParam, layerSeparator) {
var layers = layersParam.split(layerSeparator).map( var layers = layersParam.split(layerSeparator).map(
L.bind(function(layerEncoded) { L.bind(function (layerEncoded) {
var obj = null; var obj = null;
var layerString = decodeURIComponent(layerEncoded); var layerString = decodeURIComponent(layerEncoded);
@ -95,8 +95,8 @@
return layers; return layers;
}, },
parseLayers: function(layersParam) { parseLayers: function (layersParam) {
var countFoundLayers = function(count, obj) { var countFoundLayers = function (count, obj) {
if (obj) { if (obj) {
count++; count++;
} }
@ -119,14 +119,14 @@
return layers; return layers;
}, },
activateLayers: function(layers) { activateLayers: function (layers) {
var layersControl = this.options.layersControl; var layersControl = this.options.layersControl;
var added = false; var added = false;
layersControl.removeActiveLayers(); layersControl.removeActiveLayers();
layers.forEach( layers.forEach(
L.bind(function(obj, index, array) { L.bind(function (obj, index, array) {
if (obj) { if (obj) {
layersControl.activateLayer(obj); layersControl.activateLayer(obj);
if (obj && !obj.overlay) { if (obj && !obj.overlay) {
@ -142,14 +142,14 @@
} }
}, },
formatLayers: function() { formatLayers: function () {
var objList = this.options.layersControl.getActiveLayers(); var objList = this.options.layersControl.getActiveLayers();
// exclude vector layers (loaded tracks), but not when id set (route quality coding) // exclude vector layers (loaded tracks), but not when id set (route quality coding)
objList = objList.filter(function(obj) { objList = objList.filter(function (obj) {
return obj.layer instanceof L.GridLayer || obj.layer.id; return obj.layer instanceof L.GridLayer || obj.layer.id;
}); });
var layerList = objList.map( var layerList = objList.map(
L.bind(function(obj) { L.bind(function (obj) {
return encodeURIComponent(this.options.layersControl.toLayerString(obj)); return encodeURIComponent(this.options.layersControl.toLayerString(obj));
}, this) }, this)
); );
@ -157,7 +157,7 @@
return layerList.join(this.options.layerSeparator); return layerList.join(this.options.layerSeparator);
}, },
removeFrom: function(map) { removeFrom: function (map) {
if (this.changeTimeout) { if (this.changeTimeout) {
clearTimeout(this.changeTimeout); clearTimeout(this.changeTimeout);
} }
@ -169,7 +169,7 @@
this.map = null; this.map = null;
}, },
onMapMove: function() { onMapMove: function () {
// bail if we're moving the map (updating from a hash), // bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded // or if the map is not yet loaded
@ -185,7 +185,7 @@
}, },
movingMap: false, movingMap: false,
update: function() { update: function () {
var hash = location.hash; var hash = location.hash;
if (hash === this.lastHash) { if (hash === this.lastHash) {
return; return;
@ -221,12 +221,12 @@
// defer hash change updates every 100ms // defer hash change updates every 100ms
changeDefer: 100, changeDefer: 100,
changeTimeout: null, changeTimeout: null,
onHashChange: function() { onHashChange: function () {
// throttle calls to update() so that they only happen every // throttle calls to update() so that they only happen every
// `changeDefer` ms // `changeDefer` ms
if (!this.changeTimeout) { if (!this.changeTimeout) {
var that = this; var that = this;
this.changeTimeout = setTimeout(function() { this.changeTimeout = setTimeout(function () {
that.update(); that.update();
that.changeTimeout = null; that.changeTimeout = null;
}, this.changeDefer); }, this.changeDefer);
@ -235,7 +235,7 @@
isListening: false, isListening: false,
hashChangeInterval: null, hashChangeInterval: null,
startListening: function() { startListening: function () {
this.map.on('moveend layeradd layerremove', this.onMapMove, this); this.map.on('moveend layeradd layerremove', this.onMapMove, this);
if (HAS_HASHCHANGE) { if (HAS_HASHCHANGE) {
@ -247,7 +247,7 @@
this.isListening = true; this.isListening = true;
}, },
stopListening: function() { stopListening: function () {
this.map.off('moveend layeradd layerremove', this.onMapMove, this); this.map.off('moveend layeradd layerremove', this.onMapMove, this);
if (HAS_HASHCHANGE) { if (HAS_HASHCHANGE) {
@ -258,7 +258,7 @@
this.isListening = false; this.isListening = false;
}, },
_keyByValue: function(obj, value) { _keyByValue: function (obj, value) {
for (var key in obj) { for (var key in obj) {
if (obj.hasOwnProperty(key)) { if (obj.hasOwnProperty(key)) {
if (obj[key] === value) { if (obj[key] === value) {
@ -268,15 +268,15 @@
} }
} }
} }
} },
}); });
L.hash = function(map, options) { L.hash = function (map, options) {
return new L.Hash(map, options); return new L.Hash(map, options);
}; };
L.Map.prototype.addHash = function() { L.Map.prototype.addHash = function () {
this._hash = L.hash(this, this.options); this._hash = L.hash(this, this.options);
}; };
L.Map.prototype.removeHash = function() { L.Map.prototype.removeHash = function () {
this._hash.removeFrom(); this._hash.removeFrom();
}; };
})(window); })(window);

View file

@ -1,29 +1,29 @@
BR.stravaSegments = function(map, layersControl) { BR.stravaSegments = function (map, layersControl) {
var stravaControl = L.control var stravaControl = L.control
.stravaSegments({ .stravaSegments({
runningTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-running)', key: 'S' }), runningTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-running)', key: 'S' }),
bikingTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-biking)', key: 'S' }), bikingTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-biking)', key: 'S' }),
loadingTitle: i18next.t('map.loading'), loadingTitle: i18next.t('map.loading'),
stravaToken: BR.keys.strava stravaToken: BR.keys.strava,
}) })
.addTo(map); .addTo(map);
layersControl.addOverlay(stravaControl.stravaLayer, i18next.t('map.layer.strava-segments')); layersControl.addOverlay(stravaControl.stravaLayer, i18next.t('map.layer.strava-segments'));
stravaControl.onError = function(err) { stravaControl.onError = function (err) {
BR.message.showError( BR.message.showError(
i18next.t('warning.strava-error', { i18next.t('warning.strava-error', {
error: err && err.message ? err.message : err error: err && err.message ? err.message : err,
}) })
); );
}; };
L.setOptions(this, { L.setOptions(this, {
shortcut: { shortcut: {
toggleLayer: 83 // char code for 's' toggleLayer: 83, // char code for 's'
} },
}); });
// hide strava buttons when layer is inactive // hide strava buttons when layer is inactive
var toggleStravaControl = function() { var toggleStravaControl = function () {
var stravaBar = stravaControl.runningButton.button.parentElement; var stravaBar = stravaControl.runningButton.button.parentElement;
stravaBar.hidden = !stravaBar.hidden; stravaBar.hidden = !stravaBar.hidden;
}; };
@ -33,7 +33,7 @@ BR.stravaSegments = function(map, layersControl) {
L.DomEvent.addListener( L.DomEvent.addListener(
document, document,
'keydown', 'keydown',
function(e) { function (e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleLayer) { if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleLayer) {
if (map.hasLayer(stravaControl.stravaLayer)) { if (map.hasLayer(stravaControl.stravaLayer)) {
map.removeLayer(stravaControl.stravaLayer); map.removeLayer(stravaControl.stravaLayer);

View file

@ -3,46 +3,46 @@ L.BRouter = L.Class.extend({
// NOTE: the routing API used here is not public! // 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 // /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: URL_TEMPLATE:
'/brouter?lonlats={lonlats}&nogos={nogos}&polylines={polylines}&polygons={polygons}&profile={profile}&alternativeidx={alternativeidx}&format={format}', '/brouter?lonlats={lonlats}&profile={profile}&alternativeidx={alternativeidx}&format={format}&nogos={nogos}&polylines={polylines}&polygons={polygons}',
URL_PROFILE_UPLOAD: BR.conf.host + '/brouter/profile', URL_PROFILE_UPLOAD: BR.conf.host + '/brouter/profile',
PRECISION: 6, PRECISION: 6,
NUMBER_SEPARATOR: ',', NUMBER_SEPARATOR: ',',
GROUP_SEPARATOR: '|', GROUP_SEPARATOR: '|',
ABORTED_ERROR: 'aborted', ABORTED_ERROR: 'aborted',
CUSTOM_PREFIX: 'custom_', CUSTOM_PREFIX: 'custom_',
isCustomProfile: function(profileName) { isCustomProfile: function (profileName) {
return profileName && profileName.substring(0, 7) === L.BRouter.CUSTOM_PREFIX; return profileName && profileName.substring(0, 7) === L.BRouter.CUSTOM_PREFIX;
} },
}, },
options: {}, options: {},
initialize: function(options) { initialize: function (options) {
L.setOptions(this, options); L.setOptions(this, options);
this.queue = async.queue( this.queue = async.queue(
L.bind(function(task, callback) { L.bind(function (task, callback) {
this.getRoute(task.segment, callback); this.getRoute(task.segment, callback);
}, this), }, this),
1 1
); );
// patch to call callbacks on kill for cleanup (loadingTrailer) // patch to call callbacks on kill for cleanup (loadingTrailer)
this.queue.kill = function() { this.queue.kill = function () {
var aborted = this.tasks; var aborted = this.tasks;
this.drain = null; this.drain = null;
this.tasks = []; this.tasks = [];
aborted.forEach(function(task) { aborted.forEach(function (task) {
task.callback(L.BRouter.ABORTED_ERROR); task.callback(L.BRouter.ABORTED_ERROR);
}); });
}; };
}, },
setOptions: function(options) { setOptions: function (options) {
L.setOptions(this, options); L.setOptions(this, options);
}, },
getUrlParams: function(latLngs, pois, format) { getUrlParams: function (latLngs, pois, circlego, format) {
params = {}; params = {};
if (this._getLonLatsString(latLngs) != null) params.lonlats = this._getLonLatsString(latLngs); if (this._getLonLatsString(latLngs) != null) params.lonlats = this._getLonLatsString(latLngs);
@ -59,6 +59,8 @@ L.BRouter = L.Class.extend({
if (pois && this._getLonLatsNameString(pois) != null) params.pois = this._getLonLatsNameString(pois); if (pois && this._getLonLatsNameString(pois) != null) params.pois = this._getLonLatsNameString(pois);
if (circlego) params.circlego = circlego;
params.alternativeidx = this.options.alternative; params.alternativeidx = this.options.alternative;
if (format != null) { if (format != null) {
@ -77,7 +79,7 @@ L.BRouter = L.Class.extend({
return params; return params;
}, },
parseUrlParams: function(params) { parseUrlParams: function (params) {
var opts = {}; var opts = {};
if (params.lonlats) { if (params.lonlats) {
opts.lonlats = this._parseLonLats(params.lonlats); opts.lonlats = this._parseLonLats(params.lonlats);
@ -100,15 +102,27 @@ L.BRouter = L.Class.extend({
if (params.pois) { if (params.pois) {
opts.pois = this._parseLonLatNames(params.pois); opts.pois = this._parseLonLatNames(params.pois);
} }
if (params.circlego) {
var circlego = params.circlego.split(',');
if (circlego.length == 3) {
circlego = [
Number.parseFloat(circlego[0]),
Number.parseFloat(circlego[1]),
Number.parseInt(circlego[2]),
];
opts.circlego = circlego;
}
}
return opts; return opts;
}, },
getUrl: function(latLngs, pois, format, trackname, exportWaypoints) { getUrl: function (latLngs, pois, circlego, format, trackname, exportWaypoints) {
var urlParams = this.getUrlParams(latLngs, pois, format); var urlParams = this.getUrlParams(latLngs, pois, circlego, format);
var args = []; var args = [];
if (urlParams.lonlats != null && urlParams.lonlats.length > 0) if (urlParams.lonlats != null && urlParams.lonlats.length > 0)
args.push(L.Util.template('lonlats={lonlats}', urlParams)); args.push(L.Util.template('lonlats={lonlats}', urlParams));
if (urlParams.pois != null && urlParams.pois.length > 0) args.push(L.Util.template('pois={pois}', urlParams)); if (urlParams.pois != null && urlParams.pois.length > 0) args.push(L.Util.template('pois={pois}', urlParams));
if (urlParams.circlego != null) args.push(L.Util.template('circlego={circlego}', urlParams));
if (urlParams.nogos != null) args.push(L.Util.template('nogos={nogos}', urlParams)); if (urlParams.nogos != null) args.push(L.Util.template('nogos={nogos}', urlParams));
if (urlParams.polylines != null) args.push(L.Util.template('polylines={polylines}', urlParams)); if (urlParams.polylines != null) args.push(L.Util.template('polylines={polylines}', urlParams));
if (urlParams.polygons != null) args.push(L.Util.template('polygons={polygons}', urlParams)); if (urlParams.polygons != null) args.push(L.Util.template('polygons={polygons}', urlParams));
@ -118,7 +132,7 @@ L.BRouter = L.Class.extend({
if (trackname) if (trackname)
args.push( args.push(
L.Util.template('trackname={trackname}', { L.Util.template('trackname={trackname}', {
trackname: trackname trackname: trackname,
}) })
); );
if (exportWaypoints) args.push('exportWaypoints=1'); if (exportWaypoints) args.push('exportWaypoints=1');
@ -128,8 +142,8 @@ L.BRouter = L.Class.extend({
return (prepend_host ? BR.conf.host : '') + '/brouter?' + args.join('&'); return (prepend_host ? BR.conf.host : '') + '/brouter?' + args.join('&');
}, },
getRoute: function(latLngs, cb) { getRoute: function (latLngs, cb) {
var url = this.getUrl(latLngs, null, 'geojson'), var url = this.getUrl(latLngs, null, null, 'geojson'),
xhr = new XMLHttpRequest(); xhr = new XMLHttpRequest();
if (!url) { if (!url) {
@ -139,7 +153,7 @@ L.BRouter = L.Class.extend({
xhr.open('GET', url, true); xhr.open('GET', url, true);
xhr.onload = L.bind(this._handleRouteResponse, this, xhr, cb); xhr.onload = L.bind(this._handleRouteResponse, this, xhr, cb);
xhr.onerror = L.bind( xhr.onerror = L.bind(
function(xhr, cb) { function (xhr, cb) {
cb(BR.Util.getError(xhr)); cb(BR.Util.getError(xhr));
}, },
this, this,
@ -149,7 +163,7 @@ L.BRouter = L.Class.extend({
xhr.send(); xhr.send();
}, },
_handleRouteResponse: function(xhr, cb) { _handleRouteResponse: function (xhr, cb) {
var layer, geojson; var layer, geojson;
if ( if (
@ -175,11 +189,11 @@ L.BRouter = L.Class.extend({
} }
}, },
getRouteSegment: function(l1, l2, cb) { getRouteSegment: function (l1, l2, cb) {
this.queue.push({ segment: [l1, l2] }, cb); this.queue.push({ segment: [l1, l2] }, cb);
}, },
uploadProfile: function(profileId, profileText, cb) { uploadProfile: function (profileId, profileText, cb) {
var url = L.BRouter.URL_PROFILE_UPLOAD; var url = L.BRouter.URL_PROFILE_UPLOAD;
xhr = new XMLHttpRequest(); xhr = new XMLHttpRequest();
@ -190,7 +204,7 @@ L.BRouter = L.Class.extend({
xhr.open('POST', url, true); xhr.open('POST', url, true);
xhr.onload = L.bind(this._handleProfileResponse, this, xhr, cb); xhr.onload = L.bind(this._handleProfileResponse, this, xhr, cb);
xhr.onerror = function(evt) { xhr.onerror = function (evt) {
var xhr = this; var xhr = this;
cb(i18next.t('warning.upload-error', { error: xhr.statusText })); cb(i18next.t('warning.upload-error', { error: xhr.statusText }));
}; };
@ -199,7 +213,7 @@ L.BRouter = L.Class.extend({
xhr.send(profileText); xhr.send(profileText);
}, },
_assignFeatures: function(segment) { _assignFeatures: function (segment) {
if (segment.feature.properties.messages) { if (segment.feature.properties.messages) {
var featureMessages = segment.feature.properties.messages, var featureMessages = segment.feature.properties.messages,
segmentLatLngs = segment.getLatLngs(), segmentLatLngs = segment.getLatLngs(),
@ -226,7 +240,7 @@ L.BRouter = L.Class.extend({
return segment; return segment;
}, },
_getFeature: function(featureMessage) { _getFeature: function (featureMessage) {
//["Longitude", "Latitude", "Elevation", "Distance", "CostPerKm", "ElevCost", "TurnCost", "NodeCost", "InitialCost", "WayTags", "NodeTags"] //["Longitude", "Latitude", "Elevation", "Distance", "CostPerKm", "ElevCost", "TurnCost", "NodeCost", "InitialCost", "WayTags", "NodeTags"]
return { return {
cost: { cost: {
@ -234,22 +248,22 @@ L.BRouter = L.Class.extend({
elev: parseInt(featureMessage[5]), elev: parseInt(featureMessage[5]),
turn: parseInt(featureMessage[6]), turn: parseInt(featureMessage[6]),
node: parseInt(featureMessage[7]), node: parseInt(featureMessage[7]),
initial: parseInt(featureMessage[8]) initial: parseInt(featureMessage[8]),
}, },
distance: parseInt(featureMessage[3]), distance: parseInt(featureMessage[3]),
wayTags: featureMessage[9], wayTags: featureMessage[9],
nodeTags: featureMessage[10] nodeTags: featureMessage[10],
}; };
}, },
_getFeatureLatLng: function(message) { _getFeatureLatLng: function (message) {
var lon = message[0] / 1000000, var lon = message[0] / 1000000,
lat = message[1] / 1000000; lat = message[1] / 1000000;
return L.latLng(lat, lon); return L.latLng(lat, lon);
}, },
_handleProfileResponse: function(xhr, cb) { _handleProfileResponse: function (xhr, cb) {
var response; var response;
if (xhr.status === 200 && xhr.responseText && xhr.responseText.length > 0) { if (xhr.status === 200 && xhr.responseText && xhr.responseText.length > 0) {
@ -260,7 +274,7 @@ L.BRouter = L.Class.extend({
} }
}, },
_getLonLatsString: function(latLngs) { _getLonLatsString: function (latLngs) {
var s = ''; var s = '';
for (var i = 0; i < latLngs.length; i++) { for (var i = 0; i < latLngs.length; i++) {
s += this._formatLatLng(latLngs[i]); s += this._formatLatLng(latLngs[i]);
@ -271,7 +285,7 @@ L.BRouter = L.Class.extend({
return s; return s;
}, },
_parseLonLats: function(s) { _parseLonLats: function (s) {
var groups, var groups,
numbers, numbers,
lonlats = []; lonlats = [];
@ -290,7 +304,7 @@ L.BRouter = L.Class.extend({
return lonlats; return lonlats;
}, },
_getLonLatsNameString: function(latLngNames) { _getLonLatsNameString: function (latLngNames) {
var s = ''; var s = '';
for (var i = 0; i < latLngNames.length; i++) { for (var i = 0; i < latLngNames.length; i++) {
s += this._formatLatLng(latLngNames[i].latlng); s += this._formatLatLng(latLngNames[i].latlng);
@ -304,7 +318,7 @@ L.BRouter = L.Class.extend({
return s; return s;
}, },
_parseLonLatNames: function(s) { _parseLonLatNames: function (s) {
var groups, var groups,
part, part,
lonlatnames = []; lonlatnames = [];
@ -323,7 +337,7 @@ L.BRouter = L.Class.extend({
return lonlatnames; return lonlatnames;
}, },
_getNogosString: function(nogos) { _getNogosString: function (nogos) {
var s = ''; var s = '';
for (var i = 0, circle; i < nogos.length; i++) { for (var i = 0, circle; i < nogos.length; i++) {
circle = nogos[i]; circle = nogos[i];
@ -346,7 +360,7 @@ L.BRouter = L.Class.extend({
return s; return s;
}, },
_parseNogos: function(s) { _parseNogos: function (s) {
var groups, var groups,
numbers, numbers,
nogos = []; nogos = [];
@ -372,7 +386,7 @@ L.BRouter = L.Class.extend({
return nogos; return nogos;
}, },
_getNogosPolylinesString: function(nogos) { _getNogosPolylinesString: function (nogos) {
var s = ''; var s = '';
for (var i = 0, polyline, vertices; i < nogos.length; i++) { for (var i = 0, polyline, vertices; i < nogos.length; i++) {
polyline = nogos[i]; polyline = nogos[i];
@ -399,7 +413,7 @@ L.BRouter = L.Class.extend({
return s; return s;
}, },
_parseNogosPolylines: function(s) { _parseNogosPolylines: function (s) {
var groups, var groups,
numbers, numbers,
latlngs, latlngs,
@ -425,7 +439,7 @@ L.BRouter = L.Class.extend({
return nogos; return nogos;
}, },
_getNogosPolygonsString: function(nogos) { _getNogosPolygonsString: function (nogos) {
var s = ''; var s = '';
for (var i = 0, polygon, vertices; i < nogos.length; i++) { for (var i = 0, polygon, vertices; i < nogos.length; i++) {
polygon = nogos[i]; polygon = nogos[i];
@ -452,7 +466,7 @@ L.BRouter = L.Class.extend({
return s; return s;
}, },
_parseNogosPolygons: function(s) { _parseNogosPolygons: function (s) {
var groups, var groups,
numbers, numbers,
latlngs, latlngs,
@ -479,15 +493,15 @@ L.BRouter = L.Class.extend({
}, },
// formats L.LatLng object as lng,lat string // formats L.LatLng object as lng,lat string
_formatLatLng: function(latLng) { _formatLatLng: function (latLng) {
var s = ''; var s = '';
s += L.Util.formatNum(latLng.lng || latLng[1], L.BRouter.PRECISION); s += L.Util.formatNum(latLng.lng || latLng[1], L.BRouter.PRECISION);
s += L.BRouter.NUMBER_SEPARATOR; s += L.BRouter.NUMBER_SEPARATOR;
s += L.Util.formatNum(latLng.lat || latLng[0], L.BRouter.PRECISION); s += L.Util.formatNum(latLng.lat || latLng[0], L.BRouter.PRECISION);
return s; return s;
} },
}); });
L.bRouter = function(options) { L.bRouter = function (options) {
return new L.BRouter(options); return new L.BRouter(options);
}; };

View file

@ -1,6 +1,6 @@
// BRouter online demo interface // BRouter online demo interface
// TODO remove or adopt to new structure (only supports two waypoints!) // TODO remove or adopt to new structure (only supports two waypoints!)
var brouterCgi = (function() { var brouterCgi = (function () {
// http://brouter.de/cgi-bin/brouter.sh?coords=13.404681_52.520185_13.340278_52.512356_trekking_0 // http://brouter.de/cgi-bin/brouter.sh?coords=13.404681_52.520185_13.340278_52.512356_trekking_0
//var URL_TEMPLATE = '/cgi-bin/proxy.cgi?url=' + 'http://brouter.de/cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}'; //var URL_TEMPLATE = '/cgi-bin/proxy.cgi?url=' + 'http://brouter.de/cgi-bin/brouter.sh?coords={fromLng}_{fromLat}_{toLng}_{toLat}_{profile}_{alt}';
var URL_TEMPLATE = var URL_TEMPLATE =
@ -15,7 +15,7 @@ var brouterCgi = (function() {
toLat: L.Util.formatNum(latLngs[1].lat, PRECISION), toLat: L.Util.formatNum(latLngs[1].lat, PRECISION),
toLng: L.Util.formatNum(latLngs[1].lng, PRECISION), toLng: L.Util.formatNum(latLngs[1].lng, PRECISION),
profile: 'trekking', profile: 'trekking',
alt: '0' alt: '0',
}; };
var url = L.Util.template(URL_TEMPLATE, urlParams); var url = L.Util.template(URL_TEMPLATE, urlParams);
//console.log(url); //console.log(url);
@ -24,6 +24,6 @@ var brouterCgi = (function() {
} }
return { return {
getUrl: getUrl getUrl: getUrl,
}; };
})(); })();

View file

@ -9,29 +9,29 @@ BR.Track = {
* *
* @returns {Object} to pass as `options` parameter to `L.geoJson` * @returns {Object} to pass as `options` parameter to `L.geoJson`
*/ */
getGeoJsonOptions: function(layersControl) { getGeoJsonOptions: function (layersControl) {
return { return {
style: function(geoJsonFeature) { style: function (geoJsonFeature) {
var currentLayerId = layersControl.getActiveBaseLayer().layer.id; var currentLayerId = layersControl.getActiveBaseLayer().layer.id;
return { return {
color: currentLayerId === 'cyclosm' ? 'yellow' : 'blue', color: currentLayerId === 'cyclosm' ? 'yellow' : 'blue',
weight: 4 weight: 4,
}; };
}, },
interactive: false, interactive: false,
filter: function(geoJsonFeature) { filter: function (geoJsonFeature) {
// remove POIs, added separately // remove POIs, added separately
return !BR.Track.isPoiPoint(geoJsonFeature); return !BR.Track.isPoiPoint(geoJsonFeature);
}, },
pointToLayer: function(geoJsonPoint, latlng) { pointToLayer: function (geoJsonPoint, latlng) {
// route waypoint (type=from/via/to) // route waypoint (type=from/via/to)
return L.marker(latlng, { return L.marker(latlng, {
interactive: false, interactive: false,
opacity: 0.7, opacity: 0.7,
// prevent being on top of route markers // prevent being on top of route markers
zIndexOffset: -1000 zIndexOffset: -1000,
}); });
} },
}; };
}, },
@ -41,8 +41,8 @@ BR.Track = {
* @param {BR.PoiMarkers} pois POI control instance * @param {BR.PoiMarkers} pois POI control instance
* @param {Object} geoJson GeoJSON object * @param {Object} geoJson GeoJSON object
*/ */
addPoiMarkers: function(pois, geoJson) { addPoiMarkers: function (pois, geoJson) {
turf.featureEach(geoJson, function(feature, idx) { turf.featureEach(geoJson, function (feature, idx) {
if (BR.Track.isPoiPoint(feature)) { if (BR.Track.isPoiPoint(feature)) {
var coord = turf.getCoord(feature); var coord = turf.getCoord(feature);
var latlng = L.GeoJSON.coordsToLatLng(coord); var latlng = L.GeoJSON.coordsToLatLng(coord);
@ -61,7 +61,7 @@ BR.Track = {
* *
* @param {Object} geoJsonPointFeature GeoJSON Point feature * @param {Object} geoJsonPointFeature GeoJSON Point feature
*/ */
isRouteWaypoint: function(geoJsonPointFeature) { isRouteWaypoint: function (geoJsonPointFeature) {
var props = geoJsonPointFeature.properties; var props = geoJsonPointFeature.properties;
if (props && props.type) { if (props && props.type) {
var wptType = props.type; var wptType = props.type;
@ -77,7 +77,7 @@ BR.Track = {
* *
* @param {Object} geoJsonFeature GeoJSON feature * @param {Object} geoJsonFeature GeoJSON feature
*/ */
isPoiPoint: function(geoJsonFeature) { isPoiPoint: function (geoJsonFeature) {
return turf.getType(geoJsonFeature) === 'Point' && !BR.Track.isRouteWaypoint(geoJsonFeature); return turf.getType(geoJsonFeature) === 'Point' && !BR.Track.isRouteWaypoint(geoJsonFeature);
} },
}; };

View file

@ -17,7 +17,7 @@ BR.TrackEdges = L.Class.extend({
/** /**
* @param {Array} segments * @param {Array} segments
*/ */
initialize: function(segments) { initialize: function (segments) {
this.edges = this.getTrackEdges(segments); this.edges = this.getTrackEdges(segments);
}, },
@ -30,7 +30,7 @@ BR.TrackEdges = L.Class.extend({
* *
* @return {number[]} * @return {number[]}
*/ */
getTrackEdges: function(segments) { getTrackEdges: function (segments) {
var messages, var messages,
segLatLngs, segLatLngs,
length, length,
@ -70,10 +70,10 @@ BR.TrackEdges = L.Class.extend({
return edges; return edges;
}, },
getMessageLatLng: function(message) { getMessageLatLng: function (message) {
var lon = message[0] / 1000000, var lon = message[0] / 1000000,
lat = message[1] / 1000000; lat = message[1] / 1000000;
return L.latLng(lat, lon); return L.latLng(lat, lon);
} },
}); });

View file

@ -1,4 +1,4 @@
(function() { (function () {
// COPYING: Please get your own API keys from the sites listed below // COPYING: Please get your own API keys from the sites listed below
BR.keys = { BR.keys = {
@ -15,6 +15,6 @@
strava: '', strava: '',
// OpenMapSurfer (OpenRouteService API), https://openrouteservice.org/plans/ // OpenMapSurfer (OpenRouteService API), https://openrouteservice.org/plans/
openrouteservice: '' openrouteservice: '',
}; };
})(); })();

282
locales/ca.json Normal file
View file

@ -0,0 +1,282 @@
{
"about": {
"bug-reports": "Informes d'errors i petició de funcionalitats:",
"bug-reports-back": "servidor / dorsal, motor d'itineraris, aplicació Android, web brouter.de",
"bug-reports-front": "client web / frontal.",
"chat": "Xat amb usuaris i desenvolupadors",
"contact": "Contacte:",
"contact-language": "L'idioma preferit és l'anglès, ja que tenim tant contribuïdors com usuaris d'arreu del món.",
"data": "Dades:",
"data-description": "Això està basat en <a href=\"https://www.openstreetmap.org\" target=\"_blank\">OpenStreetMap</a>. Normalment s'actualitza diàriament, veure les dates a <a href=\"https://brouter.de/brouter/segments4/\" target=\"_blank\">fitxers de dades</a>.",
"description": "Serveis en línia del motor d'itineraris BRouter. Per l'aplicació Android fora de línia i més informació, veure <a href=\"https://brouter.de/\" target=\"_blank\">brouter.de</a>",
"details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Política de privacitat</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Crèdits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Registre de canvis</a></i> i\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">més informació</a></i> sobre el client.",
"support": "Debats generals/preguntes, suport",
"title": "Quant a",
"tooltip": "Mostra més informació sobre BRouter-Web"
},
"credits": {
"brouter": "BRouter",
"brouter-license": "<a target=\"_blank\" href=\"https://brouter.de/brouter\">BRouter</a> &copy; Arndt Brenschede",
"elevation-data": "Dades d'elevació",
"esri-license": "<a target=\"_blank\" href=\"http://goto.arcgisonline.com/maps/World_Imagery\">Imatgeria del món</a> &copy; <a target=\"_blank\" href=\"https://www.esri.com/\">Esri</a>, fonts: Esri, DigitalGlobe, Earthstar Geographics, CNES/Airbus DS, GeoEye, USDA FSA, USGS, Getmapping, Aerogrid, IGN, IGP, i la comunitat d'usuaris de SIG",
"esri-tiles": "Imatgeria del món d'Esri",
"map-data": "Dades del mapa",
"map-tiles": "Tessel·les del mapa",
"nominatim": "Cerca per <a href=\"https://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\" data-i18n=\"credits.nominatim\">Nominatim</a>",
"openstreetmap": "&copy; <a target=\"_blank\" href=\"https://www.openstreetmap.org/copyright\" >contribuïdors d'OpenStreetMap</a> sota <a target=\"_blank\" href=\"https://opendatacommons.org/licenses/odbl/\" >ODbL</a>"
},
"export": {
"format": "Format",
"format_csv": "CSV",
"format_geojson": "GeoJSON",
"format_gpx": "GPX",
"format_kml": "KML",
"include": "Inclou",
"include_waypoints": "Fites",
"route-from-to": "{{from}} -> {{to}} ({{distance}}km)",
"route-loop": "{{from}} ({{distance}}km)",
"title": "Exporta la ruta",
"trackname": "Nom"
},
"footer": {
"ascend": "Desnivell acumulat",
"cost": "Cost",
"distance": "Distància",
"elevation-chart": "Commuta el gràfic d'elevació",
"energy-per-100km": "Energia per 100 km",
"hours": "hores",
"hours-abbrev": "h",
"kilometer": "kilòmetres",
"kilometer-abbrev": "km",
"kilowatthour": "kilowatts hora",
"kilowatthour-abbrev": "kWh",
"mean-cost-factor": "Factor de cost mitjà",
"meter": "metres",
"meter-abbrev": "m",
"plain-ascend": "Desnivell final",
"stats-info": "Comenceu a dibuixar una ruta per obtenir les estadístiques",
"total-energy": "Energia total",
"travel-time": "Temps de viatge"
},
"keyboard": {
"backspace": "Retrocés",
"escape": "Esc",
"generic-shortcut": "{{action}} ({{key}} tecla)",
"shift": "Majúscules"
},
"layers": {
"add-base": "Afegeix una capa base",
"add-overlay": "Afegeix superposició",
"customize": "Personalitza les capes",
"opacity-slider": "Control lliscant de l'opacitat",
"placeholder-layer-name": "Nom de la capa personalitzada. (eg: OpenStreetMap)",
"placeholder-layer-url": "URL de la capa personalitzada. (eg: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png)",
"remove-selection": "Elimina la selecció"
},
"loadNogos": {
"defaultProperties": "Propietats per defecte",
"file": "Fitxer (.geojson):",
"load": "Carrega",
"nogoBuffer": "Zona d'influència de les àrees omeses (en metres):",
"nogoRadius": "Radi de les àrees omeses per punts (en metres)",
"nogoWeight": "Pes de les àrees omeses (-1 vol dir inaccessible)",
"source": "Font",
"title": "Carrega les àrees omeses",
"url": "URL: "
},
"map": {
"attribution-osm-long": "Contribuidors de l'OpenStreetMap",
"attribution-osm-short": "OpenStreetMap",
"clear-route": "Neteja les dades de la ruta",
"copyright": "Copyright",
"cycling": "Ciclisme",
"delete-last-point": "Esborra l'últim punt",
"delete-nogo-areas": "Esborra totes les àrees omeses",
"delete-pois": "Esborra tots els punts d'interès",
"delete-route": "Esborra la ruta",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Dibuixa punts d'interès",
"draw-poi-stop": "Para de dibuixar punts d'interès",
"draw-route-start": "Dibuixa una ruta",
"draw-route-stop": "Para de dibuixar la ruta",
"enter-poi-name": "Introdueix el nom del punt d'interès",
"geocoder": "Cerca",
"geocoder-placeholder": "Cerca...",
"hikebike-hillshading": "Ombreig del relleu ",
"hiking": "Excursionisme",
"layer": {
"bing": "Bing aeri",
"cycle": "OpenCycleMap (Thunderf.)",
"cycling": "Bici (camins marcats)",
"digitalglobe": "Imatgeria recent de DigitalGlobe",
"esri": "Imatgeria del món d'Esri",
"hikebike-hillshading": "Ombreig del relleu (mapa per caminades i bici)",
"hiking": "Caminada (camins marcats)",
"osm": "OpenStreetMap",
"osmde": "OpenStreetMap.de",
"outdoors": "Aire lliure (Thunderforest)",
"route-quality": "Codificació de la qualitat de la ruta",
"stamen-terrain": "Terreny (Stamen)",
"strava-segments": "Segments de Strava",
"topo": "OpenTopoMap"
},
"loading": "Carregant...",
"locate-me": "Mostra'm on sóc",
"nogo": {
"cancel": "Cancel·la el dibuix d'àrees omeses",
"click-drag": "Cliqueu i arrossegueu per dibuixar un cercle",
"draw": "Dibuixa una àrea omesa circular",
"edit": "Cliqueu per editar",
"help": "&square; = mou / redimensiona, <span class=\"fa fa-trash-o\"></span> = esborra,<br>clique al cercle per deixar d'editar"
},
"opacity-slider": "Especifica la transparència de la ruta i els marcadors",
"opacity-slider-shortcut": "{{action}}\n(Mantén premuda la tecla {{key}} per silenciar temporalment)",
"preview": "Previsualitza",
"privacy": "Privacitat",
"reverse-route": "Capgira la ruta",
"route-quality-altitude": "Codificació de l'altitud",
"route-quality-cost": "Codificació del cost",
"route-quality-incline": "Codificació de la inclinació",
"route-quality-shortcut": "{{action}} ({{key}} tecla per commutar)",
"strava-biking": "Mostra els segments de bici de Strava",
"strava-running": "Mostra els segments de córrer de Strava",
"strava-shortcut": "{{action}}\n(tecla {{key}} per commutar les capes, cliqueu per recarregar l'àrea actual)",
"zoomInTitle": "Apropa",
"zoomOutTitle": "Allunya"
},
"modal": {
"close": "Tanca"
},
"navbar": {
"about": "Quant a",
"alternative": {
"first": "1a alternativa",
"original": "Original",
"second": "2a alternativa",
"third": "3a alternativa"
},
"export": "Exporta",
"export-tooltip": "Exporta la ruta",
"load": {
"nogos": "Carrega les àrees omeses",
"title": "Carrega",
"tooltip": "{{tracksAction}} (tecla {{tracksKey}})\n{{nogosAction}} ({{nogosKey}})",
"tracks": "Carrega traces"
},
"profile": {
"car-eco": "Cotxe (econòmic)",
"car-fast": "Cotxe (ràpid)",
"car-test": "Cotxe (test)",
"custom": "Personalitzat",
"fastbike": "Bici ràpida",
"fastbike-asia-pacific": "Bici ràpida (Àsia Pacífic)",
"fastbike-lowtraffic": "Bici ràpida (poc trànsit)",
"hiking-beta": "Excursionisme (beta)",
"moped": "Ciclomotor",
"rail": "Via",
"river": "Riu",
"safety": "Seguretat",
"shortest": "El més curt",
"trekking": "Trescar amb bici",
"trekking-ignore-cr": "Trescar amb bici (ignora les rutes de bici)",
"trekking-noferries": "Trescar amb bici (sense ferris)",
"trekking-nosteps": "Trescar amb bici (sense graons)",
"trekking-steep": "Trescar amb bici (dret)",
"vm-forum-liegerad-schnell": "Trescar amb bici (ràpid)",
"vm-forum-velomobil-schnell": "Velomobile (ràpid)"
},
"profile-tooltip": "\n(tecla {{key}} per canviar)"
},
"sidebar": {
"analysis": {
"header": {
"highway": "Autopista",
"smoothness": "Suavitat",
"surface": "Superfície"
},
"table": {
"category": "Categoria",
"length": "Longitud",
"total_known": "Total conegut:",
"unknown": "Desconegut"
},
"title": "Anàlisi",
"tooltip": "Analitza la ruta"
},
"customize-profile": {
"title": "Personalitza el perfil",
"tooltip": "Personalitza el perfil"
},
"data": {
"sync-map": "Sincronitza el mapa",
"title": "Dades",
"tooltip": "Mostra la taula de dades detallades de la ruta"
},
"itinerary": {
"title": "Itinerari",
"tooltip": "Mostra l'itinerari"
},
"layers": {
"category": {
"base-layers": "Capes base",
"country": "País",
"europe": "Europa",
"europe-monolingual": "Europa monolingüe",
"overlays": "Superposicions",
"worldwide": "Arreu del món",
"worldwide-international": "Arreu del món internacional",
"worldwide-monolingual": "Arreu del món monolígüe"
},
"collapse": "Col·lapsa-ho tot",
"custom-layers": "Capes personalitzades",
"customize": "Afegeix o elimina capes personalitzades",
"expand": "Expandeix-ho tot",
"optional": "Afegeix o elimina capes opcionals",
"optional-layers": "Més",
"overlay-opacity": "Transparència de la superposició",
"table": {
"URL": "URL",
"empty": "Encara no hi ha cap capa personalitzada configurada.",
"name": "Nom",
"type": "Tipus"
},
"title": "Capes",
"tooltip": "Seleccioneu capes"
},
"profile": {
"apply": "Aplica",
"clear": "Neteja",
"help": "Ajuda",
"no_easy_configuration_warning": "No hi ha configuració fàcil per aquest perfil.",
"options": "Opcions",
"placeholder": "Escriviu el vostre propi perfil personalitzat aquí",
"profile": "Perfil"
},
"tab-tooltip": "{{action}}\n(tecla {{toggleKey}} per commutar, {{switchKey}} per canviar a la pestanya següent)"
},
"title": "Client web de BRouter",
"trackasroute": {
"explainpoi": "(mostra les fites com a PDI)",
"explaintracklayer": "(mostra traces com a capa separada)",
"file": "Fitxer de traça",
"fuzziness": "grau d'aproximació",
"pleasewait": "Espereu si us plau.",
"showpois": "PDI",
"title": "Carrega una traça com a ruta",
"tracklayer": "Capa de la traça",
"tuning": "Ajust"
},
"warning": {
"cannot-get-route": "Error en obtenir l'URL de la ruta",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "el servidor no respon",
"no-route-found": "Error: no es pot trobar una ruta pels punts donats. Podríeu provar de moure'ls més a prop de carreteres?",
"profile-error": "Error del perfil: cap resposta o resposta buida del servidor",
"strava-error": "Error en obtenir els segments de Strava: {{error}}",
"temporary-profile": "<strong>Nota:</strong> Els perfils personalitzats carregats només es desen temporalment al servidor.<br/>Deseu les vostres edicions al vostre ordinador.",
"tracks-load-error": "Error en carregar les traces: {{error}}",
"upload-error": "Error de càrrega: {{error}}"
}
}

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Alle No-go-Areas löschen", "delete-nogo-areas": "Alle No-go-Areas löschen",
"delete-pois": "Alle POI löschen", "delete-pois": "Alle POI löschen",
"delete-route": "Route löschen", "delete-route": "Route löschen",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "POI einzeichnen", "draw-poi-start": "POI einzeichnen",
"draw-poi-stop": "Einzeichnen der POI beenden", "draw-poi-stop": "Einzeichnen der POI beenden",
"draw-route-start": "Route zeichnen", "draw-route-start": "Route zeichnen",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Fehler beim Abrufen der Routen-URL", "cannot-get-route": "Fehler beim Abrufen der Routen-URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "Keine Antwort vom Server", "no-response": "Keine Antwort vom Server",
"no-route-found": "Fehler: kann für angegebene Punkte keine Route finden. Vielleicht die Punkte näher an Straßen verschieben?", "no-route-found": "Fehler: kann für angegebene Punkte keine Route finden. Vielleicht die Punkte näher an Straßen verschieben?",
"profile-error": "Profil-Fehler: keine oder leere Antwort vom Server", "profile-error": "Profil-Fehler: keine oder leere Antwort vom Server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Eliminar todas las áreas prohibidas", "delete-nogo-areas": "Eliminar todas las áreas prohibidas",
"delete-pois": "Eliminar todos los Puntos de Interés", "delete-pois": "Eliminar todos los Puntos de Interés",
"delete-route": "Eliminar ruta", "delete-route": "Eliminar ruta",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error al obtener la URL de ruta", "cannot-get-route": "Error al obtener la URL de ruta",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "sin respuesta del servidor", "no-response": "sin respuesta del servidor",
"no-route-found": "Error: no se puede encontrar una ruta para los puntos dados. ¿Quizás intentando acercarlos a las carreteras?", "no-route-found": "Error: no se puede encontrar una ruta para los puntos dados. ¿Quizás intentando acercarlos a las carreteras?",
"profile-error": "Error de perfil: no o respuesta vacía del servidor", "profile-error": "Error de perfil: no o respuesta vacía del servidor",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -3,16 +3,16 @@
"bug-reports": "Rapporter un problème ou une amélioration:", "bug-reports": "Rapporter un problème ou une amélioration:",
"bug-reports-back": "serveur, moteur de routage, appli Android, profils, site brouter.de;", "bug-reports-back": "serveur, moteur de routage, appli Android, profils, site brouter.de;",
"bug-reports-front": "client web.", "bug-reports-front": "client web.",
"chat": "Discuter avec d'autres utilisateurs et développeurs", "chat": "Discuter avec d'autres utilisateurs et développeurs ;",
"contact": "Contact:", "contact": "Contact:",
"contact-language": "Preferred language is English, as we have both international contributors and users.", "contact-language": "L'anglais est à privilégier pour les échanges, car les développeurs et utilisateurs viennent du monde entier.",
"data": "Données:", "data": "Données:",
"data-description": "Les données reposent sur <a href=\"https://www.openstreetmap.org\" target=\"_blank\">OpenStreetMap</a>. La mise à jour est généralement quotidienne, voir <a href=\"https://brouter.de/brouter/segments4/\" target=\"_blank\">les fichiers de données</a>. ", "data-description": "Les données reposent sur <a href=\"https://www.openstreetmap.org\" target=\"_blank\">OpenStreetMap</a>. La mise à jour est généralement quotidienne, voir <a href=\"https://brouter.de/brouter/segments4/\" target=\"_blank\">les fichiers de données</a>. ",
"description": "Service web pour le moteur de routage BRouter. Pour l'appli Android et de plus amples informations, voir <a href=\"https://brouter.de/\" target=\"_blank\">brouter.de</a>.", "description": "Service web pour le moteur de routage BRouter. Pour l'appli Android et de plus amples informations, voir <a href=\"https://brouter.de/\" target=\"_blank\">brouter.de</a>.",
"details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Respect de la vie privée</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Crédits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Changements</a></i> et\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">plus d'infos</a></i> sur le client web.", "details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Respect de la vie privée</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Crédits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Changements</a></i> et\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">plus d'infos</a></i> sur le client web.",
"support": "Discussions/Questions générales, support;", "support": "Discussions et questions générales, support;",
"title": "À propos", "title": "À propos",
"tooltip": "Show more information about BRouter-Web" "tooltip": "Afficher plus d'informations à propos de BRouter-Web"
}, },
"credits": { "credits": {
"brouter": "BRouter", "brouter": "BRouter",
@ -42,7 +42,7 @@
"ascend": "Dénivelé cumulé", "ascend": "Dénivelé cumulé",
"cost": "Coût", "cost": "Coût",
"distance": "Distance", "distance": "Distance",
"elevation-chart": "Toggle elevation chart", "elevation-chart": "Inverser l'affichage du profil altimétrique",
"energy-per-100km": "pour 100km", "energy-per-100km": "pour 100km",
"hours": "heures", "hours": "heures",
"hours-abbrev": "h", "hours-abbrev": "h",
@ -59,10 +59,10 @@
"travel-time": "Temps de trajet" "travel-time": "Temps de trajet"
}, },
"keyboard": { "keyboard": {
"backspace": "Backspace", "backspace": "Retour chariot",
"escape": "Escape", "escape": "Échap",
"generic-shortcut": "{{action}} ({{key}} key)", "generic-shortcut": "{{action}} (touche {{key}})",
"shift": "Shift" "shift": "Maj"
}, },
"layers": { "layers": {
"add-base": "Ajouter un fond de carte ", "add-base": "Ajouter un fond de carte ",
@ -94,13 +94,15 @@
"delete-nogo-areas": "Supprimer toutes les zones interdites", "delete-nogo-areas": "Supprimer toutes les zones interdites",
"delete-pois": "Supprimer tous les points d'intérêt ", "delete-pois": "Supprimer tous les points d'intérêt ",
"delete-route": "Supprimer l'itinéraire", "delete-route": "Supprimer l'itinéraire",
"draw-poi-start": "Draw points of interest", "draw-circlego-start": "Ajouter une zone limite de {{radius}} km",
"draw-poi-stop": "Stop drawing points of interest", "draw-circlego-stop": "Arrêter l'ajout d'une zone limite de {{radius}} km",
"draw-route-start": "Draw route", "draw-poi-start": "Ajouter des points d'intérêt",
"draw-route-stop": "Stop drawing route", "draw-poi-stop": "Arrêter l'ajout de points d'intérêt",
"draw-route-start": "Dessiner l'itinéraire",
"draw-route-stop": "Arrêter de dessiner l'itinéraire",
"enter-poi-name": "Saisir le nom du point d'intérêt", "enter-poi-name": "Saisir le nom du point d'intérêt",
"geocoder": "Search", "geocoder": "Rechercher",
"geocoder-placeholder": "Search…", "geocoder-placeholder": "Rechercher…",
"hikebike-hillshading": "Relief avec ombre", "hikebike-hillshading": "Relief avec ombre",
"hiking": "Randonnée", "hiking": "Randonnée",
"layer": { "layer": {
@ -124,22 +126,22 @@
"nogo": { "nogo": {
"cancel": "Annuler la zone interdite", "cancel": "Annuler la zone interdite",
"click-drag": "Cliquer et faire glisser pour dessiner un cercle", "click-drag": "Cliquer et faire glisser pour dessiner un cercle",
"draw": "Draw circular no-go area", "draw": "Dessiner une zone interdite circulaire",
"edit": "Cliquer pour éditer", "edit": "Cliquer pour éditer",
"help": "&square; = déplacer / redimensionner, <span class=\"fa fa-trash-o\"></span> = supprimer,<br>cliquer sur le cercle pour arrêter l'édition" "help": "&square; = déplacer / redimensionner, <span class=\"fa fa-trash-o\"></span> = supprimer,<br>cliquer sur le cercle pour arrêter l'édition"
}, },
"opacity-slider": "Set transparency of route track and markers", "opacity-slider": "Définie l'opacité de l'itinéraire et des marqueurs",
"opacity-slider-shortcut": "{{action}}\n(Hold {{key}} key to mute temporarily)", "opacity-slider-shortcut": "{{action}}\n(Maintenir la touche {{key}} pour masquer temporairement)",
"preview": "Prévisualiser", "preview": "Prévisualiser",
"privacy": "Vie privée", "privacy": "Vie privée",
"reverse-route": "Inverse l'itinéraire", "reverse-route": "Inverse l'itinéraire",
"route-quality-altitude": "Chiffrage de l'altitude", "route-quality-altitude": "Chiffrage de l'altitude",
"route-quality-cost": "Chiffrage du coût", "route-quality-cost": "Chiffrage du coût",
"route-quality-incline": "Chiffrage d'inclinaison", "route-quality-incline": "Chiffrage d'inclinaison",
"route-quality-shortcut": "{{action}} ({{key}} key to toggle)", "route-quality-shortcut": "{{action}} (touche {{key}} pour basculer)",
"strava-biking": "Afficher les segments Strava vélo", "strava-biking": "Afficher les segments Strava vélo",
"strava-running": "Afficher les segments Strava à pied", "strava-running": "Afficher les segments Strava à pied",
"strava-shortcut": "{{action}}\n({{key}} key to toggle layer, click to reload for current area)", "strava-shortcut": "{{action}}\n(touche {{key}} pour basculer de calque, cliquer pour recharger la zone actuelle)",
"zoomInTitle": "Zoomer", "zoomInTitle": "Zoomer",
"zoomOutTitle": "Dézoomer" "zoomOutTitle": "Dézoomer"
}, },
@ -155,12 +157,12 @@
"third": "3ème alternative" "third": "3ème alternative"
}, },
"export": "Exporter", "export": "Exporter",
"export-tooltip": "Export route", "export-tooltip": "Exporter l'itinéraire",
"load": { "load": {
"nogos": "Load no-go areas", "nogos": "Charger des zones interdites",
"title": "Charger", "title": "Charger",
"tooltip": "{{tracksAction}} ({{tracksKey}} key)\n{{nogosAction}} ({{nogosKey}})", "tooltip": "{{tracksAction}} (touche {{tracksKey}} )\n{{nogosAction}} ({{nogosKey}})",
"tracks": "Load tracks" "tracks": "Charger des traces"
}, },
"profile": { "profile": {
"car-eco": "Voiture (économique)", "car-eco": "Voiture (économique)",
@ -184,36 +186,36 @@
"vm-forum-liegerad-schnell": "Vélo couché (rapide)", "vm-forum-liegerad-schnell": "Vélo couché (rapide)",
"vm-forum-velomobil-schnell": "Vélomobile (rapide)" "vm-forum-velomobil-schnell": "Vélomobile (rapide)"
}, },
"profile-tooltip": "\n({{key}} key to switch)" "profile-tooltip": "\n(touche {{key}} pour échanger)"
}, },
"sidebar": { "sidebar": {
"analysis": { "analysis": {
"header": { "header": {
"highway": "Highway", "highway": "Grande route",
"smoothness": "Smoothness", "smoothness": "Qualité de roulage",
"surface": "Surface" "surface": "Revêtement"
}, },
"table": { "table": {
"category": "Category", "category": "Catégorie",
"length": "Length", "length": "Longueur",
"total_known": "Total Known:", "total_known": "Total connu:",
"unknown": "Unknown" "unknown": "Inconnu"
}, },
"title": "Analysis", "title": "Analyse",
"tooltip": "Analyse route" "tooltip": "Analyse de l'itinéraire"
}, },
"customize-profile": { "customize-profile": {
"title": "Personnaliser le profil", "title": "Personnaliser le profil",
"tooltip": "Customize profile" "tooltip": "Personnaliser le profil"
}, },
"data": { "data": {
"sync-map": "Synchroniser la carte", "sync-map": "Synchroniser la carte",
"title": "Données", "title": "Données",
"tooltip": "Show detailed route data table" "tooltip": "Afficher la table des données de l'itinéraire détaillé"
}, },
"itinerary": { "itinerary": {
"title": "Itinéraire", "title": "Itinéraire",
"tooltip": "Show itinerary" "tooltip": "Afficher l'itinéraire"
}, },
"layers": { "layers": {
"category": { "category": {
@ -240,7 +242,7 @@
"type": "Type" "type": "Type"
}, },
"title": "Calques", "title": "Calques",
"tooltip": "Select layers" "tooltip": "Sélection des calques"
}, },
"profile": { "profile": {
"apply": "Appliquer", "apply": "Appliquer",
@ -251,22 +253,24 @@
"placeholder": "Saisissez votre profil personnalisé ici.", "placeholder": "Saisissez votre profil personnalisé ici.",
"profile": "Profil" "profile": "Profil"
}, },
"tab-tooltip": "{{action}}\n({{toggleKey}} key to toggle, {{switchKey}} to switch to next tab)" "tab-tooltip": "{{action}}\n(touche {{toggleKey}} pour basculer, {{switchKey}} pour passer à l'onglet suivant)"
}, },
"title": "Client web BRouter", "title": "Client web BRouter",
"trackasroute": { "trackasroute": {
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(afficher les points de passage comme des PIs)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(afficher la piste comme un calque distinct)",
"file": "Trackfile", "file": "Fichier de piste",
"fuzziness": "fuzzines", "fuzziness": "flou",
"pleasewait": "Please wait!", "pleasewait": "Merci de patienter !",
"showpois": "POI's", "showpois": "PIs",
"title": "Load Track as Route", "title": "Charger la trace comme itinéraire",
"tracklayer": "Track Layer", "tracklayer": "Calque de trace",
"tuning": "Tuning" "tuning": "Réglages"
}, },
"warning": { "warning": {
"cannot-get-route": "Erreur lors de la réception de l'itinéraire", "cannot-get-route": "Erreur lors de la réception de l'itinéraire",
"invalid-route-from": "Le départ est trop éloigné d'une route.",
"invalid-route-to": "L'arrivée est trop éloignée d'une route.",
"no-response": "aucune réponse du serveur", "no-response": "aucune réponse du serveur",
"no-route-found": "Erreur: impossible de trouver un itinéraire correspondant aux points donnés. Essayez peut-être de rapprocher les points des routes?", "no-route-found": "Erreur: impossible de trouver un itinéraire correspondant aux points donnés. Essayez peut-être de rapprocher les points des routes?",
"profile-error": "Erreur de profil: pas de réponse ou réponse invalide du serveur", "profile-error": "Erreur de profil: pas de réponse ou réponse invalide du serveur",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Minden elkerülendő terület törlése", "delete-nogo-areas": "Minden elkerülendő terület törlése",
"delete-pois": "Minden érdekes pont (POI) törlése", "delete-pois": "Minden érdekes pont (POI) törlése",
"delete-route": "Útvonal törlése", "delete-route": "Útvonal törlése",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Érdekes pontok (POI-k) rajzolása", "draw-poi-start": "Érdekes pontok (POI-k) rajzolása",
"draw-poi-stop": "Érdekes pontok rajzolásának megszakítása", "draw-poi-stop": "Érdekes pontok rajzolásának megszakítása",
"draw-route-start": "Útvonal rajzolása", "draw-route-start": "Útvonal rajzolása",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Hiba történt az útvonal URL-jének beolvasásakor", "cannot-get-route": "Hiba történt az útvonal URL-jének beolvasásakor",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "a kiszolgáló nem válaszol", "no-response": "a kiszolgáló nem válaszol",
"no-route-found": "Hiba: az adott pontokhoz nem sikerül útvonalat találni. Esetleg próbálja meg közelebb tenni őket az utakhoz.", "no-route-found": "Hiba: az adott pontokhoz nem sikerül útvonalat találni. Esetleg próbálja meg közelebb tenni őket az utakhoz.",
"profile-error": "Profilhiba: a kiszolgáló nem válaszol vagy üres választ küld", "profile-error": "Profilhiba: a kiszolgáló nem válaszol vagy üres választ küld",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Eyða öllum bannsvæðum", "delete-nogo-areas": "Eyða öllum bannsvæðum",
"delete-pois": "Eyða öllum merkisstöðum", "delete-pois": "Eyða öllum merkisstöðum",
"delete-route": "Eyða leið", "delete-route": "Eyða leið",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Teikna leið", "draw-route-start": "Teikna leið",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Villa við að ná í URL-slóð leiðar", "cannot-get-route": "Villa við að ná í URL-slóð leiðar",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "ekkert svar frá netþjóni", "no-response": "ekkert svar frá netþjóni",
"no-route-found": "Villa: fann ekki leið fyrir uppgefna punkta. Kannski ættirðu að prófa að færa þá nær vegum?", "no-route-found": "Villa: fann ekki leið fyrir uppgefna punkta. Kannski ættirðu að prófa að færa þá nær vegum?",
"profile-error": "Villa í notkunarsniði: ekkert eða tómt svar frá netþjóni", "profile-error": "Villa í notkunarsniði: ekkert eða tómt svar frá netþjóni",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Slett alle no-go områder", "delete-nogo-areas": "Slett alle no-go områder",
"delete-pois": "Slett alle interessepunkter", "delete-pois": "Slett alle interessepunkter",
"delete-route": "Slett rute", "delete-route": "Slett rute",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Feil under mottak av rute-URL", "cannot-get-route": "Feil under mottak av rute-URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "ingen svar fra serveren", "no-response": "ingen svar fra serveren",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Verwijder alle no-go gebieden", "delete-nogo-areas": "Verwijder alle no-go gebieden",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Verwijder route", "delete-route": "Verwijder route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Teken route", "draw-route-start": "Teken route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Fout bij ophalen route URL", "cannot-get-route": "Fout bij ophalen route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "geen antwoord van server", "no-response": "geen antwoord van server",
"no-route-found": "Fout: Kan geen route vinden voor de gegeven punten.\nProbeer de punten dichter bij wegen te plaatsen", "no-route-found": "Fout: Kan geen route vinden voor de gegeven punten.\nProbeer de punten dichter bij wegen te plaatsen",
"profile-error": "Profielfout: geen of leeg antwoord van server", "profile-error": "Profielfout: geen of leeg antwoord van server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Usuń wszystkie strefy no-go", "delete-nogo-areas": "Usuń wszystkie strefy no-go",
"delete-pois": "Usuń wszystkie punkty zainteresowania", "delete-pois": "Usuń wszystkie punkty zainteresowania",
"delete-route": "Usunąć trasę?", "delete-route": "Usunąć trasę?",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Błąd pobierania URL trasy", "cannot-get-route": "Błąd pobierania URL trasy",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "brak odpowiedzi z serwera", "no-response": "brak odpowiedzi z serwera",
"no-route-found": "Błąd: nie można znaleźć trasy dla zadanych punktów. Spróbuj przesunąć je bliżej dróg.", "no-route-found": "Błąd: nie można znaleźć trasy dla zadanych punktów. Spróbuj przesunąć je bliżej dróg.",
"profile-error": "Błąd profilu: brak lub pusta odpowiedź z serwera", "profile-error": "Błąd profilu: brak lub pusta odpowiedź z serwera",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Удалить все запретные зоны", "delete-nogo-areas": "Удалить все запретные зоны",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Удалить маршрут", "delete-route": "Удалить маршрут",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Ошибка при получении URL маршрута", "cannot-get-route": "Ошибка при получении URL маршрута",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "сервер не отвечает", "no-response": "сервер не отвечает",
"no-route-found": "Ошибка: не удается найти маршрут для заданных точек. Может быть, попытаться переместить их ближе к дорогам?", "no-route-found": "Ошибка: не удается найти маршрут для заданных точек. Может быть, попытаться переместить их ближе к дорогам?",
"profile-error": "Ошибка профиля: не удалось получить ответ сервера либо получен пустой ответ.", "profile-error": "Ошибка профиля: не удалось получить ответ сервера либо получен пустой ответ.",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "Error getting route URL", "cannot-get-route": "Error getting route URL",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "no response from server", "no-response": "no response from server",
"no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?", "no-route-found": "Error: cannot find a route for given points. Maybe try to move them closer to roads?",
"profile-error": "Profile error: no or empty response from server", "profile-error": "Profile error: no or empty response from server",

View file

@ -94,6 +94,8 @@
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-circlego-start": "Draw limited {{radius}}km go-to zone",
"draw-circlego-stop": "Stop drawing limited {{radius}}km go-to zone",
"draw-poi-start": "Draw points of interest", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route", "draw-route-start": "Draw route",
@ -258,7 +260,7 @@
"explainpoi": "(show waypoints as POI's)", "explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)", "explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile", "file": "Trackfile",
"fuzziness": "fuzzines", "fuzziness": "fuzziness",
"pleasewait": "Please wait!", "pleasewait": "Please wait!",
"showpois": "POI's", "showpois": "POI's",
"title": "Load Track as Route", "title": "Load Track as Route",
@ -267,6 +269,8 @@
}, },
"warning": { "warning": {
"cannot-get-route": "取得路線URL時發生錯誤", "cannot-get-route": "取得路線URL時發生錯誤",
"invalid-route-from": "Start marker is too far from a route.",
"invalid-route-to": "Destination marker is too far from a route.",
"no-response": "伺服器沒有回應", "no-response": "伺服器沒有回應",
"no-route-found": "錯誤: 無法就給予的端點建立路線。或者嘗試將它們移近至道路附近?", "no-route-found": "錯誤: 無法就給予的端點建立路線。或者嘗試將它們移近至道路附近?",
"profile-error": "設定檔錯誤: 伺服器回傳空值或沒有回應", "profile-error": "設定檔錯誤: 伺服器回傳空值或沒有回應",

View file

@ -1,6 +1,6 @@
{ {
"name": "brouter-web", "name": "brouter-web",
"version": "0.13.0", "version": "0.14.0",
"description": "Web client for BRouter", "description": "Web client for BRouter",
"main": "js/index.js", "main": "js/index.js",
"scripts": { "scripts": {
@ -50,9 +50,9 @@
"datatables": "~1.10.18", "datatables": "~1.10.18",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"geo-data-exchange": "alexcojocaru/geo-data-exchange#v1.1.0", "geo-data-exchange": "alexcojocaru/geo-data-exchange#v1.1.0",
"i18next": "^15.0.4", "i18next": "^19.8.4",
"i18next-browser-languagedetector": "^3.0.1", "i18next-browser-languagedetector": "^6.0.1",
"i18next-xhr-backend": "^2.0.1", "i18next-xhr-backend": "^3.2.2",
"jquery": "3.5.1", "jquery": "3.5.1",
"jquery-i18next": "^1.2.1", "jquery-i18next": "^1.2.1",
"jstree": "^3.3.8", "jstree": "^3.3.8",
@ -73,47 +73,46 @@
"leaflet.snogylop": "^0.4.0", "leaflet.snogylop": "^0.4.0",
"leaflet.stravasegments": "2.3.2", "leaflet.stravasegments": "2.3.2",
"mapbbcode": "MapBBCode/mapbbcode#v1.2.0", "mapbbcode": "MapBBCode/mapbbcode#v1.2.0",
"promise-polyfill": "^8.1.0", "promise-polyfill": "^8.2.0",
"tether": "1.4.5",
"url-search-params": "~0.5.0", "url-search-params": "~0.5.0",
"whatwg-fetch": "^3.0.0" "whatwg-fetch": "^3.5.0"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^8.1.0", "autoprefixer": "^8.1.0",
"browser-sync": "^2.26.7", "browser-sync": "^2.26.13",
"del": "^1.1.1", "del": "^1.1.1",
"eslint": "^6.6.0", "eslint": "^7.15.0",
"eslint-plugin-compat": "^3.3.0", "eslint-plugin-compat": "^3.3.0",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-bump": "^2.7.0", "gulp-bump": "^3.2.0",
"gulp-cached": "^1.0.4", "gulp-cached": "^1.0.4",
"gulp-clean-css": "^4.0.0", "gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.5.2", "gulp-concat": "^2.5.2",
"gulp-confirm": "^1.0.6", "gulp-confirm": "^1.0.6",
"gulp-debug": "^2.0.1", "gulp-debug": "^4.0.0",
"gulp-git": "^2.2.0", "gulp-git": "^2.10.1",
"gulp-github-release": "^1.2.1", "gulp-github-release": "^1.2.1",
"gulp-if": "^2.0.0", "gulp-if": "^3.0.0",
"gulp-inject": "^1.2.0", "gulp-inject": "^5.0.5",
"gulp-json-concat": "^0.1.1", "gulp-json-concat": "^0.1.1",
"gulp-modify-css-urls": "^2.0.0", "gulp-modify-css-urls": "^2.0.0",
"gulp-postcss": "^7.0.1", "gulp-postcss": "^9.0.0",
"gulp-remember": "^0.3.0", "gulp-remember": "^1.0.1",
"gulp-rename": "^1.4.0", "gulp-rename": "^2.0.0",
"gulp-replace": "^0.5.4", "gulp-replace": "^1.0.0",
"gulp-sourcemaps": "^1.5.1", "gulp-sourcemaps": "^3.0.0",
"gulp-uglify": "^1.1.0", "gulp-uglify": "^3.0.2",
"gulp-util": "^3.0.7", "gulp-util": "^3.0.7",
"gulp-zip": "^4.0.0", "gulp-zip": "^5.0.2",
"husky": "^2.3.0", "husky": "^4.3.4",
"i18next-scanner": "^2.9.1", "i18next-scanner": "^3.0.0",
"merge-stream": "^2.0.0", "merge-stream": "^2.0.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"npmfiles": "^0.1.1", "npmfiles": "^0.1.3",
"patch-package": "~6.2.2", "patch-package": "~6.2.2",
"postinstall-postinstall": "~2.1.0", "postinstall-postinstall": "~2.1.0",
"prettier": "^1.17.1", "prettier": "^2.2.1",
"pretty-quick": "^1.10.0" "pretty-quick": "^3.1.0"
}, },
"overrides": { "overrides": {
"leaflet": { "leaflet": {

2507
yarn.lock

File diff suppressed because it is too large Load diff