PageSourceSearch

https://inwestujwgminie.pl/lib/leaflet_wms/leaflet.wms.js

js inwestujwgminie.pl collected 2026-10-09 02:54:42 UTC 12,774 bytes, 425 lines download raw bytes

1/*!
2 * leaflet.wms.js
3 * A collection of Leaflet utilities for working with Web Mapping services.
4 * (c) 2014, Houston Engineering, Inc.
5 * MIT License
6 */
7
8(function (factory) {
9    // Module systems magic dance, Leaflet edition
10    if (typeof define === 'function' && define.amd) {
11        // AMD
12        define(['leaflet'], factory);
13    } else if (typeof module !== 'undefined') {
14        // Node/CommonJS
15        module.exports = factory(require('leaflet'));
16    } else {
17        // Browser globals
18        if (typeof this.L === 'undefined')
19            throw 'Leaflet must be loaded first!';
20        // Namespace
21        this.L.WMS = this.L.wms = factory(this.L);
22    }
23}(function (L) {
24
25// Module object
26var wms = {};
27
28// Hacky backport of L.Layer for 0.7.3
29if (!L.Layer) {
30    L.Layer = L.LayerGroup.extend({
31        'onAdd': function(map) {
32            this._map = map;
33            if (map && this.getEvents) {
34                var events = this.getEvents();
35                for (var evt in events) {
36                    map.on(evt, events[evt], this);
37                }
38            }
39        },
40        'onRemove': function() {
41            delete this._map;
42        }
43    });
44}
45
46/*
47 * wms.Source
48 * The Source object manages a single WMS connection.  Multiple "layers" can be
49 * created with the getLayer function, but a single request will be sent for
50 * each image update.  Can be used in non-tiled "overlay" mode (default), or
51 * tiled mode, via an internal wms.Overlay or wms.TileLayer, respectively.
52 */
53wms.Source = L.Layer.extend({
54    'options': {
55        'tiled': false,
56        'identify': true
57    },
58
59    'initialize': function(url, options) {
60        this._url = url;
61        this._subLayers = {};
62        options = L.setOptions(this, options);
63        this._overlay = this.createOverlay(url, options);
64    },
65
66    'createOverlay': function(url, options) {
67        if (options.tiled) {
68            return wms.tileLayer(url, options);
69        } else {
70            return wms.overlay(url, options);
71        }
72    },
73
74    'onAdd': function(map) {
75        L.Layer.prototype.onAdd.call(this, map);
76        this.refreshOverlay();
77    },
78
79    'getEvents': function() {
80        if (this.options.identify) {
81            return {'click': this.identify};
82        } else {
83            return {};
84        }
85    },
86
87    'getLayer': function(name) {
88        return wms.layer(this, name);
89    },
90
91    'addSubLayer': function(name) {
92        this._subLayers[name] = true;
93        this.refreshOverlay();
94    },
95
96    'removeSubLayer': function(name) {
97        delete this._subLayers[name];
98        this.refreshOverlay();
99    },
100
101    'refreshOverlay': function() {
102        var subLayers = Object.keys(this._subLayers).join(",");
103        if (!this._map) {
104            return;
105        }
106        if (!subLayers) {
107            this._map.removeLayer(this._overlay);
108        } else {
109            this._overlay.setParams({'layers': subLayers});
110            this._overlay.addTo(this._map);
111        }
112    },
113
114    'identify': function(evt) {
115        // Identify map features in response to map clicks. To customize this
116        // behavior, create a class extending wms.Source and override one or
117        // more of the following hook functions.
118
119        var layers = this.getIdentifyLayers();
120        if (!layers.length) {
121            return;
122        }
123        this.getFeatureInfo(
124            evt.containerPoint, evt.latlng, layers,
125            this.showFeatureInfo
126        );
127    },
128
129    'getFeatureInfo': function(point, latlng, layers, callback) {
130        // Request WMS GetFeatureInfo and call callback with results
131        // (split from identify() to faciliate use outside of map events)
132        var params = this.getFeatureInfoParams(point, layers),
133            url = this._url + L.Util.getParamString(params, this._url);
134
135        this.showWaiting();
136        ajax.call(this, url, done);
137
138        function done(result) {
139            this.hideWaiting();
140            var text = this.parseFeatureInfo(result, url);
141            callback.call(this, latlng, text);
142        }
143    },
144
145    'getIdentifyLayers': function() {
146        // Hook to determine which layers to identify
147        if (this.options.identifyLayers)
148            return this.options.identifyLayers;
149        return Object.keys(this._subLayers);
150     },
151
152    'getFeatureInfoParams': function(point, layers) {
153        // Hook to generate parameters for WMS service GetFeatureInfo request
154        var wmsParams, overlay;
155        if (this.options.tiled) {
156            // Create overlay instance to leverage updateWmsParams
157            overlay = wms.overlay(this._url, this.options);
158            overlay.updateWmsParams(this._map);
159            wmsParams = overlay.wmsParams;
160            wmsParams.layers = layers.join(',');
161        } else {
162            // Use existing overlay
163            wmsParams = this._overlay.wmsParams;
164        }
165        var infoParams = {
166            'request': 'GetFeatureInfo',
167            'query_layers': layers.join(','),
168            'X': point.x,
169            'Y': point.y
170        };
171        return L.extend({}, wmsParams, infoParams);
172    },
173
174    'parseFeatureInfo': function(result, url) {
175        // Hook to handle parsing AJAX response
176        if (result == "error") {
177            // AJAX failed, possibly due to CORS issues.
178            // Try loading content in <iframe>.
179            result = "<iframe src='" + url + "' style='border:none'>";
180        }
181        return result;
182    },
183
184    'showFeatureInfo': function(latlng, info) {
185        // Hook to handle displaying parsed AJAX response to the user
186        if (!this._map) {
187            return;
188        }
189        this._map.openPopup(info, latlng);
190    },
191
192    'showWaiting': function() {
193        // Hook to customize AJAX wait animation
194        if (!this._map)
195            return;
196        this._map._container.style.cursor = "progress";
197    },
198
199    'hideWaiting': function() {
200        // Hook to remove AJAX wait animation
201        if (!this._map)
202            return;
203        this._map._container.style.cursor = "default";
204    }
205});
206
207wms.source = function(url, options) {
208    return new wms.Source(url, options);
209};
210
211/*
212 * Layer
213 * Leaflet "layer" with all actual rendering handled via an underlying Source
214 * object.  Can be called directly with a URL to automatically create or reuse
215 * an existing Source.  Note that the auto-source feature doesn't work well in
216 * multi-map environments; so for best results, create a Source first and use
217 * getLayer() to retrieve wms.Layer instances.
218 */
219
220wms.Layer = L.Layer.extend({
221    'initialize': function(source, layerName, options) {
222        if (!source.addSubLayer) {
223            // Assume source is a URL
224            source = wms.getSourceForUrl(source, options);
225        }
226        this._source = source;
227        this._name = layerName;
228    },
229    'onAdd': function(map) {
230        L.Layer.prototype.onAdd.call(this, map);
231        if (!this._source._map)
232            this._source.addTo(this._map);
233        this._source.addSubLayer(this._name);
234    },
235    'onRemove': function() {
236        this._source.removeSubLayer(this._name);
237    }
238});
239
240wms.layer = function(source, options) {
241    return new wms.Layer(source, options);
242};
243
244// Cache of sources for use with wms.Layer auto-source option
245var sources = {};
246wms.getSourceForUrl = function(url, options) {
247    if (!sources[url]) {
248        sources[url] = wms.source(url, options);
249    }
250    return sources[url];
251};
252
253
254// Copy tiled WMS layer from leaflet core, in case we need to subclass it later
255wms.TileLayer = L.TileLayer.WMS;
256wms.tileLayer = L.tileLayer.wms;
257
258/*
259 * wms.Overlay:
260 * "Single Tile" WMS image overlay that updates with map changes.
261 * Portions of wms.Overlay are directly extracted from L.TileLayer.WMS.
262 * See Leaflet license.
263 */
264wms.Overlay = L.Layer.extend({
265    'defaultWmsParams': {
266        'service': 'WMS',
267        'request': 'GetMap',
268        'version': '1.1.1',
269        'layers': '',
270        'styles': '',
271        'format': 'image/jpeg',
272        'transparent': false
273    },
274
275    'initialize': function(url, options) {
276        this._url = url;
277
278        // Move WMS parameters to params object
279        var optNames = {
280            'crs': true,
281            'uppercase': true,
282            'tiled': true,
283            'identify': true,
284            'opacity': true,
285            'attribution': true
286        };
287        var params = {};
288        for (var opt in options) {
289             if (options.hasOwnProperty(opt) && !optNames[opt]) {
290                 params[opt] = options[opt];
291                 delete options[opt];
292             }
293        }
294        L.setOptions(this, options);
295        this.wmsParams = L.extend({}, this.defaultWmsParams, params);
296    },
297
298    'setParams': function(params) {
299        L.extend(this.wmsParams, params);
300        this.update();
301    },
302
303    'getAttribution': function() {
304        return this.options.attribution;
305    },
306
307    'onAdd': function(map) {
308        L.Layer.prototype.onAdd.call(this, map);
309        this.update();
310    },
311
312    'onRemove': function(map) {
313        if (this._currentOverlay) {
314            map.removeLayer(this._currentOverlay);
315            delete this._currentOverlay;
316        }
317        if (this._currentUrl) {
318            delete this._currentUrl;
319        }
320        L.Layer.prototype.onRemove.call(this, map);
321    },
322
323    'getEvents': function() {
324        return {
325            'moveend': this.update
326        };
327    },
328
329    'update': function() {
330        if (!this._map) {
331            return;
332        }
333        // Determine image URL and whether it has changed since last update
334        this.updateWmsParams();
335        var url = this.getImageUrl();
336        if (this._currentUrl == url) {
337            return;
338        }
339        this._currentUrl = url;
340
341        // Keep current image overlay in place until new one loads
342        // (inspired by esri.leaflet)
343        var bounds = this._map.getBounds();
344        var overlay = L.imageOverlay(url, bounds, {'opacity': 0});
345        overlay.addTo(this._map);
346        overlay.once('load', _swap, this);
347        function _swap() {
348            if (!this._map) {
349                return;
350            }
351            if (overlay._url != this._currentUrl) {
352                this._map.removeLayer(overlay);
353                return;
354            } else if (this._currentOverlay) {
355                this._map.removeLayer(this._currentOverlay);
356            }
357            this._currentOverlay = overlay;
358            overlay.setOpacity(
359                this.options.opacity ? this.options.opacity : 1
360            );
361        }
362    },
363
364    // See L.TileLayer.WMS: onAdd() & getTileUrl()
365    'updateWmsParams': function(map) {
366        if (!map) {
367            map = this._map;
368        }
369        // Compute WMS options
370        var bounds = map.getBounds();
371        var size = map.getSize();
372        var wmsVersion = parseFloat(this.wmsParams.version);
373        var crs = this.options.crs || map.options.crs;
374        var projectionKey = wmsVersion >= 1.3 ? 'crs' : 'srs';
375        var nw = crs.project(bounds.getNorthWest());
376        var se = crs.project(bounds.getSouthEast());
377
378        // Assemble WMS parameter string
379        var params = {
380            'width': size.x,
381            'height': size.y
382        };
383        params[projectionKey] = crs.code;
384        params.bbox = (
385            wmsVersion >= 1.3 && crs === L.CRS.EPSG4326 ?
386            [se.y, nw.x, nw.y, se.x] :
387            [nw.x, se.y, se.x, nw.y]
388        ).join(',');
389
390        L.extend(this.wmsParams, params);
391    },
392
393    'getImageUrl': function() {
394        var uppercase = this.options.uppercase || false;
395        var pstr = L.Util.getParamString(this.wmsParams, this._url, uppercase);
396        return this._url + pstr;
397    }
398});
399
400wms.overlay = function(url, options) {
401    return new wms.Overlay(url, options);
402};
403
404// Simple AJAX helper (since we can't assume jQuery etc. are present)
405function ajax(url, callback) {
406    var context = this,
407        request = new XMLHttpRequest();
408    request.onreadystatechange = change;
409    request.open('GET', url);
410    request.send();
411
412    function change() {
413        if (request.readyState === 4) {
414            if (request.status === 200) {
415                callback.call(context, request.responseText);
416            } else {
417                callback.call(context, "error");
418            }
419        }
420    }
421}
422
423return wms;
424
425}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.