随笔- 121  评论- 18  文章- 0 

OpenLayers: layerSwitcher扩展,加入group layer功能

做开发时,有时候图层很多,需要有同时打开关闭多个图层的功能,但是正式版的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
;  
     },
  

 

 

posted on 2009-12-15 21:30  炜升  阅读(...)  评论(... 编辑 收藏