UNPKG

@fleetbase/leaflet-routing-machine

Version:
237 lines (198 loc) 7.78 kB
import Formatter from './formatter'; import ItineraryBuilder from './itinerary-builder'; export default L.Control.extend({ includes: (typeof L.Evented !== 'undefined' && L.Evented.prototype) || 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); if (instr.index) { 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); }, });