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' %}
|
{% extends 'base.jinja' %}
|
||||||
{% block head_extra_first %}
|
{% block head_extra_first %}
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
|
<link rel="stylesheet" href="{{ static('libs/leaflet/leaflet.css') }}"/>
|
||||||
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
|
|
||||||
crossorigin=""/>
|
|
||||||
<!-- Make sure you put this AFTER Leaflet's CSS -->
|
<!-- Make sure you put this AFTER Leaflet's CSS -->
|
||||||
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
|
<script src="{{ static('libs/leaflet/leaflet.js') }}"></script>
|
||||||
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
|
<script id="nav_data" src="{{ static('js/donar/navigate.js') }}" data-address="{{ room.address }}"
|
||||||
crossorigin="">
|
data-short="{{ room.short }}"></script>
|
||||||
</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>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block headline %}
|
{% block headline %}
|
||||||
<h1 class="text-center"> Donar </h1>
|
<h1 class="text-center"> Donar </h1>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{# TODO: implement Leaflet #}
|
|
||||||
<div id="kart"></div>
|
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
<button class="button" type="button" id="navigate">Route</button>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user