[OpenLayers-Commits] r11361 - in sandbox/jennier/openlayers: examples lib lib/OpenLayers/Layer lib/OpenLayers/Protocol

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Wed Feb 23 12:08:02 EST 2011


Author: jennier
Date: 2011-02-23 09:08:02 -0800 (Wed, 23 Feb 2011)
New Revision: 11361

Added:
   sandbox/jennier/openlayers/examples/local-storage-wms-simple.html
   sandbox/jennier/openlayers/examples/proxy.cgi
   sandbox/jennier/openlayers/lib/OpenLayers/Protocol/BrowserStorage.js
Removed:
   sandbox/jennier/openlayers/examples/proxy.cgi
Modified:
   sandbox/jennier/openlayers/lib/OpenLayers.js
   sandbox/jennier/openlayers/lib/OpenLayers/Layer/Grid.js
   sandbox/jennier/openlayers/lib/OpenLayers/Layer/WMS.js
Log:
Adding code to store tiles in local storage (defaults to Web SQL if available, and using Web Storage key/value if not).  Also adding an example that allows the user to store the tiles in the current viewport, clear the tiles in storage and displays the number of tiles stored. 

If the tile url is in local storage, then the client uses this version instead of the remote url as the image src.

Added: sandbox/jennier/openlayers/examples/local-storage-wms-simple.html
===================================================================
--- sandbox/jennier/openlayers/examples/local-storage-wms-simple.html	                        (rev 0)
+++ sandbox/jennier/openlayers/examples/local-storage-wms-simple.html	2011-02-23 17:08:02 UTC (rev 11361)
@@ -0,0 +1,66 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="style.css" type="text/css" />
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+        var lon = 5;
+        var lat = 40;
+        var zoom = 5;
+
+        var map, layerOSGeo;
+        
+        // Required for WMS that is on a different domain to this page.
+        OpenLayers.ProxyHost="proxy.cgi?url=";
+        
+        function init(){
+            
+            map = new OpenLayers.Map( 'map');
+            layerOSGeo = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+                    "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic', enableLocalCache:true},
+                    {'buffer': 0});            
+            
+            map.addLayers([layerOSGeo]);
+
+            map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+            map.addControl( new OpenLayers.Control.LayerSwitcher() );
+
+            // Set the cache counter.
+            layerOSGeo.countCache(updateCacheCount);
+
+        };
+
+        function updateCacheCount(dbname, value) {         
+            document.getElementById("count").innerHTML=value;
+        }
+
+    </script>
+  </head>
+  <body onload="init()">
+    <h1 id="title">WMS Local Storage Example</h1>
+
+    <div id="tags">
+        wms, layer, singletile, mobile
+    </div>
+    <p id="shortdesc">
+        Shows the basic use of local storage in openlayers using a WMS layer
+    </p>
+
+    <div id="map" class="smallmap"></div>
+
+    <div id="docs">
+        This is an example of how to add an WMS layer to the OpenLayers window, and how to store the 
+        tiles currently being viewed in local storage. Also allows the store to be cleared.  
+        <br/>
+        <br/>
+        <a href="#" onclick="layerOSGeo.cacheAreaViewed();layerOSGeo.countCache(updateCacheCount);return false;">Cache the area being viewed.</a><br/><br/>
+        <a href="#" onclick="layerOSGeo.clearCache();layerOSGeo.countCache(updateCacheCount);return false;">Clear the cache.</a><br/><br/>
+        Tiles Stored: <em id="count">0</em>.
+                      
+    </div>
+  </body>
+</html>
+
+
+
+


