Non puoi selezionare più di 25 argomenti
Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
374 righe
10 KiB
374 righe
10 KiB
/* global L */ |
|
|
|
// A layer control which provides for layer groupings. |
|
// Author: Ishmael Smyrnow |
|
L.Control.GroupedLayers = L.Control.extend({ |
|
|
|
options: { |
|
collapsed: true, |
|
position: 'topright', |
|
autoZIndex: true, |
|
exclusiveGroups: [], |
|
groupCheckboxes: false |
|
}, |
|
|
|
initialize: function (baseLayers, groupedOverlays, options) { |
|
var i, j; |
|
L.Util.setOptions(this, options); |
|
|
|
this._layers = []; |
|
this._lastZIndex = 0; |
|
this._handlingClick = false; |
|
this._groupList = []; |
|
this._domGroups = []; |
|
|
|
for (i in baseLayers) { |
|
this._addLayer(baseLayers[i], i); |
|
} |
|
|
|
for (i in groupedOverlays) { |
|
for (j in groupedOverlays[i]) { |
|
this._addLayer(groupedOverlays[i][j], j, i, true); |
|
} |
|
} |
|
}, |
|
|
|
onAdd: function (map) { |
|
this._initLayout(); |
|
this._update(); |
|
|
|
map |
|
.on('layeradd', this._onLayerChange, this) |
|
.on('layerremove', this._onLayerChange, this); |
|
|
|
return this._container; |
|
}, |
|
|
|
onRemove: function (map) { |
|
map |
|
.off('layeradd', this._onLayerChange, this) |
|
.off('layerremove', this._onLayerChange, this); |
|
}, |
|
|
|
addBaseLayer: function (layer, name) { |
|
this._addLayer(layer, name); |
|
this._update(); |
|
return this; |
|
}, |
|
|
|
addOverlay: function (layer, name, group) { |
|
this._addLayer(layer, name, group, true); |
|
this._update(); |
|
return this; |
|
}, |
|
|
|
removeLayer: function (layer) { |
|
var id = L.Util.stamp(layer); |
|
var _layer = this._getLayer(id); |
|
if (_layer) { |
|
delete this._layers[this._layers.indexOf(_layer)]; |
|
} |
|
this._update(); |
|
return this; |
|
}, |
|
|
|
_getLayer: function (id) { |
|
for (var i = 0; i < this._layers.length; i++) { |
|
if (this._layers[i] && L.stamp(this._layers[i].layer) === id) { |
|
return this._layers[i]; |
|
} |
|
} |
|
}, |
|
|
|
_initLayout: function () { |
|
var className = 'leaflet-control-layers', |
|
container = this._container = L.DomUtil.create('div', className); |
|
|
|
// Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released |
|
container.setAttribute('aria-haspopup', true); |
|
|
|
if (L.Browser.touch) { |
|
L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation); |
|
} else { |
|
L.DomEvent.disableClickPropagation(container); |
|
L.DomEvent.on(container, 'wheel', L.DomEvent.stopPropagation); |
|
} |
|
|
|
var form = this._form = L.DomUtil.create('form', className + '-list'); |
|
|
|
if (this.options.collapsed) { |
|
if (!L.Browser.android) { |
|
L.DomEvent |
|
.on(container, 'mouseover', this._expand, this) |
|
.on(container, 'mouseout', this._collapse, this); |
|
} |
|
var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container); |
|
link.href = '#'; |
|
link.title = 'Layers'; |
|
|
|
if (L.Browser.touch) { |
|
L.DomEvent |
|
.on(link, 'click', L.DomEvent.stop) |
|
.on(link, 'click', this._expand, this); |
|
} else { |
|
L.DomEvent.on(link, 'focus', this._expand, this); |
|
} |
|
|
|
this._map.on('click', this._collapse, this); |
|
// TODO keyboard accessibility |
|
} else { |
|
this._expand(); |
|
} |
|
|
|
this._baseLayersList = L.DomUtil.create('div', className + '-base', form); |
|
this._separator = L.DomUtil.create('div', className + '-separator', form); |
|
this._overlaysList = L.DomUtil.create('div', className + '-overlays', form); |
|
|
|
container.appendChild(form); |
|
}, |
|
|
|
_addLayer: function (layer, name, group, overlay) { |
|
var id = L.Util.stamp(layer); |
|
|
|
var _layer = { |
|
layer: layer, |
|
name: name, |
|
overlay: overlay |
|
}; |
|
this._layers.push(_layer); |
|
|
|
group = group || ''; |
|
var groupId = this._indexOf(this._groupList, group); |
|
|
|
if (groupId === -1) { |
|
groupId = this._groupList.push(group) - 1; |
|
} |
|
|
|
var exclusive = (this._indexOf(this.options.exclusiveGroups, group) !== -1); |
|
|
|
_layer.group = { |
|
name: group, |
|
id: groupId, |
|
exclusive: exclusive |
|
}; |
|
|
|
if (this.options.autoZIndex && layer.setZIndex) { |
|
this._lastZIndex++; |
|
layer.setZIndex(this._lastZIndex); |
|
} |
|
}, |
|
|
|
_update: function () { |
|
if (!this._container) { |
|
return; |
|
} |
|
|
|
this._baseLayersList.innerHTML = ''; |
|
this._overlaysList.innerHTML = ''; |
|
this._domGroups.length = 0; |
|
|
|
var baseLayersPresent = false, |
|
overlaysPresent = false, |
|
i, obj; |
|
|
|
for (var i = 0; i < this._layers.length; i++) { |
|
obj = this._layers[i]; |
|
this._addItem(obj); |
|
overlaysPresent = overlaysPresent || obj.overlay; |
|
baseLayersPresent = baseLayersPresent || !obj.overlay; |
|
} |
|
|
|
this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; |
|
}, |
|
|
|
_onLayerChange: function (e) { |
|
var obj = this._getLayer(L.Util.stamp(e.layer)), |
|
type; |
|
|
|
if (!obj) { |
|
return; |
|
} |
|
|
|
if (!this._handlingClick) { |
|
this._update(); |
|
} |
|
|
|
if (obj.overlay) { |
|
type = e.type === 'layeradd' ? 'overlayadd' : 'overlayremove'; |
|
} else { |
|
type = e.type === 'layeradd' ? 'baselayerchange' : null; |
|
} |
|
|
|
if (type) { |
|
this._map.fire(type, obj); |
|
} |
|
}, |
|
|
|
// IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe) |
|
_createRadioElement: function (name, checked) { |
|
var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"'; |
|
if (checked) { |
|
radioHtml += ' checked="checked"'; |
|
} |
|
radioHtml += '/>'; |
|
|
|
var radioFragment = document.createElement('div'); |
|
radioFragment.innerHTML = radioHtml; |
|
|
|
return radioFragment.firstChild; |
|
}, |
|
|
|
_addItem: function (obj) { |
|
var label = document.createElement('label'), |
|
input, |
|
checked = this._map.hasLayer(obj.layer), |
|
container, |
|
groupRadioName; |
|
|
|
if (obj.overlay) { |
|
if (obj.group.exclusive) { |
|
groupRadioName = 'leaflet-exclusive-group-layer-' + obj.group.id; |
|
input = this._createRadioElement(groupRadioName, checked); |
|
} else { |
|
input = document.createElement('input'); |
|
input.type = 'checkbox'; |
|
input.className = 'leaflet-control-layers-selector'; |
|
input.defaultChecked = checked; |
|
} |
|
} else { |
|
input = this._createRadioElement('leaflet-base-layers', checked); |
|
} |
|
|
|
input.layerId = L.Util.stamp(obj.layer); |
|
input.groupID = obj.group.id; |
|
L.DomEvent.on(input, 'click', this._onInputClick, this); |
|
|
|
var name = document.createElement('span'); |
|
name.innerHTML = ' ' + obj.name; |
|
|
|
label.appendChild(input); |
|
label.appendChild(name); |
|
|
|
if (obj.overlay) { |
|
container = this._overlaysList; |
|
|
|
var groupContainer = this._domGroups[obj.group.id]; |
|
|
|
// Create the group container if it doesn't exist |
|
if (!groupContainer) { |
|
groupContainer = document.createElement('div'); |
|
groupContainer.className = 'leaflet-control-layers-group'; |
|
groupContainer.id = 'leaflet-control-layers-group-' + obj.group.id; |
|
|
|
var groupLabel = document.createElement('label'); |
|
groupLabel.className = 'leaflet-control-layers-group-label'; |
|
|
|
if (obj.group.name !== '' && !obj.group.exclusive) { |
|
// ------ add a group checkbox with an _onInputClickGroup function |
|
if (this.options.groupCheckboxes) { |
|
var groupInput = document.createElement('input'); |
|
groupInput.type = 'checkbox'; |
|
groupInput.className = 'leaflet-control-layers-group-selector'; |
|
groupInput.groupID = obj.group.id; |
|
groupInput.legend = this; |
|
L.DomEvent.on(groupInput, 'click', this._onGroupInputClick, groupInput); |
|
groupLabel.appendChild(groupInput); |
|
} |
|
} |
|
|
|
var groupName = document.createElement('span'); |
|
groupName.className = 'leaflet-control-layers-group-name'; |
|
groupName.innerHTML = obj.group.name; |
|
groupLabel.appendChild(groupName); |
|
|
|
groupContainer.appendChild(groupLabel); |
|
container.appendChild(groupContainer); |
|
|
|
this._domGroups[obj.group.id] = groupContainer; |
|
} |
|
|
|
container = groupContainer; |
|
} else { |
|
container = this._baseLayersList; |
|
} |
|
|
|
container.appendChild(label); |
|
|
|
return label; |
|
}, |
|
|
|
_onGroupInputClick: function () { |
|
var i, input, obj; |
|
|
|
var this_legend = this.legend; |
|
this_legend._handlingClick = true; |
|
|
|
var inputs = this_legend._form.getElementsByTagName('input'); |
|
var inputsLen = inputs.length; |
|
|
|
for (i = 0; i < inputsLen; i++) { |
|
input = inputs[i]; |
|
if (input.groupID === this.groupID && input.className === 'leaflet-control-layers-selector') { |
|
input.checked = this.checked; |
|
obj = this_legend._getLayer(input.layerId); |
|
if (input.checked && !this_legend._map.hasLayer(obj.layer)) { |
|
this_legend._map.addLayer(obj.layer); |
|
} else if (!input.checked && this_legend._map.hasLayer(obj.layer)) { |
|
this_legend._map.removeLayer(obj.layer); |
|
} |
|
} |
|
} |
|
|
|
this_legend._handlingClick = false; |
|
}, |
|
|
|
_onInputClick: function () { |
|
var i, input, obj, |
|
inputs = this._form.getElementsByTagName('input'), |
|
inputsLen = inputs.length; |
|
|
|
this._handlingClick = true; |
|
|
|
for (i = 0; i < inputsLen; i++) { |
|
input = inputs[i]; |
|
if (input.className === 'leaflet-control-layers-selector') { |
|
obj = this._getLayer(input.layerId); |
|
|
|
if (input.checked && !this._map.hasLayer(obj.layer)) { |
|
this._map.addLayer(obj.layer); |
|
} else if (!input.checked && this._map.hasLayer(obj.layer)) { |
|
this._map.removeLayer(obj.layer); |
|
} |
|
} |
|
} |
|
|
|
this._handlingClick = false; |
|
}, |
|
|
|
_expand: function () { |
|
L.DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); |
|
// permits to have a scrollbar if overlays heighter than the map. |
|
var acceptableHeight = this._map._size.y - (this._container.offsetTop * 4); |
|
if (acceptableHeight < this._form.clientHeight) { |
|
L.DomUtil.addClass(this._form, 'leaflet-control-layers-scrollbar'); |
|
this._form.style.height = acceptableHeight + 'px'; |
|
} |
|
}, |
|
|
|
_collapse: function () { |
|
this._container.className = this._container.className.replace(' leaflet-control-layers-expanded', ''); |
|
}, |
|
|
|
_indexOf: function (arr, obj) { |
|
for (var i = 0, j = arr.length; i < j; i++) { |
|
if (arr[i] === obj) { |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
}); |
|
|
|
L.control.groupedLayers = function (baseLayers, groupedOverlays, options) { |
|
return new L.Control.GroupedLayers(baseLayers, groupedOverlays, options); |
|
};
|
|
|