fancy js
This commit is contained in:
parent
20054971b1
commit
8c88520f8c
82
ofu_app/static/js/donar/navigate.js
Normal file
82
ofu_app/static/js/donar/navigate.js
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Created by michigg on 14.10.17.
|
||||
*/
|
||||
var endLat = '';
|
||||
var endLon = '';
|
||||
var startLat = 49.8955663;
|
||||
var startLon = 10.886907899999999;
|
||||
document.addEventListener('DOMContentLoaded', loadData);
|
||||
document.addEventListener('DOMContentLoaded', resizeMap);
|
||||
document.addEventListener('DOMContentLoaded', getPos);
|
||||
|
||||
|
||||
window.onresize = resizeMap;
|
||||
|
||||
function loadData() {
|
||||
var address = document.getElementById('nav_data').getAttribute('data-address')
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
generateMap(JSON.parse(this.response))
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "https://nominatim.openstreetmap.org/search/?format=json&city=Bamberg&street=" + address, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
|
||||
function generateMap(streets) {
|
||||
var address = document.getElementById('nav_data').getAttribute('data-address')
|
||||
var address_short = document.getElementById('nav_data').getAttribute('data-short')
|
||||
console.log(streets)
|
||||
if (streets.length > 0) {
|
||||
endLon = streets[0]['lon'];
|
||||
endLat = streets[0]['lat'];
|
||||
console.log(endLat)
|
||||
var map = L.map('map').setView([endLat, endLon], 16);
|
||||
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
L.marker([endLat, endLon]).addTo(map)
|
||||
.bindPopup(address_short + '</br>' + address)
|
||||
.openPopup();
|
||||
L.marker([startLat, startLon]).addTo(map)
|
||||
.bindPopup('You are here!')
|
||||
.openPopup();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function resizeMap() {
|
||||
var height = window.innerHeight
|
||||
document.getElementById('map').style.height = height + 'px'
|
||||
}
|
||||
|
||||
function getPos() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function (position) {
|
||||
console.log(position);
|
||||
startLat = position.coords.latitude;
|
||||
startLon = position.coords.longitude;
|
||||
}, function (err) {
|
||||
console.log(err.code)
|
||||
console.log(err.message)
|
||||
})
|
||||
} else {
|
||||
document.getElementById('map').innerHTML('Geolocation not available')
|
||||
}
|
||||
}
|
||||
|
||||
function makeRoute() {
|
||||
console.log('make route')
|
||||
console.log('set waypoints:\nStart: ' + startLat + ' Lo: ' + startLon + " \nEnd: " + endLat + ' Lo: ' + endLon)
|
||||
L.Routing.control({
|
||||
waypoints: [
|
||||
L.latLng(startLat, startLon),
|
||||
L.latLng(endLat, endLon)
|
||||
]
|
||||
}).addTo(map);
|
||||
}
|
||||
3
ofu_app/static/libs/leaflet-routing-machine-3.2.5/.gitignore
vendored
Normal file
3
ofu_app/static/libs/leaflet-routing-machine-3.2.5/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
dist/*.js
|
||||
.grunt/
|
||||
55
ofu_app/static/libs/leaflet-routing-machine-3.2.5/.jshintrc
Normal file
55
ofu_app/static/libs/leaflet-routing-machine-3.2.5/.jshintrc
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
/*
|
||||
* ENVIRONMENTS
|
||||
* =================
|
||||
*/
|
||||
|
||||
// Define globals exposed by modern browsers.
|
||||
"browser": true,
|
||||
|
||||
// Define globals exposed by Node.js.
|
||||
"node": true,
|
||||
|
||||
"globals": {"L": false},
|
||||
|
||||
/*
|
||||
* ENFORCING OPTIONS
|
||||
* =================
|
||||
*/
|
||||
|
||||
// Force all variable names to use either camelCase style or UPPER_CASE
|
||||
// with underscores.
|
||||
"camelcase": true,
|
||||
|
||||
// Prohibit use of == and != in favor of === and !==.
|
||||
"eqeqeq": true,
|
||||
|
||||
// Suppress warnings about == null comparisons.
|
||||
"eqnull": true,
|
||||
|
||||
// Enforce tab width of 2 spaces.
|
||||
"indent": 2,
|
||||
|
||||
"smarttabs": true,
|
||||
|
||||
// Prohibit use of a variable before it is defined.
|
||||
"latedef": true,
|
||||
|
||||
// Require capitalized names for constructor functions.
|
||||
"newcap": true,
|
||||
|
||||
// Enforce use of single quotation marks for strings.
|
||||
"quotmark": "single",
|
||||
|
||||
// Prohibit trailing whitespace.
|
||||
"trailing": true,
|
||||
|
||||
// Prohibit use of explicitly undeclared variables.
|
||||
"undef": true,
|
||||
|
||||
// Warn when variables are defined but never used.
|
||||
"unused": true,
|
||||
|
||||
// All loops and conditionals should have braces.
|
||||
"curly": true
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
.grunt/
|
||||
@ -0,0 +1,17 @@
|
||||
before_install:
|
||||
- npm install -g grunt-cli
|
||||
before_deploy:
|
||||
- grunt before-deploy
|
||||
after_deploy:
|
||||
- grunt after-deploy
|
||||
language: node_js
|
||||
node_js:
|
||||
- 6
|
||||
notifications:
|
||||
email: false
|
||||
deploy:
|
||||
provider: npm
|
||||
email: "per@liedman.net"
|
||||
"on":
|
||||
all_branches: true
|
||||
tags: true
|
||||
@ -0,0 +1,13 @@
|
||||
## 2.2.0 (2015-03-03)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* **OSRM:** make sure waypoint options exist before checking them. ([2dd9d778]([object Object]/commit/2dd9d778baae30f0ef7f2d535a9d12ee7283a500))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* **plan:** routeWhileDragging also used when adding a new waypoint by dragging the route li ([6ab58fb2]([object Object]/commit/6ab58fb25d56f650ab0af4e168748e2997070582))
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
## ISC License
|
||||
|
||||
Copyright (c) 2014, Per Liedman (per@liedman.net)
|
||||
Turn instruction icons Copyright (c) 2014, Mapbox (mapbox.com)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
36
ofu_app/static/libs/leaflet-routing-machine-3.2.5/README.md
Normal file
36
ofu_app/static/libs/leaflet-routing-machine-3.2.5/README.md
Normal file
@ -0,0 +1,36 @@
|
||||
[Leaflet Routing Machine]((http://www.liedman.net/leaflet-routing-machine/)) [](https://www.npmjs.com/package/leaflet-routing-machine) 
|
||||
=======================
|
||||
|
||||
Find the way from A to B on a Leaflet map. The plugin supports multiple backends:
|
||||
|
||||
* [OSRM](http://project-osrm.org/) - builtin and used by default
|
||||
* [Mapbox Directions API](https://www.mapbox.com/developers/api/directions/) - builtin with the class `L.Routing.Mapbox`
|
||||
* [GraphHopper](https://graphhopper.com/) - through plugin [lrm-graphopper](https://github.com/perliedman/lrm-graphhopper)
|
||||
* [Mapzen Valhalla](https://mapzen.com/projects/valhalla/) - through plugin [lrm-valhalla](https://github.com/valhalla/lrm-valhalla)
|
||||
* [TomTom Online Routing API](http://developer.tomtom.com/io-docs) - through plugin [lrm-tomtom](https://github.com/mrohnstock/lrm-tomtom) by [Mathias Rohnstock](https://github.com/mrohnstock)
|
||||
|
||||
## Features
|
||||
|
||||
* Standard Leaflet control, with Leaflet look and feel
|
||||
* Routing from start to destination, with possibility of via points
|
||||
* Add, edit and remove waypoints through both address input and using the map
|
||||
* Multiple language support
|
||||
* Highly customizable for advanced use
|
||||
* Customizable look (theming / skins)
|
||||
* Open Source released under ISC License (more or less equivalent with the MIT license)
|
||||
|
||||
__Go to the [Leaflet Routing Machine site](http://www.liedman.net/leaflet-routing-machine/) for more information, demos, tutorials and more.__
|
||||
|
||||
## Support and New Features
|
||||
|
||||
Leaflet Routing Machine is in many ways already a feature complete routing UI. Most likely, your requirements are already covered and require very little adaptation.
|
||||
|
||||
If you have more complex requirements, need new features or just need some support, I am open to doing paid custom work and support around Leaflet Routing Machine for your organization. Contact me at [per@liedman.net](mailto:per@liedman.net) and we'll sort this out!
|
||||
|
||||
## Building
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
This requires [Node and npm](http://nodejs.org/), as well as `grunt`.
|
||||
33
ofu_app/static/libs/leaflet-routing-machine-3.2.5/bower.json
Normal file
33
ofu_app/static/libs/leaflet-routing-machine-3.2.5/bower.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "leaflet-routing-machine",
|
||||
"version": "3.2.5",
|
||||
"homepage": "https://github.com/perliedman/leaflet-routing-machine",
|
||||
"authors": [
|
||||
"Per Liedman <per@liedman.net> (http://www.liedman.net/)"
|
||||
],
|
||||
"description": "Find the way from A to B on a Leaflet map, using OSRM as backend.",
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"route"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": [
|
||||
"dist/leaflet.routing.icons.png",
|
||||
"dist/leaflet-routing-machine.css",
|
||||
"dist/leaflet.routing.icons.svg",
|
||||
"dist/leaflet-routing-machine.js",
|
||||
"dist/routing-icon.png"
|
||||
],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"src",
|
||||
"css",
|
||||
"Gruntfile.js",
|
||||
"package.json",
|
||||
"build.sh"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,733 @@
|
||||
(function (factory) {
|
||||
// Packaging/modules magic dance
|
||||
var L;
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['leaflet'], factory);
|
||||
} else if (typeof module !== 'undefined') {
|
||||
// Node/CommonJS
|
||||
L = require('leaflet');
|
||||
module.exports = factory(L);
|
||||
} else {
|
||||
// Browser globals
|
||||
if (typeof window.L === 'undefined')
|
||||
throw 'Leaflet must be loaded first';
|
||||
factory(window.L);
|
||||
}
|
||||
}(function (L) {
|
||||
'use strict';
|
||||
L.Control.Geocoder = L.Control.extend({
|
||||
options: {
|
||||
showResultIcons: false,
|
||||
collapsed: true,
|
||||
expand: 'click',
|
||||
position: 'topright',
|
||||
placeholder: 'Search...',
|
||||
errorMessage: 'Nothing found.'
|
||||
},
|
||||
|
||||
_callbackId: 0,
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
if (!this.options.geocoder) {
|
||||
this.options.geocoder = new L.Control.Geocoder.Nominatim();
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-geocoder',
|
||||
container = L.DomUtil.create('div', className),
|
||||
icon = L.DomUtil.create('div', 'leaflet-control-geocoder-icon', container),
|
||||
form = this._form = L.DomUtil.create('form', className + '-form', container),
|
||||
input;
|
||||
|
||||
this._map = map;
|
||||
this._container = container;
|
||||
input = this._input = L.DomUtil.create('input');
|
||||
input.type = 'text';
|
||||
input.placeholder = this.options.placeholder;
|
||||
|
||||
L.DomEvent.addListener(input, 'keydown', this._keydown, this);
|
||||
//L.DomEvent.addListener(input, 'onpaste', this._clearResults, this);
|
||||
//L.DomEvent.addListener(input, 'oninput', this._clearResults, this);
|
||||
|
||||
this._errorElement = document.createElement('div');
|
||||
this._errorElement.className = className + '-form-no-error';
|
||||
this._errorElement.innerHTML = this.options.errorMessage;
|
||||
|
||||
this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized');
|
||||
|
||||
form.appendChild(input);
|
||||
form.appendChild(this._errorElement);
|
||||
container.appendChild(this._alts);
|
||||
|
||||
L.DomEvent.addListener(form, 'submit', this._geocode, this);
|
||||
|
||||
if (this.options.collapsed) {
|
||||
if (this.options.expand === 'click') {
|
||||
L.DomEvent.addListener(icon, 'click', function(e) {
|
||||
// TODO: touch
|
||||
if (e.button === 0 && e.detail === 1) {
|
||||
this._toggle();
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
L.DomEvent.addListener(icon, 'mouseover', this._expand, this);
|
||||
L.DomEvent.addListener(icon, 'mouseout', this._collapse, this);
|
||||
this._map.on('movestart', this._collapse, this);
|
||||
}
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
_geocodeResult: function (results) {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
if (results.length === 1) {
|
||||
this._geocodeResultSelected(results[0]);
|
||||
} else if (results.length > 0) {
|
||||
this._alts.innerHTML = '';
|
||||
this._results = results;
|
||||
L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
this._alts.appendChild(this._createAlt(results[i], i));
|
||||
}
|
||||
} else {
|
||||
L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
}
|
||||
},
|
||||
|
||||
markGeocode: function(result) {
|
||||
this._map.fitBounds(result.bbox);
|
||||
|
||||
if (this._geocodeMarker) {
|
||||
this._map.removeLayer(this._geocodeMarker);
|
||||
}
|
||||
|
||||
this._geocodeMarker = new L.Marker(result.center)
|
||||
.bindPopup(result.html || result.name)
|
||||
.addTo(this._map)
|
||||
.openPopup();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_geocode: function(event) {
|
||||
L.DomEvent.preventDefault(event);
|
||||
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
this._clearResults();
|
||||
this.options.geocoder.geocode(this._input.value, this._geocodeResult, this);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_geocodeResultSelected: function(result) {
|
||||
if (this.options.collapsed) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._clearResults();
|
||||
}
|
||||
this.markGeocode(result);
|
||||
},
|
||||
|
||||
_toggle: function() {
|
||||
if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function () {
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
|
||||
this._input.select();
|
||||
},
|
||||
|
||||
_collapse: function () {
|
||||
this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_clearResults: function () {
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
this._selection = null;
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_createAlt: function(result, index) {
|
||||
var li = document.createElement('li'),
|
||||
a = L.DomUtil.create('a', '', li),
|
||||
icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
|
||||
text = result.html ? undefined : document.createTextNode(result.name);
|
||||
|
||||
if (icon) {
|
||||
icon.src = result.icon;
|
||||
}
|
||||
|
||||
a.href = '#';
|
||||
a.setAttribute('data-result-index', index);
|
||||
|
||||
if (result.html) {
|
||||
a.innerHTML = result.html;
|
||||
} else {
|
||||
a.appendChild(text);
|
||||
}
|
||||
|
||||
L.DomEvent.addListener(li, 'click', function clickHandler(e) {
|
||||
L.DomEvent.preventDefault(e);
|
||||
this._geocodeResultSelected(result);
|
||||
}, this);
|
||||
|
||||
return li;
|
||||
},
|
||||
|
||||
_keydown: function(e) {
|
||||
var _this = this,
|
||||
select = function select(dir) {
|
||||
if (_this._selection) {
|
||||
L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
_this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
|
||||
}
|
||||
if (!_this._selection) {
|
||||
_this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
|
||||
}
|
||||
|
||||
if (_this._selection) {
|
||||
L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
}
|
||||
};
|
||||
|
||||
switch (e.keyCode) {
|
||||
// Escape
|
||||
case 27:
|
||||
this._collapse();
|
||||
break;
|
||||
// Up
|
||||
case 38:
|
||||
select(-1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Up
|
||||
case 40:
|
||||
select(1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Enter
|
||||
case 13:
|
||||
if (this._selection) {
|
||||
var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10);
|
||||
this._geocodeResultSelected(this._results[index]);
|
||||
this._clearResults();
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.geocoder = function(id, options) {
|
||||
return new L.Control.Geocoder(id, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.callbackId = 0;
|
||||
L.Control.Geocoder.jsonp = function(url, params, callback, context, jsonpParam) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++);
|
||||
params[jsonpParam || 'callback'] = callbackId;
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = url + L.Util.getParamString(params);
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
};
|
||||
L.Control.Geocoder.getJSON = function(url, params, callback) {
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open( "GET", url + L.Util.getParamString(params), true);
|
||||
xmlHttp.send(null);
|
||||
xmlHttp.onreadystatechange = function () {
|
||||
if (xmlHttp.readyState != 4) return;
|
||||
if (xmlHttp.status != 200 && req.status != 304) return;
|
||||
callback(JSON.parse(xmlHttp.response));
|
||||
};
|
||||
};
|
||||
|
||||
L.Control.Geocoder.template = function (str, data, htmlEscape) {
|
||||
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
|
||||
var value = data[key];
|
||||
if (value === undefined) {
|
||||
value = '';
|
||||
} else if (typeof value === 'function') {
|
||||
value = value(data);
|
||||
}
|
||||
return L.Control.Geocoder.htmlEscape(value);
|
||||
});
|
||||
};
|
||||
|
||||
// Adapted from handlebars.js
|
||||
// https://github.com/wycats/handlebars.js/
|
||||
L.Control.Geocoder.htmlEscape = (function() {
|
||||
var badChars = /[&<>"'`]/g;
|
||||
var possible = /[&<>"'`]/;
|
||||
var escape = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
'\'': ''',
|
||||
'`': '`'
|
||||
};
|
||||
|
||||
function escapeChar(chr) {
|
||||
return escape[chr];
|
||||
}
|
||||
|
||||
return function(string) {
|
||||
if (string == null) {
|
||||
return '';
|
||||
} else if (!string) {
|
||||
return string + '';
|
||||
}
|
||||
|
||||
// Force a string conversion as this will be done by the append regardless and
|
||||
// the regex test will do this transparently behind the scenes, causing issues if
|
||||
// an object's to string has escaped characters in it.
|
||||
string = '' + string;
|
||||
|
||||
if (!possible.test(string)) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(badChars, escapeChar);
|
||||
};
|
||||
})();
|
||||
|
||||
L.Control.Geocoder.Nominatim = L.Class.extend({
|
||||
options: {
|
||||
serviceUrl: '//nominatim.openstreetmap.org/',
|
||||
geocodingQueryParams: {},
|
||||
reverseQueryParams: {},
|
||||
htmlTemplate: function(r) {
|
||||
var a = r.address,
|
||||
parts = [];
|
||||
if (a.road || a.building) {
|
||||
parts.push('{building} {road} {house_number}');
|
||||
}
|
||||
|
||||
if (a.city || a.town || a.village) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
|
||||
'">{postcode} {city}{town}{village}</span>');
|
||||
}
|
||||
|
||||
if (a.state || a.country) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') +
|
||||
'">{state} {country}</span>');
|
||||
}
|
||||
|
||||
return L.Control.Geocoder.template(parts.join('<br/>'), a, true);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', L.extend({
|
||||
q: query,
|
||||
limit: 5,
|
||||
format: 'json',
|
||||
addressdetails: 1
|
||||
}, this.options.geocodingQueryParams),
|
||||
function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var bbox = data[i].boundingbox;
|
||||
for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
|
||||
results[i] = {
|
||||
icon: data[i].icon,
|
||||
name: data[i].display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data[i])
|
||||
: undefined,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
|
||||
center: L.latLng(data[i].lat, data[i].lon),
|
||||
properties: data[i]
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'json_callback');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', L.extend({
|
||||
lat: location.lat,
|
||||
lon: location.lng,
|
||||
zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
|
||||
addressdetails: 1,
|
||||
format: 'json'
|
||||
}, this.options.reverseQueryParams), function(data) {
|
||||
var result = [],
|
||||
loc;
|
||||
|
||||
if (data && data.lat && data.lon) {
|
||||
loc = L.latLng(data.lat, data.lon);
|
||||
result.push({
|
||||
name: data.display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data)
|
||||
: undefined,
|
||||
center: loc,
|
||||
bounds: L.latLngBounds(loc, loc),
|
||||
properties: data
|
||||
});
|
||||
}
|
||||
|
||||
cb.call(context, result);
|
||||
}, this, 'json_callback');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.nominatim = function(options) {
|
||||
return new L.Control.Geocoder.Nominatim(options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Bing = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
this.key = key;
|
||||
},
|
||||
|
||||
geocode : function (query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
|
||||
query: query,
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng, {
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.bing = function(key) {
|
||||
return new L.Control.Geocoder.Bing(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.RaveGeo = L.Class.extend({
|
||||
options: {
|
||||
querySuffix: '',
|
||||
deepSearch: true,
|
||||
wordBased: false
|
||||
},
|
||||
|
||||
jsonp: function(params, callback, context) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++),
|
||||
paramParts = [];
|
||||
params.prepend = callbackId + '(';
|
||||
params.append = ')';
|
||||
for (var p in params) {
|
||||
paramParts.push(p + '=' + escape(params[p]));
|
||||
}
|
||||
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = this._serviceUrl + '?' + paramParts.join('&');
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
},
|
||||
|
||||
initialize: function(serviceUrl, scheme, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._serviceUrl = serviceUrl;
|
||||
this._scheme = scheme;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this._serviceUrl, {
|
||||
address: query + this.options.querySuffix,
|
||||
scheme: this._scheme,
|
||||
outputFormat: 'jsonp',
|
||||
deepSearch: this.options.deepSearch,
|
||||
wordBased: this.options.wordBased
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var r = data[i],
|
||||
c = L.latLng(r.y, r.x);
|
||||
results[i] = {
|
||||
name: r.address,
|
||||
bbox: L.latLngBounds([c]),
|
||||
center: c
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) {
|
||||
return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.MapQuest = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
// MapQuest seems to provide URI encoded API keys,
|
||||
// so to avoid encoding them twice, we decode them here
|
||||
this._key = decodeURIComponent(key);
|
||||
},
|
||||
|
||||
_formatName: function() {
|
||||
var r = [],
|
||||
i;
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i]) {
|
||||
r.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return r.join(', ');
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/address', {
|
||||
key: this._key,
|
||||
location: query,
|
||||
limit: 5,
|
||||
outFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/reverse', {
|
||||
key: this._key,
|
||||
location: location.lat + ',' + location.lng,
|
||||
outputFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapQuest = function(key) {
|
||||
return new L.Control.Geocoder.MapQuest(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Mapbox = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
|
||||
},
|
||||
|
||||
initialize: function(access_token) {
|
||||
this._access_token = access_token;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(query) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapbox = function(access_token) {
|
||||
return new L.Control.Geocoder.Mapbox(access_token);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Google = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://maps.googleapis.com/maps/api/geocode/json'
|
||||
},
|
||||
|
||||
initialize: function(key) {
|
||||
this._key = key;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
var params = {
|
||||
address: query,
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
var params = {
|
||||
latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.google = function(key) {
|
||||
return new L.Control.Geocoder.Google(key);
|
||||
};
|
||||
return L.Control.Geocoder;
|
||||
}));
|
||||
@ -0,0 +1,4 @@
|
||||
window.lrmConfig = {
|
||||
// serviceUrl: 'https://api.mapbox.com/directions/v5',
|
||||
// profile: 'mapbox/driving',
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
.map {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.results {
|
||||
background-color: white;
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
width: 320px;
|
||||
height: 480px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Leaflet OSRM Example</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="../dist/leaflet-routing-machine.css" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
<script src="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.js"></script>
|
||||
<script src="../dist/leaflet-routing-machine.js"></script>
|
||||
<script src="Control.Geocoder.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,25 @@
|
||||
var map = L.map('map');
|
||||
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
var control = L.Routing.control(L.extend(window.lrmConfig, {
|
||||
waypoints: [
|
||||
L.latLng(57.74, 11.94),
|
||||
L.latLng(57.6792, 11.949)
|
||||
],
|
||||
geocoder: L.Control.Geocoder.nominatim(),
|
||||
routeWhileDragging: true,
|
||||
reverseWaypoints: true,
|
||||
showAlternatives: true,
|
||||
altLineOptions: {
|
||||
styles: [
|
||||
{color: 'black', opacity: 0.15, weight: 9},
|
||||
{color: 'white', opacity: 0.8, weight: 6},
|
||||
{color: 'blue', opacity: 0.5, weight: 2}
|
||||
]
|
||||
}
|
||||
})).addTo(map);
|
||||
|
||||
L.Routing.errorControl(control).addTo(map);
|
||||
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Leaflet OSRM Example</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="../dist/leaflet-routing-machine.css" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
<script src="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.js"></script>
|
||||
<script src="../dist/leaflet-routing-machine.js"></script>
|
||||
<script src="Control.Geocoder.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="localized.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,26 @@
|
||||
var map = L.map('map');
|
||||
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
var control = L.Routing.control(L.extend(window.lrmConfig, {
|
||||
waypoints: [
|
||||
L.latLng(57.74, 11.94),
|
||||
L.latLng(57.6792, 11.949)
|
||||
],
|
||||
language: 'de',
|
||||
geocoder: L.Control.Geocoder.nominatim(),
|
||||
routeWhileDragging: true,
|
||||
reverseWaypoints: true,
|
||||
showAlternatives: true,
|
||||
altLineOptions: {
|
||||
styles: [
|
||||
{color: 'black', opacity: 0.15, weight: 9},
|
||||
{color: 'white', opacity: 0.8, weight: 6},
|
||||
{color: 'blue', opacity: 0.5, weight: 2}
|
||||
]
|
||||
}
|
||||
})).addTo(map);
|
||||
|
||||
L.Routing.errorControl(control).addTo(map);
|
||||
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Leaflet OSRM Example</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="../dist/leaflet-routing-machine.css" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
<script src="https://unpkg.com/leaflet@1.0.0-rc.3/dist/leaflet.js"></script>
|
||||
<script src="../dist/leaflet-routing-machine.js"></script>
|
||||
<script src="Control.Geocoder.js"></script>
|
||||
<script src="mapbox.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,26 @@
|
||||
var map = L.map('map');
|
||||
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
var control = L.Routing.control({
|
||||
waypoints: [
|
||||
L.latLng(57.74, 11.94),
|
||||
L.latLng(57.6792, 11.949)
|
||||
],
|
||||
geocoder: L.Control.Geocoder.nominatim(),
|
||||
routeWhileDragging: true,
|
||||
reverseWaypoints: true,
|
||||
showAlternatives: true,
|
||||
altLineOptions: {
|
||||
styles: [
|
||||
{color: 'black', opacity: 0.15, weight: 9},
|
||||
{color: 'white', opacity: 0.8, weight: 6},
|
||||
{color: 'blue', opacity: 0.5, weight: 2}
|
||||
]
|
||||
},
|
||||
router: L.Routing.mapbox('your-token-here')
|
||||
}).addTo(map);
|
||||
|
||||
L.Routing.errorControl(control).addTo(map);
|
||||
@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "leaflet-routing-machine",
|
||||
"version": "3.2.5",
|
||||
"description": "Routing for Leaflet",
|
||||
"directories": {
|
||||
"example": "examples",
|
||||
"dist": "dist"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "browserify -t browserify-shim -p browserify-derequire -o dist/leaflet-routing-machine.js src/index.js && uglifyjs dist/leaflet-routing-machine.js >dist/leaflet-routing-machine.min.js",
|
||||
"publish": "scripts/publish.sh",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/perliedman/leaflet-routing-machine.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"routing",
|
||||
"osrm"
|
||||
],
|
||||
"author": {
|
||||
"name": "Per Liedman",
|
||||
"email": "per@liedman.net"
|
||||
},
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/perliedman/leaflet-routing-machine/issues"
|
||||
},
|
||||
"homepage": "https://github.com/perliedman/leaflet-routing-machine",
|
||||
"browserify-shim": {
|
||||
"leaflet": "global:L"
|
||||
},
|
||||
"main": "./dist/leaflet-routing-machine.js",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.3.0",
|
||||
"browserify-derequire": "^0.9.4",
|
||||
"browserify-shim": "^3.7.0",
|
||||
"corslite": "0.0.7",
|
||||
"derequire": "^2.0.6",
|
||||
"polyline": "0.2.0",
|
||||
"uglify-js": "^2.7.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"osrm-text-instructions": "^0.1.0"
|
||||
}
|
||||
}
|
||||
38
ofu_app/static/libs/leaflet-routing-machine-3.2.5/scripts/publish.sh
Executable file
38
ofu_app/static/libs/leaflet-routing-machine-3.2.5/scripts/publish.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=`echo "console.log(require('./package.json').version)" | node`
|
||||
ORIGIN=`git remote -v|grep origin|head -n1|cut -f2|cut -d" " -f1`
|
||||
TMP=/tmp/.gh-pages-update
|
||||
CWD=`pwd`
|
||||
|
||||
git checkout -b build
|
||||
|
||||
echo Building dist files for $VERSION...
|
||||
grunt
|
||||
echo Done.
|
||||
|
||||
git add dist/* -f
|
||||
git add bower.json -f
|
||||
|
||||
git commit -m "v$VERSION"
|
||||
|
||||
git tag v$VERSION -f
|
||||
git push origin build --tags -f
|
||||
|
||||
echo Updating dist files on gh-pages...
|
||||
rm -rf $TMP
|
||||
git clone -b gh-pages . $TMP
|
||||
cd $TMP
|
||||
git remote set-url origin $ORIGIN
|
||||
git fetch origin gh-pages
|
||||
git rebase origin/gh-pages
|
||||
|
||||
cp -a $CWD/dist $TMP
|
||||
git add -f dist/
|
||||
git commit -m "Dist files $VERSION"
|
||||
git push origin gh-pages
|
||||
cd $CWD
|
||||
rm -rf $TMP
|
||||
|
||||
git checkout master
|
||||
git branch -D build
|
||||
@ -0,0 +1,210 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
module.exports = L.Class.extend({
|
||||
options: {
|
||||
timeout: 500,
|
||||
blurTimeout: 100,
|
||||
noResultsMessage: 'No results found.'
|
||||
},
|
||||
|
||||
initialize: function(elem, callback, context, options) {
|
||||
L.setOptions(this, options);
|
||||
|
||||
this._elem = elem;
|
||||
this._resultFn = options.resultFn ? L.Util.bind(options.resultFn, options.resultContext) : null;
|
||||
this._autocomplete = options.autocompleteFn ? L.Util.bind(options.autocompleteFn, options.autocompleteContext) : null;
|
||||
this._selectFn = L.Util.bind(callback, context);
|
||||
this._container = L.DomUtil.create('div', 'leaflet-routing-geocoder-result');
|
||||
this._resultTable = L.DomUtil.create('table', '', this._container);
|
||||
|
||||
// TODO: looks a bit like a kludge to register same for input and keypress -
|
||||
// browsers supporting both will get duplicate events; just registering
|
||||
// input will not catch enter, though.
|
||||
L.DomEvent.addListener(this._elem, 'input', this._keyPressed, this);
|
||||
L.DomEvent.addListener(this._elem, 'keypress', this._keyPressed, this);
|
||||
L.DomEvent.addListener(this._elem, 'keydown', this._keyDown, this);
|
||||
L.DomEvent.addListener(this._elem, 'blur', function() {
|
||||
if (this._isOpen) {
|
||||
this.close();
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-routing-geocoder-result-open');
|
||||
this._isOpen = false;
|
||||
},
|
||||
|
||||
_open: function() {
|
||||
var rect = this._elem.getBoundingClientRect();
|
||||
if (!this._container.parentElement) {
|
||||
// See notes section under https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollX
|
||||
// This abomination is required to support all flavors of IE
|
||||
var scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset
|
||||
: (document.documentElement || document.body.parentNode || document.body).scrollLeft;
|
||||
var scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset
|
||||
: (document.documentElement || document.body.parentNode || document.body).scrollTop;
|
||||
this._container.style.left = (rect.left + scrollX) + 'px';
|
||||
this._container.style.top = (rect.bottom + scrollY) + 'px';
|
||||
this._container.style.width = (rect.right - rect.left) + 'px';
|
||||
document.body.appendChild(this._container);
|
||||
}
|
||||
|
||||
L.DomUtil.addClass(this._container, 'leaflet-routing-geocoder-result-open');
|
||||
this._isOpen = true;
|
||||
},
|
||||
|
||||
_setResults: function(results) {
|
||||
var i,
|
||||
tr,
|
||||
td,
|
||||
text;
|
||||
|
||||
delete this._selection;
|
||||
this._results = results;
|
||||
|
||||
while (this._resultTable.firstChild) {
|
||||
this._resultTable.removeChild(this._resultTable.firstChild);
|
||||
}
|
||||
|
||||
for (i = 0; i < results.length; i++) {
|
||||
tr = L.DomUtil.create('tr', '', this._resultTable);
|
||||
tr.setAttribute('data-result-index', i);
|
||||
td = L.DomUtil.create('td', '', tr);
|
||||
text = document.createTextNode(results[i].name);
|
||||
td.appendChild(text);
|
||||
// mousedown + click because:
|
||||
// http://stackoverflow.com/questions/10652852/jquery-fire-click-before-blur-event
|
||||
L.DomEvent.addListener(td, 'mousedown', L.DomEvent.preventDefault);
|
||||
L.DomEvent.addListener(td, 'click', this._createClickListener(results[i]));
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
tr = L.DomUtil.create('tr', '', this._resultTable);
|
||||
td = L.DomUtil.create('td', 'leaflet-routing-geocoder-no-results', tr);
|
||||
td.innerHTML = this.options.noResultsMessage;
|
||||
}
|
||||
|
||||
this._open();
|
||||
|
||||
if (results.length > 0) {
|
||||
// Select the first entry
|
||||
this._select(1);
|
||||
}
|
||||
},
|
||||
|
||||
_createClickListener: function(r) {
|
||||
var resultSelected = this._resultSelected(r);
|
||||
return L.bind(function() {
|
||||
this._elem.blur();
|
||||
resultSelected();
|
||||
}, this);
|
||||
},
|
||||
|
||||
_resultSelected: function(r) {
|
||||
return L.bind(function() {
|
||||
this.close();
|
||||
this._elem.value = r.name;
|
||||
this._lastCompletedText = r.name;
|
||||
this._selectFn(r);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_keyPressed: function(e) {
|
||||
var index;
|
||||
|
||||
if (this._isOpen && e.keyCode === 13 && this._selection) {
|
||||
index = parseInt(this._selection.getAttribute('data-result-index'), 10);
|
||||
this._resultSelected(this._results[index])();
|
||||
L.DomEvent.preventDefault(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.keyCode === 13) {
|
||||
this._complete(this._resultFn, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._autocomplete && document.activeElement === this._elem) {
|
||||
if (this._timer) {
|
||||
clearTimeout(this._timer);
|
||||
}
|
||||
this._timer = setTimeout(L.Util.bind(function() { this._complete(this._autocomplete); }, this),
|
||||
this.options.timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
this._unselect();
|
||||
},
|
||||
|
||||
_select: function(dir) {
|
||||
var sel = this._selection;
|
||||
if (sel) {
|
||||
L.DomUtil.removeClass(sel.firstChild, 'leaflet-routing-geocoder-selected');
|
||||
sel = sel[dir > 0 ? 'nextSibling' : 'previousSibling'];
|
||||
}
|
||||
if (!sel) {
|
||||
sel = this._resultTable[dir > 0 ? 'firstChild' : 'lastChild'];
|
||||
}
|
||||
|
||||
if (sel) {
|
||||
L.DomUtil.addClass(sel.firstChild, 'leaflet-routing-geocoder-selected');
|
||||
this._selection = sel;
|
||||
}
|
||||
},
|
||||
|
||||
_unselect: function() {
|
||||
if (this._selection) {
|
||||
L.DomUtil.removeClass(this._selection.firstChild, 'leaflet-routing-geocoder-selected');
|
||||
}
|
||||
delete this._selection;
|
||||
},
|
||||
|
||||
_keyDown: function(e) {
|
||||
if (this._isOpen) {
|
||||
switch (e.keyCode) {
|
||||
// Escape
|
||||
case 27:
|
||||
this.close();
|
||||
L.DomEvent.preventDefault(e);
|
||||
return;
|
||||
// Up
|
||||
case 38:
|
||||
this._select(-1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
return;
|
||||
// Down
|
||||
case 40:
|
||||
this._select(1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_complete: function(completeFn, trySelect) {
|
||||
var v = this._elem.value;
|
||||
function completeResults(results) {
|
||||
this._lastCompletedText = v;
|
||||
if (trySelect && results.length === 1) {
|
||||
this._resultSelected(results[0])();
|
||||
} else {
|
||||
this._setResults(results);
|
||||
}
|
||||
}
|
||||
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v !== this._lastCompletedText) {
|
||||
completeFn(v, completeResults, this);
|
||||
} else if (trySelect) {
|
||||
completeResults.call(this, this._results);
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
347
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/control.js
Normal file
347
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/control.js
Normal file
@ -0,0 +1,347 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
var Itinerary = require('./itinerary');
|
||||
var Line = require('./line');
|
||||
var Plan = require('./plan');
|
||||
var OSRMv1 = require('./osrm-v1');
|
||||
|
||||
module.exports = Itinerary.extend({
|
||||
options: {
|
||||
fitSelectedRoutes: 'smart',
|
||||
routeLine: function(route, options) { return new Line(route, options); },
|
||||
autoRoute: true,
|
||||
routeWhileDragging: false,
|
||||
routeDragInterval: 500,
|
||||
waypointMode: 'connect',
|
||||
showAlternatives: false,
|
||||
defaultErrorHandler: function(e) {
|
||||
console.error('Routing error:', e.error);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._router = this.options.router || new OSRMv1(options);
|
||||
this._plan = this.options.plan || new Plan(this.options.waypoints, options);
|
||||
this._requestCount = 0;
|
||||
|
||||
Itinerary.prototype.initialize.call(this, options);
|
||||
|
||||
this.on('routeselected', this._routeSelected, this);
|
||||
if (this.options.defaultErrorHandler) {
|
||||
this.on('routingerror', this.options.defaultErrorHandler);
|
||||
}
|
||||
this._plan.on('waypointschanged', this._onWaypointsChanged, this);
|
||||
if (options.routeWhileDragging) {
|
||||
this._setupRouteDragging();
|
||||
}
|
||||
|
||||
if (this.options.autoRoute) {
|
||||
this.route();
|
||||
}
|
||||
},
|
||||
|
||||
_onZoomEnd: function() {
|
||||
if (!this._selectedRoute ||
|
||||
!this._router.requiresMoreDetail) {
|
||||
return;
|
||||
}
|
||||
|
||||
var map = this._map;
|
||||
if (this._router.requiresMoreDetail(this._selectedRoute,
|
||||
map.getZoom(), map.getBounds())) {
|
||||
this.route({
|
||||
callback: L.bind(function(err, routes) {
|
||||
var i;
|
||||
if (!err) {
|
||||
for (i = 0; i < routes.length; i++) {
|
||||
this._routes[i].properties = routes[i].properties;
|
||||
}
|
||||
this._updateLineCallback(err, routes);
|
||||
}
|
||||
|
||||
}, this),
|
||||
simplifyGeometry: false,
|
||||
geometryOnly: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
var container = Itinerary.prototype.onAdd.call(this, map);
|
||||
|
||||
this._map = map;
|
||||
this._map.addLayer(this._plan);
|
||||
|
||||
this._map.on('zoomend', this._onZoomEnd, this);
|
||||
|
||||
if (this._plan.options.geocoder) {
|
||||
container.insertBefore(this._plan.createGeocoders(), container.firstChild);
|
||||
}
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
map.off('zoomend', this._onZoomEnd, this);
|
||||
if (this._line) {
|
||||
map.removeLayer(this._line);
|
||||
}
|
||||
map.removeLayer(this._plan);
|
||||
if (this._alternatives && this._alternatives.length > 0) {
|
||||
for (var i = 0, len = this._alternatives.length; i < len; i++) {
|
||||
map.removeLayer(this._alternatives[i]);
|
||||
}
|
||||
}
|
||||
return Itinerary.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
getWaypoints: function() {
|
||||
return this._plan.getWaypoints();
|
||||
},
|
||||
|
||||
setWaypoints: function(waypoints) {
|
||||
this._plan.setWaypoints(waypoints);
|
||||
return this;
|
||||
},
|
||||
|
||||
spliceWaypoints: function() {
|
||||
var removed = this._plan.spliceWaypoints.apply(this._plan, arguments);
|
||||
return removed;
|
||||
},
|
||||
|
||||
getPlan: function() {
|
||||
return this._plan;
|
||||
},
|
||||
|
||||
getRouter: function() {
|
||||
return this._router;
|
||||
},
|
||||
|
||||
_routeSelected: function(e) {
|
||||
var route = this._selectedRoute = e.route,
|
||||
alternatives = this.options.showAlternatives && e.alternatives,
|
||||
fitMode = this.options.fitSelectedRoutes,
|
||||
fitBounds =
|
||||
(fitMode === 'smart' && !this._waypointsVisible()) ||
|
||||
(fitMode !== 'smart' && fitMode);
|
||||
|
||||
this._updateLines({route: route, alternatives: alternatives});
|
||||
|
||||
if (fitBounds) {
|
||||
this._map.fitBounds(this._line.getBounds());
|
||||
}
|
||||
|
||||
if (this.options.waypointMode === 'snap') {
|
||||
this._plan.off('waypointschanged', this._onWaypointsChanged, this);
|
||||
this.setWaypoints(route.waypoints);
|
||||
this._plan.on('waypointschanged', this._onWaypointsChanged, this);
|
||||
}
|
||||
},
|
||||
|
||||
_waypointsVisible: function() {
|
||||
var wps = this.getWaypoints(),
|
||||
mapSize,
|
||||
bounds,
|
||||
boundsSize,
|
||||
i,
|
||||
p;
|
||||
|
||||
try {
|
||||
mapSize = this._map.getSize();
|
||||
|
||||
for (i = 0; i < wps.length; i++) {
|
||||
p = this._map.latLngToLayerPoint(wps[i].latLng);
|
||||
|
||||
if (bounds) {
|
||||
bounds.extend(p);
|
||||
} else {
|
||||
bounds = L.bounds([p]);
|
||||
}
|
||||
}
|
||||
|
||||
boundsSize = bounds.getSize();
|
||||
return (boundsSize.x > mapSize.x / 5 ||
|
||||
boundsSize.y > mapSize.y / 5) && this._waypointsInViewport();
|
||||
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
_waypointsInViewport: function() {
|
||||
var wps = this.getWaypoints(),
|
||||
mapBounds,
|
||||
i;
|
||||
|
||||
try {
|
||||
mapBounds = this._map.getBounds();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < wps.length; i++) {
|
||||
if (mapBounds.contains(wps[i].latLng)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateLines: function(routes) {
|
||||
var addWaypoints = this.options.addWaypoints !== undefined ?
|
||||
this.options.addWaypoints : true;
|
||||
this._clearLines();
|
||||
|
||||
// add alternatives first so they lie below the main route
|
||||
this._alternatives = [];
|
||||
if (routes.alternatives) routes.alternatives.forEach(function(alt, i) {
|
||||
this._alternatives[i] = this.options.routeLine(alt,
|
||||
L.extend({
|
||||
isAlternative: true
|
||||
}, this.options.altLineOptions || this.options.lineOptions));
|
||||
this._alternatives[i].addTo(this._map);
|
||||
this._hookAltEvents(this._alternatives[i]);
|
||||
}, this);
|
||||
|
||||
this._line = this.options.routeLine(routes.route,
|
||||
L.extend({
|
||||
addWaypoints: addWaypoints,
|
||||
extendToWaypoints: this.options.waypointMode === 'connect'
|
||||
}, this.options.lineOptions));
|
||||
this._line.addTo(this._map);
|
||||
this._hookEvents(this._line);
|
||||
},
|
||||
|
||||
_hookEvents: function(l) {
|
||||
l.on('linetouched', function(e) {
|
||||
this._plan.dragNewWaypoint(e);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_hookAltEvents: function(l) {
|
||||
l.on('linetouched', function(e) {
|
||||
var alts = this._routes.slice();
|
||||
var selected = alts.splice(e.target._route.routesIndex, 1)[0];
|
||||
this.fire('routeselected', {route: selected, alternatives: alts});
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onWaypointsChanged: function(e) {
|
||||
if (this.options.autoRoute) {
|
||||
this.route({});
|
||||
}
|
||||
if (!this._plan.isReady()) {
|
||||
this._clearLines();
|
||||
this._clearAlts();
|
||||
}
|
||||
this.fire('waypointschanged', {waypoints: e.waypoints});
|
||||
},
|
||||
|
||||
_setupRouteDragging: function() {
|
||||
var timer = 0,
|
||||
waypoints;
|
||||
|
||||
this._plan.on('waypointdrag', L.bind(function(e) {
|
||||
waypoints = e.waypoints;
|
||||
|
||||
if (!timer) {
|
||||
timer = setTimeout(L.bind(function() {
|
||||
this.route({
|
||||
waypoints: waypoints,
|
||||
geometryOnly: true,
|
||||
callback: L.bind(this._updateLineCallback, this)
|
||||
});
|
||||
timer = undefined;
|
||||
}, this), this.options.routeDragInterval);
|
||||
}
|
||||
}, this));
|
||||
this._plan.on('waypointdragend', function() {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = undefined;
|
||||
}
|
||||
this.route();
|
||||
}, this);
|
||||
},
|
||||
|
||||
_updateLineCallback: function(err, routes) {
|
||||
if (!err) {
|
||||
routes = routes.slice();
|
||||
var selected = routes.splice(this._selectedRoute.routesIndex, 1)[0];
|
||||
this._updateLines({route: selected, alternatives: routes });
|
||||
} else if (err.type !== 'abort') {
|
||||
this._clearLines();
|
||||
}
|
||||
},
|
||||
|
||||
route: function(options) {
|
||||
var ts = ++this._requestCount,
|
||||
wps;
|
||||
|
||||
if (this._pendingRequest && this._pendingRequest.abort) {
|
||||
this._pendingRequest.abort();
|
||||
this._pendingRequest = null;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (this._plan.isReady()) {
|
||||
if (this.options.useZoomParameter) {
|
||||
options.z = this._map && this._map.getZoom();
|
||||
}
|
||||
|
||||
wps = options && options.waypoints || this._plan.getWaypoints();
|
||||
this.fire('routingstart', {waypoints: wps});
|
||||
this._pendingRequest = this._router.route(wps, function(err, routes) {
|
||||
this._pendingRequest = null;
|
||||
|
||||
if (options.callback) {
|
||||
return options.callback.call(this, err, routes);
|
||||
}
|
||||
|
||||
// Prevent race among multiple requests,
|
||||
// by checking the current request's count
|
||||
// against the last request's; ignore result if
|
||||
// this isn't the last request.
|
||||
if (ts === this._requestCount) {
|
||||
this._clearLines();
|
||||
this._clearAlts();
|
||||
if (err && err.type !== 'abort') {
|
||||
this.fire('routingerror', {error: err});
|
||||
return;
|
||||
}
|
||||
|
||||
routes.forEach(function(route, i) { route.routesIndex = i; });
|
||||
|
||||
if (!options.geometryOnly) {
|
||||
this.fire('routesfound', {waypoints: wps, routes: routes});
|
||||
this.setAlternatives(routes);
|
||||
} else {
|
||||
var selectedRoute = routes.splice(0,1)[0];
|
||||
this._routeSelected({route: selectedRoute, alternatives: routes});
|
||||
}
|
||||
}
|
||||
}, this, options);
|
||||
}
|
||||
},
|
||||
|
||||
_clearLines: function() {
|
||||
if (this._line) {
|
||||
this._map.removeLayer(this._line);
|
||||
delete this._line;
|
||||
}
|
||||
if (this._alternatives && this._alternatives.length) {
|
||||
for (var i in this._alternatives) {
|
||||
this._map.removeLayer(this._alternatives[i]);
|
||||
}
|
||||
this._alternatives = [];
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,55 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
module.exports = L.Control.extend({
|
||||
options: {
|
||||
header: 'Routing error',
|
||||
formatMessage: function(error) {
|
||||
if (error.status < 0) {
|
||||
return 'Calculating the route caused an error. Technical description follows: <code><pre>' +
|
||||
error.message + '</pre></code';
|
||||
} else {
|
||||
return 'The route could not be calculated. ' +
|
||||
error.message;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(routingControl, options) {
|
||||
L.Control.prototype.initialize.call(this, options);
|
||||
routingControl
|
||||
.on('routingerror', L.bind(function(e) {
|
||||
if (this._element) {
|
||||
this._element.children[1].innerHTML = this.options.formatMessage(e.error);
|
||||
this._element.style.visibility = 'visible';
|
||||
}
|
||||
}, this))
|
||||
.on('routingstart', L.bind(function() {
|
||||
if (this._element) {
|
||||
this._element.style.visibility = 'hidden';
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
onAdd: function() {
|
||||
var header,
|
||||
message;
|
||||
|
||||
this._element = L.DomUtil.create('div', 'leaflet-bar leaflet-routing-error');
|
||||
this._element.style.visibility = 'hidden';
|
||||
|
||||
header = L.DomUtil.create('h3', null, this._element);
|
||||
message = L.DomUtil.create('span', null, this._element);
|
||||
|
||||
header.innerHTML = this.options.header;
|
||||
|
||||
return this._element;
|
||||
},
|
||||
|
||||
onRemove: function() {
|
||||
delete this._element;
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,159 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
var Localization = require('./localization');
|
||||
|
||||
module.exports = L.Class.extend({
|
||||
options: {
|
||||
units: 'metric',
|
||||
unitNames: null,
|
||||
language: 'en',
|
||||
roundingSensitivity: 1,
|
||||
distanceTemplate: '{value} {unit}'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.setOptions(this, options);
|
||||
|
||||
var langs = L.Util.isArray(this.options.language) ?
|
||||
this.options.language :
|
||||
[this.options.language, 'en'];
|
||||
this._localization = new Localization(langs);
|
||||
},
|
||||
|
||||
formatDistance: function(d /* Number (meters) */, sensitivity) {
|
||||
var un = this.options.unitNames || this._localization.localize('units'),
|
||||
simpleRounding = sensitivity <= 0,
|
||||
round = simpleRounding ? function(v) { return v; } : L.bind(this._round, this),
|
||||
v,
|
||||
yards,
|
||||
data,
|
||||
pow10;
|
||||
|
||||
if (this.options.units === 'imperial') {
|
||||
yards = d / 0.9144;
|
||||
if (yards >= 1000) {
|
||||
data = {
|
||||
value: round(d / 1609.344, sensitivity),
|
||||
unit: un.miles
|
||||
};
|
||||
} else {
|
||||
data = {
|
||||
value: round(yards, sensitivity),
|
||||
unit: un.yards
|
||||
};
|
||||
}
|
||||
} else {
|
||||
v = round(d, sensitivity);
|
||||
data = {
|
||||
value: v >= 1000 ? (v / 1000) : v,
|
||||
unit: v >= 1000 ? un.kilometers : un.meters
|
||||
};
|
||||
}
|
||||
|
||||
if (simpleRounding) {
|
||||
data.value = data.value.toFixed(-sensitivity);
|
||||
}
|
||||
|
||||
return L.Util.template(this.options.distanceTemplate, data);
|
||||
},
|
||||
|
||||
_round: function(d, sensitivity) {
|
||||
var s = sensitivity || this.options.roundingSensitivity,
|
||||
pow10 = Math.pow(10, (Math.floor(d / s) + '').length - 1),
|
||||
r = Math.floor(d / pow10),
|
||||
p = (r > 5) ? pow10 : pow10 / 2;
|
||||
|
||||
return Math.round(d / p) * p;
|
||||
},
|
||||
|
||||
formatTime: function(t /* Number (seconds) */) {
|
||||
var un = this.options.unitNames || this._localization.localize('units');
|
||||
// More than 30 seconds precision looks ridiculous
|
||||
t = Math.round(t / 30) * 30;
|
||||
|
||||
if (t > 86400) {
|
||||
return Math.round(t / 3600) + ' ' + un.hours;
|
||||
} else if (t > 3600) {
|
||||
return Math.floor(t / 3600) + ' ' + un.hours + ' ' +
|
||||
Math.round((t % 3600) / 60) + ' ' + un.minutes;
|
||||
} else if (t > 300) {
|
||||
return Math.round(t / 60) + ' ' + un.minutes;
|
||||
} else if (t > 60) {
|
||||
return Math.floor(t / 60) + ' ' + un.minutes +
|
||||
(t % 60 !== 0 ? ' ' + (t % 60) + ' ' + un.seconds : '');
|
||||
} else {
|
||||
return t + ' ' + un.seconds;
|
||||
}
|
||||
},
|
||||
|
||||
formatInstruction: function(instr, i) {
|
||||
if (instr.text === undefined) {
|
||||
return this.capitalize(L.Util.template(this._getInstructionTemplate(instr, i),
|
||||
L.extend({}, instr, {
|
||||
exitStr: instr.exit ? this._localization.localize('formatOrder')(instr.exit) : '',
|
||||
dir: this._localization.localize(['directions', instr.direction]),
|
||||
modifier: this._localization.localize(['directions', instr.modifier])
|
||||
})));
|
||||
} else {
|
||||
return instr.text;
|
||||
}
|
||||
},
|
||||
|
||||
getIconName: function(instr, i) {
|
||||
switch (instr.type) {
|
||||
case 'Head':
|
||||
if (i === 0) {
|
||||
return 'depart';
|
||||
}
|
||||
break;
|
||||
case 'WaypointReached':
|
||||
return 'via';
|
||||
case 'Roundabout':
|
||||
return 'enter-roundabout';
|
||||
case 'DestinationReached':
|
||||
return 'arrive';
|
||||
}
|
||||
|
||||
switch (instr.modifier) {
|
||||
case 'Straight':
|
||||
return 'continue';
|
||||
case 'SlightRight':
|
||||
return 'bear-right';
|
||||
case 'Right':
|
||||
return 'turn-right';
|
||||
case 'SharpRight':
|
||||
return 'sharp-right';
|
||||
case 'TurnAround':
|
||||
case 'Uturn':
|
||||
return 'u-turn';
|
||||
case 'SharpLeft':
|
||||
return 'sharp-left';
|
||||
case 'Left':
|
||||
return 'turn-left';
|
||||
case 'SlightLeft':
|
||||
return 'bear-left';
|
||||
}
|
||||
},
|
||||
|
||||
capitalize: function(s) {
|
||||
return s.charAt(0).toUpperCase() + s.substring(1);
|
||||
},
|
||||
|
||||
_getInstructionTemplate: function(instr, i) {
|
||||
var type = instr.type === 'Straight' ? (i === 0 ? 'Head' : 'Continue') : instr.type,
|
||||
strings = this._localization.localize(['instructions', type]);
|
||||
|
||||
if (!strings) {
|
||||
strings = [
|
||||
this._localization.localize(['directions', type]),
|
||||
' ' + this._localization.localize(['instructions', 'Onto'])
|
||||
];
|
||||
}
|
||||
|
||||
return strings[0] + (strings.length > 1 && instr.road ? strings[1] : '');
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,146 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
var Autocomplete = require('./autocomplete');
|
||||
var Localization = require('./localization');
|
||||
|
||||
function selectInputText(input) {
|
||||
if (input.setSelectionRange) {
|
||||
// On iOS, select() doesn't work
|
||||
input.setSelectionRange(0, 9999);
|
||||
} else {
|
||||
// On at least IE8, setSeleectionRange doesn't exist
|
||||
input.select();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
createGeocoder: function(i, nWps, options) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-routing-geocoder'),
|
||||
input = L.DomUtil.create('input', '', container),
|
||||
remove = options.addWaypoints ? L.DomUtil.create('span', 'leaflet-routing-remove-waypoint', container) : undefined;
|
||||
|
||||
input.disabled = !options.addWaypoints;
|
||||
|
||||
return {
|
||||
container: container,
|
||||
input: input,
|
||||
closeButton: remove
|
||||
};
|
||||
},
|
||||
geocoderPlaceholder: function(i, numberWaypoints, geocoderElement) {
|
||||
var l = new Localization(geocoderElement.options.language).localize('ui');
|
||||
return i === 0 ?
|
||||
l.startPlaceholder :
|
||||
(i < numberWaypoints - 1 ?
|
||||
L.Util.template(l.viaPlaceholder, {viaNumber: i}) :
|
||||
l.endPlaceholder);
|
||||
},
|
||||
|
||||
geocoderClass: function() {
|
||||
return '';
|
||||
},
|
||||
|
||||
waypointNameFallback: function(latLng) {
|
||||
var ns = latLng.lat < 0 ? 'S' : 'N',
|
||||
ew = latLng.lng < 0 ? 'W' : 'E',
|
||||
lat = (Math.round(Math.abs(latLng.lat) * 10000) / 10000).toString(),
|
||||
lng = (Math.round(Math.abs(latLng.lng) * 10000) / 10000).toString();
|
||||
return ns + lat + ', ' + ew + lng;
|
||||
},
|
||||
maxGeocoderTolerance: 200,
|
||||
autocompleteOptions: {},
|
||||
language: 'en',
|
||||
},
|
||||
|
||||
initialize: function(wp, i, nWps, options) {
|
||||
L.setOptions(this, options);
|
||||
|
||||
var g = this.options.createGeocoder(i, nWps, this.options),
|
||||
closeButton = g.closeButton,
|
||||
geocoderInput = g.input;
|
||||
geocoderInput.setAttribute('placeholder', this.options.geocoderPlaceholder(i, nWps, this));
|
||||
geocoderInput.className = this.options.geocoderClass(i, nWps);
|
||||
|
||||
this._element = g;
|
||||
this._waypoint = wp;
|
||||
|
||||
this.update();
|
||||
// This has to be here, or geocoder's value will not be properly
|
||||
// initialized.
|
||||
// TODO: look into why and make _updateWaypointName fix this.
|
||||
geocoderInput.value = wp.name;
|
||||
|
||||
L.DomEvent.addListener(geocoderInput, 'click', function() {
|
||||
selectInputText(this);
|
||||
}, geocoderInput);
|
||||
|
||||
if (closeButton) {
|
||||
L.DomEvent.addListener(closeButton, 'click', function() {
|
||||
this.fire('delete', { waypoint: this._waypoint });
|
||||
}, this);
|
||||
}
|
||||
|
||||
new Autocomplete(geocoderInput, function(r) {
|
||||
geocoderInput.value = r.name;
|
||||
wp.name = r.name;
|
||||
wp.latLng = r.center;
|
||||
this.fire('geocoded', { waypoint: wp, value: r });
|
||||
}, this, L.extend({
|
||||
resultFn: this.options.geocoder.geocode,
|
||||
resultContext: this.options.geocoder,
|
||||
autocompleteFn: this.options.geocoder.suggest,
|
||||
autocompleteContext: this.options.geocoder
|
||||
}, this.options.autocompleteOptions));
|
||||
},
|
||||
|
||||
getContainer: function() {
|
||||
return this._element.container;
|
||||
},
|
||||
|
||||
setValue: function(v) {
|
||||
this._element.input.value = v;
|
||||
},
|
||||
|
||||
update: function(force) {
|
||||
var wp = this._waypoint,
|
||||
wpCoords;
|
||||
|
||||
wp.name = wp.name || '';
|
||||
|
||||
if (wp.latLng && (force || !wp.name)) {
|
||||
wpCoords = this.options.waypointNameFallback(wp.latLng);
|
||||
if (this.options.geocoder && this.options.geocoder.reverse) {
|
||||
this.options.geocoder.reverse(wp.latLng, 67108864 /* zoom 18 */, function(rs) {
|
||||
if (rs.length > 0 && rs[0].center.distanceTo(wp.latLng) < this.options.maxGeocoderTolerance) {
|
||||
wp.name = rs[0].name;
|
||||
} else {
|
||||
wp.name = wpCoords;
|
||||
}
|
||||
this._update();
|
||||
}, this);
|
||||
} else {
|
||||
wp.name = wpCoords;
|
||||
this._update();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
var input = this._element.input;
|
||||
input.focus();
|
||||
selectInputText(input);
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
var wp = this._waypoint,
|
||||
value = wp && wp.name ? wp.name : '';
|
||||
this.setValue(value);
|
||||
this.fire('reversegeocoded', {waypoint: wp, value: value});
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,80 @@
|
||||
var L = require('leaflet'),
|
||||
Control = require('./control'),
|
||||
Itinerary = require('./itinerary'),
|
||||
Line = require('./line'),
|
||||
OSRMv1 = require('./osrm-v1'),
|
||||
Plan = require('./plan'),
|
||||
Waypoint = require('./waypoint'),
|
||||
Autocomplete = require('./autocomplete'),
|
||||
Formatter = require('./formatter'),
|
||||
GeocoderElement = require('./geocoder-element'),
|
||||
Localization = require('./localization'),
|
||||
ItineraryBuilder = require('./itinerary-builder'),
|
||||
Mapbox = require('./mapbox'),
|
||||
ErrorControl = require('./error-control');
|
||||
|
||||
L.routing = {
|
||||
control: function(options) { return new Control(options); },
|
||||
itinerary: function(options) {
|
||||
return Itinerary(options);
|
||||
},
|
||||
line: function(route, options) {
|
||||
return new Line(route, options);
|
||||
},
|
||||
plan: function(waypoints, options) {
|
||||
return new Plan(waypoints, options);
|
||||
},
|
||||
waypoint: function(latLng, name, options) {
|
||||
return new Waypoint(latLng, name, options);
|
||||
},
|
||||
osrmv1: function(options) {
|
||||
return new OSRMv1(options);
|
||||
},
|
||||
localization: function(options) {
|
||||
return new Localization(options);
|
||||
},
|
||||
formatter: function(options) {
|
||||
return new Formatter(options);
|
||||
},
|
||||
geocoderElement: function(wp, i, nWps, plan) {
|
||||
return new L.Routing.GeocoderElement(wp, i, nWps, plan);
|
||||
},
|
||||
itineraryBuilder: function(options) {
|
||||
return new ItineraryBuilder(options);
|
||||
},
|
||||
mapbox: function(accessToken, options) {
|
||||
return new Mapbox(accessToken, options);
|
||||
},
|
||||
errorControl: function(routingControl, options) {
|
||||
return new ErrorControl(routingControl, options);
|
||||
},
|
||||
autocomplete: function(elem, callback, context, options) {
|
||||
return new Autocomplete(elem, callback, context, options);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = L.Routing = {
|
||||
Control: Control,
|
||||
Itinerary: Itinerary,
|
||||
Line: Line,
|
||||
OSRMv1: OSRMv1,
|
||||
Plan: Plan,
|
||||
Waypoint: Waypoint,
|
||||
Autocomplete: Autocomplete,
|
||||
Formatter: Formatter,
|
||||
GeocoderElement: GeocoderElement,
|
||||
Localization: Localization,
|
||||
Formatter: Formatter,
|
||||
ItineraryBuilder: ItineraryBuilder,
|
||||
|
||||
// Legacy; remove these in next major release
|
||||
control: L.routing.control,
|
||||
itinerary: L.routing.itinerary,
|
||||
line: L.routing.line,
|
||||
plan: L.routing.plan,
|
||||
waypoint: L.routing.waypoint,
|
||||
osrmv1: L.routing.osrmv1,
|
||||
geocoderElement: L.routing.geocoderElement,
|
||||
mapbox: L.routing.mapbox,
|
||||
errorControl: L.routing.errorControl,
|
||||
};
|
||||
@ -0,0 +1,44 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
module.exports = L.Class.extend({
|
||||
options: {
|
||||
containerClassName: ''
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.setOptions(this, options);
|
||||
},
|
||||
|
||||
createContainer: function(className) {
|
||||
var table = L.DomUtil.create('table', className || ''),
|
||||
colgroup = L.DomUtil.create('colgroup', '', table);
|
||||
|
||||
L.DomUtil.create('col', 'leaflet-routing-instruction-icon', colgroup);
|
||||
L.DomUtil.create('col', 'leaflet-routing-instruction-text', colgroup);
|
||||
L.DomUtil.create('col', 'leaflet-routing-instruction-distance', colgroup);
|
||||
|
||||
return table;
|
||||
},
|
||||
|
||||
createStepsContainer: function() {
|
||||
return L.DomUtil.create('tbody', '');
|
||||
},
|
||||
|
||||
createStep: function(text, distance, icon, steps) {
|
||||
var row = L.DomUtil.create('tr', '', steps),
|
||||
span,
|
||||
td;
|
||||
td = L.DomUtil.create('td', '', row);
|
||||
span = L.DomUtil.create('span', 'leaflet-routing-icon leaflet-routing-icon-'+icon, td);
|
||||
td.appendChild(span);
|
||||
td = L.DomUtil.create('td', '', row);
|
||||
td.appendChild(document.createTextNode(text));
|
||||
td = L.DomUtil.create('td', '', row);
|
||||
td.appendChild(document.createTextNode(distance));
|
||||
return row;
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,225 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
var Formatter = require('./formatter');
|
||||
var ItineraryBuilder = require('./itinerary-builder');
|
||||
|
||||
module.exports = L.Control.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
pointMarkerStyle: {
|
||||
radius: 5,
|
||||
color: '#03f',
|
||||
fillColor: 'white',
|
||||
opacity: 1,
|
||||
fillOpacity: 0.7
|
||||
},
|
||||
summaryTemplate: '<h2>{name}</h2><h3>{distance}, {time}</h3>',
|
||||
timeTemplate: '{time}',
|
||||
containerClassName: '',
|
||||
alternativeClassName: '',
|
||||
minimizedClassName: '',
|
||||
itineraryClassName: '',
|
||||
totalDistanceRoundingSensitivity: -1,
|
||||
show: true,
|
||||
collapsible: undefined,
|
||||
collapseBtn: function(itinerary) {
|
||||
var collapseBtn = L.DomUtil.create('span', itinerary.options.collapseBtnClass);
|
||||
L.DomEvent.on(collapseBtn, 'click', itinerary._toggle, itinerary);
|
||||
itinerary._container.insertBefore(collapseBtn, itinerary._container.firstChild);
|
||||
},
|
||||
collapseBtnClass: 'leaflet-routing-collapse-btn'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.setOptions(this, options);
|
||||
this._formatter = this.options.formatter || new Formatter(this.options);
|
||||
this._itineraryBuilder = this.options.itineraryBuilder || new ItineraryBuilder({
|
||||
containerClassName: this.options.itineraryClassName
|
||||
});
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
var collapsible = this.options.collapsible;
|
||||
|
||||
collapsible = collapsible || (collapsible === undefined && map.getSize().x <= 640);
|
||||
|
||||
this._container = L.DomUtil.create('div', 'leaflet-routing-container leaflet-bar ' +
|
||||
(!this.options.show ? 'leaflet-routing-container-hide ' : '') +
|
||||
(collapsible ? 'leaflet-routing-collapsible ' : '') +
|
||||
this.options.containerClassName);
|
||||
this._altContainer = this.createAlternativesContainer();
|
||||
this._container.appendChild(this._altContainer);
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
L.DomEvent.addListener(this._container, 'mousewheel', function(e) {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
});
|
||||
|
||||
if (collapsible) {
|
||||
this.options.collapseBtn(this);
|
||||
}
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function() {
|
||||
},
|
||||
|
||||
createAlternativesContainer: function() {
|
||||
return L.DomUtil.create('div', 'leaflet-routing-alternatives-container');
|
||||
},
|
||||
|
||||
setAlternatives: function(routes) {
|
||||
var i,
|
||||
alt,
|
||||
altDiv;
|
||||
|
||||
this._clearAlts();
|
||||
|
||||
this._routes = routes;
|
||||
|
||||
for (i = 0; i < this._routes.length; i++) {
|
||||
alt = this._routes[i];
|
||||
altDiv = this._createAlternative(alt, i);
|
||||
this._altContainer.appendChild(altDiv);
|
||||
this._altElements.push(altDiv);
|
||||
}
|
||||
|
||||
this._selectRoute({route: this._routes[0], alternatives: this._routes.slice(1)});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-routing-container-hide');
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
L.DomUtil.addClass(this._container, 'leaflet-routing-container-hide');
|
||||
},
|
||||
|
||||
_toggle: function() {
|
||||
var collapsed = L.DomUtil.hasClass(this._container, 'leaflet-routing-container-hide');
|
||||
this[collapsed ? 'show' : 'hide']();
|
||||
},
|
||||
|
||||
_createAlternative: function(alt, i) {
|
||||
var altDiv = L.DomUtil.create('div', 'leaflet-routing-alt ' +
|
||||
this.options.alternativeClassName +
|
||||
(i > 0 ? ' leaflet-routing-alt-minimized ' + this.options.minimizedClassName : '')),
|
||||
template = this.options.summaryTemplate,
|
||||
data = L.extend({
|
||||
name: alt.name,
|
||||
distance: this._formatter.formatDistance(alt.summary.totalDistance, this.options.totalDistanceRoundingSensitivity),
|
||||
time: this._formatter.formatTime(alt.summary.totalTime)
|
||||
}, alt);
|
||||
altDiv.innerHTML = typeof(template) === 'function' ? template(data) : L.Util.template(template, data);
|
||||
L.DomEvent.addListener(altDiv, 'click', this._onAltClicked, this);
|
||||
this.on('routeselected', this._selectAlt, this);
|
||||
|
||||
altDiv.appendChild(this._createItineraryContainer(alt));
|
||||
return altDiv;
|
||||
},
|
||||
|
||||
_clearAlts: function() {
|
||||
var el = this._altContainer;
|
||||
while (el && el.firstChild) {
|
||||
el.removeChild(el.firstChild);
|
||||
}
|
||||
|
||||
this._altElements = [];
|
||||
},
|
||||
|
||||
_createItineraryContainer: function(r) {
|
||||
var container = this._itineraryBuilder.createContainer(),
|
||||
steps = this._itineraryBuilder.createStepsContainer(),
|
||||
i,
|
||||
instr,
|
||||
step,
|
||||
distance,
|
||||
text,
|
||||
icon;
|
||||
|
||||
container.appendChild(steps);
|
||||
|
||||
for (i = 0; i < r.instructions.length; i++) {
|
||||
instr = r.instructions[i];
|
||||
text = this._formatter.formatInstruction(instr, i);
|
||||
distance = this._formatter.formatDistance(instr.distance);
|
||||
icon = this._formatter.getIconName(instr, i);
|
||||
step = this._itineraryBuilder.createStep(text, distance, icon, steps);
|
||||
|
||||
this._addRowListeners(step, r.coordinates[instr.index]);
|
||||
}
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
_addRowListeners: function(row, coordinate) {
|
||||
L.DomEvent.addListener(row, 'mouseover', function() {
|
||||
this._marker = L.circleMarker(coordinate,
|
||||
this.options.pointMarkerStyle).addTo(this._map);
|
||||
}, this);
|
||||
L.DomEvent.addListener(row, 'mouseout', function() {
|
||||
if (this._marker) {
|
||||
this._map.removeLayer(this._marker);
|
||||
delete this._marker;
|
||||
}
|
||||
}, this);
|
||||
L.DomEvent.addListener(row, 'click', function(e) {
|
||||
this._map.panTo(coordinate);
|
||||
L.DomEvent.stopPropagation(e);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onAltClicked: function(e) {
|
||||
var altElem = e.target || window.event.srcElement;
|
||||
while (!L.DomUtil.hasClass(altElem, 'leaflet-routing-alt')) {
|
||||
altElem = altElem.parentElement;
|
||||
}
|
||||
|
||||
var j = this._altElements.indexOf(altElem);
|
||||
var alts = this._routes.slice();
|
||||
var route = alts.splice(j, 1)[0];
|
||||
|
||||
this.fire('routeselected', {
|
||||
route: route,
|
||||
alternatives: alts
|
||||
});
|
||||
},
|
||||
|
||||
_selectAlt: function(e) {
|
||||
var altElem,
|
||||
j,
|
||||
n,
|
||||
classFn;
|
||||
|
||||
altElem = this._altElements[e.route.routesIndex];
|
||||
|
||||
if (L.DomUtil.hasClass(altElem, 'leaflet-routing-alt-minimized')) {
|
||||
for (j = 0; j < this._altElements.length; j++) {
|
||||
n = this._altElements[j];
|
||||
classFn = j === e.route.routesIndex ? 'removeClass' : 'addClass';
|
||||
L.DomUtil[classFn](n, 'leaflet-routing-alt-minimized');
|
||||
if (this.options.minimizedClassName) {
|
||||
L.DomUtil[classFn](n, this.options.minimizedClassName);
|
||||
}
|
||||
|
||||
if (j !== e.route.routesIndex) n.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
L.DomEvent.stop(e);
|
||||
},
|
||||
|
||||
_selectRoute: function(routes) {
|
||||
if (this._marker) {
|
||||
this._map.removeLayer(this._marker);
|
||||
delete this._marker;
|
||||
}
|
||||
this.fire('routeselected', routes);
|
||||
}
|
||||
});
|
||||
})();
|
||||
130
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/line.js
Normal file
130
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/line.js
Normal file
@ -0,0 +1,130 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
module.exports = L.LayerGroup.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
styles: [
|
||||
{color: 'black', opacity: 0.15, weight: 9},
|
||||
{color: 'white', opacity: 0.8, weight: 6},
|
||||
{color: 'red', opacity: 1, weight: 2}
|
||||
],
|
||||
missingRouteStyles: [
|
||||
{color: 'black', opacity: 0.15, weight: 7},
|
||||
{color: 'white', opacity: 0.6, weight: 4},
|
||||
{color: 'gray', opacity: 0.8, weight: 2, dashArray: '7,12'}
|
||||
],
|
||||
addWaypoints: true,
|
||||
extendToWaypoints: true,
|
||||
missingRouteTolerance: 10
|
||||
},
|
||||
|
||||
initialize: function(route, options) {
|
||||
L.setOptions(this, options);
|
||||
L.LayerGroup.prototype.initialize.call(this, options);
|
||||
this._route = route;
|
||||
|
||||
if (this.options.extendToWaypoints) {
|
||||
this._extendToWaypoints();
|
||||
}
|
||||
|
||||
this._addSegment(
|
||||
route.coordinates,
|
||||
this.options.styles,
|
||||
this.options.addWaypoints);
|
||||
},
|
||||
|
||||
getBounds: function() {
|
||||
return L.latLngBounds(this._route.coordinates);
|
||||
},
|
||||
|
||||
_findWaypointIndices: function() {
|
||||
var wps = this._route.inputWaypoints,
|
||||
indices = [],
|
||||
i;
|
||||
for (i = 0; i < wps.length; i++) {
|
||||
indices.push(this._findClosestRoutePoint(wps[i].latLng));
|
||||
}
|
||||
|
||||
return indices;
|
||||
},
|
||||
|
||||
_findClosestRoutePoint: function(latlng) {
|
||||
var minDist = Number.MAX_VALUE,
|
||||
minIndex,
|
||||
i,
|
||||
d;
|
||||
|
||||
for (i = this._route.coordinates.length - 1; i >= 0 ; i--) {
|
||||
// TODO: maybe do this in pixel space instead?
|
||||
d = latlng.distanceTo(this._route.coordinates[i]);
|
||||
if (d < minDist) {
|
||||
minIndex = i;
|
||||
minDist = d;
|
||||
}
|
||||
}
|
||||
|
||||
return minIndex;
|
||||
},
|
||||
|
||||
_extendToWaypoints: function() {
|
||||
var wps = this._route.inputWaypoints,
|
||||
wpIndices = this._getWaypointIndices(),
|
||||
i,
|
||||
wpLatLng,
|
||||
routeCoord;
|
||||
|
||||
for (i = 0; i < wps.length; i++) {
|
||||
wpLatLng = wps[i].latLng;
|
||||
routeCoord = L.latLng(this._route.coordinates[wpIndices[i]]);
|
||||
if (wpLatLng.distanceTo(routeCoord) >
|
||||
this.options.missingRouteTolerance) {
|
||||
this._addSegment([wpLatLng, routeCoord],
|
||||
this.options.missingRouteStyles);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_addSegment: function(coords, styles, mouselistener) {
|
||||
var i,
|
||||
pl;
|
||||
|
||||
for (i = 0; i < styles.length; i++) {
|
||||
pl = L.polyline(coords, styles[i]);
|
||||
this.addLayer(pl);
|
||||
if (mouselistener) {
|
||||
pl.on('mousedown', this._onLineTouched, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_findNearestWpBefore: function(i) {
|
||||
var wpIndices = this._getWaypointIndices(),
|
||||
j = wpIndices.length - 1;
|
||||
while (j >= 0 && wpIndices[j] > i) {
|
||||
j--;
|
||||
}
|
||||
|
||||
return j;
|
||||
},
|
||||
|
||||
_onLineTouched: function(e) {
|
||||
var afterIndex = this._findNearestWpBefore(this._findClosestRoutePoint(e.latlng));
|
||||
this.fire('linetouched', {
|
||||
afterIndex: afterIndex,
|
||||
latlng: e.latlng
|
||||
});
|
||||
},
|
||||
|
||||
_getWaypointIndices: function() {
|
||||
if (!this._wpIndices) {
|
||||
this._wpIndices = this._route.waypointIndices || this._findWaypointIndices();
|
||||
}
|
||||
|
||||
return this._wpIndices;
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,713 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var spanish = {
|
||||
directions: {
|
||||
N: 'norte',
|
||||
NE: 'noreste',
|
||||
E: 'este',
|
||||
SE: 'sureste',
|
||||
S: 'sur',
|
||||
SW: 'suroeste',
|
||||
W: 'oeste',
|
||||
NW: 'noroeste',
|
||||
SlightRight: 'leve giro a la derecha',
|
||||
Right: 'derecha',
|
||||
SharpRight: 'giro pronunciado a la derecha',
|
||||
SlightLeft: 'leve giro a la izquierda',
|
||||
Left: 'izquierda',
|
||||
SharpLeft: 'giro pronunciado a la izquierda',
|
||||
Uturn: 'media vuelta'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Derecho {dir}', ' sobre {road}'],
|
||||
'Continue':
|
||||
['Continuar {dir}', ' en {road}'],
|
||||
'TurnAround':
|
||||
['Dar vuelta'],
|
||||
'WaypointReached':
|
||||
['Llegó a un punto del camino'],
|
||||
'Roundabout':
|
||||
['Tomar {exitStr} salida en la rotonda', ' en {road}'],
|
||||
'DestinationReached':
|
||||
['Llegada a destino'],
|
||||
'Fork': ['En el cruce gira a {modifier}', ' hacia {road}'],
|
||||
'Merge': ['Incorpórate {modifier}', ' hacia {road}'],
|
||||
'OnRamp': ['Gira {modifier} en la salida', ' hacia {road}'],
|
||||
'OffRamp': ['Toma la salida {modifier}', ' hacia {road}'],
|
||||
'EndOfRoad': ['Gira {modifier} al final de la carretera', ' hacia {road}'],
|
||||
'Onto': 'hacia {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Inicio',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'Destino'
|
||||
},
|
||||
units: {
|
||||
meters: 'm',
|
||||
kilometers: 'km',
|
||||
yards: 'yd',
|
||||
miles: 'mi',
|
||||
hours: 'h',
|
||||
minutes: 'min',
|
||||
seconds: 's'
|
||||
}
|
||||
};
|
||||
|
||||
L.Routing = L.Routing || {};
|
||||
|
||||
var Localization = L.Class.extend({
|
||||
initialize: function(langs) {
|
||||
this._langs = L.Util.isArray(langs) ? langs : [langs, 'en'];
|
||||
|
||||
for (var i = 0, l = this._langs.length; i < l; i++) {
|
||||
if (!Localization[this._langs[i]]) {
|
||||
throw new Error('No localization for language "' + this._langs[i] + '".');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
localize: function(keys) {
|
||||
var dict,
|
||||
key,
|
||||
value;
|
||||
|
||||
keys = L.Util.isArray(keys) ? keys : [keys];
|
||||
|
||||
for (var i = 0, l = this._langs.length; i < l; i++) {
|
||||
dict = Localization[this._langs[i]];
|
||||
for (var j = 0, nKeys = keys.length; dict && j < nKeys; j++) {
|
||||
key = keys[j];
|
||||
value = dict[key];
|
||||
dict = value;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = L.extend(Localization, {
|
||||
'en': {
|
||||
directions: {
|
||||
N: 'north',
|
||||
NE: 'northeast',
|
||||
E: 'east',
|
||||
SE: 'southeast',
|
||||
S: 'south',
|
||||
SW: 'southwest',
|
||||
W: 'west',
|
||||
NW: 'northwest',
|
||||
SlightRight: 'slight right',
|
||||
Right: 'right',
|
||||
SharpRight: 'sharp right',
|
||||
SlightLeft: 'slight left',
|
||||
Left: 'left',
|
||||
SharpLeft: 'sharp left',
|
||||
Uturn: 'Turn around'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Head {dir}', ' on {road}'],
|
||||
'Continue':
|
||||
['Continue {dir}'],
|
||||
'TurnAround':
|
||||
['Turn around'],
|
||||
'WaypointReached':
|
||||
['Waypoint reached'],
|
||||
'Roundabout':
|
||||
['Take the {exitStr} exit in the roundabout', ' onto {road}'],
|
||||
'DestinationReached':
|
||||
['Destination reached'],
|
||||
'Fork': ['At the fork, turn {modifier}', ' onto {road}'],
|
||||
'Merge': ['Merge {modifier}', ' onto {road}'],
|
||||
'OnRamp': ['Turn {modifier} on the ramp', ' onto {road}'],
|
||||
'OffRamp': ['Take the ramp on the {modifier}', ' onto {road}'],
|
||||
'EndOfRoad': ['Turn {modifier} at the end of the road', ' onto {road}'],
|
||||
'Onto': 'onto {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
var i = n % 10 - 1,
|
||||
suffix = ['st', 'nd', 'rd'];
|
||||
|
||||
return suffix[i] ? n + suffix[i] : n + 'th';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Start',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'End'
|
||||
},
|
||||
units: {
|
||||
meters: 'm',
|
||||
kilometers: 'km',
|
||||
yards: 'yd',
|
||||
miles: 'mi',
|
||||
hours: 'h',
|
||||
minutes: 'min',
|
||||
seconds: 's'
|
||||
}
|
||||
},
|
||||
|
||||
'de': {
|
||||
directions: {
|
||||
N: 'Norden',
|
||||
NE: 'Nordosten',
|
||||
E: 'Osten',
|
||||
SE: 'Südosten',
|
||||
S: 'Süden',
|
||||
SW: 'Südwesten',
|
||||
W: 'Westen',
|
||||
NW: 'Nordwesten',
|
||||
SlightRight: 'leicht rechts',
|
||||
Right: 'rechts',
|
||||
SharpRight: 'scharf rechts',
|
||||
SlightLeft: 'leicht links',
|
||||
Left: 'links',
|
||||
SharpLeft: 'scharf links',
|
||||
Uturn: 'Wenden'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Richtung {dir}', ' auf {road}'],
|
||||
'Continue':
|
||||
['Geradeaus Richtung {dir}', ' auf {road}'],
|
||||
'SlightRight':
|
||||
['Leicht rechts abbiegen', ' auf {road}'],
|
||||
'Right':
|
||||
['Rechts abbiegen', ' auf {road}'],
|
||||
'SharpRight':
|
||||
['Scharf rechts abbiegen', ' auf {road}'],
|
||||
'TurnAround':
|
||||
['Wenden'],
|
||||
'SharpLeft':
|
||||
['Scharf links abbiegen', ' auf {road}'],
|
||||
'Left':
|
||||
['Links abbiegen', ' auf {road}'],
|
||||
'SlightLeft':
|
||||
['Leicht links abbiegen', ' auf {road}'],
|
||||
'WaypointReached':
|
||||
['Zwischenhalt erreicht'],
|
||||
'Roundabout':
|
||||
['Nehmen Sie die {exitStr} Ausfahrt im Kreisverkehr', ' auf {road}'],
|
||||
'DestinationReached':
|
||||
['Sie haben ihr Ziel erreicht'],
|
||||
'Fork': ['An der Kreuzung {modifier}', ' auf {road}'],
|
||||
'Merge': ['Fahren Sie {modifier} weiter', ' auf {road}'],
|
||||
'OnRamp': ['Fahren Sie {modifier} auf die Auffahrt', ' auf {road}'],
|
||||
'OffRamp': ['Nehmen Sie die Ausfahrt {modifier}', ' auf {road}'],
|
||||
'EndOfRoad': ['Fahren Sie {modifier} am Ende der Straße', ' auf {road}'],
|
||||
'Onto': 'auf {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + '.';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Start',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'Ziel'
|
||||
}
|
||||
},
|
||||
|
||||
'sv': {
|
||||
directions: {
|
||||
N: 'norr',
|
||||
NE: 'nordost',
|
||||
E: 'öst',
|
||||
SE: 'sydost',
|
||||
S: 'syd',
|
||||
SW: 'sydväst',
|
||||
W: 'väst',
|
||||
NW: 'nordväst',
|
||||
SlightRight: 'svagt höger',
|
||||
Right: 'höger',
|
||||
SharpRight: 'skarpt höger',
|
||||
SlightLeft: 'svagt vänster',
|
||||
Left: 'vänster',
|
||||
SharpLeft: 'skarpt vänster',
|
||||
Uturn: 'Vänd'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Åk åt {dir}', ' till {road}'],
|
||||
'Continue':
|
||||
['Fortsätt {dir}'],
|
||||
'SlightRight':
|
||||
['Svagt höger', ' till {road}'],
|
||||
'Right':
|
||||
['Sväng höger', ' till {road}'],
|
||||
'SharpRight':
|
||||
['Skarpt höger', ' till {road}'],
|
||||
'TurnAround':
|
||||
['Vänd'],
|
||||
'SharpLeft':
|
||||
['Skarpt vänster', ' till {road}'],
|
||||
'Left':
|
||||
['Sväng vänster', ' till {road}'],
|
||||
'SlightLeft':
|
||||
['Svagt vänster', ' till {road}'],
|
||||
'WaypointReached':
|
||||
['Viapunkt nådd'],
|
||||
'Roundabout':
|
||||
['Tag {exitStr} avfarten i rondellen', ' till {road}'],
|
||||
'DestinationReached':
|
||||
['Framme vid resans mål'],
|
||||
'Fork': ['Tag av {modifier}', ' till {road}'],
|
||||
'Merge': ['Anslut {modifier} ', ' till {road}'],
|
||||
'OnRamp': ['Tag påfarten {modifier}', ' till {road}'],
|
||||
'OffRamp': ['Tag avfarten {modifier}', ' till {road}'],
|
||||
'EndOfRoad': ['Sväng {modifier} vid vägens slut', ' till {road}'],
|
||||
'Onto': 'till {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return ['första', 'andra', 'tredje', 'fjärde', 'femte',
|
||||
'sjätte', 'sjunde', 'åttonde', 'nionde', 'tionde'
|
||||
/* Can't possibly be more than ten exits, can there? */][n - 1];
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Från',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'Till'
|
||||
}
|
||||
},
|
||||
|
||||
'es': spanish,
|
||||
'sp': spanish,
|
||||
|
||||
'nl': {
|
||||
directions: {
|
||||
N: 'noordelijke',
|
||||
NE: 'noordoostelijke',
|
||||
E: 'oostelijke',
|
||||
SE: 'zuidoostelijke',
|
||||
S: 'zuidelijke',
|
||||
SW: 'zuidewestelijke',
|
||||
W: 'westelijke',
|
||||
NW: 'noordwestelijke'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Vertrek in {dir} richting', ' de {road} op'],
|
||||
'Continue':
|
||||
['Ga in {dir} richting', ' de {road} op'],
|
||||
'SlightRight':
|
||||
['Volg de weg naar rechts', ' de {road} op'],
|
||||
'Right':
|
||||
['Ga rechtsaf', ' de {road} op'],
|
||||
'SharpRight':
|
||||
['Ga scherpe bocht naar rechts', ' de {road} op'],
|
||||
'TurnAround':
|
||||
['Keer om'],
|
||||
'SharpLeft':
|
||||
['Ga scherpe bocht naar links', ' de {road} op'],
|
||||
'Left':
|
||||
['Ga linksaf', ' de {road} op'],
|
||||
'SlightLeft':
|
||||
['Volg de weg naar links', ' de {road} op'],
|
||||
'WaypointReached':
|
||||
['Aangekomen bij tussenpunt'],
|
||||
'Roundabout':
|
||||
['Neem de {exitStr} afslag op de rotonde', ' de {road} op'],
|
||||
'DestinationReached':
|
||||
['Aangekomen op eindpunt'],
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
if (n === 1 || n >= 20) {
|
||||
return n + 'ste';
|
||||
} else {
|
||||
return n + 'de';
|
||||
}
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Vertrekpunt',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'Bestemming'
|
||||
}
|
||||
},
|
||||
'fr': {
|
||||
directions: {
|
||||
N: 'nord',
|
||||
NE: 'nord-est',
|
||||
E: 'est',
|
||||
SE: 'sud-est',
|
||||
S: 'sud',
|
||||
SW: 'sud-ouest',
|
||||
W: 'ouest',
|
||||
NW: 'nord-ouest'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Tout droit au {dir}', ' sur {road}'],
|
||||
'Continue':
|
||||
['Continuer au {dir}', ' sur {road}'],
|
||||
'SlightRight':
|
||||
['Légèrement à droite', ' sur {road}'],
|
||||
'Right':
|
||||
['A droite', ' sur {road}'],
|
||||
'SharpRight':
|
||||
['Complètement à droite', ' sur {road}'],
|
||||
'TurnAround':
|
||||
['Faire demi-tour'],
|
||||
'SharpLeft':
|
||||
['Complètement à gauche', ' sur {road}'],
|
||||
'Left':
|
||||
['A gauche', ' sur {road}'],
|
||||
'SlightLeft':
|
||||
['Légèrement à gauche', ' sur {road}'],
|
||||
'WaypointReached':
|
||||
['Point d\'étape atteint'],
|
||||
'Roundabout':
|
||||
['Au rond-point, prenez la {exitStr} sortie', ' sur {road}'],
|
||||
'DestinationReached':
|
||||
['Destination atteinte'],
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Départ',
|
||||
viaPlaceholder: 'Intermédiaire {viaNumber}',
|
||||
endPlaceholder: 'Arrivée'
|
||||
}
|
||||
},
|
||||
'it': {
|
||||
directions: {
|
||||
N: 'nord',
|
||||
NE: 'nord-est',
|
||||
E: 'est',
|
||||
SE: 'sud-est',
|
||||
S: 'sud',
|
||||
SW: 'sud-ovest',
|
||||
W: 'ovest',
|
||||
NW: 'nord-ovest'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Dritto verso {dir}', ' su {road}'],
|
||||
'Continue':
|
||||
['Continuare verso {dir}', ' su {road}'],
|
||||
'SlightRight':
|
||||
['Mantenere la destra', ' su {road}'],
|
||||
'Right':
|
||||
['A destra', ' su {road}'],
|
||||
'SharpRight':
|
||||
['Strettamente a destra', ' su {road}'],
|
||||
'TurnAround':
|
||||
['Fare inversione di marcia'],
|
||||
'SharpLeft':
|
||||
['Strettamente a sinistra', ' su {road}'],
|
||||
'Left':
|
||||
['A sinistra', ' sur {road}'],
|
||||
'SlightLeft':
|
||||
['Mantenere la sinistra', ' su {road}'],
|
||||
'WaypointReached':
|
||||
['Punto di passaggio raggiunto'],
|
||||
'Roundabout':
|
||||
['Alla rotonda, prendere la {exitStr} uscita'],
|
||||
'DestinationReached':
|
||||
['Destinazione raggiunta'],
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Partenza',
|
||||
viaPlaceholder: 'Intermedia {viaNumber}',
|
||||
endPlaceholder: 'Destinazione'
|
||||
}
|
||||
},
|
||||
'pt': {
|
||||
directions: {
|
||||
N: 'norte',
|
||||
NE: 'nordeste',
|
||||
E: 'leste',
|
||||
SE: 'sudeste',
|
||||
S: 'sul',
|
||||
SW: 'sudoeste',
|
||||
W: 'oeste',
|
||||
NW: 'noroeste',
|
||||
SlightRight: 'curva ligeira a direita',
|
||||
Right: 'direita',
|
||||
SharpRight: 'curva fechada a direita',
|
||||
SlightLeft: 'ligeira a esquerda',
|
||||
Left: 'esquerda',
|
||||
SharpLeft: 'curva fechada a esquerda',
|
||||
Uturn: 'Meia volta'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Siga {dir}', ' na {road}'],
|
||||
'Continue':
|
||||
['Continue {dir}', ' na {road}'],
|
||||
'SlightRight':
|
||||
['Curva ligeira a direita', ' na {road}'],
|
||||
'Right':
|
||||
['Curva a direita', ' na {road}'],
|
||||
'SharpRight':
|
||||
['Curva fechada a direita', ' na {road}'],
|
||||
'TurnAround':
|
||||
['Retorne'],
|
||||
'SharpLeft':
|
||||
['Curva fechada a esquerda', ' na {road}'],
|
||||
'Left':
|
||||
['Curva a esquerda', ' na {road}'],
|
||||
'SlightLeft':
|
||||
['Curva ligueira a esquerda', ' na {road}'],
|
||||
'WaypointReached':
|
||||
['Ponto de interesse atingido'],
|
||||
'Roundabout':
|
||||
['Pegue a {exitStr} saída na rotatória', ' na {road}'],
|
||||
'DestinationReached':
|
||||
['Destino atingido'],
|
||||
'Fork': ['Na encruzilhada, vire a {modifier}', ' na {road}'],
|
||||
'Merge': ['Entre à {modifier}', ' na {road}'],
|
||||
'OnRamp': ['Vire {modifier} na rampa', ' na {road}'],
|
||||
'OffRamp': ['Entre na rampa na {modifier}', ' na {road}'],
|
||||
'EndOfRoad': ['Vire {modifier} no fim da rua', ' na {road}'],
|
||||
'Onto': 'na {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Origem',
|
||||
viaPlaceholder: 'Intermédio {viaNumber}',
|
||||
endPlaceholder: 'Destino'
|
||||
}
|
||||
},
|
||||
'sk': {
|
||||
directions: {
|
||||
N: 'sever',
|
||||
NE: 'serverovýchod',
|
||||
E: 'východ',
|
||||
SE: 'juhovýchod',
|
||||
S: 'juh',
|
||||
SW: 'juhozápad',
|
||||
W: 'západ',
|
||||
NW: 'serverozápad'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Mierte na {dir}', ' na {road}'],
|
||||
'Continue':
|
||||
['Pokračujte na {dir}', ' na {road}'],
|
||||
'SlightRight':
|
||||
['Mierne doprava', ' na {road}'],
|
||||
'Right':
|
||||
['Doprava', ' na {road}'],
|
||||
'SharpRight':
|
||||
['Prudko doprava', ' na {road}'],
|
||||
'TurnAround':
|
||||
['Otočte sa'],
|
||||
'SharpLeft':
|
||||
['Prudko doľava', ' na {road}'],
|
||||
'Left':
|
||||
['Doľava', ' na {road}'],
|
||||
'SlightLeft':
|
||||
['Mierne doľava', ' na {road}'],
|
||||
'WaypointReached':
|
||||
['Ste v prejazdovom bode.'],
|
||||
'Roundabout':
|
||||
['Odbočte na {exitStr} výjazde', ' na {road}'],
|
||||
'DestinationReached':
|
||||
['Prišli ste do cieľa.'],
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
var i = n % 10 - 1,
|
||||
suffix = ['.', '.', '.'];
|
||||
|
||||
return suffix[i] ? n + suffix[i] : n + '.';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Začiatok',
|
||||
viaPlaceholder: 'Cez {viaNumber}',
|
||||
endPlaceholder: 'Koniec'
|
||||
}
|
||||
},
|
||||
'el': {
|
||||
directions: {
|
||||
N: 'βόρεια',
|
||||
NE: 'βορειοανατολικά',
|
||||
E: 'ανατολικά',
|
||||
SE: 'νοτιοανατολικά',
|
||||
S: 'νότια',
|
||||
SW: 'νοτιοδυτικά',
|
||||
W: 'δυτικά',
|
||||
NW: 'βορειοδυτικά'
|
||||
},
|
||||
instructions: {
|
||||
// instruction, postfix if the road is named
|
||||
'Head':
|
||||
['Κατευθυνθείτε {dir}', ' στην {road}'],
|
||||
'Continue':
|
||||
['Συνεχίστε {dir}', ' στην {road}'],
|
||||
'SlightRight':
|
||||
['Ελαφρώς δεξιά', ' στην {road}'],
|
||||
'Right':
|
||||
['Δεξιά', ' στην {road}'],
|
||||
'SharpRight':
|
||||
['Απότομη δεξιά στροφή', ' στην {road}'],
|
||||
'TurnAround':
|
||||
['Κάντε αναστροφή'],
|
||||
'SharpLeft':
|
||||
['Απότομη αριστερή στροφή', ' στην {road}'],
|
||||
'Left':
|
||||
['Αριστερά', ' στην {road}'],
|
||||
'SlightLeft':
|
||||
['Ελαφρώς αριστερά', ' στην {road}'],
|
||||
'WaypointReached':
|
||||
['Φτάσατε στο σημείο αναφοράς'],
|
||||
'Roundabout':
|
||||
['Ακολουθήστε την {exitStr} έξοδο στο κυκλικό κόμβο', ' στην {road}'],
|
||||
'DestinationReached':
|
||||
['Φτάσατε στον προορισμό σας'],
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Αφετηρία',
|
||||
viaPlaceholder: 'μέσω {viaNumber}',
|
||||
endPlaceholder: 'Προορισμός'
|
||||
}
|
||||
},
|
||||
'ca': {
|
||||
directions: {
|
||||
N: 'nord',
|
||||
NE: 'nord-est',
|
||||
E: 'est',
|
||||
SE: 'sud-est',
|
||||
S: 'sud',
|
||||
SW: 'sud-oest',
|
||||
W: 'oest',
|
||||
NW: 'nord-oest',
|
||||
SlightRight: 'lleu gir a la dreta',
|
||||
Right: 'dreta',
|
||||
SharpRight: 'gir pronunciat a la dreta',
|
||||
SlightLeft: 'gir pronunciat a l\'esquerra',
|
||||
Left: 'esquerra',
|
||||
SharpLeft: 'lleu gir a l\'esquerra',
|
||||
Uturn: 'mitja volta'
|
||||
},
|
||||
instructions: {
|
||||
'Head':
|
||||
['Recte {dir}', ' sobre {road}'],
|
||||
'Continue':
|
||||
['Continuar {dir}'],
|
||||
'TurnAround':
|
||||
['donar la volta'],
|
||||
'WaypointReached':
|
||||
['Ha arribat a un punt del camí'],
|
||||
'Roundabout':
|
||||
['Agafar {exitStr} sortida a la rotonda', ' a {road}'],
|
||||
'DestinationReached':
|
||||
['Arribada al destí'],
|
||||
'Fork': ['A la cruïlla gira a la {modifier}', ' cap a {road}'],
|
||||
'Merge': ['Incorpora\'t {modifier}', ' a {road}'],
|
||||
'OnRamp': ['Gira {modifier} a la sortida', ' cap a {road}'],
|
||||
'OffRamp': ['Pren la sortida {modifier}', ' cap a {road}'],
|
||||
'EndOfRoad': ['Gira {modifier} al final de la carretera', ' cap a {road}'],
|
||||
'Onto': 'cap a {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + 'º';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Origen',
|
||||
viaPlaceholder: 'Via {viaNumber}',
|
||||
endPlaceholder: 'Destí'
|
||||
},
|
||||
units: {
|
||||
meters: 'm',
|
||||
kilometers: 'km',
|
||||
yards: 'yd',
|
||||
miles: 'mi',
|
||||
hours: 'h',
|
||||
minutes: 'min',
|
||||
seconds: 's'
|
||||
}
|
||||
},
|
||||
'ru': {
|
||||
directions: {
|
||||
N: 'север',
|
||||
NE: 'северовосток',
|
||||
E: 'восток',
|
||||
SE: 'юговосток',
|
||||
S: 'юг',
|
||||
SW: 'югозапад',
|
||||
W: 'запад',
|
||||
NW: 'северозапад',
|
||||
SlightRight: 'плавно направо',
|
||||
Right: 'направо',
|
||||
SharpRight: 'резко направо',
|
||||
SlightLeft: 'плавно налево',
|
||||
Left: 'налево',
|
||||
SharpLeft: 'резко налево',
|
||||
Uturn: 'развернуться'
|
||||
},
|
||||
instructions: {
|
||||
'Head':
|
||||
['Начать движение на {dir}', ' по {road}'],
|
||||
'Continue':
|
||||
['Продолжать движение на {dir}', ' по {road}'],
|
||||
'SlightRight':
|
||||
['Плавный поворот направо', ' на {road}'],
|
||||
'Right':
|
||||
['Направо', ' на {road}'],
|
||||
'SharpRight':
|
||||
['Резкий поворот направо', ' на {road}'],
|
||||
'TurnAround':
|
||||
['Развернуться'],
|
||||
'SharpLeft':
|
||||
['Резкий поворот налево', ' на {road}'],
|
||||
'Left':
|
||||
['Поворот налево', ' на {road}'],
|
||||
'SlightLeft':
|
||||
['Плавный поворот налево', ' на {road}'],
|
||||
'WaypointReached':
|
||||
['Точка достигнута'],
|
||||
'Roundabout':
|
||||
['{exitStr} съезд с кольца', ' на {road}'],
|
||||
'DestinationReached':
|
||||
['Окончание маршрута'],
|
||||
'Fork': ['На развилке поверните {modifier}', ' на {road}'],
|
||||
'Merge': ['Перестройтесь {modifier}', ' на {road}'],
|
||||
'OnRamp': ['Поверните {modifier} на съезд', ' на {road}'],
|
||||
'OffRamp': ['Съезжайте на {modifier}', ' на {road}'],
|
||||
'EndOfRoad': ['Поверните {modifier} в конце дороги', ' на {road}'],
|
||||
'Onto': 'на {road}'
|
||||
},
|
||||
formatOrder: function(n) {
|
||||
return n + '-й';
|
||||
},
|
||||
ui: {
|
||||
startPlaceholder: 'Начало',
|
||||
viaPlaceholder: 'Через {viaNumber}',
|
||||
endPlaceholder: 'Конец'
|
||||
},
|
||||
units: {
|
||||
meters: 'м',
|
||||
kilometers: 'км',
|
||||
yards: 'ярд',
|
||||
miles: 'ми',
|
||||
hours: 'ч',
|
||||
minutes: 'м',
|
||||
seconds: 'с'
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,27 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
var OSRMv1 = require('./osrm-v1');
|
||||
|
||||
/**
|
||||
* Works against OSRM's new API in version 5.0; this has
|
||||
* the API version v1.
|
||||
*/
|
||||
module.exports = OSRMv1.extend({
|
||||
options: {
|
||||
serviceUrl: 'https://api.mapbox.com/directions/v5',
|
||||
profile: 'mapbox/driving',
|
||||
useHints: false
|
||||
},
|
||||
|
||||
initialize: function(accessToken, options) {
|
||||
L.Routing.OSRMv1.prototype.initialize.call(this, options);
|
||||
this.options.requestParameters = this.options.requestParameters || {};
|
||||
/* jshint camelcase: false */
|
||||
this.options.requestParameters.access_token = accessToken;
|
||||
/* jshint camelcase: true */
|
||||
}
|
||||
});
|
||||
})();
|
||||
368
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/osrm-v1.js
Normal file
368
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/osrm-v1.js
Normal file
@ -0,0 +1,368 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet'),
|
||||
corslite = require('corslite'),
|
||||
polyline = require('polyline'),
|
||||
osrmTextInstructions = require('osrm-text-instructions');
|
||||
|
||||
// Ignore camelcase naming for this file, since OSRM's API uses
|
||||
// underscores.
|
||||
/* jshint camelcase: false */
|
||||
|
||||
var Waypoint = require('./waypoint');
|
||||
|
||||
/**
|
||||
* Works against OSRM's new API in version 5.0; this has
|
||||
* the API version v1.
|
||||
*/
|
||||
module.exports = L.Class.extend({
|
||||
options: {
|
||||
serviceUrl: 'https://router.project-osrm.org/route/v1',
|
||||
profile: 'driving',
|
||||
timeout: 30 * 1000,
|
||||
routingOptions: {
|
||||
alternatives: true,
|
||||
steps: true
|
||||
},
|
||||
polylinePrecision: 5,
|
||||
useHints: true,
|
||||
suppressDemoServerWarning: false,
|
||||
language: 'en'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._hints = {
|
||||
locations: {}
|
||||
};
|
||||
|
||||
if (!this.options.suppressDemoServerWarning &&
|
||||
this.options.serviceUrl.indexOf('//router.project-osrm.org') >= 0) {
|
||||
console.warn('You are using OSRM\'s demo server. ' +
|
||||
'Please note that it is **NOT SUITABLE FOR PRODUCTION USE**.\n' +
|
||||
'Refer to the demo server\'s usage policy: ' +
|
||||
'https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy\n\n' +
|
||||
'To change, set the serviceUrl option.\n\n' +
|
||||
'Please do not report issues with this server to neither ' +
|
||||
'Leaflet Routing Machine or OSRM - it\'s for\n' +
|
||||
'demo only, and will sometimes not be available, or work in ' +
|
||||
'unexpected ways.\n\n' +
|
||||
'Please set up your own OSRM server, or use a paid service ' +
|
||||
'provider for production.');
|
||||
}
|
||||
},
|
||||
|
||||
route: function(waypoints, callback, context, options) {
|
||||
var timedOut = false,
|
||||
wps = [],
|
||||
url,
|
||||
timer,
|
||||
wp,
|
||||
i,
|
||||
xhr;
|
||||
|
||||
options = L.extend({}, this.options.routingOptions, options);
|
||||
url = this.buildRouteUrl(waypoints, options);
|
||||
if (this.options.requestParameters) {
|
||||
url += L.Util.getParamString(this.options.requestParameters, url);
|
||||
}
|
||||
|
||||
timer = setTimeout(function() {
|
||||
timedOut = true;
|
||||
callback.call(context || callback, {
|
||||
status: -1,
|
||||
message: 'OSRM request timed out.'
|
||||
});
|
||||
}, this.options.timeout);
|
||||
|
||||
// Create a copy of the waypoints, since they
|
||||
// might otherwise be asynchronously modified while
|
||||
// the request is being processed.
|
||||
for (i = 0; i < waypoints.length; i++) {
|
||||
wp = waypoints[i];
|
||||
wps.push(new Waypoint(wp.latLng, wp.name, wp.options));
|
||||
}
|
||||
|
||||
return xhr = corslite(url, L.bind(function(err, resp) {
|
||||
var data,
|
||||
error = {};
|
||||
|
||||
clearTimeout(timer);
|
||||
if (!timedOut) {
|
||||
if (!err) {
|
||||
try {
|
||||
data = JSON.parse(resp.responseText);
|
||||
try {
|
||||
return this._routeDone(data, wps, options, callback, context);
|
||||
} catch (ex) {
|
||||
error.status = -3;
|
||||
error.message = ex.toString();
|
||||
}
|
||||
} catch (ex) {
|
||||
error.status = -2;
|
||||
error.message = 'Error parsing OSRM response: ' + ex.toString();
|
||||
}
|
||||
} else {
|
||||
error.message = 'HTTP request failed: ' + err.type +
|
||||
(err.target && err.target.status ? ' HTTP ' + err.target.status + ': ' + err.target.statusText : '');
|
||||
error.url = url;
|
||||
error.status = -1;
|
||||
error.target = err;
|
||||
}
|
||||
|
||||
callback.call(context || callback, error);
|
||||
} else {
|
||||
xhr.abort();
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
requiresMoreDetail: function(route, zoom, bounds) {
|
||||
if (!route.properties.isSimplified) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var waypoints = route.inputWaypoints,
|
||||
i;
|
||||
for (i = 0; i < waypoints.length; ++i) {
|
||||
if (!bounds.contains(waypoints[i].latLng)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_routeDone: function(response, inputWaypoints, options, callback, context) {
|
||||
var alts = [],
|
||||
actualWaypoints,
|
||||
i,
|
||||
route;
|
||||
|
||||
context = context || callback;
|
||||
if (response.code !== 'Ok') {
|
||||
callback.call(context, {
|
||||
status: response.code
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
actualWaypoints = this._toWaypoints(inputWaypoints, response.waypoints);
|
||||
|
||||
for (i = 0; i < response.routes.length; i++) {
|
||||
route = this._convertRoute(response.routes[i]);
|
||||
route.inputWaypoints = inputWaypoints;
|
||||
route.waypoints = actualWaypoints;
|
||||
route.properties = {isSimplified: !options || !options.geometryOnly || options.simplifyGeometry};
|
||||
alts.push(route);
|
||||
}
|
||||
|
||||
this._saveHintData(response.waypoints, inputWaypoints);
|
||||
|
||||
callback.call(context, null, alts);
|
||||
},
|
||||
|
||||
_convertRoute: function(responseRoute) {
|
||||
var result = {
|
||||
name: '',
|
||||
coordinates: [],
|
||||
instructions: [],
|
||||
summary: {
|
||||
totalDistance: responseRoute.distance,
|
||||
totalTime: responseRoute.duration
|
||||
}
|
||||
},
|
||||
legNames = [],
|
||||
waypointIndices = [],
|
||||
index = 0,
|
||||
legCount = responseRoute.legs.length,
|
||||
hasSteps = responseRoute.legs[0].steps.length > 0,
|
||||
i,
|
||||
j,
|
||||
leg,
|
||||
step,
|
||||
geometry,
|
||||
type,
|
||||
modifier,
|
||||
text,
|
||||
stepToText;
|
||||
|
||||
if (this.options.stepToText) {
|
||||
stepToText = this.options.stepToText;
|
||||
} else {
|
||||
var textInstructions = osrmTextInstructions('v5', this.options.language);
|
||||
stepToText = textInstructions.compile.bind(textInstructions);
|
||||
}
|
||||
|
||||
for (i = 0; i < legCount; i++) {
|
||||
leg = responseRoute.legs[i];
|
||||
legNames.push(leg.summary && leg.summary.charAt(0).toUpperCase() + leg.summary.substring(1));
|
||||
for (j = 0; j < leg.steps.length; j++) {
|
||||
step = leg.steps[j];
|
||||
geometry = this._decodePolyline(step.geometry);
|
||||
result.coordinates.push.apply(result.coordinates, geometry);
|
||||
type = this._maneuverToInstructionType(step.maneuver, i === legCount - 1);
|
||||
modifier = this._maneuverToModifier(step.maneuver);
|
||||
text = stepToText(step);
|
||||
|
||||
if (type) {
|
||||
if ((i == 0 && step.maneuver.type == 'depart') || step.maneuver.type == 'arrive') {
|
||||
waypointIndices.push(index);
|
||||
}
|
||||
|
||||
result.instructions.push({
|
||||
type: type,
|
||||
distance: step.distance,
|
||||
time: step.duration,
|
||||
road: step.name,
|
||||
direction: this._bearingToDirection(step.maneuver.bearing_after),
|
||||
exit: step.maneuver.exit,
|
||||
index: index,
|
||||
mode: step.mode,
|
||||
modifier: modifier,
|
||||
text: text
|
||||
});
|
||||
}
|
||||
|
||||
index += geometry.length;
|
||||
}
|
||||
}
|
||||
|
||||
result.name = legNames.join(', ');
|
||||
if (!hasSteps) {
|
||||
result.coordinates = this._decodePolyline(responseRoute.geometry);
|
||||
} else {
|
||||
result.waypointIndices = waypointIndices;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_bearingToDirection: function(bearing) {
|
||||
var oct = Math.round(bearing / 45) % 8;
|
||||
return ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'][oct];
|
||||
},
|
||||
|
||||
_maneuverToInstructionType: function(maneuver, lastLeg) {
|
||||
switch (maneuver.type) {
|
||||
case 'new name':
|
||||
return 'Continue';
|
||||
case 'depart':
|
||||
return 'Head';
|
||||
case 'arrive':
|
||||
return lastLeg ? 'DestinationReached' : 'WaypointReached';
|
||||
case 'roundabout':
|
||||
case 'rotary':
|
||||
return 'Roundabout';
|
||||
case 'merge':
|
||||
case 'fork':
|
||||
case 'on ramp':
|
||||
case 'off ramp':
|
||||
case 'end of road':
|
||||
return this._camelCase(maneuver.type);
|
||||
// These are all reduced to the same instruction in the current model
|
||||
//case 'turn':
|
||||
//case 'ramp': // deprecated in v5.1
|
||||
default:
|
||||
return this._camelCase(maneuver.modifier);
|
||||
}
|
||||
},
|
||||
|
||||
_maneuverToModifier: function(maneuver) {
|
||||
var modifier = maneuver.modifier;
|
||||
|
||||
switch (maneuver.type) {
|
||||
case 'merge':
|
||||
case 'fork':
|
||||
case 'on ramp':
|
||||
case 'off ramp':
|
||||
case 'end of road':
|
||||
modifier = this._leftOrRight(modifier);
|
||||
}
|
||||
|
||||
return modifier && this._camelCase(modifier);
|
||||
},
|
||||
|
||||
_camelCase: function(s) {
|
||||
var words = s.split(' '),
|
||||
result = '';
|
||||
for (var i = 0, l = words.length; i < l; i++) {
|
||||
result += words[i].charAt(0).toUpperCase() + words[i].substring(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_leftOrRight: function(d) {
|
||||
return d.indexOf('left') >= 0 ? 'Left' : 'Right';
|
||||
},
|
||||
|
||||
_decodePolyline: function(routeGeometry) {
|
||||
var cs = polyline.decode(routeGeometry, this.options.polylinePrecision),
|
||||
result = new Array(cs.length),
|
||||
i;
|
||||
for (i = cs.length - 1; i >= 0; i--) {
|
||||
result[i] = L.latLng(cs[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_toWaypoints: function(inputWaypoints, vias) {
|
||||
var wps = [],
|
||||
i,
|
||||
viaLoc;
|
||||
for (i = 0; i < vias.length; i++) {
|
||||
viaLoc = vias[i].location;
|
||||
wps.push(new Waypoint(L.latLng(viaLoc[1], viaLoc[0]),
|
||||
inputWaypoints[i].name,
|
||||
inputWaypoints[i].options));
|
||||
}
|
||||
|
||||
return wps;
|
||||
},
|
||||
|
||||
buildRouteUrl: function(waypoints, options) {
|
||||
var locs = [],
|
||||
hints = [],
|
||||
wp,
|
||||
latLng,
|
||||
computeInstructions,
|
||||
computeAlternative = true;
|
||||
|
||||
for (var i = 0; i < waypoints.length; i++) {
|
||||
wp = waypoints[i];
|
||||
latLng = wp.latLng;
|
||||
locs.push(latLng.lng + ',' + latLng.lat);
|
||||
hints.push(this._hints.locations[this._locationKey(latLng)] || '');
|
||||
}
|
||||
|
||||
computeInstructions =
|
||||
true;
|
||||
|
||||
return this.options.serviceUrl + '/' + this.options.profile + '/' +
|
||||
locs.join(';') + '?' +
|
||||
(options.geometryOnly ? (options.simplifyGeometry ? '' : 'overview=full') : 'overview=false') +
|
||||
'&alternatives=' + computeAlternative.toString() +
|
||||
'&steps=' + computeInstructions.toString() +
|
||||
(this.options.useHints ? '&hints=' + hints.join(';') : '') +
|
||||
(options.allowUTurns ? '&continue_straight=' + !options.allowUTurns : '');
|
||||
},
|
||||
|
||||
_locationKey: function(location) {
|
||||
return location.lat + ',' + location.lng;
|
||||
},
|
||||
|
||||
_saveHintData: function(actualWaypoints, waypoints) {
|
||||
var loc;
|
||||
this._hints = {
|
||||
locations: {}
|
||||
};
|
||||
for (var i = actualWaypoints.length - 1; i >= 0; i--) {
|
||||
loc = waypoints[i].latLng;
|
||||
this._hints.locations[this._locationKey(loc)] = actualWaypoints[i].hint;
|
||||
}
|
||||
},
|
||||
});
|
||||
})();
|
||||
321
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/osrm.js
Normal file
321
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/osrm.js
Normal file
@ -0,0 +1,321 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet'),
|
||||
corslite = require('corslite'),
|
||||
polyline = require('polyline');
|
||||
|
||||
// Ignore camelcase naming for this file, since OSRM's API uses
|
||||
// underscores.
|
||||
/* jshint camelcase: false */
|
||||
|
||||
L.Routing = L.Routing || {};
|
||||
L.extend(L.Routing, require('./L.Routing.Waypoint'));
|
||||
|
||||
/**
|
||||
* This class works against OSRM version 4 and lower,
|
||||
* for version 5, use the L.Routing.OSRMv1 class.
|
||||
*/
|
||||
L.Routing.OSRM = L.Class.extend({
|
||||
options: {
|
||||
serviceUrl: 'https://router.project-osrm.org/viaroute',
|
||||
timeout: 30 * 1000,
|
||||
routingOptions: {},
|
||||
polylinePrecision: 6
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._hints = {
|
||||
locations: {}
|
||||
};
|
||||
},
|
||||
|
||||
route: function(waypoints, callback, context, options) {
|
||||
var timedOut = false,
|
||||
wps = [],
|
||||
url,
|
||||
timer,
|
||||
wp,
|
||||
i;
|
||||
|
||||
url = this.buildRouteUrl(waypoints, L.extend({}, this.options.routingOptions, options));
|
||||
|
||||
timer = setTimeout(function() {
|
||||
timedOut = true;
|
||||
callback.call(context || callback, {
|
||||
status: -1,
|
||||
message: 'OSRM request timed out.'
|
||||
});
|
||||
}, this.options.timeout);
|
||||
|
||||
// Create a copy of the waypoints, since they
|
||||
// might otherwise be asynchronously modified while
|
||||
// the request is being processed.
|
||||
for (i = 0; i < waypoints.length; i++) {
|
||||
wp = waypoints[i];
|
||||
wps.push(new L.Routing.Waypoint(wp.latLng, wp.name, wp.options));
|
||||
}
|
||||
|
||||
return corslite(url, L.bind(function(err, resp) {
|
||||
var data,
|
||||
errorMessage,
|
||||
statusCode;
|
||||
|
||||
clearTimeout(timer);
|
||||
if (!timedOut) {
|
||||
errorMessage = 'HTTP request failed: ' + err;
|
||||
statusCode = -1;
|
||||
|
||||
if (!err) {
|
||||
try {
|
||||
data = JSON.parse(resp.responseText);
|
||||
try {
|
||||
return this._routeDone(data, wps, callback, context);
|
||||
} catch (ex) {
|
||||
statusCode = -3;
|
||||
errorMessage = ex.toString();
|
||||
}
|
||||
} catch (ex) {
|
||||
statusCode = -2;
|
||||
errorMessage = 'Error parsing OSRM response: ' + ex.toString();
|
||||
}
|
||||
}
|
||||
|
||||
callback.call(context || callback, {
|
||||
status: statusCode,
|
||||
message: errorMessage
|
||||
});
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
_routeDone: function(response, inputWaypoints, callback, context) {
|
||||
var coordinates,
|
||||
alts,
|
||||
actualWaypoints,
|
||||
i;
|
||||
|
||||
context = context || callback;
|
||||
if (response.status !== 0 && response.status !== 200) {
|
||||
callback.call(context, {
|
||||
status: response.status,
|
||||
message: response.status_message
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
coordinates = this._decodePolyline(response.route_geometry);
|
||||
actualWaypoints = this._toWaypoints(inputWaypoints, response.via_points);
|
||||
alts = [{
|
||||
name: this._createName(response.route_name),
|
||||
coordinates: coordinates,
|
||||
instructions: response.route_instructions ? this._convertInstructions(response.route_instructions) : [],
|
||||
summary: response.route_summary ? this._convertSummary(response.route_summary) : [],
|
||||
inputWaypoints: inputWaypoints,
|
||||
waypoints: actualWaypoints,
|
||||
waypointIndices: this._clampIndices(response.via_indices, coordinates)
|
||||
}];
|
||||
|
||||
if (response.alternative_geometries) {
|
||||
for (i = 0; i < response.alternative_geometries.length; i++) {
|
||||
coordinates = this._decodePolyline(response.alternative_geometries[i]);
|
||||
alts.push({
|
||||
name: this._createName(response.alternative_names[i]),
|
||||
coordinates: coordinates,
|
||||
instructions: response.alternative_instructions[i] ? this._convertInstructions(response.alternative_instructions[i]) : [],
|
||||
summary: response.alternative_summaries[i] ? this._convertSummary(response.alternative_summaries[i]) : [],
|
||||
inputWaypoints: inputWaypoints,
|
||||
waypoints: actualWaypoints,
|
||||
waypointIndices: this._clampIndices(response.alternative_geometries.length === 1 ?
|
||||
// Unsure if this is a bug in OSRM or not, but alternative_indices
|
||||
// does not appear to be an array of arrays, at least not when there is
|
||||
// a single alternative route.
|
||||
response.alternative_indices : response.alternative_indices[i],
|
||||
coordinates)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// only versions <4.5.0 will support this flag
|
||||
if (response.hint_data) {
|
||||
this._saveHintData(response.hint_data, inputWaypoints);
|
||||
}
|
||||
callback.call(context, null, alts);
|
||||
},
|
||||
|
||||
_decodePolyline: function(routeGeometry) {
|
||||
var cs = polyline.decode(routeGeometry, this.options.polylinePrecision),
|
||||
result = new Array(cs.length),
|
||||
i;
|
||||
for (i = cs.length - 1; i >= 0; i--) {
|
||||
result[i] = L.latLng(cs[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_toWaypoints: function(inputWaypoints, vias) {
|
||||
var wps = [],
|
||||
i;
|
||||
for (i = 0; i < vias.length; i++) {
|
||||
wps.push(L.Routing.waypoint(L.latLng(vias[i]),
|
||||
inputWaypoints[i].name,
|
||||
inputWaypoints[i].options));
|
||||
}
|
||||
|
||||
return wps;
|
||||
},
|
||||
|
||||
_createName: function(nameParts) {
|
||||
var name = '',
|
||||
i;
|
||||
|
||||
for (i = 0; i < nameParts.length; i++) {
|
||||
if (nameParts[i]) {
|
||||
if (name) {
|
||||
name += ', ';
|
||||
}
|
||||
name += nameParts[i].charAt(0).toUpperCase() + nameParts[i].slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
},
|
||||
|
||||
buildRouteUrl: function(waypoints, options) {
|
||||
var locs = [],
|
||||
wp,
|
||||
computeInstructions,
|
||||
computeAlternative,
|
||||
locationKey,
|
||||
hint;
|
||||
|
||||
for (var i = 0; i < waypoints.length; i++) {
|
||||
wp = waypoints[i];
|
||||
locationKey = this._locationKey(wp.latLng);
|
||||
locs.push('loc=' + locationKey);
|
||||
|
||||
hint = this._hints.locations[locationKey];
|
||||
if (hint) {
|
||||
locs.push('hint=' + hint);
|
||||
}
|
||||
|
||||
if (wp.options && wp.options.allowUTurn) {
|
||||
locs.push('u=true');
|
||||
}
|
||||
}
|
||||
|
||||
computeAlternative = computeInstructions =
|
||||
!(options && options.geometryOnly);
|
||||
|
||||
return this.options.serviceUrl + '?' +
|
||||
'instructions=' + computeInstructions.toString() + '&' +
|
||||
'alt=' + computeAlternative.toString() + '&' +
|
||||
(options.z ? 'z=' + options.z + '&' : '') +
|
||||
locs.join('&') +
|
||||
(this._hints.checksum !== undefined ? '&checksum=' + this._hints.checksum : '') +
|
||||
(options.fileformat ? '&output=' + options.fileformat : '') +
|
||||
(options.allowUTurns ? '&uturns=' + options.allowUTurns : '');
|
||||
},
|
||||
|
||||
_locationKey: function(location) {
|
||||
return location.lat + ',' + location.lng;
|
||||
},
|
||||
|
||||
_saveHintData: function(hintData, waypoints) {
|
||||
var loc;
|
||||
this._hints = {
|
||||
checksum: hintData.checksum,
|
||||
locations: {}
|
||||
};
|
||||
for (var i = hintData.locations.length - 1; i >= 0; i--) {
|
||||
loc = waypoints[i].latLng;
|
||||
this._hints.locations[this._locationKey(loc)] = hintData.locations[i];
|
||||
}
|
||||
},
|
||||
|
||||
_convertSummary: function(osrmSummary) {
|
||||
return {
|
||||
totalDistance: osrmSummary.total_distance,
|
||||
totalTime: osrmSummary.total_time
|
||||
};
|
||||
},
|
||||
|
||||
_convertInstructions: function(osrmInstructions) {
|
||||
var result = [],
|
||||
i,
|
||||
instr,
|
||||
type,
|
||||
driveDir;
|
||||
|
||||
for (i = 0; i < osrmInstructions.length; i++) {
|
||||
instr = osrmInstructions[i];
|
||||
type = this._drivingDirectionType(instr[0]);
|
||||
driveDir = instr[0].split('-');
|
||||
if (type) {
|
||||
result.push({
|
||||
type: type,
|
||||
distance: instr[2],
|
||||
time: instr[4],
|
||||
road: instr[1],
|
||||
direction: instr[6],
|
||||
exit: driveDir.length > 1 ? driveDir[1] : undefined,
|
||||
index: instr[3]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_drivingDirectionType: function(d) {
|
||||
switch (parseInt(d, 10)) {
|
||||
case 1:
|
||||
return 'Straight';
|
||||
case 2:
|
||||
return 'SlightRight';
|
||||
case 3:
|
||||
return 'Right';
|
||||
case 4:
|
||||
return 'SharpRight';
|
||||
case 5:
|
||||
return 'TurnAround';
|
||||
case 6:
|
||||
return 'SharpLeft';
|
||||
case 7:
|
||||
return 'Left';
|
||||
case 8:
|
||||
return 'SlightLeft';
|
||||
case 9:
|
||||
return 'WaypointReached';
|
||||
case 10:
|
||||
// TODO: "Head on"
|
||||
// https://github.com/DennisOSRM/Project-OSRM/blob/master/DataStructures/TurnInstructions.h#L48
|
||||
return 'Straight';
|
||||
case 11:
|
||||
case 12:
|
||||
return 'Roundabout';
|
||||
case 15:
|
||||
return 'DestinationReached';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
_clampIndices: function(indices, coords) {
|
||||
var maxCoordIndex = coords.length - 1,
|
||||
i;
|
||||
for (i = 0; i < indices.length; i++) {
|
||||
indices[i] = Math.min(maxCoordIndex, Math.max(indices[i], 0));
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
});
|
||||
|
||||
L.Routing.osrm = function(options) {
|
||||
return new L.Routing.OSRM(options);
|
||||
};
|
||||
|
||||
module.exports = L.Routing;
|
||||
})();
|
||||
356
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/plan.js
Normal file
356
ofu_app/static/libs/leaflet-routing-machine-3.2.5/src/plan.js
Normal file
@ -0,0 +1,356 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
var GeocoderElement = require('./geocoder-element');
|
||||
var Waypoint = require('./waypoint');
|
||||
|
||||
module.exports = (L.Layer || L.Class).extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
dragStyles: [
|
||||
{color: 'black', opacity: 0.15, weight: 9},
|
||||
{color: 'white', opacity: 0.8, weight: 6},
|
||||
{color: 'red', opacity: 1, weight: 2, dashArray: '7,12'}
|
||||
],
|
||||
draggableWaypoints: true,
|
||||
routeWhileDragging: false,
|
||||
addWaypoints: true,
|
||||
reverseWaypoints: false,
|
||||
addButtonClassName: '',
|
||||
language: 'en',
|
||||
createGeocoderElement: function(wp, i, nWps, plan) {
|
||||
return new GeocoderElement(wp, i, nWps, plan);
|
||||
},
|
||||
createMarker: function(i, wp) {
|
||||
var options = {
|
||||
draggable: this.draggableWaypoints
|
||||
},
|
||||
marker = L.marker(wp.latLng, options);
|
||||
|
||||
return marker;
|
||||
},
|
||||
geocodersClassName: ''
|
||||
},
|
||||
|
||||
initialize: function(waypoints, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._waypoints = [];
|
||||
this.setWaypoints(waypoints);
|
||||
},
|
||||
|
||||
isReady: function() {
|
||||
var i;
|
||||
for (i = 0; i < this._waypoints.length; i++) {
|
||||
if (!this._waypoints[i].latLng) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
getWaypoints: function() {
|
||||
var i,
|
||||
wps = [];
|
||||
|
||||
for (i = 0; i < this._waypoints.length; i++) {
|
||||
wps.push(this._waypoints[i]);
|
||||
}
|
||||
|
||||
return wps;
|
||||
},
|
||||
|
||||
setWaypoints: function(waypoints) {
|
||||
var args = [0, this._waypoints.length].concat(waypoints);
|
||||
this.spliceWaypoints.apply(this, args);
|
||||
return this;
|
||||
},
|
||||
|
||||
spliceWaypoints: function() {
|
||||
var args = [arguments[0], arguments[1]],
|
||||
i;
|
||||
|
||||
for (i = 2; i < arguments.length; i++) {
|
||||
args.push(arguments[i] && arguments[i].hasOwnProperty('latLng') ? arguments[i] : new Waypoint(arguments[i]));
|
||||
}
|
||||
|
||||
[].splice.apply(this._waypoints, args);
|
||||
|
||||
// Make sure there's always at least two waypoints
|
||||
while (this._waypoints.length < 2) {
|
||||
this.spliceWaypoints(this._waypoints.length, 0, null);
|
||||
}
|
||||
|
||||
this._updateMarkers();
|
||||
this._fireChanged.apply(this, args);
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
this._map = map;
|
||||
this._updateMarkers();
|
||||
},
|
||||
|
||||
onRemove: function() {
|
||||
var i;
|
||||
this._removeMarkers();
|
||||
|
||||
if (this._newWp) {
|
||||
for (i = 0; i < this._newWp.lines.length; i++) {
|
||||
this._map.removeLayer(this._newWp.lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
delete this._map;
|
||||
},
|
||||
|
||||
createGeocoders: function() {
|
||||
var container = L.DomUtil.create('div', 'leaflet-routing-geocoders ' + this.options.geocodersClassName),
|
||||
waypoints = this._waypoints,
|
||||
addWpBtn,
|
||||
reverseBtn;
|
||||
|
||||
this._geocoderContainer = container;
|
||||
this._geocoderElems = [];
|
||||
|
||||
|
||||
if (this.options.addWaypoints) {
|
||||
addWpBtn = L.DomUtil.create('button', 'leaflet-routing-add-waypoint ' + this.options.addButtonClassName, container);
|
||||
addWpBtn.setAttribute('type', 'button');
|
||||
L.DomEvent.addListener(addWpBtn, 'click', function() {
|
||||
this.spliceWaypoints(waypoints.length, 0, null);
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (this.options.reverseWaypoints) {
|
||||
reverseBtn = L.DomUtil.create('button', 'leaflet-routing-reverse-waypoints', container);
|
||||
reverseBtn.setAttribute('type', 'button');
|
||||
L.DomEvent.addListener(reverseBtn, 'click', function() {
|
||||
this._waypoints.reverse();
|
||||
this.setWaypoints(this._waypoints);
|
||||
}, this);
|
||||
}
|
||||
|
||||
this._updateGeocoders();
|
||||
this.on('waypointsspliced', this._updateGeocoders);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
_createGeocoder: function(i) {
|
||||
var geocoder = this.options.createGeocoderElement(this._waypoints[i], i, this._waypoints.length, this.options);
|
||||
geocoder
|
||||
.on('delete', function() {
|
||||
if (i > 0 || this._waypoints.length > 2) {
|
||||
this.spliceWaypoints(i, 1);
|
||||
} else {
|
||||
this.spliceWaypoints(i, 1, new Waypoint());
|
||||
}
|
||||
}, this)
|
||||
.on('geocoded', function(e) {
|
||||
this._updateMarkers();
|
||||
this._fireChanged();
|
||||
this._focusGeocoder(i + 1);
|
||||
this.fire('waypointgeocoded', {
|
||||
waypointIndex: i,
|
||||
waypoint: e.waypoint
|
||||
});
|
||||
}, this)
|
||||
.on('reversegeocoded', function(e) {
|
||||
this.fire('waypointgeocoded', {
|
||||
waypointIndex: i,
|
||||
waypoint: e.waypoint
|
||||
});
|
||||
}, this);
|
||||
|
||||
return geocoder;
|
||||
},
|
||||
|
||||
_updateGeocoders: function() {
|
||||
var elems = [],
|
||||
i,
|
||||
geocoderElem;
|
||||
|
||||
for (i = 0; i < this._geocoderElems.length; i++) {
|
||||
this._geocoderContainer.removeChild(this._geocoderElems[i].getContainer());
|
||||
}
|
||||
|
||||
for (i = this._waypoints.length - 1; i >= 0; i--) {
|
||||
geocoderElem = this._createGeocoder(i);
|
||||
this._geocoderContainer.insertBefore(geocoderElem.getContainer(), this._geocoderContainer.firstChild);
|
||||
elems.push(geocoderElem);
|
||||
}
|
||||
|
||||
this._geocoderElems = elems.reverse();
|
||||
},
|
||||
|
||||
_removeMarkers: function() {
|
||||
var i;
|
||||
if (this._markers) {
|
||||
for (i = 0; i < this._markers.length; i++) {
|
||||
if (this._markers[i]) {
|
||||
this._map.removeLayer(this._markers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._markers = [];
|
||||
},
|
||||
|
||||
_updateMarkers: function() {
|
||||
var i,
|
||||
m;
|
||||
|
||||
if (!this._map) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._removeMarkers();
|
||||
|
||||
for (i = 0; i < this._waypoints.length; i++) {
|
||||
if (this._waypoints[i].latLng) {
|
||||
m = this.options.createMarker(i, this._waypoints[i], this._waypoints.length);
|
||||
if (m) {
|
||||
m.addTo(this._map);
|
||||
if (this.options.draggableWaypoints) {
|
||||
this._hookWaypointEvents(m, i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m = null;
|
||||
}
|
||||
this._markers.push(m);
|
||||
}
|
||||
},
|
||||
|
||||
_fireChanged: function() {
|
||||
this.fire('waypointschanged', {waypoints: this.getWaypoints()});
|
||||
|
||||
if (arguments.length >= 2) {
|
||||
this.fire('waypointsspliced', {
|
||||
index: Array.prototype.shift.call(arguments),
|
||||
nRemoved: Array.prototype.shift.call(arguments),
|
||||
added: arguments
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_hookWaypointEvents: function(m, i, trackMouseMove) {
|
||||
var eventLatLng = function(e) {
|
||||
return trackMouseMove ? e.latlng : e.target.getLatLng();
|
||||
},
|
||||
dragStart = L.bind(function(e) {
|
||||
this.fire('waypointdragstart', {index: i, latlng: eventLatLng(e)});
|
||||
}, this),
|
||||
drag = L.bind(function(e) {
|
||||
this._waypoints[i].latLng = eventLatLng(e);
|
||||
this.fire('waypointdrag', {index: i, latlng: eventLatLng(e)});
|
||||
}, this),
|
||||
dragEnd = L.bind(function(e) {
|
||||
this._waypoints[i].latLng = eventLatLng(e);
|
||||
this._waypoints[i].name = '';
|
||||
if (this._geocoderElems) {
|
||||
this._geocoderElems[i].update(true);
|
||||
}
|
||||
this.fire('waypointdragend', {index: i, latlng: eventLatLng(e)});
|
||||
this._fireChanged();
|
||||
}, this),
|
||||
mouseMove,
|
||||
mouseUp;
|
||||
|
||||
if (trackMouseMove) {
|
||||
mouseMove = L.bind(function(e) {
|
||||
this._markers[i].setLatLng(e.latlng);
|
||||
drag(e);
|
||||
}, this);
|
||||
mouseUp = L.bind(function(e) {
|
||||
this._map.dragging.enable();
|
||||
this._map.off('mouseup', mouseUp);
|
||||
this._map.off('mousemove', mouseMove);
|
||||
dragEnd(e);
|
||||
}, this);
|
||||
this._map.dragging.disable();
|
||||
this._map.on('mousemove', mouseMove);
|
||||
this._map.on('mouseup', mouseUp);
|
||||
dragStart({latlng: this._waypoints[i].latLng});
|
||||
} else {
|
||||
m.on('dragstart', dragStart);
|
||||
m.on('drag', drag);
|
||||
m.on('dragend', dragEnd);
|
||||
}
|
||||
},
|
||||
|
||||
dragNewWaypoint: function(e) {
|
||||
var newWpIndex = e.afterIndex + 1;
|
||||
if (this.options.routeWhileDragging) {
|
||||
this.spliceWaypoints(newWpIndex, 0, e.latlng);
|
||||
this._hookWaypointEvents(this._markers[newWpIndex], newWpIndex, true);
|
||||
} else {
|
||||
this._dragNewWaypoint(newWpIndex, e.latlng);
|
||||
}
|
||||
},
|
||||
|
||||
_dragNewWaypoint: function(newWpIndex, initialLatLng) {
|
||||
var wp = new Waypoint(initialLatLng),
|
||||
prevWp = this._waypoints[newWpIndex - 1],
|
||||
nextWp = this._waypoints[newWpIndex],
|
||||
marker = this.options.createMarker(newWpIndex, wp, this._waypoints.length + 1),
|
||||
lines = [],
|
||||
draggingEnabled = this._map.dragging.enabled(),
|
||||
mouseMove = L.bind(function(e) {
|
||||
var i,
|
||||
latLngs;
|
||||
if (marker) {
|
||||
marker.setLatLng(e.latlng);
|
||||
}
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
latLngs = lines[i].getLatLngs();
|
||||
latLngs.splice(1, 1, e.latlng);
|
||||
lines[i].setLatLngs(latLngs);
|
||||
}
|
||||
|
||||
L.DomEvent.stop(e);
|
||||
}, this),
|
||||
mouseUp = L.bind(function(e) {
|
||||
var i;
|
||||
if (marker) {
|
||||
this._map.removeLayer(marker);
|
||||
}
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
this._map.removeLayer(lines[i]);
|
||||
}
|
||||
this._map.off('mousemove', mouseMove);
|
||||
this._map.off('mouseup', mouseUp);
|
||||
this.spliceWaypoints(newWpIndex, 0, e.latlng);
|
||||
if (draggingEnabled) {
|
||||
this._map.dragging.enable();
|
||||
}
|
||||
}, this),
|
||||
i;
|
||||
|
||||
if (marker) {
|
||||
marker.addTo(this._map);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.options.dragStyles.length; i++) {
|
||||
lines.push(L.polyline([prevWp.latLng, initialLatLng, nextWp.latLng],
|
||||
this.options.dragStyles[i]).addTo(this._map));
|
||||
}
|
||||
|
||||
if (draggingEnabled) {
|
||||
this._map.dragging.disable();
|
||||
}
|
||||
|
||||
this._map.on('mousemove', mouseMove);
|
||||
this._map.on('mouseup', mouseUp);
|
||||
},
|
||||
|
||||
_focusGeocoder: function(i) {
|
||||
if (this._geocoderElems[i]) {
|
||||
this._geocoderElems[i].focus();
|
||||
} else {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,16 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var L = require('leaflet');
|
||||
|
||||
module.exports = L.Class.extend({
|
||||
options: {
|
||||
allowUTurn: false,
|
||||
},
|
||||
initialize: function(latLng, name, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this.latLng = L.latLng(latLng);
|
||||
this.name = name;
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Jasmine Spec Runner v2.0.0</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
|
||||
|
||||
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.5/leaflet.js"></script>
|
||||
<script src="../dist/leaflet-routing-machine.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/formatter-spec.js"></script>
|
||||
<script type="text/javascript" src="spec/osrmv1-spec.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,76 @@
|
||||
describe('L.Routing.Formatter', function() {
|
||||
describe('._round', function() {
|
||||
it('rounds 0 < x < 5 to multiple of 0.5', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(1)).toBe(1);
|
||||
expect(p._round(1.4)).toBe(1.5);
|
||||
expect(p._round(1.75)).toBe(2);
|
||||
});
|
||||
it('rounds 5 < x < 10 to nearest integer', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(7)).toBe(7);
|
||||
expect(p._round(9.4)).toBe(9);
|
||||
expect(p._round(9.8)).toBe(10);
|
||||
});
|
||||
it('rounds 10 < x < 50 values to multiples of 5', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(11.5)).toBe(10);
|
||||
expect(p._round(14)).toBe(15);
|
||||
expect(p._round(42)).toBe(40);
|
||||
expect(p._round(43)).toBe(45);
|
||||
});
|
||||
it('rounds 50 < x < 100 to multiples of 10', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(72)).toBe(70);
|
||||
expect(p._round(76)).toBe(80);
|
||||
expect(p._round(97.6)).toBe(100);
|
||||
});
|
||||
it('rounds 100 < x < 150 to multiples of 50', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(105)).toBe(100);
|
||||
expect(p._round(125)).toBe(150);
|
||||
});
|
||||
it('rounds large values to multiples of 100', function() {
|
||||
var p = new L.Routing.Formatter(undefined);
|
||||
expect(p._round(686)).toBe(700);
|
||||
expect(p._round(860)).toBe(900);
|
||||
});
|
||||
it('considers rounding sensitivity', function() {
|
||||
var p = new L.Routing.Formatter({roundingSensitivity: 5});
|
||||
expect(p._round(24)).toBe(24);
|
||||
expect(p._round(52)).toBe(50);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.formatDistance', function() {
|
||||
it('rounds long distances reasonably', function() {
|
||||
var p = new L.Routing.Formatter({
|
||||
distanceTemplate: '{value}'
|
||||
});
|
||||
expect(parseInt(p.formatDistance(22000), 10)).toBe(20);
|
||||
expect(parseInt(p.formatDistance(24000), 10)).toBe(25);
|
||||
expect(parseInt(p.formatDistance(86000), 10)).toBe(90);
|
||||
});
|
||||
it('formats imperial units properly', function() {
|
||||
var p = new L.Routing.Formatter({
|
||||
distanceTemplate: '{value}',
|
||||
units: 'imperial'
|
||||
});
|
||||
expect(parseInt(p.formatDistance(800), 10)).toBe(900);
|
||||
expect(parseInt(p.formatDistance(22000), 10)).toBe(15);
|
||||
expect(parseInt(p.formatDistance(24500), 10)).toBe(15);
|
||||
expect(parseInt(p.formatDistance(86000), 10)).toBe(55);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.formatTime', function() {
|
||||
it('rounds whole minutes without seconds', function() {
|
||||
var p = new L.Routing.Formatter();
|
||||
expect(p.formatTime(240)).toBe('4 min');
|
||||
})
|
||||
it('rounds just under five minutes to five minutes without seconds', function() {
|
||||
var p = new L.Routing.Formatter();
|
||||
expect(p.formatTime(299.10000000005)).toBe('5 min');
|
||||
})
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,28 @@
|
||||
describe('L.Routing.OSRMv1', function() {
|
||||
describe('#route', function() {
|
||||
var waypoints = [
|
||||
new L.Routing.Waypoint([57.73, 11.94]),
|
||||
new L.Routing.Waypoint([57.7, 11.9])
|
||||
];
|
||||
it('returns correct waypoints', function(done) {
|
||||
var router = new L.Routing.OSRMv1();
|
||||
router.route(waypoints, function(err, routes) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
if (!routes.length) {
|
||||
return done('No routes :(');
|
||||
}
|
||||
|
||||
waypoints.forEach(function(wp, i) {
|
||||
var returnedWp = routes[0].waypoints[i];
|
||||
expect(Math.abs(returnedWp.latLng.lat - wp.latLng.lat)).to.be.lessThan(0.1);
|
||||
expect(Math.abs(returnedWp.latLng.lng - wp.latLng.lng)).to.be.lessThan(0.1);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,94 +1,14 @@
|
||||
{% extends 'base.jinja' %}
|
||||
{% block head_extra_first %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
|
||||
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
|
||||
crossorigin=""/>
|
||||
<link rel="stylesheet" href="{{ static('libs/leaflet/leaflet.css') }}"/>
|
||||
<!-- Make sure you put this AFTER Leaflet's CSS -->
|
||||
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
|
||||
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
|
||||
crossorigin="">
|
||||
</script>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
|
||||
<link rel="stylesheet" href="leaflet-routing-machine.css"/>
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
|
||||
<script src="leaflet-routing-machine.js"></script>
|
||||
<script>
|
||||
var endLat = '';
|
||||
var endLon = '';
|
||||
var startLat = '';
|
||||
var startLon = '';
|
||||
document.addEventListener('DOMContentLoaded', loadData);
|
||||
document.addEventListener('DOMContentLoaded', resizeMap);
|
||||
document.addEventListener('DOMContentLoaded', getPos);
|
||||
document.getElementById("navigate").onclick = makeRoute();
|
||||
|
||||
window.onresize = resizeMap;
|
||||
|
||||
function loadData() {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
generateMap(JSON.parse(this.response))
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "https://nominatim.openstreetmap.org/search/?format=json&city=Bamberg&street={{ room.address }}", true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
|
||||
function generateMap(streets) {
|
||||
if (streets.length > 0) {
|
||||
endLon = streets[0]['lon'];
|
||||
endLat = streets[0]['lat'];
|
||||
var map = L.map('map').setView([endLat, endLon], 16);
|
||||
|
||||
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
L.marker([endLat, endLon]).addTo(map)
|
||||
.bindPopup('{{ room.short }} </br> {{ room.address }}')
|
||||
.openPopup();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function resizeMap() {
|
||||
var height = window.innerHeight
|
||||
document.getElementById('map').style.height = height + 'px'
|
||||
}
|
||||
|
||||
function getPos() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function (position) {
|
||||
console.log(position);
|
||||
startLat = position.coords.latitude;
|
||||
startLon = position.coords.longitude;
|
||||
}, function (err) {
|
||||
console.log(err.code)
|
||||
console.log(err.message)
|
||||
})
|
||||
} else {
|
||||
document.getElementById('map').innerHTML('Geolocation not available')
|
||||
}
|
||||
}
|
||||
|
||||
function makeRoute() {
|
||||
L.Routing.control({
|
||||
waypoints: [
|
||||
L.latLng(startLat, startLon),
|
||||
L.latLng(endLat, endLon)
|
||||
]
|
||||
}).addTo(map);
|
||||
}
|
||||
</script>
|
||||
<script src="{{ static('libs/leaflet/leaflet.js') }}"></script>
|
||||
<script id="nav_data" src="{{ static('js/donar/navigate.js') }}" data-address="{{ room.address }}"
|
||||
data-short="{{ room.short }}"></script>
|
||||
{% endblock %}
|
||||
{% block headline %}
|
||||
<h1 class="text-center"> Donar </h1>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{# TODO: implement Leaflet #}
|
||||
<div id="kart"></div>
|
||||
<div id="map"></div>
|
||||
<button class="button" type="button" id="navigate">Route</button>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user