做开发时,有时候图层很多,需要有同时打开关闭多个图层的功能,但是正式版的layerSwitcher不支持group layer功能.
从网上搜到layerSwitcher的扩展,是在源代码里添加对grouplayer的操作和事件支持.
对layerSwitcher.js进行修改后,需要重新build一下,生成新的openlayers.js
在写script添加图层的时候,加入group信息,如下例子:

代码
var
dm
=
new
OpenLayers.Layer.WMS(
"
DM Solutions Transit
"
,
"
http://www2.dmsolutions.ca/cgi-bin/mswms_gmap
"
,
{layers:
"
rail,road
"
,
transparent:
"
true
"
, format:
"
image/png
"
},
{ //将"DM Solutions Transit"放入名叫Transit的组里
group:
"Transit"
});
如果想嵌套图层,只需要加“/”表示层级关系
...
group:
"Transit/Roads"
,
...
看看效果图:

这是修改后的layerSwitcher.js的压缩文件: 下载
下面详细列出layerSwitcher.js需要添加的代码:
粗体字为添加的代码
代码
minimizeDiv:
null
,
/*
*
* Property: maximizeDiv
* {DOMElement}
*/
maximizeDiv:
null
,
/*
*
* APIProperty: ascending
* {Boolean}
*/
ascending:
true
,
/*
* * Property: groupDivs
* Object with {DOMElements}, {Booleans} and {Strings}
*/
groups: {
groupDivs:{},
checked: {},
layers:{},
display: {}
},
代码
clearLayersArray:
function
(layersType) {
var
layers
=
this
[layersType
+
"
Layers
"
];
if
(layers) {
for
(
var
i
=
0
, len
=
layers.length; i
<
len ; i
++
) {
var
layer
=
layers[i];
OpenLayers.Event.stopObservingElement(layer.inputElem);
OpenLayers.Event.stopObservingElement(layer.labelSpan);
}
}
this
[layersType
+
"
LayersDiv
"
].innerHTML
=
""
;
this
[layersType
+
"
Layers
"
]
=
[];
this.groups.groupDivs =
{};
},
代码
redraw:
function
() {
//
if the state hasn't changed since last redraw, no need
//
to do anything. Just return the existing div.
if
(
!
this
.checkRedraw()) {
return
this
.div;
}
//
clear out previous layers
this
.clearLayersArray(
"
base
"
);
this
.clearLayersArray(
"
data
"
);
var
containsOverlays
=
false
;
var
containsBaseLayers
=
false
;
//
Save state -- for checking layer if the map state changed.
//
We save this before redrawing, because in the process of redrawing
//
we will trigger more visibility changes, and we want to not redraw
//
and enter an infinite loop.
var
len
=
this
.map.layers.length;
this
.layerStates
=
new
Array(len);
for
(
var
i
=
0
; i
<
len; i
++
) {
var
layer
=
this
.map.layers[i];
this
.layerStates[i]
=
{
'
name
'
: layer.name,
'
visibility
'
: layer.visibility,
'
inRange
'
: layer.inRange,
'
id
'
: layer.id
};
/**
* create group divs
*/
if (layer.group && !
layer.isBaseLayer) {
layer.group = layer.group.replace(/\/$/,"");
layer.group = layer.group.replace(/^\//,"");
this
.createGroupDiv(layer.group);
}
}
var
layers
=
this
.map.layers.slice();
代码
//
create line break
var
br
=
document.createElement(
"
br
"
);
var
groupArray
=
(baseLayer)
?
this
.baseLayers
:
this
.dataLayers;
groupArray.push({
'
layer
'
: layer,
'
inputElem
'
: inputElem,
'
labelSpan
'
: labelSpan
});
var
groupDiv
=
(baseLayer)
?
this
.baseLayersDiv
:
this
.dataLayersDiv;
groupDiv.appendChild(inputElem);
groupDiv.appendChild(labelSpan);
groupDiv.appendChild(br);
/*
* layer group for data layers
*/
if (!
baseLayer) {
// no group
if (layer.group == null
) {
this
.dataLayersDiv.appendChild(inputElem);
this
.dataLayersDiv.appendChild(labelSpan);
this
.dataLayersDiv.appendChild(br);
}
// group exists it is most probably allready there
else
{
var groupname =
layer.group;
var div = this
.groups.groupDivs[groupname];
div.appendChild(inputElem);
div.appendChild(labelSpan);
div.appendChild(br);
// append layer to the group
this
.appendLayerToGroups(layer);
}
}
// base layers
else
{
this
.baseLayersDiv.appendChild(inputElem);
this
.baseLayersDiv.appendChild(labelSpan);
this
.baseLayersDiv.appendChild(br);
}
}
}
//
if no overlays, dont display the overlay label
this
.dataLbl.style.display
=
(containsOverlays)
?
""
:
"
none
"
;
代码
onInputClick:
function
(e) {
if
(
!
this
.inputElem.disabled) {
if
(
this
.inputElem.type
==
"
radio
"
) {
this
.inputElem.checked
=
true
;
this
.layer.map.setBaseLayer(
this
.layer);
}
else
{
this
.inputElem.checked
=
!
this
.inputElem.checked;
this
.layerSwitcher.updateMap();
}
}
OpenLayers.Event.stop(e);
},
/**
* Method:
* A group label has been clicked, check or uncheck its corresponding input
*
* Parameters:
* e - {Event}
*
* Context:
* - {DOMElement} inputElem
* - {<OpenLayers.Control.LayerSwitcher>} layerSwitcher
* - {DOMElement} groupDiv
*/
onInputGroupClick: function
(e) {
// setup the check value
var check = !this
.inputElem.checked;
// get all <input></input> tags in this div
var inputs = this.groupDiv.getElementsByTagName("input"
);
// check the group input, other inputs are in groupDiv,
// inputElem is in parent div
this.inputElem.checked=
check;
// store to groupCheckd structure, where it can be later found
this.layerSwitcher.groups.checked[this.inputElem.value] =
check;
for (var i = 0; i < inputs.length; i++
) {
// same as above
inputs[i].checked=
check;
this.layerSwitcher.groups.checked[inputs[i].value] =
check;
}
// groups are done, now the layers
var dataLayers = this
.layerSwitcher.dataLayers;
for (var j = 0; j < dataLayers.length; j++
) {
var layerEntry =
dataLayers[j];
if (this
.layerSwitcher.isInGroup(
this
.inputElem.value,layerEntry.layer.id)) {
layerEntry.inputElem.checked =
check;
layerEntry.layer.setVisibility(check);
}
}
OpenLayers.Event.stop(e);
},
代码
onLayerClick:
function
(e) {
this
.updateMap();
},
/*
*
* Method: onGroupClick
* Make the div with layers invisible
*
* Context:
* layergroup - {String}
* groups - {Array} of {DOMElements}
*/
onGroupClick: function
(e) {
var layergroup = this
.layergroup;
var div = this
.groups.groupDivs[layergroup];
if
(div) {
if (div.style.display != "block"
) {
div.style.display = "block"
;
this.groups.display[layergroup] = "block"
;
}
else
{
div.style.display = "none"
;
this.groups.display[layergroup] = "none"
;
}
}
},
代码
mouseUp:
function
(evt) {
if
(
this
.isMouseDown) {
this
.isMouseDown
=
false
;
this
.ignoreEvent(evt);
}
},
/*
*
* Method: createGroupDiv
* Creates <div></div> element for group of layers defined by input string.
*
* Parameters:
* layergroup - {Strin} with group structure as "Parent Group/It's child"
*
* Returns:
* {DOMElement} <div></div> object for this group of layers
*/
createGroupDiv: function
(layergroup) {
var groupNames = layergroup.split("/"); // array with layer names
var groupName = groupNames[groupNames.length-1]; // name of the last group in the line
var br = document.createElement("br"
);
var groupDiv = this
.groups.groupDivs[layergroup];
// groupDiv does not exist: create
if (!
groupDiv) {
// search for the parent div - it can be another group div, or
// this dataLayersDiv directly
var parentDiv = this.groups.groupDivs[groupNames.slice(0,groupNames.length-2).join("/"
)];
if (!
parentDiv) {
// dataLayersDiv is parent div
if (groupNames.length == 1
) {
parentDiv = this
.dataLayersDiv;
}
// there is no such thing, like parent div,
else
{
parentDiv = this.createGroupDiv( groupNames.slice(0,groupNames.length-1).join("/"
));
}
}
// create the div
groupDiv = document.createElement("div"
);
groupDiv.classes="olLayerGroup"
;
groupDiv.style.marginLeft="10px"
;
groupDiv.style.marginBottom="5px"
;
if (!this
.groups.display[layergroup]) {
this.groups.display[layergroup] = "block"
;
}
groupDiv.style.display= this
.groups.display[layergroup];
this.groups.groupDivs[layergroup] =
groupDiv;
// create the label
var groupLbl = document.createElement("span"
);
groupLbl.innerHTML="<u>"+groupName+"</u><br/>"
;
groupLbl.style.marginTop = "3px"
;
groupLbl.style.marginLeft = "3px"
;
groupLbl.style.marginBottom = "3px"
;
groupLbl.style.fontWeight = "bold"
;
// setup mouse click event on groupLbl
OpenLayers.Event.observe(groupLbl, "mouseup"
,
OpenLayers.Function.bindAsEventListener(
this
.onGroupClick, {layergroup: layergroup, groups:
this
.groups}));
// create input checkbox
var groupInput = document.createElement("input"
);
groupInput.id = "input_" + groupNames.join("_"
);
groupInput.name = groupNames.join("_"
);
groupInput.type = "checkbox"
;
groupInput.value =
layergroup;
groupInput.checked = false
;
groupInput.defaultChecked = false
;
if (!this
.groups.checked[layergroup]) {
this.groups.checked[layergroup] = false
;
}
groupInput.checked = this
.groups.checked[layergroup];
groupInput.defaultChecked = this
.groups.checked[layergroup];
// create empty array of layers
if (!this
.groups.layers[layergroup]) {
this.groups.layers[layergroup] =
[];
}
// setup mouse click event on groupInput
var context =
{groupDiv: groupDiv,
layerSwitcher: this
,
inputElem: groupInput};
OpenLayers.Event.observe(groupInput, "mouseup"
,
OpenLayers.Function.bindAsEventListener(
this
.onInputGroupClick, context));
// append to parent div
parentDiv.appendChild(groupInput);
parentDiv.appendChild(groupLbl);
parentDiv.appendChild(groupDiv);
}
return this
.groups.groupDivs[layergroup];
},
appendLayerToGroups: function
(layer) {
var groupNames = layer.group.split("/"
);
var groupName = null
;
for (var i = 1; i <= groupNames.length; i++
) {
var groupName = groupNames.slice(0,i).join("/"
);
if (!this
.isInGroup(groupName,layer.id)) {
this
.groups.layers[groupName].push(layer);
}
}
},
isInGroup: function
(groupName, id) {
for (var j = 0; j < this.groups.layers[groupName].length; j++
) {
if (this.groups.layers[groupName][j].id ==
id) {
return true
;
}
}
return false
;
},