[OpenLayers-Commits] r11300 - in sandbox/igorti/openlayers: examples lib/OpenLayers/Control

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Wed Feb 23 06:19:04 EST 2011


Author: igorti
Date: 2011-02-23 03:19:03 -0800 (Wed, 23 Feb 2011)
New Revision: 11300

Added:
   sandbox/igorti/openlayers/examples/mobile-layerswitcher.html
   sandbox/igorti/openlayers/lib/OpenLayers/Control/MobileLayerSwitcher.js
Log:
Applied mobilelayerswitcher patch

Added: sandbox/igorti/openlayers/examples/mobile-layerswitcher.html
===================================================================
--- sandbox/igorti/openlayers/examples/mobile-layerswitcher.html	                        (rev 0)
+++ sandbox/igorti/openlayers/examples/mobile-layerswitcher.html	2011-02-23 11:19:03 UTC (rev 11300)
@@ -0,0 +1,60 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <title>OpenLayers Mobile Layer Switcher Example</title>
+    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="style.css" type="text/css" />
+	<style type="text/css">
+		html, body, #map{
+			width:100%;
+			height:100%;
+			margin:0px;
+		}
+	</style>
+	<script src="http://maps.google.com/maps/api/js?v=3.3&amp;sensor=false"></script>
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+        var map;
+        function init(){
+            map = new OpenLayers.Map('map', { controls: [] });
+            map.addControl(new OpenLayers.Control.Navigation());			
+			map.addControl(new OpenLayers.Control.MobileLayerSwitcher());
+
+			var osm = new OpenLayers.Layer.OSM();            
+			var gmap = new OpenLayers.Layer.Google("Google Streets");
+			
+			var vectorLayer1 = new OpenLayers.Layer.Vector("Vector Layer 1");
+
+            var point1 = new OpenLayers.Geometry.Point(1526200, 7572700);
+            var pointFeature1 = new OpenLayers.Feature.Vector(point1,null,null);
+            var point2 = new OpenLayers.Geometry.Point(4782500, 5679500);
+            var pointFeature2 = new OpenLayers.Feature.Vector(point2,null,null);
+            var point3 = new OpenLayers.Geometry.Point(-8883800, 4461400);
+            var pointFeature3 = new OpenLayers.Feature.Vector(point3,null,null);
+
+			vectorLayer1.addFeatures([pointFeature1,pointFeature2,pointFeature3]);
+			
+			var vectorLayer2 = new OpenLayers.Layer.Vector("Vector Layer 2");
+
+            var point4 = new OpenLayers.Geometry.Point(1406200, 6002700);
+            var pointFeature4 = new OpenLayers.Feature.Vector(point4,null,null);
+            var point5 = new OpenLayers.Geometry.Point(4502500, 4009500);
+            var pointFeature5 = new OpenLayers.Feature.Vector(point5,null,null);
+            var point6 = new OpenLayers.Geometry.Point(-7003800, 3001400);
+            var pointFeature6 = new OpenLayers.Feature.Vector(point6,null,null);
+
+			vectorLayer2.addFeatures([pointFeature4,pointFeature5,pointFeature6]);
+			
+			
+            map.addLayers([osm, gmap, vectorLayer1,vectorLayer2]);
+				
+            if (!map.getCenter()) 
+				map.zoomToMaxExtent();
+        }
+    </script>
+  </head>
+  <body onload="init()">
+    <div id="map"></div>
+  </body>
+</html>

