L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ onAdd: function (map) { // Triggered when the layer is added to a map. // Register a click listener, then do all the upstream WMS things L.TileLayer.WMS.prototype.onAdd.call(this, map); map.on('click', this.getFeatureInfo, this); }, onRemove: function (map) { // Triggered when the layer is removed from a map. // Unregister a click listener, then do all the upstream WMS things L.TileLayer.WMS.prototype.onRemove.call(this, map); map.off('click', this.getFeatureInfo, this); }, getFeatureInfo: function (evt) { // Make an AJAX request to the server and hope for the best var url = this.getFeatureInfoUrl(evt.latlng), showResults = L.Util.bind(this.showGetFeatureInfo, this); $.ajax({ url: url, success: function (data, status, xhr) { var err = typeof data === 'string' ? null : data; showResults(err, evt.latlng, data); }, error: function (xhr, status, error) { showResults(error); } }); }, getFeatureInfoUrl: function (latlng) { // Construct a GetFeatureInfo request URL given a point var point = this._map.latLngToContainerPoint(latlng, this._map.getZoom()), size = this._map.getSize(), params = { request: 'GetFeatureInfo', service: 'WMS', srs: 'EPSG:4326', styles: this.wmsParams.styles, transparent: this.wmsParams.transparent, version: this.wmsParams.version, format: this.wmsParams.format, bbox: this._map.getBounds().toBBoxString(), height: size.y, width: size.x, layers: this.wmsParams.layers, query_layers: this.wmsParams.layers, info_format: 'text/html' }; params[params.version === '1.3.0' ? 'i' : 'x'] = point.x; params[params.version === '1.3.0' ? 'j' : 'y'] = point.y; return this._url + L.Util.getParamString(params, this._url, true); }, showGetFeatureInfo: function (err, latlng, content) { if (err) { console.log(err); return; } // do nothing if there's an error // Otherwise show the content in a popup, or something. L.popup({ maxWidth: 800}) .setLatLng(latlng) .setContent(content) .openOn(this._map); } }); L.tileLayer.betterWms = function (url, options) { return new L.TileLayer.BetterWMS(url, options); }; /* * L.Control.WMSLegend is used to add a WMS Legend to the map */ L.Control.WMSLegend = L.Control.extend({ options: { position: 'topleft', uri: '' }, onAdd: function () { var controlClassName = 'leaflet-control-wms-legend', legendClassName = 'wms-legend', stop = L.DomEvent.stopPropagation; this.container = L.DomUtil.create('div', controlClassName); this.img = L.DomUtil.create('img', legendClassName, this.container); this.img.src = this.options.uri; this.img.alt = 'Legend'; L.DomEvent .on(this.img, 'click', this._click, this) .on(this.container, 'click', this._click, this) .on(this.img, 'mousedown', stop) .on(this.img, 'dblclick', stop) .on(this.img, 'click', L.DomEvent.preventDefault) .on(this.img, 'click', stop); this.height = null; this.width = null; return this.container; }, _click: function (e) { L.DomEvent.stopPropagation(e); L.DomEvent.preventDefault(e); // toggle legend visibility var style = window.getComputedStyle(this.img); if (style.display === 'none') { this.container.style.height = this.height + 'px'; this.container.style.width = this.width + 'px'; this.img.style.display = this.displayStyle; } else { if (this.width === null && this.height === null) { // Only do inside the above check to prevent the container // growing on successive uses this.height = this.container.offsetHeight; this.width = this.container.offsetWidth; } this.displayStyle = this.img.style.display; this.img.style.display = 'none'; this.container.style.height = '20px'; this.container.style.width = '20px'; } }, }); L.wmsLegend = function (uri) { var wmsLegendControl = new L.Control.WMSLegend; wmsLegendControl.options.uri = uri; map.addControl(wmsLegendControl); return wmsLegendControl; };