做开发时,有时候图层很多,需要有同时打开关闭多个图层的功能,但是正式版的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"
});
" 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" ,
...
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: {}
},
/* *
* 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 = {};
},
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
};
/**
// 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();
*/
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 " ;
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);
},
/**
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);
},
* 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" ;
}
}
},
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 ;
},
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 ;
},
本文介绍如何通过扩展OpenLayers的LayerSwitcher组件来实现图层分组管理功能。通过对LayerSwitcher.js的修改,增加了对图层分组的支持,并提供了一种简单的方法来创建和管理图层组。
80

被折叠的 条评论
为什么被折叠?



