/*! * leaflet.wms.js * A collection of Leaflet utilities for working with Web Mapping services. * (c) 2014-2016, Houston Engineering, Inc. * MIT License */ (function (factory) { // Module systems magic dance, Leaflet edition if (typeof define === 'function' && define.amd) { // AMD define(['leaflet'], factory); } else if (typeof module !== 'undefined') { // Node/CommonJS module.exports = factory(require('leaflet')); } else { // Browser globals if (typeof this.L === 'undefined') throw 'Leaflet must be loaded first!'; // Namespace this.L.WMS = this.L.wms = factory(this.L); } }(function (L) { // Module object var wms = {}; // Quick shim for Object.keys() if (!('keys' in Object)) { Object.keys = function(obj) { var result = []; for (var i in obj) { if (obj.hasOwnProperty(i)) { result.push(i); } } return result; }; } /* * wms.Source * The Source object manages a single WMS connection. Multiple "layers" can be * created with the getLayer function, but a single request will be sent for * each image update. Can be used in non-tiled "overlay" mode (default), or * tiled mode, via an internal wms.Overlay or wms.TileLayer, respectively. */ wms.Source = L.Layer.extend({ 'options': { 'untiled': true, 'identify': true }, 'initialize': function(url, options) { L.setOptions(this, options); if (this.options.tiled) { this.options.untiled = false; } this._url = url; this._subLayers = {}; this._overlay = this.createOverlay(this.options.untiled); }, 'createOverlay': function(untiled) { // Create overlay with all options other than untiled & identify var overlayOptions = {}; for (var opt in this.options) { if (opt != 'untiled' && opt != 'identify') { overlayOptions[opt] = this.options[opt]; } } if (untiled) { return wms.overlay(this._url, overlayOptions); } else { return wms.tileLayer(this._url, overlayOptions); } }, 'onAdd': function() { this.refreshOverlay(); }, 'getEvents': function() { if (this.options.identify) { return {'click': this.identify}; } else { return {}; } }, 'setOpacity': function(opacity) { this.options.opacity = opacity; if (this._overlay) { this._overlay.setOpacity(opacity); } }, 'bringToBack': function() { this.options.isBack = true; if (this._overlay) { this._overlay.bringToBack(); } }, 'bringToFront': function() { this.options.isBack = false; if (this._overlay) { this._overlay.bringToFront(); } }, 'getLayer': function(name) { return wms.layer(this, name); }, 'addSubLayer': function(name) { this._subLayers[name] = true; this.refreshOverlay(); }, 'removeSubLayer': function(name) { delete this._subLayers[name]; this.refreshOverlay(); }, 'refreshOverlay': function() { var subLayers = Object.keys(this._subLayers).join(","); if (!this._map) { return; } if (!subLayers) { this._overlay.remove(); } else { this._overlay.setParams({'layers': subLayers}); this._overlay.addTo(this._map); } }, 'identify': function(evt) { // Identify map features in response to map clicks. To customize this // behavior, create a class extending wms.Source and override one or // more of the following hook functions. var layers = this.getIdentifyLayers(); if (!layers.length) { return; } this.getFeatureInfo( evt.containerPoint, evt.latlng, layers, this.showFeatureInfo ); }, 'getFeatureInfo': function(point, latlng, layers, callback) { // Request WMS GetFeatureInfo and call callback with results // (split from identify() to faciliate use outside of map events) var params = this.getFeatureInfoParams(point, layers), url = this._url + L.Util.getParamString(params, this._url); this.showWaiting(); this.ajax(url, done); function done(result) { this.hideWaiting(); var text = this.parseFeatureInfo(result, url); callback.call(this, latlng, text); } }, 'ajax': function(url, callback) { ajax.call(this, url, callback); }, 'getIdentifyLayers': function() { // Hook to determine which layers to identify if (this.options.identifyLayers) return this.options.identifyLayers; return Object.keys(this._subLayers); }, 'getFeatureInfoParams': function(point, layers) { // Hook to generate parameters for WMS service GetFeatureInfo request var wmsParams, overlay; if (this.options.untiled) { // Use existing overlay wmsParams = this._overlay.wmsParams; } else { // Create overlay instance to leverage updateWmsParams overlay = this.createOverlay(true); overlay.updateWmsParams(this._map); wmsParams = overlay.wmsParams; wmsParams.layers = layers.join(','); } var infoParams = { 'request': 'GetFeatureInfo', 'query_layers': layers.join(','), 'X': Math.round(point.x), 'Y': Math.round(point.y) }; return L.extend({}, wmsParams, infoParams); }, 'parseFeatureInfo': function(result, url) { // Hook to handle parsing AJAX response if (result == "error") { // AJAX failed, possibly due to CORS issues. // Try loading content in