-
-
Save apollolm/8720143 to your computer and use it in GitHub Desktop.
DynamicSingleTile is similar to SingleTileWMS overlay for Leaflet map framework, except that it's requesting images from a custom Node.js map server built with mapnik (Chubbs Spatial Server/PGRestAPI)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* from - https://gist.github.com/fnicollet/5764080 | |
* Modified by Ryan Whitley - Jan 30, 2013 | |
* L.DynamicSingleTile uses L.ImageOverlay to display a single-tile layer from node-mapnik. | |
* url parameter must accept width, height and bbox. | |
*/ | |
L.DynamicSingleTile = L.ImageOverlay.extend({ | |
initialize: function (url, bounds, options) { // (String, Object) | |
this._url = url; | |
if (url.indexOf("{s}") != -1) { | |
this.options.subdomains = options.subdomains = '1234'; | |
} | |
this._isSwap = false; | |
this._imageSwap = null; | |
L.setOptions(this, options); | |
}, | |
onAdd: function (map) { | |
this._map = map; | |
// | |
this._bounds = map.getBounds(); | |
// pan | |
map.on('moveend', this._onViewReset, this); | |
// hide on zoom | |
if (map.options.zoomAnimation && L.Browser.any3d) { | |
map.on('zoomanim', this._onZoomAnim, this); | |
} | |
// request a first image on add | |
this._onViewReset(); | |
// override | |
//L.ImageOverlay.prototype.onAdd.call(this, map); | |
}, | |
onRemove: function (map) { | |
// super() | |
L.ImageOverlay.prototype.onRemove.call(this, map); | |
// add | |
if (this._imageSwap) { | |
map.getPanes().overlayPane.removeChild(this._imageSwap); | |
} | |
map.off('moveend', this._onViewReset, this); | |
map.off('zoomanim', this._onZoomAnim, this); | |
}, | |
_onViewReset: function () { | |
this._futureBounds = this._map.getBounds(); | |
var size = this._map.getSize(); | |
var b = this._map.getBounds(); | |
var metersBounds = { southWest: L.CRS.EPSG3857.project(b.getSouthWest()), northEast: L.CRS.EPSG3857.project(b.getNorthEast()) }; | |
var imageSrc = this._url + L.Util.getParamString(this.Params, this._url) + "&width=" + size.x + "&height=" + size.y + "&bbox=" + metersBounds.southWest.x + "," + metersBounds.northEast.y + "," + metersBounds.northEast.x + "," + metersBounds.southWest.y; | |
this.swapImage(imageSrc, this._futureBounds); | |
}, | |
_reset: function () { | |
var el = this._isSwap ? this._imageSwap : this._image; | |
if (!el) { | |
return; | |
} | |
/** @type {L.LatLng} */ | |
var nwLatLng = this._bounds.getNorthWest(); | |
var seLatLng = this._bounds.getSouthEast(); | |
var topLeft = this._map.latLngToLayerPoint(nwLatLng); | |
var bottomRight = this._map.latLngToLayerPoint(seLatLng); | |
var size = bottomRight.subtract(topLeft); | |
L.DomUtil.setPosition(el, topLeft); | |
el.width = size.x; | |
el.height = size.y; | |
}, | |
_onZoomAnim: function () { | |
if (this._imageSwap) { | |
this._imageSwap.style.visibility = 'hidden'; | |
} | |
if (this._image) { | |
this._image.style.visibility = 'hidden'; | |
} | |
}, | |
_onSwapImageLoad: function () { | |
if (this._isSwap) { | |
this._imageSwap.style.visibility = 'hidden'; | |
this._image.style.visibility = ''; | |
} else { | |
this._imageSwap.style.visibility = ''; | |
this._image.style.visibility = 'hidden'; | |
} | |
this._isSwap = !this._isSwap; | |
this._bounds = this._futureBounds; | |
this._reset(); | |
}, | |
_updateOpacity : function (){ | |
L.DomUtil.setOpacity(this._image, this.options.opacity); | |
L.DomUtil.setOpacity(this._imageSwap, this.options.opacity); | |
}, | |
swapImage: function (src, bounds) { | |
if (!this._imagesCreated) { | |
this._image = this._createImageSwap(); | |
this._imageSwap = this._createImageSwap(); | |
this._imagesCreated = true; | |
} | |
if (this._isSwap) { | |
this._image.src = src; | |
} else { | |
this._imageSwap.src = src; | |
} | |
this._updateOpacity(); | |
// do not assign the bound here, this will be done after the next image | |
this._futureBounds = bounds; | |
// allows to re-position the image while waiting for the swap. | |
// attention : the does not work while resizing, because of the wrong bound (size in pixel) | |
this._reset(); | |
}, | |
_createImageSwap: function () { | |
var el = L.DomUtil.create('img', 'leaflet-image-layer'); | |
L.Util.extend(el, { | |
galleryimg: 'no', | |
onselectstart: L.Util.falseFn, | |
onmousemove: L.Util.falseFn, | |
onload: L.Util.bind(this._onSwapImageLoad, this) | |
}); | |
this._map._panes.overlayPane.appendChild(el); | |
el.style.visibility = ''; | |
return el; | |
} | |
}); | |
L.dynamicSingleTile = function (url, bounds, options) { | |
return new L.DynamicSingleTile(url, bounds, options); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment