695 lines
27 KiB
JavaScript
695 lines
27 KiB
JavaScript
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('ol/control/Control'), require('ol/Observable'), require('ol/layer/Group')) :
|
|
typeof define === 'function' && define.amd ? define(['ol/control/Control', 'ol/Observable', 'ol/layer/Group'], factory) :
|
|
(global.LayerSwitcher = factory(global.ol.control.Control,global.ol.Observable,global.ol.layer.Group));
|
|
}(this, (function (Control,ol_Observable,LayerGroup) { 'use strict';
|
|
|
|
Control = 'default' in Control ? Control['default'] : Control;
|
|
LayerGroup = 'default' in LayerGroup ? LayerGroup['default'] : LayerGroup;
|
|
|
|
var classCallCheck = function (instance, Constructor) {
|
|
if (!(instance instanceof Constructor)) {
|
|
throw new TypeError("Cannot call a class as a function");
|
|
}
|
|
};
|
|
|
|
var createClass = function () {
|
|
function defineProperties(target, props) {
|
|
for (var i = 0; i < props.length; i++) {
|
|
var descriptor = props[i];
|
|
descriptor.enumerable = descriptor.enumerable || false;
|
|
descriptor.configurable = true;
|
|
if ("value" in descriptor) descriptor.writable = true;
|
|
Object.defineProperty(target, descriptor.key, descriptor);
|
|
}
|
|
}
|
|
|
|
return function (Constructor, protoProps, staticProps) {
|
|
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
|
if (staticProps) defineProperties(Constructor, staticProps);
|
|
return Constructor;
|
|
};
|
|
}();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var get = function get(object, property, receiver) {
|
|
if (object === null) object = Function.prototype;
|
|
var desc = Object.getOwnPropertyDescriptor(object, property);
|
|
|
|
if (desc === undefined) {
|
|
var parent = Object.getPrototypeOf(object);
|
|
|
|
if (parent === null) {
|
|
return undefined;
|
|
} else {
|
|
return get(parent, property, receiver);
|
|
}
|
|
} else if ("value" in desc) {
|
|
return desc.value;
|
|
} else {
|
|
var getter = desc.get;
|
|
|
|
if (getter === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
return getter.call(receiver);
|
|
}
|
|
};
|
|
|
|
var inherits = function (subClass, superClass) {
|
|
if (typeof superClass !== "function" && superClass !== null) {
|
|
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
}
|
|
|
|
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
constructor: {
|
|
value: subClass,
|
|
enumerable: false,
|
|
writable: true,
|
|
configurable: true
|
|
}
|
|
});
|
|
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var possibleConstructorReturn = function (self, call) {
|
|
if (!self) {
|
|
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
}
|
|
|
|
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
};
|
|
|
|
/**
|
|
* @protected
|
|
*/
|
|
var CSS_PREFIX = 'layer-switcher-';
|
|
/**
|
|
* OpenLayers LayerSwitcher Control, displays a list of layers and groups
|
|
* associated with a map which have a `title` property.
|
|
*
|
|
* To be shown in the LayerSwitcher panel layers must have a `title` property;
|
|
* base map layers should have a `type` property set to `base`. Group layers
|
|
* (`LayerGroup`) can be used to visually group layers together; a group
|
|
* with a `fold` property set to either `'open'` or `'close'` will be displayed
|
|
* with a toggle.
|
|
*
|
|
* See [BaseLayerOptions](#baselayeroptions) for a full list of LayerSwitcher
|
|
* properties for layers (`TileLayer`, `ImageLayer`, `VectorTile` etc.) and
|
|
* [GroupLayerOptions](#grouplayeroptions) for group layer (`LayerGroup`)
|
|
* LayerSwitcher properties.
|
|
*
|
|
* Layer and group properties can either be set by adding extra properties
|
|
* to their options when they are created or via their set method.
|
|
*
|
|
* Specify a `title` for a Layer by adding a `title` property to it's options object:
|
|
* ```javascript
|
|
* var lyr = new ol.layer.Tile({
|
|
* // Specify a title property which will be displayed by the layer switcher
|
|
* title: 'OpenStreetMap',
|
|
* visible: true,
|
|
* source: new ol.source.OSM()
|
|
* })
|
|
* ```
|
|
*
|
|
* Alternatively the properties can be set via the `set` method after a layer has been created:
|
|
* ```javascript
|
|
* var lyr = new ol.layer.Tile({
|
|
* visible: true,
|
|
* source: new ol.source.OSM()
|
|
* })
|
|
* // Specify a title property which will be displayed by the layer switcher
|
|
* lyr.set('title', 'OpenStreetMap');
|
|
* ```
|
|
*
|
|
* To create a LayerSwitcher and add it to a map, create a new instance then pass it to the map's [`addControl` method](https://openlayers.org/en/latest/apidoc/module-ol_PluggableMap-PluggableMap.html#addControl).
|
|
* ```javascript
|
|
* var layerSwitcher = new LayerSwitcher({
|
|
* reverse: true,
|
|
* groupSelectStyle: 'group'
|
|
* });
|
|
* map.addControl(layerSwitcher);
|
|
* ```
|
|
*
|
|
* @constructor
|
|
* @extends {ol/control/Control~Control}
|
|
* @param opt_options LayerSwitcher options, see [LayerSwitcher Options](#options) and [RenderOptions](#renderoptions) which LayerSwitcher `Options` extends for more details.
|
|
*/
|
|
|
|
var LayerSwitcher = function (_Control) {
|
|
inherits(LayerSwitcher, _Control);
|
|
|
|
function LayerSwitcher(opt_options) {
|
|
classCallCheck(this, LayerSwitcher);
|
|
|
|
var options = Object.assign({}, opt_options);
|
|
// TODO Next: Rename to showButtonTitle
|
|
var tipLabel = options.tipLabel ? options.tipLabel : 'Legend';
|
|
// TODO Next: Rename to hideButtonTitle
|
|
var collapseTipLabel = options.collapseTipLabel ? options.collapseTipLabel : 'Collapse legend';
|
|
var element = document.createElement('div');
|
|
|
|
var _this = possibleConstructorReturn(this, (LayerSwitcher.__proto__ || Object.getPrototypeOf(LayerSwitcher)).call(this, { element: element, target: options.target }));
|
|
|
|
_this.activationMode = options.activationMode || 'mouseover';
|
|
_this.startActive = options.startActive === true;
|
|
// TODO Next: Rename to showButtonContent
|
|
var label = options.label !== undefined ? options.label : '';
|
|
// TODO Next: Rename to hideButtonContent
|
|
var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\xBB';
|
|
_this.groupSelectStyle = LayerSwitcher.getGroupSelectStyle(options.groupSelectStyle);
|
|
_this.reverse = options.reverse !== false;
|
|
_this.mapListeners = [];
|
|
_this.hiddenClassName = 'ol-unselectable ol-control layer-switcher';
|
|
if (LayerSwitcher.isTouchDevice_()) {
|
|
_this.hiddenClassName += ' touch';
|
|
}
|
|
_this.shownClassName = 'shown';
|
|
element.className = _this.hiddenClassName;
|
|
var button = document.createElement('button');
|
|
button.setAttribute('title', tipLabel);
|
|
button.setAttribute('aria-label', tipLabel);
|
|
element.appendChild(button);
|
|
_this.panel = document.createElement('div');
|
|
_this.panel.className = 'panel';
|
|
element.appendChild(_this.panel);
|
|
LayerSwitcher.enableTouchScroll_(_this.panel);
|
|
button.textContent = label;
|
|
element.classList.add(CSS_PREFIX + 'group-select-style-' + _this.groupSelectStyle);
|
|
element.classList.add(CSS_PREFIX + 'activation-mode-' + _this.activationMode);
|
|
if (_this.activationMode === 'click') {
|
|
// TODO Next: Remove in favour of layer-switcher-activation-mode-click
|
|
element.classList.add('activationModeClick');
|
|
if (_this.startActive) {
|
|
button.textContent = collapseLabel;
|
|
button.setAttribute('title', collapseTipLabel);
|
|
button.setAttribute('aria-label', collapseTipLabel);
|
|
}
|
|
button.onclick = function (e) {
|
|
var evt = e || window.event;
|
|
if (_this.element.classList.contains(_this.shownClassName)) {
|
|
_this.hidePanel();
|
|
button.textContent = label;
|
|
button.setAttribute('title', tipLabel);
|
|
button.setAttribute('aria-label', tipLabel);
|
|
} else {
|
|
_this.showPanel();
|
|
button.textContent = collapseLabel;
|
|
button.setAttribute('title', collapseTipLabel);
|
|
button.setAttribute('aria-label', collapseTipLabel);
|
|
}
|
|
evt.preventDefault();
|
|
};
|
|
} else {
|
|
button.onmouseover = function () {
|
|
_this.showPanel();
|
|
};
|
|
button.onclick = function (e) {
|
|
var evt = e || window.event;
|
|
_this.showPanel();
|
|
evt.preventDefault();
|
|
};
|
|
_this.panel.onmouseout = function (evt) {
|
|
if (!_this.panel.contains(evt.relatedTarget)) {
|
|
_this.hidePanel();
|
|
}
|
|
};
|
|
}
|
|
return _this;
|
|
}
|
|
/**
|
|
* Set the map instance the control is associated with.
|
|
* @param map The map instance.
|
|
*/
|
|
|
|
|
|
createClass(LayerSwitcher, [{
|
|
key: 'setMap',
|
|
value: function setMap(map) {
|
|
var _this2 = this;
|
|
|
|
// Clean up listeners associated with the previous map
|
|
for (var i = 0; i < this.mapListeners.length; i++) {
|
|
ol_Observable.unByKey(this.mapListeners[i]);
|
|
}
|
|
this.mapListeners.length = 0;
|
|
// Wire up listeners etc. and store reference to new map
|
|
get(LayerSwitcher.prototype.__proto__ || Object.getPrototypeOf(LayerSwitcher.prototype), 'setMap', this).call(this, map);
|
|
if (map) {
|
|
if (this.startActive) {
|
|
this.showPanel();
|
|
} else {
|
|
this.renderPanel();
|
|
}
|
|
if (this.activationMode !== 'click') {
|
|
this.mapListeners.push(map.on('pointerdown', function () {
|
|
_this2.hidePanel();
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Show the layer panel.
|
|
*/
|
|
|
|
}, {
|
|
key: 'showPanel',
|
|
value: function showPanel() {
|
|
if (!this.element.classList.contains(this.shownClassName)) {
|
|
this.element.classList.add(this.shownClassName);
|
|
this.renderPanel();
|
|
}
|
|
}
|
|
/**
|
|
* Hide the layer panel.
|
|
*/
|
|
|
|
}, {
|
|
key: 'hidePanel',
|
|
value: function hidePanel() {
|
|
if (this.element.classList.contains(this.shownClassName)) {
|
|
this.element.classList.remove(this.shownClassName);
|
|
}
|
|
}
|
|
/**
|
|
* Re-draw the layer panel to represent the current state of the layers.
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderPanel',
|
|
value: function renderPanel() {
|
|
this.dispatchEvent('render');
|
|
LayerSwitcher.renderPanel(this.getMap(), this.panel, {
|
|
groupSelectStyle: this.groupSelectStyle,
|
|
reverse: this.reverse
|
|
});
|
|
this.dispatchEvent('rendercomplete');
|
|
}
|
|
/**
|
|
* **_[static]_** - Re-draw the layer panel to represent the current state of the layers.
|
|
* @param map The OpenLayers Map instance to render layers for
|
|
* @param panel The DOM Element into which the layer tree will be rendered
|
|
* @param options Options for panel, group, and layers
|
|
*/
|
|
|
|
}], [{
|
|
key: 'renderPanel',
|
|
value: function renderPanel(map, panel, options) {
|
|
// Create the event.
|
|
var render_event = new Event('render');
|
|
// Dispatch the event.
|
|
panel.dispatchEvent(render_event);
|
|
options = options || {};
|
|
options.groupSelectStyle = LayerSwitcher.getGroupSelectStyle(options.groupSelectStyle);
|
|
LayerSwitcher.ensureTopVisibleBaseLayerShown(map, options.groupSelectStyle);
|
|
while (panel.firstChild) {
|
|
panel.removeChild(panel.firstChild);
|
|
}
|
|
// Reset indeterminate state for all layers and groups before
|
|
// applying based on groupSelectStyle
|
|
LayerSwitcher.forEachRecursive(map, function (l, _idx, _a) {
|
|
l.set('indeterminate', false);
|
|
});
|
|
if (options.groupSelectStyle === 'children' || options.groupSelectStyle === 'none') {
|
|
// Set visibile and indeterminate state of groups based on
|
|
// their children's visibility
|
|
LayerSwitcher.setGroupVisibility(map);
|
|
} else if (options.groupSelectStyle === 'group') {
|
|
// Set child indetermiate state based on their parent's visibility
|
|
LayerSwitcher.setChildVisibility(map);
|
|
}
|
|
var ul = document.createElement('ul');
|
|
panel.appendChild(ul);
|
|
// passing two map arguments instead of lyr as we're passing the map as the root of the layers tree
|
|
LayerSwitcher.renderLayers_(map, map, ul, options, function render(_changedLyr) {
|
|
LayerSwitcher.renderPanel(map, panel, options);
|
|
});
|
|
// Create the event.
|
|
var rendercomplete_event = new Event('rendercomplete');
|
|
// Dispatch the event.
|
|
panel.dispatchEvent(rendercomplete_event);
|
|
}
|
|
/**
|
|
* **_[static]_** - Determine if a given layer group contains base layers
|
|
* @param grp Group to test
|
|
*/
|
|
|
|
}, {
|
|
key: 'isBaseGroup',
|
|
value: function isBaseGroup(grp) {
|
|
if (grp instanceof LayerGroup) {
|
|
var lyrs = grp.getLayers().getArray();
|
|
return lyrs.length && lyrs[0].get('type') === 'base';
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'setGroupVisibility',
|
|
value: function setGroupVisibility(map) {
|
|
// Get a list of groups, with the deepest first
|
|
var groups = LayerSwitcher.getGroupsAndLayers(map, function (l) {
|
|
return l instanceof LayerGroup && !l.get('combine') && !LayerSwitcher.isBaseGroup(l);
|
|
}).reverse();
|
|
// console.log(groups.map(g => g.get('title')));
|
|
groups.forEach(function (grp) {
|
|
// TODO Can we use getLayersArray, is it public in the esm build?
|
|
var descendantVisibility = grp.getLayersArray().map(function (l) {
|
|
var state = l.getVisible();
|
|
// console.log('>', l.get('title'), state);
|
|
return state;
|
|
});
|
|
// console.log(descendantVisibility);
|
|
if (descendantVisibility.every(function (v) {
|
|
return v === true;
|
|
})) {
|
|
grp.setVisible(true);
|
|
grp.set('indeterminate', false);
|
|
} else if (descendantVisibility.every(function (v) {
|
|
return v === false;
|
|
})) {
|
|
grp.setVisible(false);
|
|
grp.set('indeterminate', false);
|
|
} else {
|
|
grp.setVisible(true);
|
|
grp.set('indeterminate', true);
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: 'setChildVisibility',
|
|
value: function setChildVisibility(map) {
|
|
// console.log('setChildVisibility');
|
|
var groups = LayerSwitcher.getGroupsAndLayers(map, function (l) {
|
|
return l instanceof LayerGroup && !l.get('combine') && !LayerSwitcher.isBaseGroup(l);
|
|
});
|
|
groups.forEach(function (grp) {
|
|
var group = grp;
|
|
// console.log(group.get('title'));
|
|
var groupVisible = group.getVisible();
|
|
var groupIndeterminate = group.get('indeterminate');
|
|
group.getLayers().getArray().forEach(function (l) {
|
|
l.set('indeterminate', false);
|
|
if ((!groupVisible || groupIndeterminate) && l.getVisible()) {
|
|
l.set('indeterminate', true);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Ensure only the top-most base layer is visible if more than one is visible.
|
|
* @param map The map instance.
|
|
* @param groupSelectStyle
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'ensureTopVisibleBaseLayerShown',
|
|
value: function ensureTopVisibleBaseLayerShown(map, groupSelectStyle) {
|
|
var lastVisibleBaseLyr = void 0;
|
|
LayerSwitcher.forEachRecursive(map, function (lyr, _idx, _arr) {
|
|
if (lyr.get('type') === 'base' && lyr.getVisible()) {
|
|
lastVisibleBaseLyr = lyr;
|
|
}
|
|
});
|
|
if (lastVisibleBaseLyr) LayerSwitcher.setVisible_(map, lastVisibleBaseLyr, true, groupSelectStyle);
|
|
}
|
|
/**
|
|
* **_[static]_** - Get an Array of all layers and groups displayed by the LayerSwitcher (has a `'title'` property)
|
|
* contained by the specified map or layer group; optionally filtering via `filterFn`
|
|
* @param grp The map or layer group for which layers are found.
|
|
* @param filterFn Optional function used to filter the returned layers
|
|
*/
|
|
|
|
}, {
|
|
key: 'getGroupsAndLayers',
|
|
value: function getGroupsAndLayers(grp, filterFn) {
|
|
var layers = [];
|
|
filterFn = filterFn || function (_lyr, _idx, _arr) {
|
|
return true;
|
|
};
|
|
LayerSwitcher.forEachRecursive(grp, function (lyr, idx, arr) {
|
|
if (lyr.get('title')) {
|
|
if (filterFn(lyr, idx, arr)) {
|
|
layers.push(lyr);
|
|
}
|
|
}
|
|
});
|
|
return layers;
|
|
}
|
|
/**
|
|
* Toggle the visible state of a layer.
|
|
* Takes care of hiding other layers in the same exclusive group if the layer
|
|
* is toggle to visible.
|
|
* @protected
|
|
* @param map The map instance.
|
|
* @param lyr layer whose visibility will be toggled.
|
|
* @param visible Set whether the layer is shown
|
|
* @param groupSelectStyle
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'setVisible_',
|
|
value: function setVisible_(map, lyr, visible, groupSelectStyle) {
|
|
// console.log(lyr.get('title'), visible, groupSelectStyle);
|
|
lyr.setVisible(visible);
|
|
if (visible && lyr.get('type') === 'base') {
|
|
// Hide all other base layers regardless of grouping
|
|
LayerSwitcher.forEachRecursive(map, function (l, _idx, _arr) {
|
|
if (l != lyr && l.get('type') === 'base') {
|
|
l.setVisible(false);
|
|
}
|
|
});
|
|
}
|
|
if (lyr instanceof LayerGroup && !lyr.get('combine') && groupSelectStyle === 'children') {
|
|
lyr.getLayers().forEach(function (l) {
|
|
LayerSwitcher.setVisible_(map, l, lyr.getVisible(), groupSelectStyle);
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Render all layers that are children of a group.
|
|
* @param map The map instance.
|
|
* @param lyr Layer to be rendered (should have a title property).
|
|
* @param idx Position in parent group list.
|
|
* @param options Options for groups and layers
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderLayer_',
|
|
value: function renderLayer_(map, lyr, idx, options, render) {
|
|
var li = document.createElement('li');
|
|
var lyrTitle = lyr.get('title');
|
|
var checkboxId = LayerSwitcher.uuid();
|
|
var label = document.createElement('label');
|
|
if (lyr instanceof LayerGroup && !lyr.get('combine')) {
|
|
var isBaseGroup = LayerSwitcher.isBaseGroup(lyr);
|
|
li.classList.add('group');
|
|
if (isBaseGroup) {
|
|
li.classList.add(CSS_PREFIX + 'base-group');
|
|
}
|
|
// Group folding
|
|
if (lyr.get('fold')) {
|
|
li.classList.add(CSS_PREFIX + 'fold');
|
|
li.classList.add(CSS_PREFIX + lyr.get('fold'));
|
|
var btn = document.createElement('button');
|
|
btn.onclick = function (e) {
|
|
var evt = e || window.event;
|
|
LayerSwitcher.toggleFold_(lyr, li);
|
|
evt.preventDefault();
|
|
};
|
|
li.appendChild(btn);
|
|
}
|
|
if (!isBaseGroup && options.groupSelectStyle != 'none') {
|
|
var input = document.createElement('input');
|
|
input.type = 'checkbox';
|
|
input.id = checkboxId;
|
|
input.checked = lyr.getVisible();
|
|
input.indeterminate = lyr.get('indeterminate');
|
|
input.onchange = function (e) {
|
|
var target = e.target;
|
|
LayerSwitcher.setVisible_(map, lyr, target.checked, options.groupSelectStyle);
|
|
render(lyr);
|
|
};
|
|
li.appendChild(input);
|
|
label.htmlFor = checkboxId;
|
|
}
|
|
label.innerHTML = lyrTitle;
|
|
li.appendChild(label);
|
|
var ul = document.createElement('ul');
|
|
li.appendChild(ul);
|
|
LayerSwitcher.renderLayers_(map, lyr, ul, options, render);
|
|
} else {
|
|
li.className = 'layer';
|
|
var _input = document.createElement('input');
|
|
if (lyr.get('type') === 'base') {
|
|
_input.type = 'radio';
|
|
_input.name = 'base';
|
|
} else {
|
|
_input.type = 'checkbox';
|
|
}
|
|
_input.id = checkboxId;
|
|
_input.checked = lyr.get('visible');
|
|
_input.indeterminate = lyr.get('indeterminate');
|
|
_input.onchange = function (e) {
|
|
var target = e.target;
|
|
LayerSwitcher.setVisible_(map, lyr, target.checked, options.groupSelectStyle);
|
|
render(lyr);
|
|
};
|
|
li.appendChild(_input);
|
|
label.htmlFor = checkboxId;
|
|
label.innerHTML = lyrTitle;
|
|
var rsl = map.getView().getResolution();
|
|
if (rsl > lyr.getMaxResolution() || rsl < lyr.getMinResolution()) {
|
|
label.className += ' disabled';
|
|
}
|
|
li.appendChild(label);
|
|
}
|
|
return li;
|
|
}
|
|
/**
|
|
* Render all layers that are children of a group.
|
|
* @param map The map instance.
|
|
* @param lyr Group layer whose children will be rendered.
|
|
* @param elm DOM element that children will be appended to.
|
|
* @param options Options for groups and layers
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderLayers_',
|
|
value: function renderLayers_(map, lyr, elm, options, render) {
|
|
var lyrs = lyr.getLayers().getArray().slice();
|
|
if (options.reverse) lyrs = lyrs.reverse();
|
|
for (var i = 0, l; i < lyrs.length; i++) {
|
|
l = lyrs[i];
|
|
if (l.get('title')) {
|
|
elm.appendChild(LayerSwitcher.renderLayer_(map, l, i, options, render));
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* **_[static]_** - Call the supplied function for each layer in the passed layer group
|
|
* recursing nested groups.
|
|
* @param lyr The layer group to start iterating from.
|
|
* @param fn Callback which will be called for each layer
|
|
* found under `lyr`.
|
|
*/
|
|
|
|
}, {
|
|
key: 'forEachRecursive',
|
|
value: function forEachRecursive(lyr, fn) {
|
|
lyr.getLayers().forEach(function (lyr, idx, a) {
|
|
fn(lyr, idx, a);
|
|
if (lyr instanceof LayerGroup) {
|
|
LayerSwitcher.forEachRecursive(lyr, fn);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* **_[static]_** - Generate a UUID
|
|
* Adapted from http://stackoverflow.com/a/2117523/526860
|
|
* @returns {String} UUID
|
|
*/
|
|
|
|
}, {
|
|
key: 'uuid',
|
|
value: function uuid() {
|
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
var r = Math.random() * 16 | 0,
|
|
v = c == 'x' ? r : r & 0x3 | 0x8;
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
/**
|
|
* Apply workaround to enable scrolling of overflowing content within an
|
|
* element. Adapted from https://gist.github.com/chrismbarr/4107472
|
|
* @param elm Element on which to enable touch scrolling
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'enableTouchScroll_',
|
|
value: function enableTouchScroll_(elm) {
|
|
if (LayerSwitcher.isTouchDevice_()) {
|
|
var scrollStartPos = 0;
|
|
elm.addEventListener('touchstart', function (event) {
|
|
scrollStartPos = this.scrollTop + event.touches[0].pageY;
|
|
}, false);
|
|
elm.addEventListener('touchmove', function (event) {
|
|
this.scrollTop = scrollStartPos - event.touches[0].pageY;
|
|
}, false);
|
|
}
|
|
}
|
|
/**
|
|
* Determine if the current browser supports touch events. Adapted from
|
|
* https://gist.github.com/chrismbarr/4107472
|
|
* @returns {Boolean} True if client can have 'TouchEvent' event
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'isTouchDevice_',
|
|
value: function isTouchDevice_() {
|
|
try {
|
|
document.createEvent('TouchEvent');
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
/**
|
|
* Fold/unfold layer group
|
|
* @param lyr Layer group to fold/unfold
|
|
* @param li List item containing layer group
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'toggleFold_',
|
|
value: function toggleFold_(lyr, li) {
|
|
li.classList.remove(CSS_PREFIX + lyr.get('fold'));
|
|
lyr.set('fold', lyr.get('fold') === 'open' ? 'close' : 'open');
|
|
li.classList.add(CSS_PREFIX + lyr.get('fold'));
|
|
}
|
|
/**
|
|
* If a valid groupSelectStyle value is not provided then return the default
|
|
* @param groupSelectStyle The string to check for validity
|
|
* @returns The value groupSelectStyle, if valid, the default otherwise
|
|
* @protected
|
|
*/
|
|
|
|
}, {
|
|
key: 'getGroupSelectStyle',
|
|
value: function getGroupSelectStyle(groupSelectStyle) {
|
|
return ['none', 'children', 'group'].indexOf(groupSelectStyle) >= 0 ? groupSelectStyle : 'children';
|
|
}
|
|
}]);
|
|
return LayerSwitcher;
|
|
}(Control);
|
|
if (window['ol'] && window['ol']['control']) {
|
|
window['ol']['control']['LayerSwitcher'] = LayerSwitcher;
|
|
}
|
|
|
|
return LayerSwitcher;
|
|
|
|
})));
|