Property changes on: sandbox/jennier/openlayers/examples/local-storage-wms-simple.html
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Deleted: sandbox/jennier/openlayers/examples/proxy.cgi
===================================================================
--- sandbox/jennier/openlayers/examples/proxy.cgi	2011-02-23 17:07:45 UTC (rev 11360)
+++ sandbox/jennier/openlayers/examples/proxy.cgi	2011-02-23 17:08:02 UTC (rev 11361)
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-
-
-"""This is a blind proxy that we use to get around browser
-restrictions that prevent the Javascript from loading pages not on the
-same server as the Javascript.  This has several problems: it's less
-efficient, it might break some sites, and it's a security risk because
-people can use this proxy to browse the web and possibly do bad stuff
-with it.  It only loads pages via http and https, but it can load any
-content type. It supports GET and POST requests."""
-
-import urllib2
-import cgi
-import sys, os
-
-# Designed to prevent Open Proxy type stuff.
-
-allowedHosts = ['www.openlayers.org', 'openlayers.org', 
-                'labs.metacarta.com', 'world.freemap.in', 
-                'prototype.openmnnd.org', 'geo.openplans.org',
-                'sigma.openplans.org', 'demo.opengeo.org',
-                'www.openstreetmap.org', 'sample.azavea.com',
-                'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', 
-                'vmap0.tiles.osgeo.org']
-
-method = os.environ["REQUEST_METHOD"]
-
-if method == "POST":
-    qs = os.environ["QUERY_STRING"]
-    d = cgi.parse_qs(qs)
-    if d.has_key("url"):
-        url = d["url"][0]
-    else:
-        url = "http://www.openlayers.org"
-else:
-    fs = cgi.FieldStorage()
-    url = fs.getvalue('url', "http://www.openlayers.org")
-
-try:
-    host = url.split("/")[2]
-    if allowedHosts and not host in allowedHosts:
-        print "Status: 502 Bad Gateway"
-        print "Content-Type: text/plain"
-        print
-        print "This proxy does not allow you to access that location (%s)." % (host,)
-        print
-        print os.environ
-  
-    elif url.startswith("http://") or url.startswith("https://"):
-    
-        if method == "POST":
-            length = int(os.environ["CONTENT_LENGTH"])
-            headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
-            body = sys.stdin.read(length)
-            r = urllib2.Request(url, body, headers)
-            y = urllib2.urlopen(r)
-        else:
-            y = urllib2.urlopen(url)
-        
-        # print content type header
-        i = y.info()
-        if i.has_key("Content-Type"):
-            print "Content-Type: %s" % (i["Content-Type"])
-        else:
-            print "Content-Type: text/plain"
-        print
-        
-        print y.read()
-        
-        y.close()
-    else:
-        print "Content-Type: text/plain"
-        print
-        print "Illegal request."
-
-except Exception, E:
-    print "Status: 500 Unexpected Error"
-    print "Content-Type: text/plain"
-    print 
-    print "Some unexpected error occurred. Error text was:", E

Added: sandbox/jennier/openlayers/examples/proxy.cgi
===================================================================
--- sandbox/jennier/openlayers/examples/proxy.cgi	                        (rev 0)
+++ sandbox/jennier/openlayers/examples/proxy.cgi	2011-02-23 17:08:02 UTC (rev 11361)
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+
+
+"""This is a blind proxy that we use to get around browser
+restrictions that prevent the Javascript from loading pages not on the
+same server as the Javascript.  This has several problems: it's less
+efficient, it might break some sites, and it's a security risk because
+people can use this proxy to browse the web and possibly do bad stuff
+with it.  It only loads pages via http and https, but it can load any
+content type. It supports GET and POST requests."""
+
+import urllib2
+import cgi
+import sys, os
+
+# Designed to prevent Open Proxy type stuff.
+
+allowedHosts = ['www.openlayers.org', 'openlayers.org', 
+                'labs.metacarta.com', 'world.freemap.in', 
+                'prototype.openmnnd.org', 'geo.openplans.org',
+                'sigma.openplans.org', 'demo.opengeo.org',
+                'www.openstreetmap.org', 'sample.azavea.com',
+                'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', 
+                'vmap0.tiles.osgeo.org', 'terraservice.net',
+                'gisdata.usgs.gov']
+
+method = os.environ["REQUEST_METHOD"]
+
+if method == "POST":
+    qs = os.environ["QUERY_STRING"]
+    d = cgi.parse_qs(qs)
+    if d.has_key("url"):
+        url = d["url"][0]
+    else:
+        url = "http://www.openlayers.org"
+else:
+    fs = cgi.FieldStorage()
+    url = fs.getvalue('url', "http://www.openlayers.org")
+
+try:
+    host = url.split("/")[2]
+    if allowedHosts and not host in allowedHosts:
+        print "Status: 502 Bad Gateway"
+        print "Content-Type: text/plain"
+        print
+        print "This proxy does not allow you to access that location (%s)." % (host,)
+        print
+        print os.environ
+  
+    elif url.startswith("http://") or url.startswith("https://"):
+    
+        if method == "POST":
+            length = int(os.environ["CONTENT_LENGTH"])
+            headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
+            body = sys.stdin.read(length)
+            r = urllib2.Request(url, body, headers)
+            y = urllib2.urlopen(r)
+        else:
+            y = urllib2.urlopen(url)
+        
+        # print content type header
+        i = y.info()
+        if i.has_key("Content-Type"):
+            print "Content-Type: %s" % (i["Content-Type"])
+        else:
+            print "Content-Type: text/plain"
+        print
+        
+        print y.read()
+        
+        y.close()
+    else:
+        print "Content-Type: text/plain"
+        print
+        print "Illegal request."
+
+except Exception, E:
+    print "Status: 500 Unexpected Error"
+    print "Content-Type: text/plain"
+    print 
+    print "Some unexpected error occurred. Error text was:", E


