define(function(require) { "use strict"; var EditTreePopup = require('components/TreeVarietiesMap/EditTreePopupComponent'); var forEach = require('mout/array/forEach'); var L = require('leaflet'); var pluck = require('mout/array/pluck'); var TreesLayer = require('components/TreeVarietiesMap/TreesLayerComponent'); return L.Class.extend({ initialize: function(varieties) { this.controlLayers = L.control.layers(null, null, { collapsed: false }); this.editTreePopup = new EditTreePopup(varieties); this.addVarietyHandler = this.addVariety.bind(this); this.onVarietiesChangeHandler = this.onVarietiesChange.bind(this); varieties.subscribe(this.onVarietiesChangeHandler, null, 'arrayChange'); }, addVariety: function(variety) { this.controlLayers .addOverlay(new TreesLayer(variety.trees, this.editTreePopup), variety.name); }, onAdd: function(map) { this.controlLayers.addTo(map); }, onRemove: function(map) { this.controlLayers.removeFrom(map); }, onVarietiesChange: function(changes) { forEach(pluck(changes, 'value'), this.addVarietyHandler); } }); });
(function() { 'use strict'; var L = require('leaflet'); L.Routing = L.Routing || {}; L.Routing.ItineraryBuilder = L.Class.extend({ options: { containerClassName: '' }, initialize: function(options) { L.setOptions(this, options); }, createContainer: function() { return L.DomUtil.create('table', this.options.containerClassName); }, 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; } }); module.exports = L.Routing; })();
(function() { 'use strict'; var L = require('leaflet'); L.Routing = L.Routing || {}; L.Routing.Waypoint = L.Class.extend({ options: { allowUTurn: false, }, initialize: function(latLng, name, options) { L.Util.setOptions(this, options); this.latLng = L.latLng(latLng); this.name = name; } }); L.Routing.waypoint = function(latLng, name, options) { return new L.Routing.Waypoint(latLng, name, options); }; module.exports = L.Routing; })();
var MapIcon = Leaflet.Class.extend({ /* options: { iconUrl: (String) iconSize: (Point) (can be set through CSS) iconAnchor: (Point) (centered by default, can be set in CSS with negative margins) popupAnchor: (Point) (if not specified, popup opens in the anchor point) shadowUrl: (String) (no shadow by default) shadowSize: (Point) shadowAnchor: (Point) className: (String) }, */ initialize: function (options) { this.options = Object.assign({}, options); }, createIcon: function (oldIcon) { return this._createIcon('icon', oldIcon); }, createShadow: function (oldIcon) { return this._createIcon('shadow', oldIcon); }, _createIcon: function (name, oldIcon) { var el = this._createIconEl(name, oldIcon && oldIcon.tagName ? oldIcon : null); this._setIconStyles(el, name); return el; }, _setIconStyles: function (el, name) { var options = this.options; var size = Leaflet.point(options[name + 'Size']); var anchor = Leaflet.point((name === 'shadow') ? options.shadowAnchor : options.iconAnchor); if (anchor == null && size != null) { anchor = size.divideBy(2, true); } el.classList.add('leaflet-marker-' + name); if (options.className) { el.classList.add(options.className); } if (anchor) { el.style.marginLeft = (-anchor.x) + 'px'; el.style.marginTop = (-anchor.y) + 'px'; } if (size) { el.style.width = size.x + 'px'; el.style.height = size.y + 'px'; } }, _createIconEl: function (name, el) { var src = this._getIconUrl(name); if (el) { while (el.firstChild) { el.removeChild(el.firstChild); } } else { el = document.createElement('div'); } if (src) { var img = document.createElement('img'); img.src = src; el.appendChild(img); } return el; }, _getIconUrl: function (name) { return this.options[name + 'Url']; } });
export var ArcGis = L.Class.extend({ options: { service_url: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer' }, initialize: function(accessToken, options) { L.setOptions(this, options); this._accessToken = accessToken; }, geocode: function(query, cb, context) { var params = { SingleLine: query, outFields: 'Addr_Type', forStorage: false, maxLocations: 10, f: 'json' }; if (this._key && this._key.length) { params.token = this._key; } getJSON( this.options.service_url + '/findAddressCandidates', L.extend(params, this.options.geocodingQueryParams), function(data) { var results = [], loc, latLng, latLngBounds; if (data.candidates && data.candidates.length) { for (var i = 0; i <= data.candidates.length - 1; i++) { loc = data.candidates[i]; latLng = L.latLng(loc.location.y, loc.location.x); latLngBounds = L.latLngBounds( L.latLng(loc.extent.ymax, loc.extent.xmax), L.latLng(loc.extent.ymin, loc.extent.xmin) ); results[i] = { name: loc.address, bbox: latLngBounds, center: latLng }; } } cb.call(context, results); } ); }, suggest: function(query, cb, context) { return this.geocode(query, cb, context); }, reverse: function(location, scale, cb, context) { var params = { location: encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat), distance: 100, f: 'json' }; getJSON(this.options.service_url + '/reverseGeocode', params, function(data) { var result = [], loc; if (data && !data.error) { loc = L.latLng(data.location.y, data.location.x); result.push({ name: data.address.Match_addr, center: loc, bounds: L.latLngBounds(loc, loc) }); } cb.call(context, result); }); } });
L.Symbol.Dash = L.Class.extend({ options: { pixelSize: 10, pathOptions: { } }, initialize: function (options) { L.Util.setOptions(this, options); this.options.pathOptions.clickable = false; }, buildSymbol: function(dirPoint, latLngs, map, index, total) { const opts = this.options; const d2r = Math.PI / 180; // for a dot, nothing more to compute if(opts.pixelSize <= 1) { return L.polyline([dirPoint.latLng, dirPoint.latLng], opts.pathOptions); } const midPoint = map.project(dirPoint.latLng); const angle = (-(dirPoint.heading - 90)) * d2r; const a = L.point( midPoint.x + opts.pixelSize * Math.cos(angle + Math.PI) / 2, midPoint.y + opts.pixelSize * Math.sin(angle) / 2 ); // compute second point by central symmetry to avoid unecessary cos/sin const b = midPoint.add(midPoint.subtract(a)); return L.polyline([map.unproject(a), map.unproject(b)], opts.pathOptions); } });
L.Editable.BaseEditor = L.Class.extend({ initialize: function (map, feature, options) { L.setOptions(this, options); this.map = map; this.feature = feature; this.feature.editor = this; this.editLayer = new L.LayerGroup(); this.tools = this.options.editTools || map.editTools; }, enable: function () { if (this._enabled) return this; this.tools.editLayer.addLayer(this.editLayer); this.onEnable(); this._enabled = true; this.feature.on('remove', this.disable, this); return this; }, disable: function () { this.feature.off('remove', this.disable, this); this.editLayer.clearLayers(); this.tools.editLayer.removeLayer(this.editLayer); this.onDisable(); delete this._enabled; if (this._drawing) this.cancelDrawing(); return this; }, drawing: function () { return !!this._drawing; }, fireAndForward: function (type, e) { e = e || {}; e.layer = this.feature; this.feature.fire(type, e); this.tools.fireAndForward(type, e); }, onEnable: function () { this.fireAndForward('editable:enable'); }, onDisable: function () { this.fireAndForward('editable:disable'); }, onEditing: function () { this.fireAndForward('editable:editing'); }, onStartDrawing: function () { this.fireAndForward('editable:drawing:start'); }, onEndDrawing: function () { this.fireAndForward('editable:drawing:end'); }, onCancelDrawing: function () { this.fireAndForward('editable:drawing:cancel'); }, onCommitDrawing: function (e) { this.fireAndForward('editable:drawing:commit', e); }, startDrawing: function () { if (!this._drawing) this._drawing = L.Editable.FORWARD; this.tools.registerForDrawing(this); this.onStartDrawing(); }, commitDrawing: function (e) { this.onCommitDrawing(e); this.endDrawing(); }, cancelDrawing: function () { this.onCancelDrawing(); this.endDrawing(); }, endDrawing: function () { this._drawing = false; this.tools.unregisterForDrawing(this); this.onEndDrawing(); }, onDrawingClick: function (e) { if (!this.drawing) return; L.Editable.makeCancellable(e); this.fireAndForward('editable:drawing:click', e); if (e._cancelled) return; this.processDrawingClick(e); }, onMove: function (e) { this.fireAndForward('editable:drawing:move', e); }, onMouseMove: function (e) { this.onMove(e); } });
module.exports = L.Class.extend({ includes: L.Mixin.Events, options: { opacity: 1, padding: L.Path.CLIP_PADDING, zIndex: 1, usePathContainer: false }, /** * @class SvgLayer - basically, just the SVG container simiar to the one * used by leaflet internally to render vector layers * * @extends {L.Class} * @constructor * @param {Object=} options */ initialize: function(options) { /** * @type {Element} */ this._container = null; /** * @type {SVGElement} */ this._pathRoot = null; /** * @type {L.Map} */ this._map = null; /** * @type {L.Bounds} */ this._pathViewport = null; /** * @type {Boolean} */ this._pathZooming = false; L.Util.setOptions(this, options); }, /** * @param {L.Map} map * @return {SvgLayer} */ onAdd: function(map) { this._map = map; this._initPathRoot(); return this; }, /** * @param {L.Map} map * @return {SvgLayer} */ addTo: function(map) { map.addLayer(this); return this; }, /** * @param {L.Map} map * @return {SvgLayer} */ onRemove: function(map) { if (this._map.options.zoomAnimation && L.Browser.any3d) { this._map.off({ 'zoomanim': this._animatePathZoom, 'zoomend': this._endPathZoom }, this); } this._map.off('moveend', this._updateSvgViewport, this); this._map.getPanes().overlayPane.removeChild(this._container); return this; }, /** * @param {L.Map} map * @return {SvgLayer} */ removeFrom: function(map) { map.removeLayer(this); return this; }, /** * @return {SvgLayer} */ bringToFront: function () { var root = this._container.parentNode; var container = this._container; if (container && root.lastChild !== container) { root.appendChild(container); } return this; }, /** * @return {SvgLayer} */ bringToBack: function () { var root = this._container.parentNode; var container = this._container; var first = root.firstChild; if (container && first !== container) { root.insertBefore(container, first); } return this; }, /** * @param {Number} opacity * @return {SVGLayer} */ setOpacity: function (opacity) { this.options.opacity = opacity; this._updateOpacity(); return this; }, /** * @param {Number} zIndex * @return {SVGLayet} */ setZIndex: function (zIndex) { this.options.zIndex = zIndex; this._updateZIndex(); return this; }, /** * Create svg root */ _createRoot: function() { this._container = L.DomUtil.create('div', 'leaflet-schematic-layer'); if (this.options.usePathContainer) { if (!this._map._pathRoot) { this._map._initPathRoot(); } this._pathRoot = this._map._pathRoot; } else { this._pathRoot = L.Path.prototype._createElement('svg'); this._container.appendChild(this._pathRoot); } }, /** * Init the root element */ _initPathRoot: function () { if (!this._pathRoot) { var pane = this._map.getPanes().overlayPane; this._createRoot(); pane.insertBefore(this._container, pane.firstChild); if (this._map.options.zoomAnimation && L.Browser.any3d) { L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-animated'); this._map.on({ 'zoomanim': this._animatePathZoom, 'zoomend': this._endPathZoom }, this); } else { L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-hide'); } this._map.on('moveend', this._updateSvgViewport, this); this._updateSvgViewport(); this._updateOpacity(); this._updateZIndex(); } }, /** * Sets conatiner opacity */ _updateOpacity: function() { L.DomUtil.setOpacity(this._container, this.options.opacity); }, /** * Sets container zIndex */ _updateZIndex: function () { if (this._container && this.options.zIndex !== undefined) { this._container.style.zIndex = this.options.zIndex; } }, /** * To override in the child classes * @return {L.Bounds} */ _getViewport: function() { return this._pathViewport; }, /** * Update root position to get the viewport covered */ _updateContentViewport: function () { var p = this.options.padding; var size = this._map.getSize(); var panePos = L.DomUtil.getPosition(this._map._mapPane); var min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)._round()); var max = min.add(size.multiplyBy(1 + p * 2)._round()); this._pathViewport = new L.Bounds([min.x, min.y], [max.x, max.y]); }, /** * @param {ZoomEvent} e */ _animatePathZoom: function (e) { if (!this.options.usePathContainer) { var scale = this._map.getZoomScale(e.zoom); var offset = this._map ._getCenterOffset(e.center) ._multiplyBy(-scale) ._add(this._getViewport().min); this._pathRoot.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ') '; } this._pathZooming = true; }, /** * Here we can do additional post-animation transforms */ _endPathZoom: function () { this._pathZooming = false; }, /** * Apply the viewport correction */ _updateSvgViewport: function () { if (this._pathZooming) { // Do not update SVGs while a zoom animation is going on // otherwise the animation will break. // When the zoom animation ends we will be updated again anyway // This fixes the case where you do a momentum move and // zoom while the move is still ongoing. return; } this._updateContentViewport(); var vp = this._getViewport(); var min = vp.min; var max = vp.max; var width = max.x - min.x; var height = max.y - min.y; var root = this._pathRoot; var pane = this._map.getPanes().overlayPane; // Hack to make flicker on drag end on mobile webkit less irritating if (L.Browser.mobileWebkit) { this._container.removeChild(root); } if (!this.options.usePathContainer) { L.DomUtil.setPosition(this._pathRoot, min); root.setAttribute('width', width); root.setAttribute('height', height); root.setAttribute('viewBox', [min.x, min.y, width, height].join(' ')); } if (L.Browser.mobileWebkit && !this.options.usePathContainer) { this._container.appendChild(root); } } });
module.exports = L.Class.extend({ initialize: function() { this.projections = { 'EPSG:4326': proj4.WGS84 }; }, get: function(name, cb, context) { var parts = name.split(':'), authority, code, transformation, proj; if (parts.length === 2) { authority = parts[0].toUpperCase(); codeParts = codePattern.exec(parts[1]); } else if (parts.length === 1) { authority = 'EPSG'; codeParts = codePattern.exec(parts[0]); } else { throw 'Unable to parse SRS name'; } if (!codeParts || !codeParts[1]) { throw 'Unable to parse SRS name'; } code = codeParts[1]; transformation = codeParts[3]; name = authority + ':' + code; proj = this.projections[name]; if (!proj) { try { proj4.Proj(name); // Known, since no exception this._store(name, cb, context); } catch (e) { this._fetch(authority, code, transformation, cb, context); } } else { cb.call(context || cb, name, proj); } }, _fetch: function(authority, code, transformation, cb, context) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'http://epsg.io/' + code + (transformation ? '-' + transformation : '') + '.js'; document.getElementsByTagName('head')[0].appendChild(script); // Transformation is not part of the name returned by epsg.io, so // the polling doesn't care. this._poll(authority, code, cb, context); }, _poll: function(authority, code, cb, context) { var _this = this, name = authority + ':' + code; try { proj4.Proj(name); this._store(name, cb, context); } catch (e) { setTimeout(function() { _this._poll(authority, code, cb, context); }, 100); } }, _store: function(name, cb, context) { var p = proj4.Proj(name); this.projections[name] = p; cb.call(context || cb, name, p); } });
define(function(require) { "use strict"; var filter = require('mout/array/filter'); var forEach = require('mout/array/forEach'); var L = require('leaflet'); var pluck = require('mout/array/pluck'); return L.Class.extend({ /** * Initialize the trees layer * * @constructor * @param {Array[]} trees * @param {Popup} editMarkerPopup */ initialize: function(trees, editMarkerPopup) { this.editMarkerPopup = editMarkerPopup; this.layerGroup = L.layerGroup(); this.trees = trees; this.addTreeHandler = this.addTree.bind(this); this.onTreesChangeHandler = this.onTreesChange.bind(this); this.trees.subscribe(this.onTreesChangeHandler, null, 'arrayChange'); }, /** * On add * * @param {Object} map */ onAdd: function(map) { this.layerGroup.addTo(map); }, /** * On remove */ onRemove: function(map) { map.removeLayer(this.layerGroup); }, /** * */ addTree: function(tree) { var marker = L.marker( [tree.latitude(), tree.longitude()], { opacity: 0.75 } ); // this probably leaks memory, right? marker.on('click', function() { this.editMarkerPopup.setTree(tree); marker.bindPopup(this.editMarkerPopup) .openPopup(); }.bind(this)); this.layerGroup .addLayer(marker); }, /** * On trees change handler * * @param {Object[]} changes */ onTreesChange: function(changes) { forEach( // call add tree on each pluck( // pluck the value of the change filter( // filter non-added statuses changes, function(change) { return change.status == 'added' } ), 'value' ), this.addTreeHandler ); // TODO handle deletes } }); });
class: L.Class.extend({ options: { geocodeUrl: 'http://geocoder.api.here.com/6.2/geocode.json', reverseGeocodeUrl: 'http://reverse.geocoder.api.here.com/6.2/reversegeocode.json', app_id: '<insert your app_id here>', app_code: '<insert your app_code here>', geocodingQueryParams: {}, reverseQueryParams: {}, }, initialize: function(options) { L.setOptions(this, options); }, geocode: function(query, cb, context) { var params = { searchtext: query, gen: 9, app_id: this.options.app_id, app_code: this.options.app_code, jsonattributes: 1, }; params = L.Util.extend(params, this.options.geocodingQueryParams); this.getJSON(this.options.geocodeUrl, params, cb, context); }, reverse: function(location, scale, cb, context) { var params = { prox: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng), mode: 'retrieveAddresses', app_id: this.options.app_id, app_code: this.options.app_code, gen: 9, jsonattributes: 1, }; params = L.Util.extend(params, this.options.reverseQueryParams); this.getJSON(this.options.reverseGeocodeUrl, params, cb, context); }, getJSON: function(url, params, cb, context) { getJSON(url, params, function(data) { var results = [], loc, latLng, latLngBounds; if (data.response.view && data.response.view.length) { for (var i = 0; i <= data.response.view[0].result.length - 1; i++) { loc = data.response.view[0].result[i].location; latLng = L.latLng(loc.displayPosition.latitude, loc.displayPosition.longitude); latLngBounds = L.latLngBounds( L.latLng(loc.mapView.topLeft.latitude, loc.mapView.topLeft.longitude), L.latLng(loc.mapView.bottomRight.latitude, loc.mapView.bottomRight.longitude) ); results[i] = { name: loc.address.label, bbox: latLngBounds, center: latLng, }; } } cb.call(context, results); }); }, }),
class: L.Class.extend({ options: { serviceUrl: 'https://api.what3words.com/v2/', }, initialize: function(accessToken) { this._accessToken = accessToken; }, geocode: function(query, cb, context) { //get three words and make a dot based string getJSON( this.options.serviceUrl + 'forward', { key: this._accessToken, addr: query.split(/\s+/).join('.'), }, function(data) { var results = [], latLng, latLngBounds; if (data.hasOwnProperty('geometry')) { latLng = L.latLng(data.geometry['lat'], data.geometry['lng']); latLngBounds = L.latLngBounds(latLng, latLng); results[0] = { name: data.words, bbox: latLngBounds, center: latLng, }; } cb.call(context, results); } ); }, suggest: function(query, cb, context) { return this.geocode(query, cb, context); }, reverse: function(location, scale, cb, context) { getJSON( this.options.serviceUrl + 'reverse', { key: this._accessToken, coords: [location.lat, location.lng].join(','), }, function(data) { var results = [], latLng, latLngBounds; if (data.status.status === 200) { latLng = L.latLng(data.geometry['lat'], data.geometry['lng']); latLngBounds = L.latLngBounds(latLng, latLng); results[0] = { name: data.words, bbox: latLngBounds, center: latLng, }; } cb.call(context, results); } ); }, }),
export var Renderer = L.Class.extend({ options: { proportionalPolygon: false, clickable: true }, initialize: function (rendererJson, options) { this._rendererJson = rendererJson; this._pointSymbols = false; this._symbols = []; this._visualVariables = this._parseVisualVariables(rendererJson.visualVariables); L.Util.setOptions(this, options); }, _parseVisualVariables: function (visualVariables) { var visVars = {}; if (visualVariables) { for (var i = 0; i < visualVariables.length; i++) { visVars[visualVariables[i].type] = visualVariables[i]; } } return visVars; }, _createDefaultSymbol: function () { if (this._rendererJson.defaultSymbol) { this._defaultSymbol = this._newSymbol(this._rendererJson.defaultSymbol); this._defaultSymbol._isDefault = true; } }, _newSymbol: function (symbolJson) { if (symbolJson.type === 'esriSMS' || symbolJson.type === 'esriPMS') { this._pointSymbols = true; return pointSymbol(symbolJson, this.options); } if (symbolJson.type === 'esriSLS') { return lineSymbol(symbolJson, this.options); } if (symbolJson.type === 'esriSFS') { return polygonSymbol(symbolJson, this.options); } }, _getSymbol: function () { // override }, attachStylesToLayer: function (layer) { if (this._pointSymbols) { layer.options.pointToLayer = L.Util.bind(this.pointToLayer, this); } else { layer.options.style = L.Util.bind(this.style, this); layer._originalStyle = layer.options.style; } }, pointToLayer: function (geojson, latlng, options) { var sym = this._getSymbol(geojson); if (sym && sym.pointToLayer) { return sym.pointToLayer(geojson, latlng, this._visualVariables, options); } // invisible symbology return L.circleMarker(latlng, {radius: 0, opacity: 0}); }, style: function (feature) { var userStyles; if (this.options.userDefinedStyle) { userStyles = this.options.userDefinedStyle(feature); } // find the symbol to represent this feature var sym = this._getSymbol(feature); if (sym) { return this.mergeStyles(sym.style(feature, this._visualVariables), userStyles); } else { // invisible symbology return this.mergeStyles({opacity: 0, fillOpacity: 0}, userStyles); } }, mergeStyles: function (styles, userStyles) { var mergedStyles = {}; var attr; // copy renderer style attributes for (attr in styles) { if (styles.hasOwnProperty(attr)) { mergedStyles[attr] = styles[attr]; } } // override with user defined style attributes if (userStyles) { for (attr in userStyles) { if (userStyles.hasOwnProperty(attr)) { mergedStyles[attr] = userStyles[attr]; } } } return mergedStyles; } });
var InteractionLayer = L.Class.extend({ includes : L.Mixin.Events, options : { resolution : 4, pointerCursor : true }, /** Initializes this layer */ initialize : function(options) { L.setOptions(this, options); // this._move = _.throttle(this._move, 20); // this._update = _.debounce(this._update, 10); }, /** * This method is called when this layer is added to the map. */ onAdd : function(map) { this._map = map; this._container = this._map._container; // this._update(); // map.on('click', this._click, this); map.on('mousemove', this._move, this); // map.on('moveend', this._update, this); }, /** * This method is called when this layer is removed from the map. */ onRemove : function() { var map = this._map; map.off('click', this._click, this); map.off('mousemove', this._move, this); // map.off('moveend', this._update, this); this._removeMouseCursorStyle(); }, /** Map click handler */ _click : function(e) { var on = this._objectForEvent(e); if (on.data) { this.fire('click', on); } }, /** Map move handler */ _move : function(e) { var on = this._objectForEvent(e); if (on.data !== this._mouseOn) { if (this._mouseOn) { this.fire('mouseout', { latlng : e.latlng, data : this._mouseOn }); this._removeMouseCursorStyle(); } if (on.data) { this.fire('mouseover', on); this._setMouseCursorStyle(); } this._mouseOn = on.data; } else if (on.data) { this.fire('mousemove', on); } }, /** * Checks if the cursor style of the container should be changed to pointer * cursor */ _setMouseCursorStyle : function() { if (!this.options.pointerCursor) return; if (!this._container._pointerCursorCount) { this._container._pointerCursorCount = 1; this._container.style.cursor = 'pointer'; } else { this._container._pointerCursorCount++; } }, /** Removes cursor style from the container */ _removeMouseCursorStyle : function() { if (!this.options.pointerCursor) return; if (this._container._pointerCursorCount) { this._container._pointerCursorCount--; if (this._container._pointerCursorCount === 0) { this._container.style.cursor = ''; delete this._container._pointerCursorCount; } } }, /** * Returns an object from UTF grid corresponding to the coordinates of the * mouse event. */ _objectForEvent : function(e) { throw new Error('This method should be implemented ' + // 'in subclasses.'); }, });
export var Photon = L.Class.extend({ options: { serviceUrl: 'https://photon.komoot.de/api/', reverseUrl: 'https://photon.komoot.de/reverse/', nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country'] }, initialize: function(options) { L.setOptions(this, options); }, geocode: function(query, cb, context) { var params = L.extend( { q: query }, this.options.geocodingQueryParams ); getJSON( this.options.serviceUrl, params, L.bind(function(data) { cb.call(context, this._decodeFeatures(data)); }, this) ); }, suggest: function(query, cb, context) { return this.geocode(query, cb, context); }, reverse: function(latLng, scale, cb, context) { var params = L.extend( { lat: latLng.lat, lon: latLng.lng }, this.options.reverseQueryParams ); getJSON( this.options.reverseUrl, params, L.bind(function(data) { cb.call(context, this._decodeFeatures(data)); }, this) ); }, _decodeFeatures: function(data) { var results = [], i, f, c, latLng, extent, bbox; if (data && data.features) { for (i = 0; i < data.features.length; i++) { f = data.features[i]; c = f.geometry.coordinates; latLng = L.latLng(c[1], c[0]); extent = f.properties.extent; if (extent) { bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]); } else { bbox = L.latLngBounds(latLng, latLng); } results.push({ name: this._decodeFeatureName(f), html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined, center: latLng, bbox: bbox, properties: f.properties }); } } return results; }, _decodeFeatureName: function(f) { return (this.options.nameProperties || []) .map(function(p) { return f.properties[p]; }) .filter(function(v) { return !!v; }) .join(', '); } });
var L = require('leaflet'); L.AbstractWorker = L.Class.extend({ initialize: function () { }, onAdd: function (map) { }, onRemove: function (map) { }, process: function(tile, callback) { callback(tile); }, abort: function(tile) { }, clear: function() { } }); // dummy worker (= no worker) when used directly L.noWorker = function () { return new L.AbstractWorker(); };
(function() { 'use strict'; var L = require('leaflet'); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Localization')); 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' }, language: 'en', roundingSensitivity: 1, distanceTemplate: '{value} {unit}' }, initialize: function(options) { L.setOptions(this, options); }, formatDistance: function(d /* Number (meters) */) { var un = this.options.unitNames, v, data; if (this.options.units === 'imperial') { d = d / 1.609344; if (d >= 1000) { data = { value: (this._round(d) / 1000), unit: un.miles }; } else { data = { value: this._round(d / 1.760), unit: un.yards }; } } else { v = this._round(d); data = { value: v >= 1000 ? (v / 1000) : v, unit: v >= 1000 ? un.kilometers : un.meters }; } return L.Util.template(this.options.distanceTemplate, data); }, _round: function(d) { var pow10 = Math.pow(10, (Math.floor(d / this.options.roundingSensitivity) + '').length - 1), r = Math.floor(d / pow10), p = (r > 5) ? pow10 : pow10 / 2; return Math.round(d / p) * p; }, formatTime: function(t /* Number (seconds) */) { if (t > 86400) { return Math.round(t / 3600) + ' h'; } else if (t > 3600) { return Math.floor(t / 3600) + ' h ' + Math.round((t % 3600) / 60) + ' min'; } else if (t > 300) { return Math.round(t / 60) + ' min'; } else if (t > 60) { return Math.floor(t / 60) + ' min' + (t % 60 !== 0 ? ' ' + (t % 60) + ' s' : ''); } else { return t + ' s'; } }, 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)); } else { return instr.text; } }, 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 'WaypointReached': return 'via'; case 'Roundabout': return 'enter-roundabout'; case 'DestinationReached': return 'arrive'; } }, _getInstructionTemplate: function(instr, i) { var type = instr.type === 'Straight' ? (i === 0 ? 'Head' : 'Continue') : instr.type, strings = L.Routing.Localization[this.options.language].instructions[type]; return strings[0] + (strings.length > 1 && instr.road ? strings[1] : ''); } }); module.exports = L.Routing; })();
(function() { 'use strict'; var L = require('leaflet'); L.Routing = L.Routing || {}; L.extend(L.Routing, require('./L.Routing.Util')); L.extend(L.Routing, require('./L.Routing.Waypoint')); L.Routing.GraphHopper = L.Class.extend({ options: { serviceUrl: 'https://graphhopper.com/api/1/route', timeout: 30 * 1000 }, initialize: function(apiKey, options) { this._apiKey = apiKey; L.Util.setOptions(this, options); }, route: function(waypoints, callback, context, options) { var timedOut = false, wps = [], url, timer, wp, i; options = options || {}; url = this.buildRouteUrl(waypoints, options); timer = setTimeout(function() { timedOut = true; callback.call(context || callback, { status: -1, message: 'GraphHopper 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)); } L.Routing._jsonp(url, function(data) { clearTimeout(timer); if (!timedOut) { this._routeDone(data, wps, callback, context); } }, this, 'callback'); return this; }, _routeDone: function(response, inputWaypoints, callback, context) { var alts = [], mappedWaypoints, coordinates, i, path; context = context || callback; if (response.info.errors && response.info.errors.length) { callback.call(context, { // TODO: include all errors status: response.info.errors[0].details, message: response.info.errors[0].message }); return; } for (i = 0; i < response.paths.length; i++) { path = response.paths[i]; coordinates = L.Routing._decodePolyline(path.points, 5); mappedWaypoints = this._mapWaypointIndices(inputWaypoints, path.instructions, coordinates); alts.push({ name: '', coordinates: coordinates, instructions: this._convertInstructions(path.instructions), summary: { totalDistance: path.distance, totalTime: path.time / 1000, }, inputWaypoints: inputWaypoints, actualWaypoints: mappedWaypoints.waypoints, waypointIndices: mappedWaypoints.waypointIndices }); } callback.call(context, null, alts); }, _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; }, buildRouteUrl: function(waypoints, options) { var computeInstructions = !(options && options.geometryOnly), locs = [], i; for (i = 0; i < waypoints.length; i++) { locs.push('point=' + waypoints[i].latLng.lat + ',' + waypoints[i].latLng.lng); } return this.options.serviceUrl + '?' + locs.join('&') + '&instructions=' + computeInstructions + '&type=jsonp' + '&key=' + this._apiKey; }, _convertInstructions: function(instructions) { var signToType = { '-3': 'SharpLeft', '-2': 'Left', '-1': 'SlightLeft', 0: 'Straight', 1: 'SlightRight', 2: 'Right', 3: 'SharpRight', 4: 'DestinationReached', 5: 'WaypointReached' }, result = [], i, instr; for (i = 0; i < instructions.length; i++) { instr = instructions[i]; result.push({ type: signToType[instr.sign], text: instr.text, distance: instr.distance, time: instr.time / 1000, index: instr.interval[0] }); } return result; }, _mapWaypointIndices: function(waypoints, instructions, coordinates) { var wps = [], wpIndices = [], i, idx; wpIndices.push(0); wps.push(new L.Routing.Waypoint(coordinates[0], waypoints[0].name)); for (i = 0; i < instructions.length; i++) { if (instructions[i].sign === 5) { // VIA_REACHED idx = instructions[i].interval[0]; wpIndices.push(idx); wps.push(new L.Routing.Waypoint(coordinates[idx], waypoints[wps.length + 1].name)); } } wpIndices.push(coordinates.length - 1); wps.push(new L.Routing.Waypoint(coordinates[coordinates.length - 1], waypoints[waypoints.length - 1].name)); return { waypointIndices: wpIndices, waypoints: wps }; } }); L.Routing.graphHopper = function(options) { return new L.Routing.GraphHopper(options); }; module.exports = L.Routing; })();
(function() { 'use strict'; var L = require('leaflet'), corslite = require('@mapbox/corslite'), polyline = require('@mapbox/polyline'), osrmTextInstructions = require('osrm-text-instructions')('v5'); // 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 { var message = err.type + (err.target && err.target.status ? ' HTTP ' + err.target.status + ': ' + err.target.statusText : ''); if (err.responseText) { try { data = JSON.parse(err.responseText); if (data.message) message = data.message; } catch (ex) { } } error.message = 'HTTP request failed: ' + message; 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 { stepToText = L.bind(osrmTextInstructions.compile, osrmTextInstructions, this.options.language); } 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, {legCount: legCount, legIndex: i}); 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; } }, }); })();
class: L.Class.extend({ initialize: function(key) { this.key = key; }, geocode: function(query, cb, context) { jsonp( 'https://dev.virtualearth.net/REST/v1/Locations', { query: query, key: this.key, }, function(data) { var results = []; if (data.resourceSets.length > 0) { 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) { 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' ); }, }),
class: L.Class.extend({ options: { serviceUrl: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/' }, initialize: function(accessToken, options) { L.setOptions(this, options); this._accessToken = accessToken; }, geocode: function(query, cb, context) { Util.getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', { access_token: this._accessToken, }, 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); }); }, suggest: function(query, cb, context) { return this.geocode(query, cb, context); }, reverse: function(location, scale, cb, context) { Util.getJSON(this.options.serviceUrl + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', { access_token: this._accessToken, }, 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); }); } }),
class: L.Class.extend({ options: { serviceUrl: 'https://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 || a.hamlet) { parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') + '">{postcode} {city} {town} {village} {hamlet}</span>'); } if (a.state || a.country) { parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') + '">{state} {country}</span>'); } return Util.template(parts.join('<br/>'), a, true); } }, initialize: function(options) { L.Util.setOptions(this, options); }, geocode: function(query, cb, context) { Util.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) { Util.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'); } }),
(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')); /** * 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/route/v1', profile: 'driving', timeout: 30 * 1000, routingOptions: { alternatives: true, steps: true }, polylinePrecision: 5 }, 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; options = L.extend({}, this.options.routingOptions, options); url = this.buildRouteUrl(waypoints, 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)); } 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, options, 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)); return 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 = [], index = 0, legCount = responseRoute.legs.length, hasSteps = responseRoute.legs[0].steps.length > 0, i, j, leg, step, geometry, type; for (i = 0; i < legCount; i++) { leg = responseRoute.legs[i]; legNames.push(leg.summary); 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); 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 }); } index += geometry.length; } } result.name = legNames.join(', '); if (!hasSteps) { result.coordinates = this._decodePolyline(responseRoute.geometry); } 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 'arrive': return lastLeg ? 'DestinationReached' : 'WaypointReached'; case 'roundabout': case 'rotary': return 'Roundabout'; // These are all reduced to the same instruction in the current model //case 'turn': //case 'end of road': //case 'merge': //case 'on ramp': // new in v5.1 //case 'off ramp': // new in v5.1 //case 'ramp': // deprecated in v5.1 //case 'fork': default: switch (maneuver.modifier) { case 'straight': return 'Straight'; case 'slight right': return 'SlightRight'; case 'right': return 'Right'; case 'sharp right': return 'SharpRight'; case 'sharp left': return 'SharpLeft'; case 'left': return 'Left'; case 'slight left': return 'SlightLeft'; case 'uturn': return 'TurnAround'; default: return null; } return null; } }, _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].location), 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 = !(options && options.geometryOnly); return this.options.serviceUrl + '/' + this.options.profile + '/' + locs.join(';') + '?' + (options.geometryOnly ? (options.simplifyGeometry ? '' : 'overview=full') : 'overview=false') + '&alternatives=' + computeAlternative.toString() + '&steps=' + computeInstructions.toString() + '&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; } }, }); L.Routing.osrmv1 = function(options) { return new L.Routing.OSRMv1(options); }; module.exports = L.Routing; })();
class: L.Class.extend({ options: { serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json', geocodingQueryParams: {}, reverseQueryParams: {} }, initialize: function(key, options) { this._key = key; L.setOptions(this, options); // Backwards compatibility this.options.serviceUrl = this.options.service_url || this.options.serviceUrl; }, geocode: function(query, cb, context) { var params = { address: query, }; if (this._key && this._key.length) { params.key = this._key; } params = L.Util.extend(params, this.options.geocodingQueryParams); Util.getJSON(this.options.serviceUrl, 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, properties: loc.address_components }; } } cb.call(context, results); }); }, reverse: function(location, scale, cb, context) { var params = { latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng) }; params = L.Util.extend(params, this.options.reverseQueryParams); if (this._key && this._key.length) { params.key = this._key; } Util.getJSON(this.options.serviceUrl, 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, properties: loc.address_components }; } } cb.call(context, results); }); } }),
module.exports = L.Class.extend({ includes: L.Mixin.Events, initialize: function(id) { var _this = this; this.map = L.map(id, { attributionControl: false }); this.geojsonLayer = {}; this.geomLayer = L.geoJson(null, { style: createStyle, pointToLayer: function(feature, latlng) { return L.circle(latlng, 24); }, onEachFeature: function(f, layer) { _this.geojsonLayer[L.stamp(f)] = layer; featureControl(f, layer); } }); L.tileLayer(config.tiles.url, { attribution: config.tiles.atttribution }).addTo(this.map); L.control.attribution({ position: 'bottomleft' }).addTo(this.map); this.geomLayer.addTo(this.map); this.map.setView([0, 0], 2); this.map.on('click', L.bind(function(e) { this.fire('click', e); }, this)); }, add: function(geojson) { this.geomLayer.addData(geojson); this.map.fitBounds(this.geomLayer.getBounds(), {maxZoom: 14}); this.fire('added', { geojson: geojson, layer: this.geojsonLayer[L.stamp(geojson)] }); }, remove: function(geojson) { var id = L.stamp(geojson); this.geomLayer.removeLayer(this.geojsonLayer[id]); delete this.geomLayer[id]; }, highlightFeature: function(geojson) { var layer = this.geojsonLayer[L.stamp(geojson)]; this.map.fitBounds(layer.getBounds(), {maxZoom: 15}); } });
L.Google = L.Class.extend({ includes: L.Mixin.Events, options: { minZoom: 0, maxZoom: 18, tileSize: 256, subdomains: '', errorTileUrl: '', attribution: '', opacity: 1, continuousWorld: false, noWrap: false, }, // Possible types: SATELLITE, ROADMAP, HYBRID initialize: function(type, options) { L.Util.setOptions(this, options); this._type = google.maps.MapTypeId[type || 'SATELLITE']; }, onAdd: function(map, insertAtTheBottom) { this._map = map; this._insertAtTheBottom = insertAtTheBottom; // create a container div for tiles this._initContainer(); this._initMapObject(); // set up events map.on('viewreset', this._resetCallback, this); this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this); map.on('move', this._update, this); //map.on('moveend', this._update, this); this._reset(); this._update(); }, onRemove: function(map) { this._map._container.removeChild(this._container); //this._container = null; this._map.off('viewreset', this._resetCallback, this); this._map.off('move', this._update, this); //this._map.off('moveend', this._update, this); }, getAttribution: function() { return this.options.attribution; }, setOpacity: function(opacity) { this.options.opacity = opacity; if (opacity < 1) { L.DomUtil.setOpacity(this._container, opacity); } }, _initContainer: function() { var tilePane = this._map._container var first = tilePane.firstChild; if (!this._container) { this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left'); this._container.id = "_GMapContainer"; } if (true) { tilePane.insertBefore(this._container, first); this.setOpacity(this.options.opacity); var size = this._map.getSize(); this._container.style.width = size.x + 'px'; this._container.style.height = size.y + 'px'; } }, _initMapObject: function() { this._google_center = new google.maps.LatLng(0, 0); var map = new google.maps.Map(this._container, { center: this._google_center, zoom: 0, mapTypeId: this._type, disableDefaultUI: true, keyboardShortcuts: false, draggable: false, disableDoubleClickZoom: true, scrollwheel: false, streetViewControl: false }); var _this = this; this._reposition = google.maps.event.addListenerOnce(map, "center_changed", function() { _this.onReposition(); }); map.backgroundColor = '#ff0000'; this._google = map; }, _resetCallback: function(e) { this._reset(e.hard); }, _reset: function(clearOldContainer) { this._initContainer(); }, _update: function() { this._resize(); var bounds = this._map.getBounds(); var ne = bounds.getNorthEast(); var sw = bounds.getSouthWest(); var google_bounds = new google.maps.LatLngBounds( new google.maps.LatLng(sw.lat, sw.lng), new google.maps.LatLng(ne.lat, ne.lng) ); var center = this._map.getCenter(); var _center = new google.maps.LatLng(center.lat, center.lng); this._google.setCenter(_center); this._google.setZoom(this._map.getZoom()); //this._google.fitBounds(google_bounds); }, _resize: function() { var size = this._map.getSize(); if (this._container.style.width == size.x && this._container.style.height == size.y) return; this._container.style.width = size.x + 'px'; this._container.style.height = size.y + 'px'; google.maps.event.trigger(this._google, "resize"); }, onReposition: function() {} });
/* * Defines an interface for a single filter - for example, Filter By Aid Category. */ var L = require('leaflet'); var BaseFilter = L.Class.extend({ includes: L.Mixin.Events, render: function () { this.fire('update'); }, update: function () {}, reset: function () {} }); module.exports = BaseFilter;
load: function () { const LEAFLET_MAJOR_VERSION = parseInt(L.version.split('.')[0], 10) const googleParams = { includes: L.Mixin.Events, options: { minZoom: 0, maxZoom: 18, tileSize: 256, subdomains: 'abc', errorTileUrl: '', attribution: '', opacity: 1, continuousWorld: false, noWrap: false, mapOptions: { backgroundColor: '#dddddd', }, }, // Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN initialize: function (type = 'ROADMAP', options) { L.Util.setOptions(this, options) this._type = type this._ready = google.maps.Map !== undefined if (!this._ready) { L.Google.asyncWait.push(this) } }, onAdd: function (map, insertAtTheBottom) { this._map = map this._insertAtTheBottom = insertAtTheBottom // create a container div for tiles this._initContainer() this._initMapObject() // set up events map.on('viewreset', this._resetCallback, this) if (LEAFLET_MAJOR_VERSION === 0) { this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this) } else { this._limitedUpdate = L.Util.throttle(this._update, 150, this) } map.on('move', this._update, this) map.on('zoomanim', this._handleZoomAnim, this) // 20px instead of 1em to avoid a slight overlap with google's attribution map._controlCorners.bottomright.style.marginBottom = '20px' this._reset() this._update() }, onRemove: function (map) { map._container.removeChild(this._container) map.off('viewreset', this._resetCallback, this) map.off('move', this._update, this) map.off('zoomanim', this._handleZoomAnim, this) map._controlCorners.bottomright.style.marginBottom = '0em' }, getAttribution: function () { return this.options.attribution }, setOpacity: function (opacity) { this.options.opacity = opacity if (opacity < 1) { L.DomUtil.setOpacity(this._container, opacity) } }, setElementSize: function (e, size) { e.style.width = size.x + 'px' e.style.height = size.y + 'px' }, _initContainer: function () { let tilePane = this._map._container let first = tilePane.firstChild if (!this._container) { let gMapExtraContainerClasses = LEAFLET_MAJOR_VERSION === 0 ? ' leaflet-top leaflet-left' : '' this._container = L.DomUtil.create('div', 'leaflet-google-layer' + gMapExtraContainerClasses) this._container.id = '_GMapContainer_' + L.Util.stamp(this) this._container.style.zIndex = 'auto' } tilePane.insertBefore(this._container, first) this.setOpacity(this.options.opacity) this.setElementSize(this._container, this._map.getSize()) }, _initMapObject: function () { if (!this._ready) return this._google_center = new google.maps.LatLng(0, 0) let map = new google.maps.Map(this._container, { center: this._google_center, zoom: 0, tilt: 0, mapTypeId: google.maps.MapTypeId[this._type], disableDefaultUI: true, keyboardShortcuts: false, draggable: false, disableDoubleClickZoom: true, scrollwheel: false, streetViewControl: false, styles: this.options.mapOptions.styles, backgroundColor: this.options.mapOptions.backgroundColor, }) let _this = this this._reposition = google.maps.event.addListenerOnce(map, 'center_changed', function () { _this.onReposition() }) this._google = map google.maps.event.addListenerOnce(map, 'idle', function () { _this._checkZoomLevels() }) google.maps.event.addListenerOnce(map, 'tilesloaded', function () { _this.fire('load') }) // Reporting that map-object was initialized. this.fire('MapObjectInitialized', { mapObject: map, }) }, _checkZoomLevels: function () { // setting the zoom level on the Google map may result in a different zoom level than the one requested // (it won't go beyond the level for which they have data). // verify and make sure the zoom levels on both Leaflet and Google maps are consistent if (this._google.getZoom() !== this._map.getZoom()) { // zoom levels are out of sync. Set the leaflet zoom level to match the google one this._map.setZoom(this._google.getZoom()) } }, _resetCallback: function (e) { this._reset(e.hard) }, _reset: function () { this._initContainer() }, _update: function () { if (!this._google) return this._resize() let center = this._map.getCenter() let _center = new google.maps.LatLng(center.lat, center.lng) this._google.setCenter(_center) this._google.setZoom(Math.round(this._map.getZoom())) this._checkZoomLevels() }, _resize: function () { let size = this._map.getSize() if (this._container.style.width === size.x && this._container.style.height === size.y) { return } this.setElementSize(this._container, size) this.onReposition() }, _handleZoomAnim: function (e) { let center = e.center let _center = new google.maps.LatLng(center.lat, center.lng) this._google.setCenter(_center) this._google.setZoom(Math.round(e.zoom)) }, onReposition: function () { if (!this._google) return google.maps.event.trigger(this._google, 'resize') }, } if (LEAFLET_MAJOR_VERSION === 0) { L.Google = L.Class.extend(googleParams) } else { L.Google = L.Layer.extend(googleParams) } L.Google.asyncWait = [] L.Google.asyncInitialize = function () { for (let i = 0; i < L.Google.asyncWait.length; i++) { let o = L.Google.asyncWait[i] o._ready = true if (o._container) { o._initMapObject() o._update() } } L.Google.asyncWait = [] } },
(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')); 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)); } 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)); return 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; })();
L.Google.TileLayer = L.Class.extend({ includes: L.Mixin.Events, options: { minZoom: 0, maxZoom: 18, tileSize: 256, subdomains: 'abc', errorTileUrl: '', attribution: '', opacity: 1, continuousWorld: false, noWrap: false, mapOptions: { backgroundColor: '#fff' } }, // Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN initialize: function(type, options) { L.Util.setOptions(this, options); this._ready = google.maps.Map !== undefined; if (!this._ready) L.Google.asyncWait.push(this); this._type = type || 'SATELLITE'; }, _layerAdd: function (e) { var map = e.target; // check in case layer gets added and then removed before the map is ready if (!map.hasLayer(this)) { return; } this._map = map; this._zoomAnimated = map._zoomAnimated; this.onAdd(map); if (this.getAttribution && this._map.attributionControl) { this._map.attributionControl.addAttribution(this.getAttribution()); } if (this.getEvents) { map.on(this.getEvents(), this); } this.fire('add'); map.fire('layeradd', {layer: this}); }, onAdd: function(map, insertAtTheBottom) { this._map = map; this._insertAtTheBottom = insertAtTheBottom; // create a container div for tiles this._initContainer(); this._initMapObject(); // set up events map.on('viewreset', this._resetCallback, this); this._limitedUpdate = L.Util.throttle(this._update, 150, this); map.on('move', this._update, this); map.on('zoomanim', this._handleZoomAnim, this); //20px instead of 1em to avoid a slight overlap with google's attribution map._controlCorners.bottomright.style.marginBottom = '20px'; this._reset(); this._update(); }, onRemove: function(map) { map._container.removeChild(this._container); map.off('viewreset', this._resetCallback, this); map.off('move', this._update, this); map.off('zoomanim', this._handleZoomAnim, this); map._controlCorners.bottomright.style.marginBottom = '0em'; }, getAttribution: function() { return this.options.attribution; }, setOpacity: function(opacity) { this.options.opacity = opacity; if (opacity < 1) { L.DomUtil.setOpacity(this._container, opacity); } }, setElementSize: function(e, size) { e.style.width = size.x + 'px'; e.style.height = size.y + 'px'; }, _initContainer: function() { var tilePane = this._map._container, first = tilePane.firstChild; if (!this._container) { this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left'); this._container.id = '_GMapContainer_' + L.Util.stamp(this); this._container.style.zIndex = 'auto'; } tilePane.insertBefore(this._container, first); this.setOpacity(this.options.opacity); this.setElementSize(this._container, this._map.getSize()); }, _initMapObject: function() { if (!this._ready) return; this._google_center = new google.maps.LatLng(0, 0); var map = new google.maps.Map(this._container, { center: this._google_center, zoom: 0, tilt: 0, mapTypeId: google.maps.MapTypeId[this._type], disableDefaultUI: true, keyboardShortcuts: false, draggable: false, disableDoubleClickZoom: true, scrollwheel: false, streetViewControl: false, styles: this.options.mapOptions.styles, backgroundColor: this.options.mapOptions.backgroundColor }); var _this = this; this._reposition = google.maps.event.addListenerOnce(map, 'center_changed', function() { _this.onReposition(); }); this._google = map; google.maps.event.addListenerOnce(map, 'idle', function() { _this._checkZoomLevels(); }); //Reporting that map-object was initialized. this.fire('MapObjectInitialized', { mapObject: map }); }, _checkZoomLevels: function() { //setting the zoom level on the Google map may result in a different zoom level than the one requested //(it won't go beyond the level for which they have data). // verify and make sure the zoom levels on both Leaflet and Google maps are consistent if (this._google.getZoom() !== this._map.getZoom()) { //zoom levels are out of sync. Set the leaflet zoom level to match the google one this._map.setZoom( this._google.getZoom() ); } }, _resetCallback: function(e) { this._reset(e.hard); }, _reset: function(clearOldContainer) { this._initContainer(); }, _update: function(e) { if (!this._google) return; this._resize(); var center = this._map.getCenter(); var _center = new google.maps.LatLng(center.lat, center.lng); this._google.setCenter(_center); this._google.setZoom(Math.round(this._map.getZoom())); this._checkZoomLevels(); }, _resize: function() { var size = this._map.getSize(); if (this._container.style.width === size.x && this._container.style.height === size.y) return; this.setElementSize(this._container, size); this.onReposition(); }, _handleZoomAnim: function (e) { var center = e.center; var _center = new google.maps.LatLng(center.lat, center.lng); this._google.setCenter(_center); this._google.setZoom(Math.round(e.zoom)); }, onReposition: function() { if (!this._google) return; google.maps.event.trigger(this._google, 'resize'); } });