UNPKG

esri-leaflet

Version:

Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services.

257 lines (214 loc) 6.98 kB
import L from 'leaflet'; import { cors } from '../Support'; import { setEsriAttribution } from '../Util'; var Overlay = L.ImageOverlay.extend({ onAdd: function (map) { this._topLeft = map.getPixelBounds().min; L.ImageOverlay.prototype.onAdd.call(this, map); }, _reset: function () { if (this._map.options.crs === L.CRS.EPSG3857) { L.ImageOverlay.prototype._reset.call(this); } else { L.DomUtil.setPosition(this._image, this._topLeft.subtract(this._map.getPixelOrigin())); } } }); export var RasterLayer = L.Layer.extend({ options: { opacity: 1, position: 'front', f: 'image', useCors: cors, attribution: null, interactive: false, alt: '' }, onAdd: function (map) { // include 'Powered by Esri' in map attribution setEsriAttribution(map); this._update = L.Util.throttle(this._update, this.options.updateInterval, this); map.on('moveend', this._update, this); // if we had an image loaded and it matches the // current bounds show the image otherwise remove it if (this._currentImage && this._currentImage._bounds.equals(this._map.getBounds())) { map.addLayer(this._currentImage); } else if (this._currentImage) { this._map.removeLayer(this._currentImage); this._currentImage = null; } this._update(); if (this._popup) { this._map.on('click', this._getPopupData, this); this._map.on('dblclick', this._resetPopupState, this); } // add copyright text listed in service metadata this.metadata(function (err, metadata) { if (!err && !this.options.attribution && map.attributionControl && metadata.copyrightText) { this.options.attribution = metadata.copyrightText; map.attributionControl.addAttribution(this.getAttribution()); } }, this); }, onRemove: function (map) { if (this._currentImage) { this._map.removeLayer(this._currentImage); } if (this._popup) { this._map.off('click', this._getPopupData, this); this._map.off('dblclick', this._resetPopupState, this); } this._map.off('moveend', this._update, this); }, bindPopup: function (fn, popupOptions) { this._shouldRenderPopup = false; this._lastClick = false; this._popup = L.popup(popupOptions); this._popupFunction = fn; if (this._map) { this._map.on('click', this._getPopupData, this); this._map.on('dblclick', this._resetPopupState, this); } return this; }, unbindPopup: function () { if (this._map) { this._map.closePopup(this._popup); this._map.off('click', this._getPopupData, this); this._map.off('dblclick', this._resetPopupState, this); } this._popup = false; return this; }, bringToFront: function () { this.options.position = 'front'; if (this._currentImage) { this._currentImage.bringToFront(); } return this; }, bringToBack: function () { this.options.position = 'back'; if (this._currentImage) { this._currentImage.bringToBack(); } return this; }, getAttribution: function () { return this.options.attribution; }, getOpacity: function () { return this.options.opacity; }, setOpacity: function (opacity) { this.options.opacity = opacity; this._currentImage.setOpacity(opacity); return this; }, getTimeRange: function () { return [this.options.from, this.options.to]; }, setTimeRange: function (from, to) { this.options.from = from; this.options.to = to; this._update(); return this; }, metadata: function (callback, context) { this.service.metadata(callback, context); return this; }, authenticate: function (token) { this.service.authenticate(token); return this; }, _renderImage: function (url, bounds, contentType) { if (this._map) { // if no output directory has been specified for a service, MIME data will be returned if (contentType) { url = 'data:' + contentType + ';base64,' + url; } // create a new image overlay and add it to the map // to start loading the image // opacity is 0 while the image is loading var image = new Overlay(url, bounds, { opacity: 0, crossOrigin: this.options.useCors, alt: this.options.alt, pane: this.options.pane || this.getPane(), interactive: this.options.interactive }).addTo(this._map); // once the image loads image.once('load', function (e) { if (this._map) { var newImage = e.target; var oldImage = this._currentImage; // if the bounds of this image matches the bounds that // _renderImage was called with and we have a map with the same bounds // hide the old image if there is one and set the opacity // of the new image otherwise remove the new image if (newImage._bounds.equals(bounds) && newImage._bounds.equals(this._map.getBounds())) { this._currentImage = newImage; if (this.options.position === 'front') { this.bringToFront(); } else { this.bringToBack(); } if (this._map && this._currentImage._map) { this._currentImage.setOpacity(this.options.opacity); } else { this._currentImage._map.removeLayer(this._currentImage); } if (oldImage && this._map) { this._map.removeLayer(oldImage); } if (oldImage && oldImage._map) { oldImage._map.removeLayer(oldImage); } } else { this._map.removeLayer(newImage); } } this.fire('load', { bounds: bounds }); }, this); this.fire('loading', { bounds: bounds }); } }, _update: function () { if (!this._map) { return; } var zoom = this._map.getZoom(); var bounds = this._map.getBounds(); if (this._animatingZoom) { return; } if (this._map._panTransition && this._map._panTransition._inProgress) { return; } if (zoom > this.options.maxZoom || zoom < this.options.minZoom) { this._currentImage._map.removeLayer(this._currentImage); return; } var params = this._buildExportParams(); this._requestExport(params, bounds); }, _renderPopup: function (latlng, error, results, response) { latlng = L.latLng(latlng); if (this._shouldRenderPopup && this._lastClick.equals(latlng)) { // add the popup to the map where the mouse was clicked at var content = this._popupFunction(error, results, response); if (content) { this._popup.setLatLng(latlng).setContent(content).openOn(this._map); } } }, _resetPopupState: function (e) { this._shouldRenderPopup = false; this._lastClick = e.latlng; } });