From 98ccd3c334ec8fe9f6766a6781f16f01a9f01c28 Mon Sep 17 00:00:00 2001 From: Krivchikov Dmitry Date: Mon, 10 Oct 2016 22:18:47 +0300 Subject: [PATCH] =?UTF-8?q?BIG=20FIX=20-=20=D0=BD=D0=BE=D0=B2=D0=B0=D1=8F?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=B1=D0=B8=D0=B1?= =?UTF-8?q?=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B8=20=D1=81=20=D1=80?= =?UTF-8?q?=D0=BE=D1=83=D1=82=D0=B8=D0=BD=D0=B3=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/leaflet-routing-machine.js | 1032 +++++++++++++++++--------- public/js/map.js | 16 +- public/js/route.js | 63 +- 3 files changed, 723 insertions(+), 388 deletions(-) diff --git a/public/js/leaflet-routing-machine.js b/public/js/leaflet-routing-machine.js index 27f0deb..c548700 100644 --- a/public/js/leaflet-routing-machine.js +++ b/public/js/leaflet-routing-machine.js @@ -1,4 +1,9 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),(f.L||(f.L={})).Routing=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>} coordinates + * @param {Number} precision + * @returns {String} + */ polyline.encode = function(coordinates, precision) { - if (!coordinates.length) return ''; + if (!coordinates.length) { return ''; } var factor = Math.pow(10, precision || 5), output = encode(coordinates[0][0], factor) + encode(coordinates[0][1], factor); @@ -182,7 +209,49 @@ polyline.encode = function(coordinates, precision) { return output; }; -if (typeof module !== undefined) module.exports = polyline; +function flipped(coords) { + var flipped = []; + for (var i = 0; i < coords.length; i++) { + flipped.push(coords[i].slice().reverse()); + } + return flipped; +} + +/** + * Encodes a GeoJSON LineString feature/geometry. + * + * @param {Object} geojson + * @param {Number} precision + * @returns {String} + */ +polyline.fromGeoJSON = function(geojson, precision) { + if (geojson && geojson.type === 'Feature') { + geojson = geojson.geometry; + } + if (!geojson || geojson.type !== 'LineString') { + throw new Error('Input must be a GeoJSON LineString'); + } + return polyline.encode(flipped(geojson.coordinates), precision); +}; + +/** + * Decodes to a GeoJSON LineString geometry. + * + * @param {String} str + * @param {Number} precision + * @returns {Object} + */ +polyline.toGeoJSON = function(str, precision) { + var coords = polyline.decode(str, precision); + return { + type: 'LineString', + coordinates: flipped(coords) + }; +}; + +if (typeof module === 'object' && module.exports) { + module.exports = polyline; +} },{}],3:[function(require,module,exports){ (function() { @@ -228,8 +297,14 @@ if (typeof module !== undefined) module.exports = polyline; _open: function() { var rect = this._elem.getBoundingClientRect(); if (!this._container.parentElement) { - this._container.style.left = (rect.left + window.scrollX) + 'px'; - this._container.style.top = (rect.bottom + window.scrollY) + 'px'; + // 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); } @@ -395,13 +470,14 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Itinerary')); L.extend(L.Routing, require('./L.Routing.Line')); L.extend(L.Routing, require('./L.Routing.Plan')); - L.extend(L.Routing, require('./L.Routing.OSRM')); + L.extend(L.Routing, require('./L.Routing.OSRMv1')); + L.extend(L.Routing, require('./L.Routing.Mapbox')); L.extend(L.Routing, require('./L.Routing.ErrorControl')); L.Routing.Control = L.Routing.Itinerary.extend({ @@ -412,20 +488,25 @@ if (typeof module !== undefined) module.exports = polyline; routeWhileDragging: false, routeDragInterval: 500, waypointMode: 'connect', - useZoomParameter: false, - showAlternatives: false + 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 L.Routing.OSRM(options); + this._router = this.options.router || new L.Routing.OSRMv1(options); this._plan = this.options.plan || L.Routing.plan(this.options.waypoints, options); this._requestCount = 0; L.Routing.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(); @@ -442,13 +523,31 @@ if (typeof module !== undefined) module.exports = polyline; this._map = map; this._map.addLayer(this._plan); - if (this.options.useZoomParameter) { - this._map.on('zoomend', function() { + this._map.on('zoomend', 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(this._updateLineCallback, this) + 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 }); - }, this); - } + } + }, this); if (this._plan.options.geocoder) { container.insertBefore(this._plan.createGeocoders(), container.firstChild); @@ -462,6 +561,11 @@ if (typeof module !== undefined) module.exports = polyline; 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 L.Routing.Itinerary.prototype.onRemove.call(this, map); }, @@ -488,7 +592,7 @@ if (typeof module !== undefined) module.exports = polyline; }, _routeSelected: function(e) { - var route = e.route, + var route = this._selectedRoute = e.route, alternatives = this.options.showAlternatives && e.alternatives, fitMode = this.options.fitSelectedRoutes, fitBounds = @@ -637,8 +741,10 @@ if (typeof module !== undefined) module.exports = polyline; _updateLineCallback: function(err, routes) { if (!err) { - this._updateLines({route: routes[0], alternatives: routes.slice(1) }); - } else { + 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(); } }, @@ -647,6 +753,11 @@ if (typeof module !== undefined) module.exports = polyline; var ts = ++this._requestCount, wps; + if (this._pendingRequest && this._pendingRequest.abort) { + this._pendingRequest.abort(); + this._pendingRequest = null; + } + options = options || {}; if (this._plan.isReady()) { @@ -656,15 +767,21 @@ if (typeof module !== undefined) module.exports = polyline; wps = options && options.waypoints || this._plan.getWaypoints(); this.fire('routingstart', {waypoints: wps}); - this._router.route(wps, options.callback || function(err, routes) { + 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 timestamp + // by checking the current request's count // against the last request's; ignore result if - // this isn't the latest request. + // this isn't the last request. if (ts === this._requestCount) { this._clearLines(); this._clearAlts(); - if (err) { + if (err && err.type !== 'abort') { this.fire('routingerror', {error: err}); return; } @@ -705,7 +822,7 @@ if (typeof module !== undefined) module.exports = polyline; })(); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./L.Routing.ErrorControl":5,"./L.Routing.Itinerary":8,"./L.Routing.Line":10,"./L.Routing.OSRM":12,"./L.Routing.Plan":13}],5:[function(require,module,exports){ +},{"./L.Routing.ErrorControl":5,"./L.Routing.Itinerary":8,"./L.Routing.Line":10,"./L.Routing.Mapbox":12,"./L.Routing.OSRMv1":13,"./L.Routing.Plan":14}],5:[function(require,module,exports){ (function() { 'use strict'; @@ -771,7 +888,7 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; @@ -780,15 +897,7 @@ if (typeof module !== undefined) module.exports = polyline; L.Routing.Formatter = L.Class.extend({ options: { units: 'metric', - unitNames: { - meters: 'm', - kilometers: 'km', - yards: 'yd', - miles: 'mi', - hours: 'h', - minutes: 'mín', - seconds: 's' - }, + unitNames: null, language: 'en', roundingSensitivity: 1, distanceTemplate: '{value} {unit}' @@ -796,10 +905,15 @@ if (typeof module !== undefined) module.exports = polyline; 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 L.Routing.Localization(langs); }, formatDistance: function(d /* Number (meters) */, sensitivity) { - var un = this.options.unitNames, + var un = this.options.unitNames || this._localization.localize('units'), simpleRounding = sensitivity <= 0, round = simpleRounding ? function(v) { return v; } : L.bind(this._round, this), v, @@ -829,8 +943,7 @@ if (typeof module !== undefined) module.exports = polyline; } if (simpleRounding) { - pow10 = Math.pow(10, -sensitivity); - data.value = Math.round(data.value * pow10) / pow10; + data.value = data.value.toFixed(-sensitivity); } return L.Util.template(this.options.distanceTemplate, data); @@ -846,29 +959,33 @@ if (typeof module !== undefined) module.exports = polyline; }, 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) + ' h'; + return Math.round(t / 3600) + ' ' + un.hours; } else if (t > 3600) { - return Math.floor(t / 3600) + ' h ' + - Math.round((t % 3600) / 60) + ' min'; + return Math.floor(t / 3600) + ' ' + un.hours + ' ' + + Math.round((t % 3600) / 60) + ' ' + un.minutes; } else if (t > 300) { - return Math.round(t / 60) + ' min'; + return Math.round(t / 60) + ' ' + un.minutes; } else if (t > 60) { - return Math.floor(t / 60) + ' min' + - (t % 60 !== 0 ? ' ' + (t % 60) + ' s' : ''); + return Math.floor(t / 60) + ' ' + un.minutes + + (t % 60 !== 0 ? ' ' + (t % 60) + ' ' + un.seconds : ''); } else { - return t + ' s'; + return t + ' ' + un.seconds; } }, formatInstruction: function(instr, i) { if (instr.text === undefined) { - return L.Util.template(this._getInstructionTemplate(instr, i), - L.extend({ - exitStr: instr.exit ? L.Routing.Localization[this.options.language].formatOrder(instr.exit) : '', - dir: L.Routing.Localization[this.options.language].directions[instr.direction] - }, - instr)); + 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; } @@ -876,22 +993,11 @@ if (typeof module !== undefined) module.exports = polyline; getIconName: function(instr, i) { switch (instr.type) { - case 'Straight': - return (i === 0 ? 'depart' : 'continue'); - case 'SlightRight': - return 'bear-right'; - case 'Right': - return 'turn-right'; - case 'SharpRight': - return 'sharp-right'; - case 'TurnAround': - return 'u-turn'; - case 'SharpLeft': - return 'sharp-left'; - case 'Left': - return 'turn-left'; - case 'SlightLeft': - return 'bear-left'; + case 'Head': + if (i === 0) { + return 'depart'; + } + break; case 'WaypointReached': return 'via'; case 'Roundabout': @@ -899,11 +1005,42 @@ if (typeof module !== undefined) module.exports = polyline; 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 = L.Routing.Localization[this.options.language].instructions[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] : ''); } @@ -919,7 +1056,7 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Autocomplete')); @@ -950,8 +1087,8 @@ if (typeof module !== undefined) module.exports = polyline; closeButton: remove }; }, - geocoderPlaceholder: function(i, numberWaypoints, plan) { - var l = L.Routing.Localization[plan.options.language].ui; + geocoderPlaceholder: function(i, numberWaypoints, geocoderElement) { + var l = new L.Routing.Localization(geocoderElement.options.language).localize('ui'); return i === 0 ? l.startPlaceholder : (i < numberWaypoints - 1 ? @@ -1075,7 +1212,7 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Formatter')); @@ -1312,7 +1449,7 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.Routing.ItineraryBuilder = L.Class.extend({ @@ -1363,7 +1500,7 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; @@ -1400,11 +1537,7 @@ if (typeof module !== undefined) module.exports = polyline; this.options.styles, this.options.addWaypoints); }, - - addTo: function(map) { - map.addLayer(this); - return this; - }, + getBounds: function() { return L.latLngBounds(this._route.coordinates); }, @@ -1507,9 +1640,101 @@ if (typeof module !== undefined) module.exports = polyline; },{}],11:[function(require,module,exports){ (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 || {}; - L.Routing.Localization = { + L.Routing.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 (!L.Routing.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 = L.Routing.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; + } + } + } + }); + + L.Routing.Localization = L.extend(L.Routing.Localization, { 'en': { directions: { N: 'north', @@ -1519,34 +1744,35 @@ if (typeof module !== undefined) module.exports = polyline; S: 'south', SW: 'southwest', W: 'west', - NW: 'northwest' + 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}', ' on {road}'], - 'SlightRight': - ['Slight right', ' onto {road}'], - 'Right': - ['Right', ' onto {road}'], - 'SharpRight': - ['Sharp right', ' onto {road}'], + ['Continue {dir}'], 'TurnAround': ['Turn around'], - 'SharpLeft': - ['Sharp left', ' onto {road}'], - 'Left': - ['Left', ' onto {road}'], - 'SlightLeft': - ['Slight left', ' onto {road}'], '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, @@ -1558,6 +1784,15 @@ if (typeof module !== undefined) module.exports = polyline; startPlaceholder: 'Start', viaPlaceholder: 'Via {viaNumber}', endPlaceholder: 'End' + }, + units: { + meters: 'm', + kilometers: 'km', + yards: 'yd', + miles: 'mi', + hours: 'h', + minutes: 'min', + seconds: 's' } }, @@ -1618,34 +1853,47 @@ if (typeof module !== undefined) module.exports = polyline; S: 'syd', SW: 'sydväst', W: 'väst', - NW: 'nordvä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}', ' på {road}'], + ['Åk åt {dir}', ' till {road}'], 'Continue': - ['Fortsätt {dir}', ' på {road}'], + ['Fortsätt {dir}'], 'SlightRight': - ['Svagt höger', ' på {road}'], + ['Svagt höger', ' till {road}'], 'Right': - ['Sväng höger', ' på {road}'], + ['Sväng höger', ' till {road}'], 'SharpRight': - ['Skarpt höger', ' på {road}'], + ['Skarpt höger', ' till {road}'], 'TurnAround': ['Vänd'], 'SharpLeft': - ['Skarpt vänster', ' på {road}'], + ['Skarpt vänster', ' till {road}'], 'Left': - ['Sväng vänster', ' på {road}'], + ['Sväng vänster', ' till {road}'], 'SlightLeft': - ['Svagt vänster', ' på {road}'], + ['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', @@ -1659,53 +1907,9 @@ if (typeof module !== undefined) module.exports = polyline; } }, - 'sp': { - directions: { - N: 'norte', - NE: 'noreste', - E: 'este', - SE: 'sureste', - S: 'sur', - SW: 'suroeste', - W: 'oeste', - NW: 'noroeste' - }, - instructions: { - // instruction, postfix if the road is named - 'Head': - ['Derecho {dir}', ' sobre {road}'], - 'Continue': - ['Continuar {dir}', ' en {road}'], - 'SlightRight': - ['Leve giro a la derecha', ' sobre {road}'], - 'Right': - ['Derecha', ' sobre {road}'], - 'SharpRight': - ['Giro pronunciado a la derecha', ' sobre {road}'], - 'TurnAround': - ['Dar vuelta'], - 'SharpLeft': - ['Giro pronunciado a la izquierda', ' sobre {road}'], - 'Left': - ['Izquierda', ' en {road}'], - 'SlightLeft': - ['Leve giro a la izquierda', ' en {road}'], - 'WaypointReached': - ['Llegó a un punto del camino'], - 'Roundabout': - ['Tomar {exitStr} salida en la rotonda', ' en {road}'], - 'DestinationReached': - ['Llegada a destino'], - }, - formatOrder: function(n) { - return n + 'º'; - }, - ui: { - startPlaceholder: 'Inicio', - viaPlaceholder: 'Via {viaNumber}', - endPlaceholder: 'Destino' - } - }, + 'es': spanish, + 'sp': spanish, + 'nl': { directions: { N: 'noordelijke', @@ -1860,7 +2064,14 @@ if (typeof module !== undefined) module.exports = polyline; S: 'sul', SW: 'sudoeste', W: 'oeste', - NW: 'noroeste' + 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 @@ -1888,6 +2099,12 @@ if (typeof module !== undefined) module.exports = polyline; ['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 + 'º'; @@ -1994,8 +2211,64 @@ if (typeof module !== undefined) module.exports = polyline; 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' + } } - }; + }); module.exports = L.Routing; })(); @@ -2005,7 +2278,45 @@ if (typeof module !== undefined) module.exports = polyline; (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null), + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); + + L.Routing = L.Routing || {}; + L.extend(L.Routing, require('./L.Routing.OSRMv1')); + + /** + * Works against OSRM's new API in version 5.0; this has + * the API version v1. + */ + L.Routing.Mapbox = L.Routing.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 */ + } + }); + + L.Routing.mapbox = function(accessToken, options) { + return new L.Routing.Mapbox(accessToken, options); + }; + + module.exports = L.Routing; +})(); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./L.Routing.OSRMv1":13}],13:[function(require,module,exports){ +(function (global){ +(function() { + 'use strict'; + + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null), corslite = require('corslite'), polyline = require('polyline'); @@ -2016,12 +2327,21 @@ if (typeof module !== undefined) module.exports = polyline; L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Waypoint')); - L.Routing.OSRM = L.Class.extend({ + /** + * Works against OSRM's new API in version 5.0; this has + * the API version v1. + */ + L.Routing.OSRMv1 = L.Class.extend({ options: { - serviceUrl: 'https://router.project-osrm.org/viaroute', + serviceUrl: 'https://router.project-osrm.org/route/v1', + profile: 'driving', timeout: 30 * 1000, - routingOptions: {}, - polylinePrecision: 6 + routingOptions: { + alternatives: true, + steps: true + }, + polylinePrecision: 5, + useHints: true }, initialize: function(options) { @@ -2037,9 +2357,14 @@ if (typeof module !== undefined) module.exports = polyline; url, timer, wp, - i; + i, + xhr; - url = this.buildRouteUrl(waypoints, L.extend({}, this.options.routingOptions, options)); + 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; @@ -2057,93 +2382,199 @@ if (typeof module !== undefined) module.exports = polyline; wps.push(new L.Routing.Waypoint(wp.latLng, wp.name, wp.options)); } - corslite(url, L.bind(function(err, resp) { + return xhr = corslite(url, L.bind(function(err, resp) { var data, - errorMessage, - statusCode; + error = {}; 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); + return this._routeDone(data, wps, options, callback, context); } catch (ex) { - statusCode = -3; - errorMessage = ex.toString(); + error.status = -3; + error.error = ex.toString(); } } catch (ex) { - statusCode = -2; - errorMessage = 'Error parsing OSRM response: ' + ex.toString(); + error.status = -2; + error.error = 'Error parsing OSRM response: ' + ex.toString(); } + } else { + error = L.extend({}, err, { + error: 'HTTP request failed: ' + err.type, + status: -1 + }) } - callback.call(context || callback, { - status: statusCode, - message: errorMessage - }); + callback.call(context || callback, error); + } else { + xhr.abort(); } }, this)); - - return this; }, - _routeDone: function(response, inputWaypoints, callback, context) { - var coordinates, - alts, + 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; + i, + route; context = context || callback; - if (response.status !== 0 && response.status !== 200) { + if (response.code !== 'Ok') { callback.call(context, { - status: response.status, - message: response.status_message + status: response.code }); 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) - }]; + actualWaypoints = this._toWaypoints(inputWaypoints, response.waypoints); - 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) - }); + 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 = [], + index = 0, + legCount = responseRoute.legs.length, + hasSteps = responseRoute.legs[0].steps.length > 0, + i, + j, + leg, + step, + geometry, + type, + modifier; + + 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); + + if (type) { + 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 + }); + } + + index += geometry.length; } } - // only versions <4.5.0 will support this flag - if (response.hint_data) { - this._saveHintData(response.hint_data, inputWaypoints); + result.name = legNames.join(', '); + if (!hasSteps) { + result.coordinates = this._decodePolyline(responseRoute.geometry); } - callback.call(context, null, alts); + + 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) { @@ -2159,181 +2590,80 @@ if (typeof module !== undefined) module.exports = polyline; _toWaypoints: function(inputWaypoints, vias) { var wps = [], - i; + i, + viaLoc; for (i = 0; i < vias.length; i++) { - wps.push(L.Routing.waypoint(L.latLng(vias[i]), + viaLoc = vias[i].location; + wps.push(L.Routing.waypoint(L.latLng(viaLoc[1], viaLoc[0]), inputWaypoints[i].name, - inputWaypoints[i].options)); + 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 = [], + hints = [], wp, + latLng, computeInstructions, - computeAlternative, - locationKey, - hint; + computeAlternative = true; 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'); - } + latLng = wp.latLng; + locs.push(latLng.lng + ',' + latLng.lat); + hints.push(this._hints.locations[this._locationKey(latLng)] || ''); } - computeAlternative = computeInstructions = + 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 : ''); + 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(hintData, waypoints) { + _saveHintData: function(actualWaypoints, waypoints) { var loc; this._hints = { - checksum: hintData.checksum, locations: {} }; - for (var i = hintData.locations.length - 1; i >= 0; i--) { + for (var i = actualWaypoints.length - 1; i >= 0; i--) { loc = waypoints[i].latLng; - this._hints.locations[this._locationKey(loc)] = hintData.locations[i]; + this._hints.locations[this._locationKey(loc)] = actualWaypoints[i].hint; } }, - - _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); + L.Routing.osrmv1 = function(options) { + return new L.Routing.OSRMv1(options); }; module.exports = L.Routing; })(); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./L.Routing.Waypoint":14,"corslite":1,"polyline":2}],13:[function(require,module,exports){ +},{"./L.Routing.Waypoint":15,"corslite":1,"polyline":2}],14:[function(require,module,exports){ (function (global){ (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.GeocoderElement')); L.extend(L.Routing, require('./L.Routing.Waypoint')); - L.Routing.Plan = L.Class.extend({ + L.Routing.Plan = (L.Layer || L.Class).extend({ includes: L.Mixin.Events, options: { @@ -2675,12 +3005,12 @@ if (typeof module !== undefined) module.exports = polyline; })(); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./L.Routing.GeocoderElement":7,"./L.Routing.Waypoint":14}],14:[function(require,module,exports){ +},{"./L.Routing.GeocoderElement":7,"./L.Routing.Waypoint":15}],15:[function(require,module,exports){ (function (global){ (function() { 'use strict'; - var L = (typeof window !== "undefined" ? window.L : typeof global !== "undefined" ? global.L : null); + var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null); L.Routing = L.Routing || {}; L.Routing.Waypoint = L.Class.extend({ diff --git a/public/js/map.js b/public/js/map.js index a5cf646..d8ba720 100644 --- a/public/js/map.js +++ b/public/js/map.js @@ -191,7 +191,9 @@ function constructPoint(data) } else { history.pushState({pointId: id}, document.title, "/?point=" + e.target.options.id); document.title = e.target.options.title; - yaCounter24682772.hit("/?point=" + e.target.options.id); + if (typeof yaCounter24682772 != 'undefined') { + yaCounter24682772.hit("/?point=" + e.target.options.id); + } } }); @@ -377,7 +379,9 @@ function drawInfoPopup(id, showPopup, doNotPushToHistory) { if (!doNotPushToHistory) { history.pushState({pointId: id}, document.title, "/?point=" + id); - yaCounter24682772.hit("/?point=" + id); + if (typeof yaCounter24682772 != 'undefined') { + yaCounter24682772.hit("/?point=" + id); + } } document.title = marker.options.title + ' – wikipoints.ru'; @@ -389,10 +393,14 @@ function drawInfoPopup(id, showPopup, doNotPushToHistory) { } }, 200); - yaCounter24682772.reachGoal('VIEW_POINT'); + if (typeof yaCounter24682772 != 'undefined') { + yaCounter24682772.reachGoal('VIEW_POINT'); + } if (data.isPaid == true) { - yaCounter24682772.reachGoal('VIEW_PAID_POINT'); + if (typeof yaCounter24682772 != 'undefined') { + yaCounter24682772.reachGoal('VIEW_PAID_POINT'); + } } return true; diff --git a/public/js/route.js b/public/js/route.js index bbcd031..d35f112 100644 --- a/public/js/route.js +++ b/public/js/route.js @@ -9,8 +9,6 @@ function buildRoute(fit) { wayPoints = Array(); - if (route) - myMap.removeLayer(route); $('#wayPoints div').each(function(i, el) { @@ -32,47 +30,46 @@ function buildRoute(fit) markers.addLayer(points[costomPointName]); } } - - if (i == 0) - { - bounds = [[lat, lng],[lat, lng]]; - } else { - if (lat < bounds[0][0]) bounds[0][0] = lat; - if (lng < bounds[0][1]) bounds[0][1] = lng; - if (lat > bounds[1][0]) bounds[1][0] = lat; - if (lng > bounds[1][1]) bounds[1][1] = lng; - } }); - if (fit === true) - { - myMap.fitBounds(bounds).zoomOut(); - } - if (wayPoints.length > 1) { - L.Routing.osrm().route(wayPoints, function(err, routes) { - if (err) { - console.error(err); - alert('Произошла ошибка. Вероятно построить маршрут по выбранным точкам невозможно.'); - } else { - route = L.Routing.line(routes[0], {styles:[ - {color: 'black', opacity: 0.5, weight: 9}, - {color: 'green', opacity: 0.7, weight: 7}, - {color: 'orange', opacity: 1, weight: 3} - ]}); + if (route) { + route.setWaypoints([]) + } - distance = Math.round(routes[0].summary.totalDistance / 1000); - $('#routeDistance').html('Протяженность ' + distance + ' км.'); + route = L.Routing.control({waypoints: wayPoints, + lineOptions: + {styles: [ + {color: 'black', opacity: 0.5, weight: 9}, + {color: 'green', opacity: 0.7, weight: 7}, + {color: 'orange', opacity: 1, weight: 3}]}, + fitSelectedRoutes: (fit === true), + createMarker: function () { + return null; + }}); - route.addTo(myMap); - } + + route.on('routesfound', function (e) { + distance = Math.round(e.routes[0].summary.totalDistance / 1000); + $('#routeDistance').html('Протяженность ' + distance + ' км.'); + route.addTo(myMap); + route.hide(); }); - yaCounter24682772.reachGoal('BUILD_ROUTE'); + route.on('routingerror', function (e) { + alert('Произошла ошибка. Вероятно построить маршрут по выбранным точкам невозможно.'); + }); + + + + if (typeof yaCounter24682772 != 'undefined') { + yaCounter24682772.reachGoal('BUILD_ROUTE'); + } + + routeToURL(); } - routeToURL(); } /**