Added: sandbox/igorti/openlayers/lib/OpenLayers/Control/MobileLayerSwitcher.js
===================================================================
--- sandbox/igorti/openlayers/lib/OpenLayers/Control/MobileLayerSwitcher.js	                        (rev 0)
+++ sandbox/igorti/openlayers/lib/OpenLayers/Control/MobileLayerSwitcher.js	2011-02-23 11:19:03 UTC (rev 11300)
@@ -0,0 +1,482 @@
+/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/** 
+ * @requires OpenLayers/Control.js
+ * @requires OpenLayers/Lang.js
+ * @requires Rico/Corner.js
+ */
+
+/**
+ * Class: OpenLayers.Control.LayerSwitcher
+ * The LayerSwitcher control displays a table of contents for the map. This 
+ * allows the user interface to switch between BaseLasyers and to show or hide
+ * Overlays. By default the switcher is shown minimized on the right edge of 
+ * the map, the user may expand it by clicking on the handle.
+ *
+ * To create the LayerSwitcher outside of the map, pass the Id of a html div 
+ * as the first argument to the constructor.
+ * 
+ * Inherits from:
+ *  - <OpenLayers.Control>
+ */
+OpenLayers.Control.MobileLayerSwitcher = 
+  OpenLayers.Class(OpenLayers.Control, {
+    
+    /**  
+     * Property: layerStates 
+     * {Array(Object)} Basically a copy of the "state" of the map's layers 
+     *     the last time the control was drawn. We have this in order to avoid
+     *     unnecessarily redrawing the control.
+     */
+    layerStates: null,
+	
+	/**
+     * Property: triggerBtn
+     * {DOMElement} 
+     */
+	triggerBtn: null,
+	
+	/**
+     * Property: dataLbl
+     * {DOMElement} 
+     */
+	dataLbl: null,
+	
+	/**
+     * Property: dataLayersUl
+     * {DOMElement} 
+     */
+	dataLayersUl: null,
+	
+	/**
+     * Property: baseLbl
+     * {DOMElement} 
+     */
+	baseLbl: null,
+	
+	/**
+     * Property: baseLayersUl
+     * {DOMElement} 
+     */
+	baseLayersUl: null,
+	
+	/**
+     * Property: closeNtn
+     * {DOMElement} 
+     */
+	closeBtn: null,
+	
+    /** 
+     * Property: baseLayers
+     * {Array(<OpenLayers.Layer>)}
+     */
+    baseLayers: null,
+
+    /** 
+     * Property: dataLayers
+     * {Array(<OpenLayers.Layer>)} 
+     */
+    dataLayers: null,
+    
+    /**
+     * APIProperty: ascending
+     * {Boolean} 
+     */
+    ascending: true,
+ 
+    /**
+     * Constructor: OpenLayers.Control.LayerSwitcher
+     * 
+     * Parameters:
+     * options - {Object}
+     */
+    initialize: function(options) {
+        OpenLayers.Control.prototype.initialize.apply(this, arguments);
+        this.layerStates = [];
+    },
+
+    /**
+     * APIMethod: destroy 
+     */    
+    destroy: function() {
+        
+        OpenLayers.Event.stopObservingElement(this.div);
+
+        //OpenLayers.Event.stopObservingElement(this.minimizeDiv);
+        //OpenLayers.Event.stopObservingElement(this.maximizeDiv);
+
+        //clear out layers info and unregister their events 
+        this.clearLayersArray("base");
+        this.clearLayersArray("data");
+        
+        this.map.events.un({
+            "addlayer": this.redraw,
+            "changelayer": this.redraw,
+            "removelayer": this.redraw,
+            "changebaselayer": this.redraw,
+            scope: this
+        });
+        
+        OpenLayers.Control.prototype.destroy.apply(this, arguments);
+    },
+
+    /** 
+     * Method: setMap
+     *
+     * Properties:
+     * map - {<OpenLayers.Map>} 
+     */
+    setMap: function(map) {
+        OpenLayers.Control.prototype.setMap.apply(this, arguments);
+
+        this.map.events.on({
+            "addlayer": this.redraw,
+            "changelayer": this.redraw,
+            "removelayer": this.redraw,
+            "changebaselayer": this.redraw,
+            scope: this
+        });
+    },
+
+    /**
+     * Method: draw
+     *
+     * Returns:
+     * {DOMElement} A reference to the DIV DOMElement containing the 
+     *     switcher tabs.
+     */  
+    draw: function() {
+        OpenLayers.Control.prototype.draw.apply(this);
+	
+        // create layout divs
+        this.loadContents();
+
+        // set mode to minimize
+        if(!this.outsideViewport) {
+            this.minimizeControl();
+        }
+
+        // populate div with current info
+        this.redraw();    
+		this.events = new OpenLayers.Events(this, this.div);
+		
+		//prevent all kinds of map events when layerswitcher is opened
+		for(var i = 0; i < this.events.BROWSER_EVENTS.length; i++){
+			this.events.registerPriority(this.events.BROWSER_EVENTS[i], this, function(){ return false;});
+		}
+		
+        return this.div;
+    },
+
+    /** 
+     * Method: clearLayersArray
+     * User specifies either "base" or "data". we then clear all the
+     *     corresponding listeners, the div, and reinitialize a new array.
+     * 
+     * Parameters:
+     * layersType - {String}  
+     */
+    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 + "LayersUl"].innerHTML = "";
+        this[layersType + "Layers"] = [];
+    },
+
+
+    /**
+     * Method: checkRedraw
+     * Checks if the layer state has changed since the last redraw() call.
+     * 
+     * Returns:
+     * {Boolean} The layer state changed since the last redraw() call. 
+     */
+    checkRedraw: function() {
+        var redraw = false;
+        if ( !this.layerStates.length ||
+             (this.map.layers.length != this.layerStates.length) ) {
+            redraw = true;
+        } else {
+            for (var i=0, len=this.layerStates.length; i<len; i++) {
+                var layerState = this.layerStates[i];
+                var layer = this.map.layers[i];
+                if ( (layerState.name != layer.name) || 
+                     (layerState.inRange != layer.inRange) || 
+                     (layerState.id != layer.id) || 
+                     (layerState.visibility != layer.visibility) ) {
+                    redraw = true;
+                    break;
+                }    
+            }
+        }    
+        return redraw;
+    },
+    
+    /** 
+     * Method: redraw
+     * Goes through and takes the current state of the Map and rebuilds the
+     *     control to display that state. Groups base layers into a 
+     *     radio-button group and lists each data layer with a checkbox.
+     *
+     * Returns: 
+     * {DOMElement} A reference to the DIV DOMElement containing the control
+     */  
+    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; 
+        } 
+
+		if(this.div.style.zIndex)
+			this.triggerBtn.style.zIndex = this.div.style.zIndex-1;
+        
+		//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
+            };
+        }    
+
+        var layers = this.map.layers.slice();
+        
+		if (!this.ascending) 
+			layers.reverse();		
+		
+        for(var i=0, len=layers.length; i<len; i++) {
+            var layer = layers[i];
+            var baseLayer = layer.isBaseLayer;
+
+            if (layer.displayInLayerSwitcher) {
+                
+				if (baseLayer) {
+                    containsBaseLayers = true;	
+                } else {
+                    containsOverlays = true;
+                }    
+
+                // only check a baselayer if it is *the* baselayer, check data
+                //  layers if they are visible
+                var checked = (baseLayer) ? (layer == this.map.baseLayer)
+                                          : layer.getVisibility();
+    
+                // create input element
+                var inputElem = document.createElement("input");
+                inputElem.id = this.id + "_input_" + layer.name;
+                inputElem.name = (baseLayer) ? this.id + "_baseLayers" : layer.name;
+                inputElem.type = (baseLayer) ? "radio" : "checkbox";
+                inputElem.value = layer.name;
+                inputElem.checked = checked;
+                inputElem.defaultChecked = checked;
+
+                if (!baseLayer && !layer.inRange) {
+                    inputElem.disabled = true;
+                }
+                var context = {
+                    'inputElem': inputElem,
+                    'layer': layer,
+                    'layerSwitcher': this
+                };
+                OpenLayers.Event.observe(inputElem, "mouseup", 
+                    OpenLayers.Function.bindAsEventListener(this.onInputClick,
+                                                            context)
+                );
+                
+                // create span
+                var label = document.createElement("label");
+                
+                if (!baseLayer && !layer.inRange) {
+                    label.style.color = "gray";
+                }
+				
+				var textNode = document.createTextNode(layer.name);
+				
+                label.appendChild(inputElem);
+				label.appendChild(textNode);
+                
+                OpenLayers.Event.observe(label, "click", 
+                    OpenLayers.Function.bindAsEventListener(this.onInputClick,
+                                                            context)
+                );
+                
+                var groupArray = (baseLayer) ? this.baseLayers
+                                             : this.dataLayers;
+                groupArray.push({
+                    'layer': layer,
+                    'inputElem': inputElem,
+                    'labelSpan': label
+                });
+				
+				var li = document.createElement("li");
+				li.appendChild(label);
+				
+				if(baseLayer)
+					this.baseLayersUl.appendChild(li);
+				else
+					this.dataLayersUl.appendChild(li);
+				                             
+            }
+        }    
+		
+ 		if(!containsBaseLayers)
+			this.baseLbl.style.display = "none";
+		else
+			this.baseLbl.style.display = "";
+			
+		if(!containsOverlays)
+			this.dataLbl.style.display = "none";
+		else
+			this.dataLbl.style.display = "";
+		
+        return this.div;
+    },
+
+    /** 
+     * Method:
+     * A label has been clicked, check or uncheck its corresponding input
+     * 
+     * Parameters:
+     * e - {Event} 
+     *
+     * Context:  
+     *  - {DOMElement} inputElem
+     *  - {<OpenLayers.Control.LayerSwitcher>} layerSwitcher
+     *  - {<OpenLayers.Layer>} layer
+     */
+    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: updateMap
+     * Cycles through the loaded data and base layer input arrays and makes
+     *     the necessary calls to the Map object such that that the map's 
+     *     visual state corresponds to what the user has selected in 
+     *     the control.
+     */
+    updateMap: function() {
+
+        // set the newly selected base layer        
+        for(var i=0, len=this.baseLayers.length; i<len; i++) {
+            var layerEntry = this.baseLayers[i];
+            if (layerEntry.inputElem.checked) {
+                this.map.setBaseLayer(layerEntry.layer, false);
+            }
+        }
+
+        // set the correct visibilities for the overlays
+        for(var i=0, len=this.dataLayers.length; i<len; i++) {
+            var layerEntry = this.dataLayers[i];   
+            layerEntry.layer.setVisibility(layerEntry.inputElem.checked);
+        }
+
+    },
+
+    /** 
+     * Method: maximizeControl
+     * Set up the labels and divs for the control
+     * 
+     * Parameters:
+     * e - {Event} 
+     */
+    maximizeControl: function(e) {
+		this.div.style.display = "block";
+
+        if (e != null) {
+            OpenLayers.Event.stop(e);                                            
+        }
+    },
+    
+    /** 
+     * Method: minimizeControl
+     * Hide all the contents of the control, shrink the size, 
+     *     add the maximize icon
+     *
+     * Parameters:
+     * e - {Event} 
+     */
+    minimizeControl: function(e) {
+        this.div.style.display = "none";
+
+        if (e != null) {
+            OpenLayers.Event.stop(e);                                            
+        }
+    },
+    
+    /** 
+     * Method: loadContents
+     * Set up the labels and divs for the control
+     */
+    loadContents: function() {
+		this.triggerBtn = document.createElement("div");
+		this.triggerBtn.innerHTML = "Layers";
+		OpenLayers.Element.addClass(this.triggerBtn, "olControlMobileLayerSwitcherTrigger");
+		
+		OpenLayers.Event.observe(this.triggerBtn, "click", 
+            OpenLayers.Function.bindAsEventListener(this.maximizeControl, this)
+        );
+		
+		this.closeBtn = document.createElement("a");
+		this.closeBtn.href = "#";
+		this.closeBtn.innerHTML = "Close";
+		OpenLayers.Element.addClass(this.closeBtn, "btnClose");
+		
+		OpenLayers.Event.observe(this.closeBtn, "click", 
+            OpenLayers.Function.bindAsEventListener(this.minimizeControl, this)
+        );
+		
+		this.baseLbl = document.createElement("span");
+		this.baseLbl.innerHTML = OpenLayers.i18n("baseLayer");
+		this.baseLayersUl = document.createElement("ul");
+		
+		this.dataLbl = document.createElement("span");
+		this.dataLbl.innerHTML = OpenLayers.i18n("overlays");
+		this.dataLayersUl = document.createElement("ul");
+		
+		this.div.appendChild(this.closeBtn);
+		this.div.appendChild(this.baseLbl);
+		this.div.appendChild(this.baseLayersUl);
+		this.div.appendChild(this.dataLbl);
+		this.div.appendChild(this.dataLayersUl);
+		
+		this.map.div.appendChild(this.triggerBtn);			
+    },
+
+    CLASS_NAME: "OpenLayers.Control.MobileLayerSwitcher"
+});



More information about the Commits mailing list