Property changes on: sandbox/jennier/openlayers/examples/proxy.cgi
___________________________________________________________________
Added: svn:executable
   + *

Modified: sandbox/jennier/openlayers/lib/OpenLayers/Layer/Grid.js
===================================================================
--- sandbox/jennier/openlayers/lib/OpenLayers/Layer/Grid.js	2011-02-23 17:07:45 UTC (rev 11360)
+++ sandbox/jennier/openlayers/lib/OpenLayers/Layer/Grid.js	2011-02-23 17:08:02 UTC (rev 11361)
@@ -7,6 +7,7 @@
 /**
  * @requires OpenLayers/Layer/HTTPRequest.js
  * @requires OpenLayers/Console.js
+ * @requires OpenLayers/Protocol/BrowserStorage.js
  */
 
 /**
@@ -86,8 +87,13 @@
      * {Integer} How many tiles are still loading?
      */
     numLoadingTiles: 0,
-
+    
     /**
+     * Used for local storage of map tiles.
+     */
+    store: null,
+    
+    /**
      * APIProperty: tileLoadingDelay
      * {Integer} - Number of milliseconds before we shift and load
      *     tiles. Default is 100.
@@ -126,6 +132,12 @@
         this._moveGriddedTiles = OpenLayers.Function.bind(
             this.moveGriddedTiles, this
         );
+                
+        if (this.params.ENABLELOCALCACHE && !this.store) {
+        	
+        	this.store = new OpenLayers.Protocol.BrowserStorage('OLTiles: '+name, '1.0', 'OpenLayers Tiles', 2 * 1024 * 1024);
+
+        }
     },
 
     /**
@@ -828,5 +840,102 @@
                                      tileBottom + tileMapHeight);
     },
     
+    
+    /**
+     * Method: getURL
+     * Return a GetMap query string for this layer or the data URI for this 
+     * image from local storage. To be used as the img src.
+     *
+     * Parameters:
+     * url - {<String>} The URL we want to test.
+     *
+     * Returns:
+     * {String} a GetMap query string for this layer or the data URI for this 
+     * image from local storage. To be used as the img src.
+     */
+     getURL: function (url) {
+        
+    	// If we want to use the local cache, check to see if they exist and 
+    	// use those values if they do.
+        if (this.params.ENABLELOCALCACHE) {
+        	
+        	// Check if the map being requested is on the same domain/port
+	        var sameOrigin = !(url.indexOf("http") == 0);
+	        var urlParts = !sameOrigin && url.match(this.URL_SPLIT_REGEX);
+	        if (urlParts) {
+	            var location = window.location;
+	            sameOrigin =
+	                urlParts[1] == location.protocol &&
+	                urlParts[3] == location.hostname;
+	            var uPort = urlParts[4], lPort = location.port;
+	            if (uPort != 80 && uPort != "" || lPort != "80" && lPort != "") {
+	                sameOrigin = sameOrigin && uPort == lPort;
+	            }
+	        }
+         
+	        // For proxy need to url encode the params. 
+	        if (!sameOrigin && OpenLayers.ProxyHost) {
+	        	url = OpenLayers.ProxyHost+encodeURIComponent(url);
+	        } else if (!sameOrigin){
+	            OpenLayers.Console.warn(
+	                    OpenLayers.i18n("proxyNeeded"), {url: url});
+	        }
+        
+	        // check to see if the tile exists in the cache
+	        var imageCached = this.store.get(url);	    	
+	    	
+	    	
+    	} 
+    	
+        return url;
+        	
+    },
+    
+    /**
+     * Note the area stored will depend on the buffer value that has been set.
+     */
+    cacheAreaViewed:function() {
+
+        if (this.params.ENABLELOCALCACHE) {
+	        	
+	    	var tileImageCount = 0;
+	    	
+	    	// Go through all the tiles in the current view and get their URL.
+	    	for (var i=0; i<this.grid.length; i++) {
+	    		for (var j=0; j<this.grid[i].length; j++) {
+	
+	    			var canvas = document.createElement("canvas");
+	    			canvas.width = this.tileSize.w;
+	    			canvas.height = this.tileSize.h;
+	    			var ctx = canvas.getContext("2d");
+	    			ctx.drawImage(this.grid[i][j].imgDiv, 0, 0);
+	    			// Below does not work in FireFox
+	    			//var imageData = canvas.toDataURL(this.params.FORMAT,'quality=20');
+	    			var imageData = canvas.toDataURL();
+	    	    	
+	    			this.store.set(this.grid[i][j].url,imageData);
+	    	    	
+	    			tileImageCount++;
+	    		}
+	    	}
+	    	
+	    	console.log("Stored "+tileImageCount+" Tiles");
+        }
+        
+    	return false;
+    },
+
+    clearCache:function() {
+    	if (this.store) {
+    		this.store.clear();
+    	}     		
+    },
+
+    countCache:function(resultHandler) {
+    	if (this.store) {
+    		return this.store.count(resultHandler);
+    	}
+    	return 0;
+    },    
     CLASS_NAME: "OpenLayers.Layer.Grid"
 });

