[OpenLayers-Commits] r11360 - in sandbox/igorti/openlayers:
examples lib lib/OpenLayers/Control theme/default
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Wed Feb 23 12:07:45 EST 2011
Author: igorti
Date: 2011-02-23 09:07:45 -0800 (Wed, 23 Feb 2011)
New Revision: 11360
Added:
sandbox/igorti/openlayers/examples/mobile-layerswitcher.html
sandbox/igorti/openlayers/lib/OpenLayers/Control/MobileLayerSwitcher.js
Modified:
sandbox/igorti/openlayers/lib/OpenLayers.js
sandbox/igorti/openlayers/theme/default/style.css
Log:
install layerswitcher in sandbox
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 17:07:45 UTC (rev 11360)
@@ -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&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 17:07:45 UTC (rev 11360)
@@ -0,0 +1,478 @@
+/* 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
+ };
+
+ // 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);
+
+ var groupArray = (baseLayer) ? this.baseLayers
+ : this.dataLayers;
+ groupArray.push({
+ 'layer': layer,
+ 'inputElem': inputElem,
+ 'labelSpan': label
+ });
+
+ var li = document.createElement("li");
+ li.appendChild(label);
+
+ OpenLayers.Event.observe(li, "click",
+ OpenLayers.Function.bindAsEventListener(this.onInputClick,
+ context)
+ );
+
+ 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"
+});
Modified: sandbox/igorti/openlayers/lib/OpenLayers.js
===================================================================
--- sandbox/igorti/openlayers/lib/OpenLayers.js 2011-02-23 17:04:21 UTC (rev 11359)
+++ sandbox/igorti/openlayers/lib/OpenLayers.js 2011-02-23 17:07:45 UTC (rev 11360)
@@ -195,6 +195,7 @@
"OpenLayers/Control/Snapping.js",
"OpenLayers/Control/Split.js",
"OpenLayers/Control/LayerSwitcher.js",
+ "OpenLayers/Control/MobileLayerSwitcher.js",
"OpenLayers/Control/DrawFeature.js",
"OpenLayers/Control/DragFeature.js",
"OpenLayers/Control/ModifyFeature.js",
Modified: sandbox/igorti/openlayers/theme/default/style.css
===================================================================
--- sandbox/igorti/openlayers/theme/default/style.css 2011-02-23 17:04:21 UTC (rev 11359)
+++ sandbox/igorti/openlayers/theme/default/style.css 2011-02-23 17:07:45 UTC (rev 11360)
@@ -413,3 +413,58 @@
.olBingAttribution.road {
color: #333;
}
+
+/**
+ * MobileLayer switcher
+ */
+.olControlMobileLayerSwitcher {
+ width: 90%;
+ height:90%;
+ border:2px solid #CED6D9;
+ background-color: #FFFFFF;
+ display:none;
+ padding-top:25px;
+ overflow-y:auto;
+ position:absolute;
+ margin-left:-50%;
+ left:55%;
+ top:1%;
+}
+
+.olControlMobileLayerSwitcher span{
+ padding-left:15px;
+ font-size:1.2em;
+ font-weight:bold;
+}
+
+.olControlMobileLayerSwitcher a.btnClose {
+ background-image: url("img/close.gif");
+ display: block;
+ height: 17px;
+ width: 17px;
+ position: absolute;
+ right: 5px;
+ text-indent: -9999px;
+ top: 5px;
+ z-index:2001;
+}
+
+.olControlMobileLayerSwitcher ul {
+ padding-left:0px;
+ list-style-type:none;
+ margin:2px;
+}
+
+.olControlMobileLayerSwitcher ul li{
+ padding:5px 20px;
+ border-bottom:1px solid #efefef;
+}
+
+.olControlMobileLayerSwitcherTrigger{
+ position:absolute;
+ top:5px;
+ right:5px;
+ padding:10px;
+ background-color:#000000;
+ color:#FFFFFF;
+}
More information about the Commits
mailing list