Modified: sandbox/jennier/openlayers/lib/OpenLayers/Layer/WMS.js
===================================================================
--- sandbox/jennier/openlayers/lib/OpenLayers/Layer/WMS.js	2011-02-23 17:07:45 UTC (rev 11360)
+++ sandbox/jennier/openlayers/lib/OpenLayers/Layer/WMS.js	2011-02-23 17:08:02 UTC (rev 11361)
@@ -198,8 +198,11 @@
             bounds.toArray(reverseAxisOrder);
         newParams.WIDTH = imageSize.w;
         newParams.HEIGHT = imageSize.h;
-        var requestString = this.getFullRequestString(newParams);
-        return requestString;
+        var url= this.getFullRequestString(newParams);
+        
+        // Check to see if the Image has been stored locally
+        return OpenLayers.Layer.Grid.prototype.getURL.apply(this, [url]);
+        
     },
 
     /**

Added: sandbox/jennier/openlayers/lib/OpenLayers/Protocol/BrowserStorage.js
===================================================================
--- sandbox/jennier/openlayers/lib/OpenLayers/Protocol/BrowserStorage.js	                        (rev 0)
+++ sandbox/jennier/openlayers/lib/OpenLayers/Protocol/BrowserStorage.js	2011-02-23 17:08:02 UTC (rev 11361)
@@ -0,0 +1,190 @@
+/* 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/Protocol.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.BroswerStorage
+ * Class for access to SQL Web Storage or Web (local) Storage.
+ * Allows you to store, retrieve and get information about what
+ * is stored. 
+ *
+ * Inherits from:
+ *  - <OpenLayers.Protocol>
+ */
+OpenLayers.Protocol.BrowserStorage = OpenLayers.Class(OpenLayers.Protocol, {
+	
+    initialize: function(name, version, description, size) {
+	    var store;
+	    // Default to Web SQL Storage
+	    try { 
+	    	store = this.sqlStore;	
+	    	return store.initialize(name, version, description, size);
+	    } catch (e) {
+	    	/* Does not support Web SQL Storage */
+	    }
+	    
+	    // Use Web (Local) Storage if Web SQL not available. 
+	    try {
+	    	store = this.localStore;
+	    	return store.initialize(name, version, description, size);
+	    	
+	    } catch (e) {	    	
+	    	/* Does not support Web (local) Storage */
+	    	// TODO Throw an error
+	    	console.debug(e);
+	    }
+	     
+    },
+	
+  /* localStore ****************************************************************/
+
+  localStore: {
+    	
+    name:null,
+    version:null,
+    description:null,
+    size:null,
+    	
+    initialize: function(name, version, description, size) {
+    	if (localStorage) {    	  
+    	  this.name = name;
+		  this.version = version;
+		  this.description = description;
+		  this.size = size;
+    	} else {
+    		throw new Error("Local storage is not supported.");
+    	}
+		return this;
+	},
+	set: function(key, value) {
+		try {
+			localStorage.setItem(key,value);
+		} catch (e) { 
+			if((e.name).toUpperCase() == 'QUOTA_EXCEEDED_ERR') {
+			  //TODO Replace with correct error handling.
+			  alert ("Unable to cache area, cache is full.");
+			}
+		}
+	},
+	get: function(key) {
+		return localStorage.getItem(key);
+	},
+	clear: function() {
+		localStorage.clear();
+	},
+	count: function(resultHandler) {		
+		resultHandler("LocalStorage", localStorage.length);
+	}
+  },
+
+  /* sqlStore ******************************************************************/
+
+  sqlStore: {
+	
+    name:null,
+    version:null,
+    description:null,
+    size:null,
+	db: null,
+		  
+	initialize: function(name, version, description, size) {
+	    try {
+		  this.name = name;
+		  this.version = version;
+		  this.description = description;
+		  this.size = size;
+		  this.db = openDatabase(name, version, description, size);
+		  
+		  this.db.transaction( 
+			function(tx) {
+				tx.executeSql("Create table OLTable (key TEXT, value BLOB) ",
+				[], 
+				function(tx, result) { 
+		       		/* No results  */
+				}, function(tx, error) {
+					/* table may already exist */
+			       	console.debug(error);
+				});	
+		  });
+		  
+	    } catch (e) {
+	    	throw new Error("Web SQL storage is not supported.");
+	    }
+	    return this;
+
+	},
+	set: function(key, value) {
+		var name = this.name;
+		// TODO Check for existing entries to prevent duplicates.
+		this.db.transaction( 
+			function(tx) {
+				tx.executeSql("Insert into OLTable (key, value) values (?,?)",
+				[key,value], 
+				function(tx, result) { 
+            		/* No results as it's an insert */
+				}, function(tx, error) {
+	    	    	console.debug(error);
+				});
+		});
+	},
+	get: function(key) {
+		var name = this.name;
+		this.db.transaction( 
+			function(tx) {
+				console.log("Select value from OLTable where key=?");
+				tx.executeSql("Select value from OLTable where key=?",
+				[key], 
+				function(tx, result) {
+				  if(result.rows.length){
+					return result.rows.item(0).data;
+				  }
+			    }, function(tx, error) {
+		        	console.debug(error);
+				});
+		});
+	},
+	
+	clear: function() {
+		this.db.transaction( 
+				function(tx) {
+					tx.executeSql("Delete from OLTable",
+					[], 
+					function(tx, result) {
+						/* No results */
+				    }, function(tx, error) {
+			        	console.debug(error);
+					});
+			});
+	},
+	count: function(resultHandler) {
+
+		var count;
+		var name = this.name;
+		this.db.transaction(
+				function(tx) {
+					console.log("Select count(*) as count from OLTable");
+					tx.executeSql("Select count(*) as count from OLTable",
+					[], 
+					function(tx, result) {
+					  if(result.rows.length){						
+						 resultHandler(name,result.rows.item(0)['count']);
+					  }
+				    }, function(tx, error) {
+			        	console.debug(error);
+					});
+			}, 
+			function(tx, result) {
+				console.debug(tx);
+			    }, function(tx, error) {
+		        	console.debug(tx);
+				});
+	}
+  },
+
+  CLASS_NAME: "OpenLayers.Protocol.BrowserStorage"
+});
\ No newline at end of file


Property changes on: sandbox/jennier/openlayers/lib/OpenLayers/Protocol/BrowserStorage.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: sandbox/jennier/openlayers/lib/OpenLayers.js
===================================================================
--- sandbox/jennier/openlayers/lib/OpenLayers.js	2011-02-23 17:07:45 UTC (rev 11360)
+++ sandbox/jennier/openlayers/lib/OpenLayers.js	2011-02-23 17:08:02 UTC (rev 11361)
@@ -242,6 +242,7 @@
                 "OpenLayers/Protocol.js",
                 "OpenLayers/Protocol/HTTP.js",
                 "OpenLayers/Protocol/SQL.js",
+                "OpenLayers/Protocol/BrowserStorage.js",
                 "OpenLayers/Protocol/SQL/Gears.js",
                 "OpenLayers/Protocol/WFS.js",
                 "OpenLayers/Protocol/WFS/v1.js",



More information about the Commits mailing list