[OpenLayers-Commits] r10826 - in sandbox/tschaub/canvas: . build examples lib/OpenLayers lib/OpenLayers/Control lib/OpenLayers/Layer lib/OpenLayers/Layer/Google lib/OpenLayers/Layer/WMS lib/OpenLayers/Strategy lib/OpenLayers/Symbolizer lib/OpenLayers/Tile lib/OpenLayers/Tile/Image tests tests/Control tests/Layer/WMS tests/Strategy tests/Symbolizer tests/Tile tests/Tile/Image tools

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Wed Oct 13 15:07:54 EDT 2010


Author: tschaub
Date: 2010-10-13 12:07:54 -0700 (Wed, 13 Oct 2010)
New Revision: 10826

Added:
   sandbox/tschaub/canvas/examples/example.js
   sandbox/tschaub/canvas/examples/strategy-cluster-extended.html
   sandbox/tschaub/canvas/examples/strategy-cluster-extended.js
   sandbox/tschaub/canvas/examples/wms-long-url.html
   sandbox/tschaub/canvas/examples/wms-long-url.js
Modified:
   sandbox/tschaub/canvas/
   sandbox/tschaub/canvas/build/library.cfg
   sandbox/tschaub/canvas/examples/WMSPost.html
   sandbox/tschaub/canvas/examples/example.html
   sandbox/tschaub/canvas/examples/mm.html
   sandbox/tschaub/canvas/examples/vector-features.html
   sandbox/tschaub/canvas/lib/OpenLayers/Control.js
   sandbox/tschaub/canvas/lib/OpenLayers/Control/Measure.js
   sandbox/tschaub/canvas/lib/OpenLayers/Control/Panel.js
   sandbox/tschaub/canvas/lib/OpenLayers/Layer/Google/v3.js
   sandbox/tschaub/canvas/lib/OpenLayers/Layer/Grid.js
   sandbox/tschaub/canvas/lib/OpenLayers/Layer/TileCache.js
   sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS.js
   sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS/Post.js
   sandbox/tschaub/canvas/lib/OpenLayers/Strategy/Fixed.js
   sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Line.js
   sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Point.js
   sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Polygon.js
   sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Text.js
   sandbox/tschaub/canvas/lib/OpenLayers/Tile.js
   sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image.js
   sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image/IFrame.js
   sandbox/tschaub/canvas/lib/OpenLayers/Util.js
   sandbox/tschaub/canvas/release-license.txt
   sandbox/tschaub/canvas/tests/Control/Measure.html
   sandbox/tschaub/canvas/tests/Control/Panel.html
   sandbox/tschaub/canvas/tests/Layer/WMS/Post.html
   sandbox/tschaub/canvas/tests/Strategy/Fixed.html
   sandbox/tschaub/canvas/tests/Symbolizer/Line.html
   sandbox/tschaub/canvas/tests/Symbolizer/Point.html
   sandbox/tschaub/canvas/tests/Symbolizer/Polygon.html
   sandbox/tschaub/canvas/tests/Symbolizer/Text.html
   sandbox/tschaub/canvas/tests/Tile/Image.html
   sandbox/tschaub/canvas/tests/Tile/Image/IFrame.html
   sandbox/tschaub/canvas/tests/Util.html
   sandbox/tschaub/canvas/tools/mergejs.py
Log:
Merge r10737:10819 from trunk.


Property changes on: sandbox/tschaub/canvas
___________________________________________________________________
Modified: svn:mergeinfo
   - /sandbox/roberthl/openlayers:9745-9748
/trunk/openlayers:10820-10824
   + /sandbox/roberthl/openlayers:9745-9748
/trunk/openlayers:10737-10825

Modified: sandbox/tschaub/canvas/build/library.cfg
===================================================================
--- sandbox/tschaub/canvas/build/library.cfg	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/build/library.cfg	2010-10-13 19:07:54 UTC (rev 10826)
@@ -14,8 +14,7 @@
 [include]
 
 [exclude]
-Firebug/firebug.js
-Firebug/firebugx.js
+Firebug
 OpenLayers.js
 OpenLayers/Format/GeoRSS.js
 OpenLayers/Format/GML.js
@@ -50,19 +49,6 @@
 OpenLayers/Renderer/SVG.js
 OpenLayers/Renderer/VML.js
 OpenLayers/Renderer.js
-OpenLayers/Lang/ca.js
-OpenLayers/Lang/cs-CZ.js
-OpenLayers/Lang/da-DK.js
-OpenLayers/Lang/de.js
-OpenLayers/Lang/en-CA.js
-OpenLayers/Lang/es.js
-OpenLayers/Lang/fr.js
-OpenLayers/Lang/it.js
-OpenLayers/Lang/nb.js
-OpenLayers/Lang/nl.js
-OpenLayers/Lang/pt-BR.js
-OpenLayers/Lang/sv-SE.js
-OpenLayers/Lang/zh-TW.js
-OpenLayers/Lang/zh-CN.js
+OpenLayers/Lang
 
 

Modified: sandbox/tschaub/canvas/examples/WMSPost.html
===================================================================
--- sandbox/tschaub/canvas/examples/WMSPost.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/examples/WMSPost.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -161,6 +161,8 @@
     <div id="map" style="width: 512; height: 256; border: 1px solid red;"></div>
 
     <div id="docs">
+        <p><b>Deprecated.</b> See <a href="wms-long-url.html">wms-long-url.html</a>
+            for the recommended way to avoid long URLs.</p><p>
         This example uses a large SLD created on the client side to style a WMS
         layer.  This example uses a WMS.Post layer which transfers data via the
         HTTP-POST protocol. <br>
@@ -171,7 +173,7 @@
         instead. The default setting (["mozilla", "firefox", "opera"])
         excludes problematic browsers without removing the ability to use long
         request parameters, because all these browsers support long urls via
-        GET.
+        GET.</p>
     </div>
   </body>
 </html>

Modified: sandbox/tschaub/canvas/examples/example.html
===================================================================
--- sandbox/tschaub/canvas/examples/example.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/examples/example.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -1,57 +1,22 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>OpenLayers Example</title>
-    <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">
-        // making this a global variable so that it is accessible for
-        // debugging/inspecting in Firebug
-        var map = null;
-
-        function init(){
-
-            map = new OpenLayers.Map('map');
-
-            var ol_wms = new OpenLayers.Layer.WMS(
-                "OpenLayers WMS",
-                "http://vmap0.tiles.osgeo.org/wms/vmap0",
-                {layers: 'basic'}
-            );
-
-            var jpl_wms = new OpenLayers.Layer.WMS(
-                "NASA Global Mosaic",
-                "http://t1.hypercube.telascience.org/cgi-bin/landsat7", 
-                {layers: "landsat7"}
-            );
-
-            var dm_wms = new OpenLayers.Layer.WMS(
-                "Canadian Data",
-                "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap",
-                {
-                    layers: "bathymetry,land_fn,park,drain_fn,drainage," +
-                            "prov_bound,fedlimit,rail,road,popplace",
-                    transparent: "true",
-                    format: "image/png"
-                },
-                {isBaseLayer: false, visibility: false}
-            );
-
-            map.addLayers([ol_wms, jpl_wms, dm_wms]);
-            map.addControl(new OpenLayers.Control.LayerSwitcher());
-            map.zoomToMaxExtent();
-        }
-    </script>
-  </head>
-  <body onload="init()">
-    <h1 id="title">OpenLayers Example</h1>
-    <div id="tags">
-        simple, basic
-    </div>
-    <p id="shortdesc">
-        Demonstrate a simple map with an overlay that includes layer switching controls.
-    </p>
-    <div id="map" class="smallmap"></div>
-    <div id="docs"></div>
-  </body>
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>OpenLayers Example</title>
+        <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
+        <link rel="stylesheet" href="style.css" type="text/css">
+    </head>
+    <body>
+        <h1 id="title">OpenLayers Example</h1>
+        <div id="tags">simple, basic</div>
+        <p id="shortdesc">
+            Demonstrate a simple map with an overlay that includes layer switching controls.
+        </p>
+        <div id="map" class="smallmap"></div>
+        <div id="docs">
+            <p>This is a basic example demonstrating the use of a map with two layers and a few controls.</p>
+            <p>View the <a href="example.js" target="_blank">example.js</a> source to see how this is done.</p>
+        </div>
+        <script src="../lib/OpenLayers.js"></script>
+        <script src="example.js"></script>
+    </body>
 </html>

Copied: sandbox/tschaub/canvas/examples/example.js (from rev 10819, trunk/openlayers/examples/example.js)
===================================================================
--- sandbox/tschaub/canvas/examples/example.js	                        (rev 0)
+++ sandbox/tschaub/canvas/examples/example.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -0,0 +1,23 @@
+var map = new OpenLayers.Map("map");
+
+var ol_wms = new OpenLayers.Layer.WMS(
+    "OpenLayers WMS",
+    "http://vmap0.tiles.osgeo.org/wms/vmap0",
+    {layers: "basic"}
+);
+
+var dm_wms = new OpenLayers.Layer.WMS(
+    "Canadian Data",
+    "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap",
+    {
+        layers: "bathymetry,land_fn,park,drain_fn,drainage," +
+                "prov_bound,fedlimit,rail,road,popplace",
+        transparent: "true",
+        format: "image/png"
+    },
+    {isBaseLayer: false, visibility: false}
+);
+
+map.addLayers([ol_wms, dm_wms]);
+map.addControl(new OpenLayers.Control.LayerSwitcher());
+map.zoomToMaxExtent();

Modified: sandbox/tschaub/canvas/examples/mm.html
===================================================================
--- sandbox/tschaub/canvas/examples/mm.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/examples/mm.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -12,7 +12,8 @@
     </style>
 
 
-    <script type="text/javascript" src="http://clients.multimap.com/API/maps/1.1/metacarta_04"></script>
+    <!-- multimap api key for http://(www.)openlayers.org -->
+    <script type="text/javascript" src="http://developer.multimap.com/API/maps/1.2/OA10072915821139765"></script>
 
 
     <script src="../lib/OpenLayers.js"></script>

Copied: sandbox/tschaub/canvas/examples/strategy-cluster-extended.html (from rev 10819, trunk/openlayers/examples/strategy-cluster-extended.html)
===================================================================
--- sandbox/tschaub/canvas/examples/strategy-cluster-extended.html	                        (rev 0)
+++ sandbox/tschaub/canvas/examples/strategy-cluster-extended.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Extended clustering 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">
+            label {
+                cursor: pointer
+            }
+            
+            #wrap {
+                width: 925px;
+                margin: 10px;
+            }
+            
+            #strategy-chooser, #generalinfo, #info {
+                width: 400px;
+                padding: 0;
+                float: right;
+                clear: right;
+                margin-bottom: 4px;
+            }
+            
+            #map {
+                float: left;
+            }
+        </style>
+    </head>
+    <body>
+        <h1 id="title">Extended clustering</h1>
+        <div id="tags">
+            cluster, advanced
+        </div>
+        <p id="shortdesc">
+            Shows the usage of custom classes for a fine grained control about 
+            the clustering behaviour.
+        </p>
+        <div id="wrap">
+            <div id="map" class="smallmap">
+            </div>
+            <div id="strategy-chooser">
+                <p>
+                    Select the desired clustering strategy:
+                </p>
+                <label>
+                    <input type="radio" name="strategy" value="none" id="no-strategy" checked="checked">No strategy
+                </label>
+                <br/>
+                <label>
+                    <input type="radio" name="strategy" value="cluster" id="cluster-strategy">Simple cluster-strategy
+                </label>
+                <br/>
+                <label>
+                    <input type="radio" name="strategy" value="attribute-cluster" id="attributive-cluster-strategy">Attributive cluster-strategy
+                </label>
+                <br/>
+                <label>
+                    <input type="radio" name="strategy" value="rule-cluster" id="rulebased-cluster-strategy">Rulebased cluster-strategy
+                </label>
+            </div>
+            <div id="generalinfo">
+            </div>
+            <div id="info">
+            </div>
+        </div>
+        <div id="docs" style="clear: both; padding-top: 10px">
+            <p>
+                The vectorlayer in this example contains random data with an 
+                attribute "clazz" that can take the values 1, 2, 3 and 4. The  
+                features with clazz = 4 are considered more important than the 
+                others.
+            </p>
+            <p>
+                The radiobuttons on the right of the map control the 
+                cluster strategy to be applied to the features.
+            </p>
+            <ul>
+                <li>
+                    <strong>No strategy</strong>
+                    means that all features are 
+                    rendered, no clustering shall be applied
+                </li>
+                <li>
+                    <strong>Simple cluster-strategy</strong>
+                    applies the cluster 
+                    strategy with default options to the layer. You should notice 
+                    that many of the important features with clazz = 4 are getting
+                    lost, since clustering happens regardless of feature attributes
+                </li>
+                <li>
+                    <strong>Attributive cluster-strategy</strong>
+                    uses a 
+                    customized cluster strategy. This strategy is configured to 
+                    cluster features of the same clazz only. You should be able to see all 
+                    red points (clazz = 4) even though the data is clustered. A 
+                    cluster now contains only features of the same clazz.
+                </li>
+                <li>
+                    <strong>Rulebased cluster-strategy</strong>
+                    uses another 
+                    customized cluster strategy. This strategy is configured to  
+                    cluster features that follow a certain rule only. In this case only  
+                    features with a clazz different from 4 are considered as 
+                    candidates for clustering. That means that usually you have fewer 
+                    clusters on the map, yet all with clazz = 4 are easily 
+                    distinguishable
+                </li>
+            </ul>
+            <p>
+                Hover over the features to get a short infomation about the 
+                feature or cluster of features. 
+            </p>
+        </div>
+        <p>
+            View the <a href="strategy-cluster-extended.js" target="_blank">strategy-cluster-extended.js</a>
+            source to see how this is done.
+        </p>
+        <script type="text/javascript" src="../lib/OpenLayers.js"></script>
+        <script type="text/javascript" src="strategy-cluster-extended.js"></script>
+    </body>
+</html>

Copied: sandbox/tschaub/canvas/examples/strategy-cluster-extended.js (from rev 10819, trunk/openlayers/examples/strategy-cluster-extended.js)
===================================================================
--- sandbox/tschaub/canvas/examples/strategy-cluster-extended.js	                        (rev 0)
+++ sandbox/tschaub/canvas/examples/strategy-cluster-extended.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -0,0 +1,247 @@
+/**
+ * Class: OpenLayers.Strategy.AttributeCluster
+ * Strategy for vector feature clustering based on feature attributes.
+ *
+ * Inherits from:
+ *  - <OpenLayers.Strategy.Cluster>
+ */
+OpenLayers.Strategy.AttributeCluster = OpenLayers.Class(OpenLayers.Strategy.Cluster, {
+    /**
+     * the attribute to use for comparison
+     */
+    attribute: null,
+    /**
+     * Method: shouldCluster
+     * Determine whether to include a feature in a given cluster.
+     *
+     * Parameters:
+     * cluster - {<OpenLayers.Feature.Vector>} A cluster.
+     * feature - {<OpenLayers.Feature.Vector>} A feature.
+     *
+     * Returns:
+     * {Boolean} The feature should be included in the cluster.
+     */
+    shouldCluster: function(cluster, feature) {
+        var cc_attrval = cluster.cluster[0].attributes[this.attribute];
+        var fc_attrval = feature.attributes[this.attribute];
+        var superProto = OpenLayers.Strategy.Cluster.prototype;
+        return cc_attrval === fc_attrval && 
+               superProto.shouldCluster.apply(this, arguments);
+    },
+    CLASS_NAME: "OpenLayers.Strategy.AttributeCluster"
+});
+
+/**
+ * Class: OpenLayers.Strategy.RuleCluster
+ * Strategy for vector feature clustering according to a given rule.
+ *
+ * Inherits from:
+ *  - <OpenLayers.Strategy.Cluster>
+ */
+OpenLayers.Strategy.RuleCluster = OpenLayers.Class(OpenLayers.Strategy.Cluster, {
+    /**
+     * the rule to use for comparison
+     */
+    rule: null,
+    /**
+     * Method: shouldCluster
+     * Determine whether to include a feature in a given cluster.
+     *
+     * Parameters:
+     * cluster - {<OpenLayers.Feature.Vector>} A cluster.
+     * feature - {<OpenLayers.Feature.Vector>} A feature.
+     *
+     * Returns:
+     * {Boolean} The feature should be included in the cluster.
+     */
+    shouldCluster: function(cluster, feature) {
+        var superProto = OpenLayers.Strategy.Cluster.prototype;
+        return this.rule.evaluate(cluster.cluster[0]) &&
+               this.rule.evaluate(feature) &&
+               superProto.shouldCluster.apply(this, arguments);
+    },
+    CLASS_NAME: "OpenLayers.Strategy.RuleCluster"
+});
+
+
+// global variables
+var map, vectorlayer, features, stylemap, select;
+
+// wrap the instanciation code in an anonymous function that gets executed
+// immeadeately
+(function(){
+
+    // The function that gets called on feature selection: shows information 
+    // about the feature/cluser in a div on the page 
+	var showInformation = function(evt){
+        var feature = evt.feature;
+		var info = 'Last hovered feature:<br>';
+		if (feature.cluster) {
+			info += '&nbsp;&nbsp;Cluster of ' + feature.attributes.count + ' features:';
+			var clazzes = {
+				'1': 0,
+				'2': 0,
+				'3': 0,
+				'4': 0
+			};
+			for (var i = 0; i < feature.attributes.count; i++) {
+				var feat = feature.cluster[i];
+				clazzes[feat.attributes.clazz]++;
+			}
+			for (var j=1; j<=4; j++) {
+				var plural_s = (clazzes[j] !== 1) ? 's' : '';
+				info += '<br>&nbsp;&nbsp;&nbsp;&nbsp;&bull;&nbsp;clazz ' + j + ': ' + clazzes[j] + ' feature' + plural_s;
+			}
+		} else {
+			info += '&nbsp;&nbsp;Single feature of clazz = ' + feature.attributes.clazz;
+		}
+		$('info').innerHTML = info;
+    };
+
+	// The function that gets called on feature selection. Shows information 
+    // about the number of "points" on the map.
+	var updateGeneralInformation = function() {
+		var info = 'Currently ' + vectorlayer.features.length + ' points are shown on the map.';
+		$('generalinfo').innerHTML = info;
+	};
+	
+	// instanciate the map
+	map = new OpenLayers.Map("map");
+    
+	// background WMS
+    var ol_wms = new OpenLayers.Layer.WMS("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {
+        layers: "basic"
+    });
+    
+	// context to style the vectorlayer
+    var context = {
+        getColor: function(feature){
+            var color = '#aaaaaa';
+			if (feature.attributes.clazz && feature.attributes.clazz === 4) {
+				color = '#ee0000';
+			} else if(feature.cluster) {
+				var onlyFour = true;
+				for (var i = 0; i < feature.cluster.length; i++) {
+					if (onlyFour && feature.cluster[i].attributes.clazz !== 4) {
+						onlyFour = false;
+					}
+				}
+				if (onlyFour === true) {
+					color = '#ee0000';
+				}
+			}
+			return color;
+        }
+    };
+	
+    // style the vectorlayer
+    stylemap = new OpenLayers.StyleMap({
+        'default': new OpenLayers.Style({
+            pointRadius: 5,
+            fillColor: "${getColor}",
+            fillOpacity: 0.7,
+            strokeColor: "#666666",
+            strokeWidth: 1,
+            strokeOpacity: 1,
+			graphicZIndex: 1
+        }, {
+            context: context
+        }),
+		'select' : new OpenLayers.Style({
+            pointRadius: 5,
+            fillColor: "#ffff00",
+            fillOpacity: 1,
+            strokeColor: "#666666",
+            strokeWidth: 1,
+            strokeOpacity: 1,
+			graphicZIndex: 2
+        })
+    });
+    
+    // the vectorlayer
+    vectorlayer = new OpenLayers.Layer.Vector('Vectorlayer', {styleMap: stylemap, strategies: []});
+    
+	// the select control
+	select = new OpenLayers.Control.SelectFeature(
+        vectorlayer, {hover: true}
+    );
+    map.addControl(select);
+    select.activate();
+    vectorlayer.events.on({"featureselected": showInformation});
+	
+    map.addLayers([ol_wms, vectorlayer]);
+    map.addControl(new OpenLayers.Control.LayerSwitcher());
+    map.zoomToMaxExtent();
+    
+    features = [];
+    // adding lots of features:
+    for (var i = 0; i < 700; i++) {
+        var r1 = Math.random();
+        var r2 = Math.random();
+        var r3 = Math.random();
+        var r4 = Math.random();
+        var px = r1 * 180 * ((r2 < 0.5) ? -1 : 1); 
+        var py = r3 * 90 * ((r4 < 0.5) ? -1 : 1);
+        var p = new OpenLayers.Geometry.Point(px, py);
+        var clazz = (i % 10 === 0) ? 4 : Math.ceil(r4 * 3);
+        var f = new OpenLayers.Feature.Vector(p, {clazz: clazz});
+        features.push(f);
+    }
+    vectorlayer.addFeatures(features);
+    updateGeneralInformation();
+
+    // the behaviour and methods for the radioboxes    
+    var changeStrategy = function() {
+        var strategies = [];
+        // this is the checkbox
+        switch(this.value) {
+            case 'cluster':
+                // standard clustering
+				strategies.push(new OpenLayers.Strategy.Cluster());
+                break;
+            case 'attribute-cluster':
+                // use the custom class: only cluster features of the same clazz
+				strategies.push(new OpenLayers.Strategy.AttributeCluster({
+                    attribute:'clazz'
+                }));
+                break;
+            case 'rule-cluster':
+                // use the custom class: only cluster features that have a 
+				// clazz smaller than 4
+				strategies.push(new OpenLayers.Strategy.RuleCluster({
+                    rule: new OpenLayers.Rule({
+                        filter: new OpenLayers.Filter.Comparison({
+                            type: OpenLayers.Filter.Comparison.LESS_THAN,
+                            property: "clazz",
+                            value: 4
+                        })
+                    })
+                }));
+                break;
+        }
+		// remove layer and control
+        map.removeLayer(vectorlayer);
+		map.removeControl(select);
+		// rebuild layer
+        vectorlayer = new OpenLayers.Layer.Vector('Vectorlayer', {styleMap: stylemap, strategies: strategies});
+        map.addLayer( vectorlayer );
+        vectorlayer.addFeatures(features);
+        // rebuild select control
+		select = new OpenLayers.Control.SelectFeature(
+	        vectorlayer, {hover: true}
+	    );
+	    map.addControl(select);
+	    select.activate();
+	    vectorlayer.events.on({"featureselected": showInformation});
+		// update meta information
+		updateGeneralInformation();
+    };
+	// bind the behviour to the radios
+    var inputs = document.getElementsByTagName('input');
+    for( var cnt = 0; cnt < inputs.length; cnt++) {
+      var input = inputs[cnt];
+      if (input.name === 'strategy') {
+         input.onclick = changeStrategy;
+      }
+    }
+})();

Modified: sandbox/tschaub/canvas/examples/vector-features.html
===================================================================
--- sandbox/tschaub/canvas/examples/vector-features.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/examples/vector-features.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>OpenLayers: Vector Features</title>
@@ -63,7 +64,7 @@
             style_mark.graphicYOffset = -style_mark.graphicHeight;
             style_mark.externalGraphic = "../img/marker.png";
             // graphicTitle only works in Firefox and Internet Explorer
-			style_mark.graphicTitle = "this is a test tooltip";
+            style_mark.graphicTitle = "this is a test tooltip";
 
             var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", {style: layer_style});
 

Copied: sandbox/tschaub/canvas/examples/wms-long-url.html (from rev 10819, trunk/openlayers/examples/wms-long-url.html)
===================================================================
--- sandbox/tschaub/canvas/examples/wms-long-url.html	                        (rev 0)
+++ sandbox/tschaub/canvas/examples/wms-long-url.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>WMS with POST Requests to Avoid Long URLs</title>
+    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="style.css" type="text/css" />
+  </head>
+  <body>
+    <h1 id="title">WMS with POST Requests to Avoid Long URLs</h1>
+
+    <div id="tags">
+        sld, sld_body, post, iframe, advanced
+    </div>
+
+    <div id="shortdesc">Render tiles in IMG or IFRAME elements, depending on
+        the complexity of the GetMap request</div>
+
+    <div id="map" class="smallmap"></div>
+
+    <div id="docs">
+        <p>The <code>maxGetUrlLength</code> property of the layer's
+            <code>tileOptions</code> option causes tiles to be requested using
+            HTTP POST when the length of the GET url would exceed the specified
+            length (2048 characters is recommended). In real life applications,
+            this happens often when using the SLD_BODY request parameter for
+            inline styling.
+        </p><p>
+            <input type="radio" name="group" id="longurl" checked="checked">
+            Long URL - POST requests
+            <br>
+            <input type="radio" name="group" id="shorturl">
+            Short URL - GET requests
+        </p><p>
+            View the <a href="wms-long-url.js" target="_blank">wms-long-url.js</a>
+            source to see how this is done.
+        </p>
+    </div>
+    <script src="../lib/OpenLayers.js"></script>
+    <script src="wms-long-url.js"></script>
+  </body>
+</html>

Copied: sandbox/tschaub/canvas/examples/wms-long-url.js (from rev 10819, trunk/openlayers/examples/wms-long-url.js)
===================================================================
--- sandbox/tschaub/canvas/examples/wms-long-url.js	                        (rev 0)
+++ sandbox/tschaub/canvas/examples/wms-long-url.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -0,0 +1,19 @@
+// a long text that we set as dummy param (makeTheUrlLong) to make the url long
+var longText = new Array(205).join("1234567890");
+
+var map = new OpenLayers.Map( 'map' );
+var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+        "http://vmap0.tiles.osgeo.org/wms/vmap0",
+        {layers: 'basic', makeTheUrlLong: longText},
+        {tileOptions: {maxGetUrlLength: 2048}}
+);
+map.addLayer(layer);
+map.zoomToMaxExtent();
+
+// add behavior to dom elements
+document.getElementById("longurl").onclick = function() {
+    layer.mergeNewParams({makeTheUrlLong: longText})
+}
+document.getElementById("shorturl").onclick = function() {
+    layer.mergeNewParams({makeTheUrlLong: null})
+}

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Control/Measure.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Control/Measure.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Control/Measure.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -93,7 +93,7 @@
      * {Number} Timeout id of trigger for measurepartial.
      */
     delayedTrigger: null,
-    
+
     /**
      * APIProperty: persist
      * {Boolean} Keep the temporary measurement sketch drawn after the
@@ -131,11 +131,20 @@
     },
     
     /**
+     * APIMethod: deactivate
+     */
+    deactivate: function() {
+        this.cancelDelay();
+        return OpenLayers.Control.prototype.deactivate.apply(this, arguments);
+    },
+
+    /**
      * APIMethod: cancel
      * Stop the control from measuring.  If <persist> is true, the temporary
      *     sketch will be erased.
      */
     cancel: function() {
+        this.cancelDelay();
         this.handler.cancel();
     },
     
@@ -165,9 +174,7 @@
      * geometry - {<OpenLayers.Geometry>}
      */
     measureComplete: function(geometry) {
-        if(this.delayedTrigger) {
-            window.clearTimeout(this.delayedTrigger);
-        }
+        this.cancelDelay();
         this.measure(geometry, "measure");
     },
     
@@ -180,10 +187,17 @@
      * geometry - {<OpenLayers.Geometry>} The sketch geometry.
      */
     measurePartial: function(point, geometry) {
-        if (geometry.getLength() > 0) {
-            geometry = geometry.clone();
+        this.cancelDelay();
+        geometry = geometry.clone();
+        // when we're wating for a dblclick, we have to trigger measurepartial
+        // after some delay to deal with reflow issues in IE
+        if (this.handler.freehandMode(this.handler.evt)) {
+            // no dblclick in freehand mode
+            this.measure(geometry, "measurepartial");
+        } else {
             this.delayedTrigger = window.setTimeout(
                 OpenLayers.Function.bind(function() {
+                    this.delayedTrigger = null;
                     this.measure(geometry, "measurepartial");
                 }, this),
                 this.partialDelay
@@ -192,6 +206,17 @@
     },
 
     /**
+     * Method: cancelDelay
+     * Cancels the delay measurement that measurePartial began.
+     */
+    cancelDelay: function() {
+        if (this.delayedTrigger !== null) {
+            window.clearTimeout(this.delayedTrigger);
+            this.delayedTrigger = null;
+        }
+    },
+
+    /**
      * Method: measure
      *
      * Parameters:

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Control/Panel.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Control/Panel.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Control/Panel.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -167,10 +167,8 @@
      * Method: redraw
      */
     redraw: function() {
-        if (this.div.children.length>0) {
-            for (var l=this.div.children.length, i=l-1 ; i>=0 ; i--) {
-                this.div.removeChild(this.div.children[i]);
-            }
+        for (var l=this.div.childNodes.length, i=l-1; i>=0; i--) {
+            this.div.removeChild(this.div.childNodes[i]);
         }
         this.div.innerHTML = "";
         if (this.active) {

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Control.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Control.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Control.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -343,7 +343,10 @@
                     this.displayClass.replace(/ /g, "") + "Active"
                 );
             }
-            this.events.triggerEvent("deactivate");
+            // deal with the case where the control is destroyed
+            if(this.events) {
+                this.events.triggerEvent("deactivate");
+            }
             return true;
         }
         return false;

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Layer/Google/v3.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Layer/Google/v3.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Layer/Google/v3.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -90,7 +90,8 @@
                 keyboardShortcuts: false,
                 draggable: false,
                 disableDoubleClickZoom: true,
-                scrollwheel: false
+                scrollwheel: false,
+                streetViewControl: false
             });
             
             // cache elements for use by any other google layers added to

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Layer/Grid.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Layer/Grid.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Layer/Grid.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -25,6 +25,12 @@
      */
     tileSize: null,
     
+    /** APIProperty: tileOptions
+     *  {Object} optional configuration options for <OpenLayers.Tile> instances
+     *  created by this Layer, if supported by the tile class.
+     */
+    tileOptions: null,
+    
     /**
      * Property: grid
      * {Array(Array(<OpenLayers.Tile>))} This is an array of rows, each row is 

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Layer/TileCache.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Layer/TileCache.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Layer/TileCache.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -6,6 +6,7 @@
 
 /**
  * @requires OpenLayers/Layer/Grid.js
+ * @requires OpenLayers/Tile/Image.js
  */
 
 /**

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS/Post.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS/Post.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS/Post.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -15,18 +15,16 @@
  * Web Mapping Services via HTTP-POST (application/x-www-form-urlencoded). 
  * Create a new WMS layer with the <OpenLayers.Layer.WMS.Post> constructor.
  *
+ * *Deprecated*. Instead of this layer, use <OpenLayers.Layer.WMS> with
+ * <OpenLayers.Tile.Image.maxGetUrlLength> configured in the layer's
+ * <OpenLayers.Layer.WMS.tileOptions>.
+ *
  * Inherits from:
  *  - <OpenLayers.Layer.WMS>
  */
 OpenLayers.Layer.WMS.Post = OpenLayers.Class(OpenLayers.Layer.WMS, {
 
     /**
-     * Property: tileClass
-     * {Object} Class, used to create tiles.
-     */
-    tileClass: null,
-
-    /**
      * APIProperty: unsupportedBrowsers
      * {Array} Array with browsers, which should use the HTTP-GET protocol 
      * instead of HTTP-POST for fetching tiles from a WMS .
@@ -46,6 +44,12 @@
      * possible to modify the initialized tiles (iframes)
      */
     SUPPORTED_TRANSITIONS: [],
+    
+    /**
+     * Property: usePost
+     * {Boolean}
+     */
+    usePost: null,
 
     /**
      * Constructor: OpenLayers.Layer.WMS.Post
@@ -72,10 +76,8 @@
         newArguments.push(name, url, params, options);
         OpenLayers.Layer.WMS.prototype.initialize.apply(this, newArguments);
 
-        this.tileClass = OpenLayers.Util.indexOf(
-            this.unsupportedBrowsers, OpenLayers.Util.getBrowserName()) != -1
-                ? OpenLayers.Tile.Image
-                : OpenLayers.Tile.Image.IFrame;
+        this.usePost = OpenLayers.Util.indexOf(
+            this.unsupportedBrowsers, OpenLayers.Util.getBrowserName()) == -1;
     },
     
     /**
@@ -91,8 +93,10 @@
      * {<OpenLayers.Tile.Image.IFrame>} The added OpenLayers.Tile.Image.IFrame
      */
     addTile: function(bounds,position) {
-        return new this.tileClass(
-            this, position, bounds, null, this.tileSize);
+        return new OpenLayers.Tile.Image(
+            this, position, bounds, null, this.tileSize, {
+                maxGetUrlLength: this.usePost ? 0 : null
+            });
     },
 
     CLASS_NAME: 'OpenLayers.Layer.WMS.Post'

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Layer/WMS.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -215,7 +215,7 @@
      */
     addTile:function(bounds,position) {
         return new OpenLayers.Tile.Image(this, position, bounds, 
-                                         null, this.tileSize);
+                                         null, this.tileSize, this.tileOptions);
     },
 
     /**

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Strategy/Fixed.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Strategy/Fixed.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Strategy/Fixed.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -98,13 +98,14 @@
      * options - {Object} options to pass to protocol read.
      */
     load: function(options) {
-        this.layer.events.triggerEvent("loadstart");
-        this.layer.protocol.read(OpenLayers.Util.applyDefaults({
-            callback: this.merge,
-            filter: this.layer.filter,
-            scope: this
+        var layer = this.layer;
+        layer.events.triggerEvent("loadstart");
+        layer.protocol.read(OpenLayers.Util.applyDefaults({
+            callback: OpenLayers.Function.bind(this.merge, this,
+                layer.map.getProjectionObject()),
+            filter: layer.filter
         }, options));
-        this.layer.events.un({
+        layer.events.un({
             "visibilitychanged": this.load,
             scope: this
         });
@@ -113,25 +114,28 @@
     /**
      * Method: merge
      * Add all features to the layer.
+     *
+     * Parameters:
+     * mapProjection - {OpenLayers.Projection} the map projection
+     * resp - {Object} options to pass to protocol read.
      */
-    merge: function(resp) {
-        this.layer.destroyFeatures();
+    merge: function(mapProjection, resp) {
+        var layer = this.layer;
+        layer.destroyFeatures();
         var features = resp.features;
         if (features && features.length > 0) {
-            var remote = this.layer.projection;
-            var local = this.layer.map.getProjectionObject();
-            if(!local.equals(remote)) {
+            if(!mapProjection.equals(layer.projection)) {
                 var geom;
                 for(var i=0, len=features.length; i<len; ++i) {
                     geom = features[i].geometry;
                     if(geom) {
-                        geom.transform(remote, local);
+                        geom.transform(layer.projection, mapProjection);
                     }
                 }
             }
-            this.layer.addFeatures(features);
+            layer.addFeatures(features);
         }
-        this.layer.events.triggerEvent("loadend");
+        layer.events.triggerEvent("loadend");
     },
 
     CLASS_NAME: "OpenLayers.Strategy.Fixed"

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Line.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Line.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Line.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -16,27 +16,31 @@
     /**
      * APIProperty: strokeColor
      * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
-     *     for red).
+     *     for red).  
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeColor: null,
     
     /**
      * APIProperty: strokeOpacity
      * {Number} Stroke opacity (0-1).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeOpacity: null,
     
     /**
      * APIProperty: strokeWidth
      * {Number} Pixel stroke width.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeWidth: null,
     
     /**
      * APIProperty: strokeLinecap
      * {String} Stroke cap type ("butt", "round", or "square").
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeLinecap: null,
     
     /**
      * Property: strokeDashstyle
@@ -44,8 +48,9 @@
      *     OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
      *     "longdash", "longdashdot", or "solid") will not work in SLD, but
      *     most SLD patterns will render correctly in OpenLayers.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeDashstyle: null,
 
     /**
      * Constructor: OpenLayers.Symbolizer.Line

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Point.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Point.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Point.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -17,26 +17,30 @@
      * APIProperty: strokeColor
      * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
      *     for red).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeColor: null,
     
     /**
      * APIProperty: strokeOpacity
      * {Number} Stroke opacity (0-1).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeOpacity: null,
     
     /**
      * APIProperty: strokeWidth
      * {Number} Pixel stroke width.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeWidth: null,
     
     /**
      * APIProperty: strokeLinecap
      * {String} Stroke cap type ("butt", "round", or "square").
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeLinecap: null,
     
     /**
      * Property: strokeDashstyle
@@ -44,80 +48,92 @@
      *     OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
      *     "longdash", "longdashdot", or "solid") will not work in SLD, but
      *     most SLD patterns will render correctly in OpenLayers.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeDashstyle: null,
 
     /**
      * APIProperty: fillColor
      * {String} RGB hex fill color (e.g. "#ff0000" for red).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fillColor: null,
     
     /**
      * APIProperty: fillOpacity
      * {Number} Fill opacity (0-1).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fillOpacity: null, 
 
     /**
      * APIProperty: pointRadius
      * {Number} Pixel point radius.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    pointRadius: null,
 
     /**
      * APIProperty: externalGraphic
      * {String} Url to an external graphic that will be used for rendering 
      *     points.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    externalGraphic: null,
     
     /**
      * APIProperty: graphicWidth
      * {Number} Pixel width for sizing an external graphic.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicWidth: null,
     
     /**
      * APIProperty: graphicHeight
      * {Number} Pixel height for sizing an external graphic.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicHeight: null,
     
     /**
      * APIProperty: graphicOpacity
      * {Number} Opacity (0-1) for an external graphic.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicOpacity: null,
     
     /**
      * APIProperty: graphicXOffset
      * {Number} Pixel offset along the positive x axis for displacing an 
      *     external graphic.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicXOffset: null,
     
     /**
      * APIProperty: graphicYOffset
      * {Number} Pixel offset along the positive y axis for displacing an 
      *     external graphic.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicYOffset: null,
 
     /**
      * APIProperty: rotation
      * {Number} The rotation of a graphic in the clockwise direction about its 
      *     center point (or any point off center as specified by 
      *     <graphicXOffset> and <graphicYOffset>).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    rotation: null,
     
     /**
      * APIProperty: graphicName
      * {String} Named graphic to use when rendering points.  Supported values 
      *     include "circle", "square", "star", "x", "cross", and "triangle".
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    graphicName: null,
     
     /**
      * Constructor: OpenLayers.Symbolizer.Point

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Polygon.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Polygon.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Polygon.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -17,26 +17,30 @@
      * APIProperty: strokeColor
      * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
      *     for red).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeColor: null,
     
     /**
      * APIProperty: strokeOpacity
      * {Number} Stroke opacity (0-1).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeOpacity: null,
     
     /**
      * APIProperty: strokeWidth
      * {Number} Pixel stroke width.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeWidth: null,
     
     /**
      * APIProperty: strokeLinecap
      * {String} Stroke cap type ("butt", "round", or "square").
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeLinecap: null,
     
     /**
      * Property: strokeDashstyle
@@ -44,20 +48,23 @@
      *     OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
      *     "longdash", "longdashdot", or "solid") will not work in SLD, but
      *     most SLD patterns will render correctly in OpenLayers.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    strokeDashstyle: null,
 
     /**
      * APIProperty: fillColor
      * {String} RGB hex fill color (e.g. "#ff0000" for red).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fillColor: null,
     
     /**
      * APIProperty: fillOpacity
      * {Number} Fill opacity (0-1).
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fillOpacity: null, 
 
     /**
      * Constructor: OpenLayers.Symbolizer.Polygon

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Text.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Text.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Symbolizer/Text.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -16,32 +16,37 @@
     /** 
      * APIProperty: label
      * {String} The text for the label.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    label: null,
     
     /** 
      * APIProperty: fontFamily
      * {String} The font family for the label.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fontFamily: null,
 
     /** 
      * APIProperty: fontSize
      * {String} The font size for the label.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fontSize: null,
 
     /** 
      * APIProperty: fontWeight
      * {String} The font weight for the label.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fontWeight: null,
     
     /**
      * Property: fontStyle
      * {String} The font style for the label.
+     * 
+     * No default set here.  Use OpenLayers.Renderer.defaultRenderer for defaults.
      */
-    fontStyle: null,
 
     /**
      * Constructor: OpenLayers.Symbolizer.Text

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image/IFrame.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image/IFrame.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image/IFrame.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -9,87 +9,49 @@
  */
 
 /**
- * Class: OpenLayers.Tile.Image.IFrame
- * Instances of OpenLayers.Tile.Image.IFrame are used to manage the image tiles
- * used by Layer.WMS.Post loaded via HTTP-POST-protocol. Create a new image
- * tile with the <OpenLayers.Tile.Image.IFrame> constructor.
+ * Constant: OpenLayers.Tile.Image.IFrame
+ * Mixin for tiles that use form-encoded POST requests to get images from
+ * remote services. Images will be loaded using HTTP-POST into an IFrame.
  *
+ * This mixin will be applied to <OpenLayers.Tile.Image> instances
+ * configured with <OpenLayers.Tile.Image.allowPost> or
+ * <OpenLayers.Tile.Image.enforcePost> set to true.
+ *
  * Inherits from:
  *  - <OpenLayers.Tile.Image>
  */
-OpenLayers.Tile.Image.IFrame = OpenLayers.Class(OpenLayers.Tile.Image, {
+OpenLayers.Tile.Image.IFrame = {
     
     /**
-     * Property: layerAlphaHack
-     * {Boolean} Always false for an instance.
-     */
+     * Property: useIFrame
+     * {Boolean} true if we are currently using an IFrame to render POST
+     * responses, false if we are using an img element to render GET responses.
+     */ 
+    useIFrame: null,
 
     /**
-     * Constructor: OpenLayers.Tile.Image.IFrame
-     * Constructor for a new <OpenLayers.Tile.Image.IFrame> instance.
-     * 
-     * Parameters:
-     * layer - {<OpenLayers.Layer>} layer that the tile will go in.
-     * position - {<OpenLayers.Pixel>}
-     * bounds - {<OpenLayers.Bounds>}
-     * size - {<OpenLayers.Size>}
-     */   
-    initialize: function(layer, position, bounds, url, size) {
-        OpenLayers.Tile.Image.prototype.initialize.apply(this, arguments);
-        this.layerAlphaHack = false;
-    },
-
-    /** 
-     * Method: destroy
-     * nullify references to prevent circular references and memory leaks
-     */
-    destroy: function() {
-        if(this.imgDiv != null) {
-            // unregister the "load" handler
-            OpenLayers.Event.stopObservingElement(this.imgDiv.firstChild);
-        }
-        OpenLayers.Tile.Image.prototype.destroy.apply(this, arguments);
-    },
-
-    /**
      * Method: clear
      * Removes the iframe from DOM (avoids back-button problems).
      */
     clear: function() {
-        if(this.imgDiv) {
-            var iFrame = this.imgDiv.firstChild;
-            OpenLayers.Event.stopObservingElement(iFrame);
-            this.imgDiv.removeChild(iFrame);
+        if (this.useIFrame) {
+            if (this.imgDiv) {
+                var iFrame = this.imgDiv.firstChild;
+                OpenLayers.Event.stopObservingElement(iFrame);
+                this.imgDiv.removeChild(iFrame);
+                delete iFrame;
+            }
+        } else {
+            OpenLayers.Tile.Image.prototype.clear.apply(this, arguments)
         }
     },
 
     /**
-     * Method: clone
-     *
-     * Parameters:
-     * obj - {<OpenLayers.Tile.Image.IFrame>} The tile to be cloned
-     *
-     * Returns:
-     * {<OpenLayers.Tile.Image.IFrame>} An exact clone of this 
-     * <OpenLayers.Tile.Image.IFrame>
-     */
-    clone: function (obj) {
-        if (obj == null) {
-            obj = new OpenLayers.Tile.Image.IFrame(
-                this.layer, this.position, this.bounds, this.url, this.size);
-        } 
-        
-        //pick up properties from superclass
-        obj = OpenLayers.Tile.Image.prototype.clone.apply(this, [obj]);
-        
-        return obj;
-    },
-
-    /**
      * Method: renderTile
      */
      renderTile: function() {
-        if(OpenLayers.Tile.Image.prototype.renderTile.apply(this, arguments)) {
+        if (OpenLayers.Tile.Image.prototype.renderTile.apply(this, arguments) &&
+                                                            this.useIFrame) {
             // create a html form and add it temporary to the layer div
             var form = this.createRequestForm();
             this.imgDiv.appendChild(form);
@@ -97,7 +59,9 @@
             // submit the form (means fetching the image)
             form.submit();
             this.imgDiv.removeChild(form);
+            delete form;
         }
+        return true;
     },
 
     /**
@@ -105,49 +69,56 @@
      * Creates the imgDiv property on the tile.
      */
     initImgDiv: function() {
-        this.imgDiv = this.createImgDiv();
+        this.useIFrame = this.maxGetUrlLength !== null && !this.layer.async &&
+            this.url.length > this.maxGetUrlLength;
+        if (this.imgDiv != null) {
+            var nodeName = this.imgDiv.nodeName.toLowerCase();
+            if ((this.useIFrame && nodeName == "img") ||
+                                        (!this.useIFrame && nodeName == "div")) {
+                // switch between get and post
+                this.removeImgDiv();
+                this.imgDiv = null;
+            }
+        }
+        if (this.useIFrame) {
+            if (this.imgDiv == null) {
+                var eventPane = document.createElement("div");
 
-        OpenLayers.Util.modifyDOMElement(this.imgDiv, this.id, null,
-            this.layer.getImageSize(), "relative");
-        this.imgDiv.className = 'olTileImage';
+                if(OpenLayers.Util.getBrowserName() == "msie") {
+                    // IE cannot handle events on elements without backgroundcolor.
+                    // So we use this little hack to make elements transparent
+                    eventPane.style.backgroundColor = '#FFFFFF';
+                    eventPane.style.filter          = 'chroma(color=#FFFFFF)';
+                }
 
-        this.frame.appendChild(this.imgDiv); 
-        this.layer.div.appendChild(this.frame); 
+                OpenLayers.Util.modifyDOMElement(eventPane, null,
+                    new OpenLayers.Pixel(0,0), this.layer.getImageSize(), "absolute");
 
-        if(this.layer.opacity != null) {
-            
-            OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null, null,
-                                             null, null, null, 
-                                             this.layer.opacity);
-        }
+                this.imgDiv = document.createElement("div");
+                this.imgDiv.appendChild(eventPane);
 
-        // we need this reference to check back the viewRequestID
-        this.imgDiv.map = this.layer.map;
-    },
+                OpenLayers.Util.modifyDOMElement(this.imgDiv, this.id, null,
+                    this.layer.getImageSize(), "relative");
+                this.imgDiv.className = 'olTileImage';
 
-    /**
-     * Method: createImgDiv
-     * Creates a div with iframe.and eventPane
-     *
-     * Returns:
-     * {DOMElement}
-     */
-    createImgDiv: function() {
-        var eventPane = document.createElement("div");
+                this.frame.appendChild(this.imgDiv); 
+                this.layer.div.appendChild(this.frame); 
 
-        if(OpenLayers.Util.getBrowserName() == "msie") {
-            // IE cannot handle events on elements without backgroundcolor. So we
-            // use this little hack to make elements transparent
-            eventPane.style.backgroundColor = '#FFFFFF';
-            eventPane.style.filter          = 'chroma(color=#FFFFFF)';
-        }
+                if(this.layer.opacity != null) {
 
-        OpenLayers.Util.modifyDOMElement(eventPane, null,
-            new OpenLayers.Pixel(0,0), this.layer.getImageSize(), "absolute");
+                    OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null,
+                                                     null, null, null, null, 
+                                                     this.layer.opacity);
+                }
 
-        var imgDiv = document.createElement("div");
-        imgDiv.appendChild(eventPane);
-        return imgDiv;
+                // we need this reference to check back the viewRequestID
+                this.imgDiv.map = this.layer.map;
+            }
+            this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
+
+        } else {
+            OpenLayers.Tile.Image.prototype.initImgDiv.apply(this, arguments);
+        }
     },
 
     /**
@@ -238,13 +209,7 @@
         // adding all parameters in layer params as hidden fields to the html
         // form element
         var imageSize = this.layer.getImageSize();
-        var params = OpenLayers.Util.extend(
-            {
-                "BBOX": this.encodeBBOX ? this.bounds.toBBOX() :
-                        this.bounds.toArray(),
-                "WIDTH": imageSize.w,
-                "HEIGHT": imageSize.h
-            }, this.layer.params);
+        var params = OpenLayers.Util.getParameters(this.url);
             
         for(var par in params) {
             var field = document.createElement('input');
@@ -255,8 +220,5 @@
         }   
 
         return form;
-    },
-    
-    CLASS_NAME: "OpenLayers.Tile.Image.IFrame"
-  }
-);
+    }
+}

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Tile/Image.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -76,7 +76,24 @@
      *     effects when the tile is moved or changes resolution.
      */
     backBufferTile: null,
-
+    
+    /**
+     * APIProperty: maxGetUrlLength
+     * {Number} If set, requests that would result in GET urls with more
+     * characters than the number provided will be made using form-encoded
+     * HTTP POST. It is good practice to avoid urls that are longer than 2048
+     * characters.
+     *
+     * Caution:
+     * Older versions of Gecko based browsers (e.g. Firefox < 3.5) and
+     * Opera < 10.0 do not fully support this option.
+     *
+     * Note:
+     * Do not use this option for layers that have a transitionEffect
+     * configured - IFrame tiles from POST requests can not be resized.
+     */
+    maxGetUrlLength: null,
+    
     /** TBD 3.0 - reorder the parameters to the init function to remove 
      *             URL. the getUrl() function on the layer gets called on 
      *             each draw(), so no need to specify it here.
@@ -90,17 +107,22 @@
      * bounds - {<OpenLayers.Bounds>}
      * url - {<String>} Deprecated. Remove me in 3.0.
      * size - {<OpenLayers.Size>}
+     * options - {Object}
      */   
-    initialize: function(layer, position, bounds, url, size) {
+    initialize: function(layer, position, bounds, url, size, options) {
         OpenLayers.Tile.prototype.initialize.apply(this, arguments);
 
+        if (this.maxGetUrlLength != null) {
+            OpenLayers.Util.extend(this, OpenLayers.Tile.Image.IFrame);
+        }
+
         this.url = url; //deprecated remove me
         
         this.frame = document.createElement('div'); 
         this.frame.style.overflow = 'hidden'; 
         this.frame.style.position = 'absolute'; 
 
-        this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();
+        this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();        
     },
 
     /** 
@@ -109,22 +131,7 @@
      */
     destroy: function() {
         if (this.imgDiv != null)  {
-            if (this.layerAlphaHack) {
-                // unregister the "load" handler
-                OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);                
-            }
-
-            // unregister the "load" and "error" handlers. Only the "error" handler if
-            // this.layerAlphaHack is true.
-            OpenLayers.Event.stopObservingElement(this.imgDiv);
-            
-            if (this.imgDiv.parentNode == this.frame) {
-                this.frame.removeChild(this.imgDiv);
-                this.imgDiv.map = null;
-            }
-            this.imgDiv.urls = null;
-            // abort any currently loading image
-            this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
+            this.removeImgDiv();
         }
         this.imgDiv = null;
         if ((this.frame != null) && (this.frame.parentNode == this.layer.div)) { 
@@ -142,7 +149,7 @@
         
         OpenLayers.Tile.prototype.destroy.apply(this, arguments);
     },
-
+    
     /**
      * Method: clone
      *
@@ -281,13 +288,8 @@
      *     position it correctly, and set its url.
      */
     renderTile: function() {
-        if (this.imgDiv == null) {
+        if (this.layer.async) {
             this.initImgDiv();
-        }
-
-        this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
-        
-        if (this.layer.async) {
             // Asyncronous image requests call the asynchronous getURL method
             // on the layer to fetch an image that covers 'this.bounds', in the scope of
             // 'this', setting the 'url' property of the layer itself, and running
@@ -297,12 +299,9 @@
             // syncronous image requests get the url and position the frame immediately,
             // and don't wait for an image request to come back.
           
-            // needed for changing to a different server for onload error
-            if (this.layer.url instanceof Array) {
-                this.imgDiv.urls = this.layer.url.slice();
-            }
-          
             this.url = this.layer.getURL(this.bounds);
+
+            this.initImgDiv();
           
             // position the frame immediately
             this.positionImage(); 
@@ -356,94 +355,129 @@
      * Creates the imgDiv property on the tile.
      */
     initImgDiv: function() {
-        
-        var offset = this.layer.imageOffset; 
-        var size = this.layer.getImageSize(this.bounds); 
-     
-        if (this.layerAlphaHack) {
-            this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null,
-                                                           offset,
-                                                           size,
-                                                           null,
-                                                           "relative",
-                                                           null,
-                                                           null,
-                                                           null,
-                                                           true);
-        } else {
-            this.imgDiv = OpenLayers.Util.createImage(null,
-                                                      offset,
-                                                      size,
-                                                      null,
-                                                      "relative",
-                                                      null,
-                                                      null,
-                                                      true);
-        }
-        
-        this.imgDiv.className = 'olTileImage';
+        if (this.imgDiv == null) {
+            var offset = this.layer.imageOffset; 
+            var size = this.layer.getImageSize(this.bounds); 
 
-        /* checkImgURL used to be used to called as a work around, but it
-           ended up hiding problems instead of solving them and broke things
-           like relative URLs. See discussion on the dev list:
-           http://openlayers.org/pipermail/dev/2007-January/000205.html
+            if (this.layerAlphaHack) {
+                this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null,
+                                                               offset,
+                                                               size,
+                                                               null,
+                                                               "relative",
+                                                               null,
+                                                               null,
+                                                               null,
+                                                               true);
+            } else {
+                this.imgDiv = OpenLayers.Util.createImage(null,
+                                                          offset,
+                                                          size,
+                                                          null,
+                                                          "relative",
+                                                          null,
+                                                          null,
+                                                          true);
+            }
 
-        OpenLayers.Event.observe( this.imgDiv, "load",
-            OpenLayers.Function.bind(this.checkImgURL, this) );
-        */
-        this.frame.style.zIndex = this.isBackBuffer ? 0 : 1;
-        this.frame.appendChild(this.imgDiv); 
-        this.layer.div.appendChild(this.frame); 
+            // needed for changing to a different server for onload error
+            if (this.layer.url instanceof Array) {
+                this.imgDiv.urls = this.layer.url.slice();
+            }
+      
+            this.imgDiv.className = 'olTileImage';
 
-        if(this.layer.opacity != null) {
-            
-            OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null, null,
-                                             null, null, null, 
-                                             this.layer.opacity);
-        }
+            /* checkImgURL used to be used to called as a work around, but it
+               ended up hiding problems instead of solving them and broke things
+               like relative URLs. See discussion on the dev list:
+               http://openlayers.org/pipermail/dev/2007-January/000205.html
 
-        // we need this reference to check back the viewRequestID
-        this.imgDiv.map = this.layer.map;
+            OpenLayers.Event.observe( this.imgDiv, "load",
+                OpenLayers.Function.bind(this.checkImgURL, this) );
+            */
+            this.frame.style.zIndex = this.isBackBuffer ? 0 : 1;
+            this.frame.appendChild(this.imgDiv); 
+            this.layer.div.appendChild(this.frame); 
 
-        //bind a listener to the onload of the image div so that we 
-        // can register when a tile has finished loading.
-        var onload = function() {
-            
-            //normally isLoading should always be true here but there are some 
-            // right funky conditions where loading and then reloading a tile
-            // with the same url *really*fast*. this check prevents sending 
-            // a 'loadend' if the msg has already been sent
-            //
-            if (this.isLoading) { 
-                this.isLoading = false; 
-                this.events.triggerEvent("loadend"); 
+            if(this.layer.opacity != null) {
+
+                OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null, null,
+                                                 null, null, null, 
+                                                 this.layer.opacity);
             }
-        };
+
+            // we need this reference to check back the viewRequestID
+            this.imgDiv.map = this.layer.map;
+
+            //bind a listener to the onload of the image div so that we 
+            // can register when a tile has finished loading.
+            var onload = function() {
+
+                //normally isLoading should always be true here but there are some 
+                // right funky conditions where loading and then reloading a tile
+                // with the same url *really*fast*. this check prevents sending 
+                // a 'loadend' if the msg has already been sent
+                //
+                if (this.isLoading) { 
+                    this.isLoading = false; 
+                    this.events.triggerEvent("loadend"); 
+                }
+            };
+
+            if (this.layerAlphaHack) { 
+                OpenLayers.Event.observe(this.imgDiv.childNodes[0], 'load', 
+                                         OpenLayers.Function.bind(onload, this));    
+            } else { 
+                OpenLayers.Event.observe(this.imgDiv, 'load', 
+                                     OpenLayers.Function.bind(onload, this)); 
+            } 
+
+
+            // Bind a listener to the onerror of the image div so that we
+            // can registere when a tile has finished loading with errors.
+            var onerror = function() {
+
+                // If we have gone through all image reload attempts, it is time
+                // to realize that we are done with this image. Since
+                // OpenLayers.Util.onImageLoadError already has taken care about
+                // the error, we can continue as if the image was loaded
+                // successfully.
+                if (this.imgDiv._attempts > OpenLayers.IMAGE_RELOAD_ATTEMPTS) {
+                    onload.call(this);
+                }
+            };
+            OpenLayers.Event.observe(this.imgDiv, "error",
+                                     OpenLayers.Function.bind(onerror, this));
+        }
         
-        if (this.layerAlphaHack) { 
-            OpenLayers.Event.observe(this.imgDiv.childNodes[0], 'load', 
-                                     OpenLayers.Function.bind(onload, this));    
-        } else { 
-            OpenLayers.Event.observe(this.imgDiv, 'load', 
-                                 OpenLayers.Function.bind(onload, this)); 
-        } 
+        this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
+    },
+
+    /**
+     * Method: removeImgDiv
+     * Removes the imgDiv from the DOM and stops listening to events on it.
+     */
+    removeImgDiv: function() {
+        // unregister the "load" and "error" handlers. Only the "error" handler if
+        // this.layerAlphaHack is true.
+        OpenLayers.Event.stopObservingElement(this.imgDiv);
         
+        if (this.imgDiv.parentNode == this.frame) {
+            this.frame.removeChild(this.imgDiv);
+            this.imgDiv.map = null;
+        }
+        this.imgDiv.urls = null;
 
-        // Bind a listener to the onerror of the image div so that we
-        // can registere when a tile has finished loading with errors.
-        var onerror = function() {
-
-            // If we have gone through all image reload attempts, it is time
-            // to realize that we are done with this image. Since
-            // OpenLayers.Util.onImageLoadError already has taken care about
-            // the error, we can continue as if the image was loaded
-            // successfully.
-            if (this.imgDiv._attempts > OpenLayers.IMAGE_RELOAD_ATTEMPTS) {
-                onload.call(this);
-            }
-        };
-        OpenLayers.Event.observe(this.imgDiv, "error",
-                                 OpenLayers.Function.bind(onerror, this));
+        var child = this.imgDiv.firstChild;
+        //check for children (alphaHack img or IFrame)
+        if (child) {
+            OpenLayers.Event.stopObservingElement(child);
+            this.imgDiv.removeChild(child);
+            delete child;
+        } else {
+            // abort any currently loading image
+            this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
+        }
     },
 
     /**

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Tile.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Tile.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Tile.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -94,8 +94,9 @@
      * bounds - {<OpenLayers.Bounds>}
      * url - {<String>}
      * size - {<OpenLayers.Size>}
+     * options - {Object}
      */   
-    initialize: function(layer, position, bounds, url, size) {
+    initialize: function(layer, position, bounds, url, size, options) {
         this.layer = layer;
         this.position = position.clone();
         this.bounds = bounds.clone();
@@ -106,6 +107,8 @@
         this.id = OpenLayers.Util.createUniqueID("Tile_");
         
         this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
+
+        OpenLayers.Util.extend(this, options);
     },
 
     /**

Modified: sandbox/tschaub/canvas/lib/OpenLayers/Util.js
===================================================================
--- sandbox/tschaub/canvas/lib/OpenLayers/Util.js	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/lib/OpenLayers/Util.js	2010-10-13 19:07:54 UTC (rev 10826)
@@ -1062,12 +1062,26 @@
     for(var i=0, len=pairs.length; i<len; ++i) {
         var keyValue = pairs[i].split('=');
         if (keyValue[0]) {
-            var key = decodeURIComponent(keyValue[0]);
-            var value = keyValue[1] || ''; //empty string if no value
 
-            //decode individual values (being liberal by replacing "+" with " ")
-            value = decodeURIComponent(value.replace(/\+/g, " ")).split(",");
+            var key = keyValue[0];
+            try {
+                key = decodeURIComponent(key);
+            } catch (err) {
+                key = unescape(key);
+            }
+            
+            // being liberal by replacing "+" with " "
+            var value = (keyValue[1] || '').replace(/\+/g, " ");
 
+            try {
+                value = decodeURIComponent(value);
+            } catch (err) {
+                value = unescape(value);
+            }
+            
+            // follow OGC convention of comma delimited values
+            value = value.split(",")
+
             //if there's only one value, do not return as array                    
             if (value.length == 1) {
                 value = value[0];

Modified: sandbox/tschaub/canvas/release-license.txt
===================================================================
--- sandbox/tschaub/canvas/release-license.txt	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/release-license.txt	2010-10-13 19:07:54 UTC (rev 10826)
@@ -1,3 +1,3 @@
 This license information is now available at:
-
+ 
 http://svn.openlayers.org/trunk/openlayers/license.txt

Modified: sandbox/tschaub/canvas/tests/Control/Measure.html
===================================================================
--- sandbox/tschaub/canvas/tests/Control/Measure.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Control/Measure.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -68,52 +68,161 @@
         
     }
 
-    function test_partial(t) {
-        t.plan(1);
+    function test_partial(t) {        
 
-        // set up
-
-        var map, layer, control, geometry, log;
-
-        map = new OpenLayers.Map("map", {units: "m"});
-
-        layer = new OpenLayers.Layer(null, {isBaseLayer: true});
-        map.addLayer(layer);
-
-        map.zoomToMaxExtent();
-
-        control = new OpenLayers.Control.Measure(OpenLayers.Handler.Path, {
-            partialDelay: null
+        t.plan(28);        
+        
+        var map = new OpenLayers.Map({
+            div: "map",
+            units: "m",
+            resolutions: [1],
+            layers: [
+                new OpenLayers.Layer(null, {
+                    isBaseLayer: true
+                })
+            ],
+            center: new OpenLayers.LonLat(0, 0)
         });
 
+        var log = [];
+        var control = new OpenLayers.Control.Measure(
+            OpenLayers.Handler.Path, {persist: true, 
+                eventListeners: {
+                    measurepartial: function(evt) {
+                        log.push(evt);
+                    },
+                    measure: function(evt){
+                        log.push(evt);
+                    }
+                }
+            }
+        );
         map.addControl(control);
         control.activate();
+        
+        
+        // convenience function to trigger mouse events
+        function trigger(type, x, y) {
+            map.events.triggerEvent(type, {
+                xy: new OpenLayers.Pixel(x, y)
+            })
+        };
+        
+        // delay in seconds
+        var delay = control.partialDelay / 1000;
+        
+        // establish first point
+        trigger("mousedown", 0, 0);
+        trigger("mouseup", 0, 0);
 
-        control.events.on({
-            "measurepartial": function(e) {
-                log.measure = e.measure;
-            }
-        });
+        
+        // a) move 10 pixels and click
+        trigger("mousemove", 0, 10);
+        trigger("mousedown", 0, 10);
+        trigger("mouseup", 0, 10);
+        
+        // confirm measurepartial is not fired before delay
+        t.eq(log.length, 0, "a) no event fired yet")
 
-        // test
+        t.delay_call( 
+            // wait for delay then confirm event was logged
+            delay, function() {
+                t.eq(log.length, 1, "a) event logged")
+                t.eq(log[0].type, "measurepartial", "a) event logged");
+                t.eq(log[0].measure, 10, "a) correct measure");
+                
+                // b) move 10 pixels and click
+                trigger("mousemove", 0, 20);
+                trigger("mousedown", 0, 20);
+                trigger("mouseup", 0, 20);
+                
+                // confirm measurepartial is not fired before delay
+                t.eq(log.length, 1, "b) no event fired yet")
+                
+            },
+            delay, function() {
+                t.eq(log.length, 2, "b) event logged");
+                t.eq(log[1].type, "measurepartial", "b) correct type");
+                t.eq(log[1].measure, 20, "b) correct measure");
 
-        geometry = new OpenLayers.Geometry.LineString([
-            new OpenLayers.Geometry.Point(1, 1),
-            new OpenLayers.Geometry.Point(2, 1)
-        ]);
+                // c) move 10 pixels and click
+                trigger("mousemove", 0, 30);
+                trigger("mousedown", 0, 30);
+                trigger("mouseup", 0, 30);
+            },
+            // wait for half delay and confirm event not logged
+            delay / 2, function() {
+                // confirm measurepartial is not fired before delay
+                t.eq(log.length, 2, "c) no event fired yet")
+            },
+            // wait for rest of delay and confirm event logged
+            delay / 2, function() {
+                t.eq(log.length, 3, "c) event logged");
+                t.eq(log[2].type, "measurepartial", "c) correct type");
+                t.eq(log[2].measure, 30, "c) correct measure");
+                
+                // d) move 10 pixels and click
+                trigger("mousemove", 0, 40);
+                trigger("mousedown", 0, 40);
+                trigger("mouseup", 0, 40);
 
-        log = {};
-        control.measurePartial(null, geometry);
-        geometry.components[1].x = 3;
-        t.delay_call(0.2, function() {
+                // confirm measurepartial is not fired before delay
+                t.eq(log.length, 3, "d) no event fired yet")
+                
+                // e) double click to finish
+                trigger("dblclick", 0, 40);
 
-            t.eq(log.measure, 1, "partial measure is correct");
+                t.eq(log.length, 4, "e) event logged");
+                t.eq(log[3].type, "measure", "e) correct type");
+                t.eq(log[3].measure, 40, "e) correct measure");                
+            },
+            // wait for rest of delay and confirm no measurepartial logged
+            delay, function() {
+                // confirm measurepartial is not fired after dblclick
+                t.eq(log.length, 4, "e) no additional event fired");
+                
+                // change to freehand mode and confirm synchronous event dispatch
+                control.handler.freehand = true;
+                // clear log
+                log = [];
+                
+                // f) establish first freehand point
+                trigger("mousedown", 0, 0);
+                t.eq(log.length, 0, "f) no event fired yet")
+                
+                // g) move 10 pixels
+                trigger("mousemove", 10, 0);
 
-            // tear down
-            map.destroy
-        });
-    };
+                t.eq(log.length, 1, "g) event logged");
+                t.eq(log[0].type, "measurepartial", "g) correct type");
+                t.eq(log[0].measure, 10, "g) correct measure");
+                
+                // h) move 10 pixels
+                trigger("mousemove", 20, 0);
 
+                t.eq(log.length, 2, "h) event logged");
+                t.eq(log[1].type, "measurepartial", "h) correct type");
+                t.eq(log[1].measure, 20, "h) correct measure");
+                
+                // i) mouse up to finish
+                trigger("mouseup", 20, 0);
+
+                t.eq(log.length, 3, "i) event logged");
+                t.eq(log[2].type, "measure", "i) correct type");
+                t.eq(log[2].measure, 20, "i) correct measure");
+                
+                // j) clean up
+                log = [];
+                map.destroy();
+            },
+            // wait for delay and confirm event not logged
+            delay, function() {
+                t.eq(log.length, 0, "j) no event fired after destroy");
+            }
+        );
+        
+    }
+    
   </script>
 </head>
 <body>

Modified: sandbox/tschaub/canvas/tests/Control/Panel.html
===================================================================
--- sandbox/tschaub/canvas/tests/Control/Panel.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Control/Panel.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -243,7 +243,7 @@
         panel.activate();
         var div = panel.div;
         panel.destroy();
-        t.ok(panel.div.innerHTML == "", 
+        t.eq(panel.div, null, 
             "Panel is not displayed after destroy without any active control");
         map.destroy();
     }

Modified: sandbox/tschaub/canvas/tests/Layer/WMS/Post.html
===================================================================
--- sandbox/tschaub/canvas/tests/Layer/WMS/Post.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Layer/WMS/Post.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -16,19 +16,20 @@
         t.plan( 2 );
 
         var url = "http://octo.metacarta.com/cgi-bin/mapserv";
+        var options = { unsupportedBrowsers: []};
         layer = new OpenLayers.Layer.WMS.Post(name, url, params);
 
-        t.ok(
-            layer.tileClass == OpenLayers.Tile.Image.IFrame,
-            "instantiate OpenLayers.Tile.Image.IFrame tiles.");
+        t.eq(
+            layer.usePost, true,
+            "Supported browsers use IFrame tiles.");
 
         layer.destroy();
 
         var options = { unsupportedBrowsers: [OpenLayers.Util.getBrowserName()]};
         layer = new OpenLayers.Layer.WMS.Post(name, url, params, options);
-        t.ok(
-            layer.tileClass == OpenLayers.Tile.Image,
-            "unsupported browser instantiate Image tiles.");
+        t.eq(
+            layer.usePost, false,
+            "unsupported browsers use Image tiles.");
         layer.destroy();
     }
 
@@ -49,8 +50,8 @@
         }
         else {
             t.ok(
-                tile instanceof OpenLayers.Tile.Image.IFrame,
-                "tile is an instance of OpenLayers.Tile.Image.IFrame");
+                tile.useIFrame !== undefined,
+                "tile is created with the OpenLayers.Tile.Image.IFrame mixin");
         }
         map.destroy();
 
@@ -73,8 +74,8 @@
         map.addLayer(layer);
         var tile2 = layer.addTile(bounds, pixel);
         t.ok(
-            tile2 instanceof OpenLayers.Tile.Image.IFrame,
-            "supported browser: tile is an instance of Tile.Image.IFrame");
+            tile2.createIFrame,
+            "supported browser: tile is created with the Tile.Image.IFrame mixin");
         map.destroy();
     }
 

Modified: sandbox/tschaub/canvas/tests/Strategy/Fixed.html
===================================================================
--- sandbox/tschaub/canvas/tests/Strategy/Fixed.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Strategy/Fixed.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -153,7 +153,7 @@
         ];
 
         // call merge with a mocked up response
-        strategy.merge({features: features});
+        strategy.merge(new OpenLayers.Projection("EPSG:900913"), {features: features});
         
         // confirm that the original features were destroyed
         t.eq(layer.features.length, 2, "old features destroyed");
@@ -177,7 +177,7 @@
         ];
         
         // call merge again with mocked up response
-        strategy.merge({features: features});
+        strategy.merge(new OpenLayers.Projection("EPSG:900913"), {features: features});
 
         // test that feature geometries have not been transformed
         t.geom_eq(layer.features[0].geometry, features[0].geometry, "[same proj] feature 0 geometry not transformed");
@@ -185,6 +185,56 @@
         
     }
 
+    function test_load(t) {
+        t.plan(4);
+
+        // set up
+
+        var log;
+
+        var map = new OpenLayers.Map({
+            div: "map",
+            projection: new OpenLayers.Projection("EPSG:900913"),
+            layers: [new OpenLayers.Layer("", {isBaseLayer: true})]
+        });
+
+        var response = new OpenLayers.Protocol.Response();
+
+        var strategy = new OpenLayers.Strategy.Fixed({
+            merge: function(p, r) {
+                log = {scope: this, projection: p, response: r};
+            }
+        });
+
+        var layer = new OpenLayers.Layer.Vector("vector", {
+            strategies: [strategy],
+            protocol: {
+                read: function(o) {
+                    o.callback.call(o.scope, response);
+                }
+            }
+        });
+
+        map.addLayer(layer);
+
+        // test
+
+        strategy.load();
+
+        // verify that the callback is correctly bound
+        t.ok(log !== undefined,
+             "merge was called");
+        t.ok(log.scope == strategy,
+             "merge called with expected scope");
+        t.eq(log.projection.getCode(), map.getProjectionObject().getCode(),
+             "merge called the map projection as the first arg");
+        t.ok(log.response == response,
+             "merge called with response as the first arg");
+
+        // tear down
+
+        map.destroy();
+    }
   </script>
 </head>
 <body>

Modified: sandbox/tschaub/canvas/tests/Symbolizer/Line.html
===================================================================
--- sandbox/tschaub/canvas/tests/Symbolizer/Line.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Symbolizer/Line.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -24,6 +24,16 @@
         t.eq(clone.foo, "bar", "clone copies properties");
         
     }
+    
+    function test_defaults(t) {
+        t.plan(5);
+        var symbolizer = new OpenLayers.Symbolizer.Line();
+        t.ok(symbolizer.strokeColor === undefined, "no default strokeColor");
+        t.ok(symbolizer.strokeOpacity === undefined, "no default strokeOpacity");
+        t.ok(symbolizer.strokeWidth === undefined, "no default strokeWidth");
+        t.ok(symbolizer.strokeLinecap === undefined, "no default strokeLinecap");
+        t.ok(symbolizer.strokeDashstyle === undefined, "no default strokeDashstyle");
+    }
 
 
     </script> 

Modified: sandbox/tschaub/canvas/tests/Symbolizer/Point.html
===================================================================
--- sandbox/tschaub/canvas/tests/Symbolizer/Point.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Symbolizer/Point.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -25,6 +25,26 @@
         
     }
 
+    function test_defaults(t) {
+        t.plan(16);
+        var symbolizer = new OpenLayers.Symbolizer.Point();
+        t.ok(symbolizer.strokeColor === undefined, "no default strokeColor");
+        t.ok(symbolizer.strokeOpacity === undefined, "no default strokeOpacity");
+        t.ok(symbolizer.strokeWidth === undefined, "no default strokeWidth");
+        t.ok(symbolizer.strokeLinecap === undefined, "no default strokeLinecap");
+        t.ok(symbolizer.strokeDashstyle === undefined, "no default strokeDashstyle");
+        t.ok(symbolizer.fillColor === undefined, "no default fillColor");
+        t.ok(symbolizer.fillOpacity === undefined, "no default fillOpacity");
+        t.ok(symbolizer.pointRadius === undefined, "no default pointRadius");
+        t.ok(symbolizer.externalGraphic === undefined, "no default externalGraphic");
+        t.ok(symbolizer.graphicWidth === undefined, "no default graphicWidth");
+        t.ok(symbolizer.graphicHeight === undefined, "no default graphicHeight");
+        t.ok(symbolizer.graphicOpacity === undefined, "no default graphicOpacity");
+        t.ok(symbolizer.graphicXOffset === undefined, "no default graphicXOffset");
+        t.ok(symbolizer.graphicYOffset === undefined, "no default graphicYOffset");
+        t.ok(symbolizer.rotation === undefined, "no default rotation");
+        t.ok(symbolizer.graphicName === undefined, "no default graphicName");
+    }
 
     </script> 
 </head>

Modified: sandbox/tschaub/canvas/tests/Symbolizer/Polygon.html
===================================================================
--- sandbox/tschaub/canvas/tests/Symbolizer/Polygon.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Symbolizer/Polygon.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -25,7 +25,19 @@
         
     }
 
+    function test_defaults(t) {
+        t.plan(7);
+        var symbolizer = new OpenLayers.Symbolizer.Polygon();
+        t.ok(symbolizer.strokeColor === undefined, "no default strokeColor");
+        t.ok(symbolizer.strokeOpacity === undefined, "no default strokeOpacity");
+        t.ok(symbolizer.strokeWidth === undefined, "no default strokeWidth");
+        t.ok(symbolizer.strokeLinecap === undefined, "no default strokeLinecap");
+        t.ok(symbolizer.strokeDashstyle === undefined, "no default strokeDashstyle");
+        t.ok(symbolizer.fillColor === undefined, "no default fillColor");
+        t.ok(symbolizer.fillOpacity === undefined, "no default fillOpacity");
+    }
 
+
     </script> 
 </head>
 <body></body> 

Modified: sandbox/tschaub/canvas/tests/Symbolizer/Text.html
===================================================================
--- sandbox/tschaub/canvas/tests/Symbolizer/Text.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Symbolizer/Text.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -25,7 +25,17 @@
         
     }
 
+    function test_defaults(t) {
+        t.plan(5);
+        var symbolizer = new OpenLayers.Symbolizer.Point();
+        t.ok(symbolizer.label === undefined, "no default label");
+        t.ok(symbolizer.fontFamily === undefined, "no default fontFamily");
+        t.ok(symbolizer.fontSize === undefined, "no default fontSize");
+        t.ok(symbolizer.fontWeight === undefined, "no default fontWeight");
+        t.ok(symbolizer.fontStyle === undefined, "no default fontStyle");
+    }
 
+
     </script> 
 </head>
 <body></body> 

Modified: sandbox/tschaub/canvas/tests/Tile/Image/IFrame.html
===================================================================
--- sandbox/tschaub/canvas/tests/Tile/Image/IFrame.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Tile/Image/IFrame.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -14,66 +14,48 @@
     var name     = "OpenaLayers WMS";
     var wmsUrl   = "http://labs.metacarta.com/wms/vmap0?";
     
-    function test_Tile_Image_IFrame_constructor (t) {
-        t.plan( 2 );
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
-        var tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
-        
-        t.ok( tile instanceof OpenLayers.Tile.Image.IFrame, "new OpenLayers.Tile.Image.IFrame returns Tile object" );
-        t.eq( tile.layerAlphaHack, false, "layerAlphaHack is set to false.");
-    
-        layer.destroy();
-    }
-
-    function test_Tile_Image_IFrame_destroy (t) {
-        t.plan( 2 );
+    function test_Tile_Image_IFrame_create (t) {
+        t.plan( 3 );
         map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
+        var bar = new Array(205).join("1234567890");
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic', foo: bar}, {tileOptions: {maxGetUrlLength: 2048}}); 
         map.addLayer(layer);
 
-        var tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, null, size);
+        var tile = layer.addTile(bounds, position);
         tile.renderTile();
         tile.positionImage();
+        t.eq(tile.imgDiv.firstChild.nodeName.toLowerCase(), "iframe", "IFrame used for long URL");
         
+        layer.mergeNewParams({foo: null});
+        tile.renderTile();
+        tile.positionImage();
+        t.eq(tile.imgDiv.nodeName.toLowerCase(), "img", "IMG used for short URL");
+        
+        tile.maxGetUrlLength = 0;
+        tile.renderTile();
+        tile.positionImage();
+        t.eq(tile.imgDiv.firstChild.nodeName.toLowerCase(), "iframe", "IFrame used when maxGetUrlLength is 0");
+        
         tile.destroy();
-        t.eq( tile.imgDiv, null, "IFrame successfully removed from DOM");
-        t.eq( tile.frame, null, "Event div successfully removed from DOM");
-
+        layer.destroy();
         map.destroy();
     }
 
-    function test_Tile_Image_IFrame_clone (t) {
-        t.plan( 9 );
-        
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
-        tile  = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
-        tile.iFrame = {};
-        var clone = tile.clone();
-        
-        t.ok( clone instanceof OpenLayers.Tile.Image.IFrame, "clone is a Tile.Image.IFrame object" );
-        t.ok( clone.layer == layer, "clone.layer is set correctly");
-        t.ok( clone.position.equals(position), "clone.position is set correctly");
-        t.ok( clone.bounds.equals(bounds), "clone.bounds is set correctly");
-        t.eq( clone.url, url, "clone.url is set correctly");
-        t.ok( clone.size.equals(size), "clone.size is set correctly");
-        t.ok( clone.frame, "clone has a frame");
-        t.ok( clone.frame != tile.frame, "clone's frame is a new one");
-        t.ok( clone.imgDiv == null, "clone's imgDiv was not copied");
-    }
-    
     function test_Tile_Image_IFrame_clear (t) {
         t.plan( 1 );
         
         map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
-        tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
+        tile = layer.addTile(bounds, position);
         tile.draw();
         tile.clear();
 
-        t.ok(
-            tile.imgDiv.firstChild.nodeName != "IFRAME",
+        t.eq(
+            tile.imgDiv.firstChild.nodeName.toLowerCase(), "div",
             "IFrame successfully removed from DOM");
+        tile.destroy();
+        layer.destroy();
         map.destroy();
     }
 
@@ -81,9 +63,10 @@
         t.plan( 4 );
 
         map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
-        tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
+        tile = layer.addTile(bounds, position);
+        tile.url = layer.getURL(bounds);
         tile.initImgDiv();
 
         if(isMozilla) {
@@ -103,9 +86,9 @@
         t.plan( 3 );
 
         map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
-        var tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
+        var tile = layer.addTile(bounds, position);
         tile.renderTile();
         var imgDiv = tile.imgDiv;
         var iFrame    = imgDiv.firstChild;
@@ -128,9 +111,9 @@
         t.plan( 8 );
         
         map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS.Post(name, wmsUrl, {layers: 'basic'}); 
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
-        var tile = new OpenLayers.Tile.Image.IFrame(layer, position, bounds, url, size);
+        var tile = layer.addTile(bounds, position);
         var iFrame = tile.createIFrame();
 
         var id = tile.id+'_iFrame';
@@ -161,15 +144,17 @@
             SRS: "EPSG:4326", BBOX: [1,2,3,4],
             WIDTH: String(size.w), HEIGHT: String(size.h)
         };
-        var newLayer = new OpenLayers.Layer.WMS.Post("Name",
-                                         "http://labs.metacarta.com/TESTURL",
-                                         tParams,
-                                         {tileSize: size});  
+        var newLayer = new OpenLayers.Layer.WMS("Name",
+                     "http://labs.metacarta.com/TESTURL",
+                     tParams,
+                     {tileSize: size, tileOptions: {maxGetUrlLength: 0}});  
         map = new OpenLayers.Map('map'); 
         map.addLayer(newLayer);  
-        tile = new OpenLayers.Tile.Image.IFrame(newLayer, position, bounds, url, size);
+        tile = newLayer.addTile(bounds, position);
+        tile.url = newLayer.getURL(bounds);
         tile.initImgDiv();
 
+        tile.url = newLayer.getURL(bounds);
         var form = tile.createRequestForm();
         if(isMozilla) {
             t.ok( form instanceof HTMLElement, "created html form successfully.");
@@ -187,25 +172,13 @@
         t.eq( form.target, tile.id+'_iFrame', "form target correctly set.");
         t.eq( form.action, url, "form action correctly set.");
 
-        var contain  = true;
+        var formParams = {};
         var children = form.childNodes;
-        for(var par in newLayer.params) {
-            var test = false;
-            
-            for(var i=0; i<children.length; i++) {
-                if(children.item(i).name == par && children.item(i).value == newLayer.params[par]) {
-                    test = true;
-                    break;
-                }
-            }
-
-            if(test == false) {
-                contain = false;
-                break;
-            }
-
+        for(var i=0; i<form.childNodes.length; i++) {
+            formParams[children[i].name] = children[i].value
         }
-        t.eq( contain, true, "html form elements equal layer's parameters.");
+        newLayer.params.BBOX = newLayer.params.BBOX.join(",");
+        t.eq(newLayer.params, formParams, "html form elements equal layer's parameters.");
 
         tile.draw();
         tile.clear();
@@ -214,7 +187,9 @@
             tile.imgDiv.firstChild.nodeName == "IFRAME",
             "Iframe has been reinserted properly"
         );
-
+        
+        tile.destroy();
+        newLayer.destroy();
         map.destroy();
     }
 </script>

Modified: sandbox/tschaub/canvas/tests/Tile/Image.html
===================================================================
--- sandbox/tschaub/canvas/tests/Tile/Image.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Tile/Image.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -87,6 +87,29 @@
         t.ok( clone.imgDiv == null, "clone's imgDiv was not copied");
     }
     
+    function test_Tile_Image_IFrame_viewRequestID (t) {
+        t.plan( 2 );
+        var map   = new OpenLayers.Map('map');
+        var layer = new OpenLayers.Layer.WMS(
+            "Name",
+            "http://labs.metacarta.com/TESTURL?",
+            {layers: 'basic'}
+        ); 
+        map.addLayer(layer);
+
+        var position = new OpenLayers.Pixel(20,30);
+        var bounds = new OpenLayers.Bounds(1,2,3,4);
+        tile = layer.addTile(bounds, position);
+        tile.renderTile();
+        t.eq(tile.imgDiv.viewRequestID, map.viewRequestID, "viewRequestID correct after renderTile");
+        map.viewRequestID++;
+        tile.renderTile();
+        t.eq(tile.imgDiv.viewRequestID, map.viewRequestID, "viewRequestID correct after subsequent renderTile");
+        tile.destroy();
+        layer.destroy();
+        map.destroy();
+    }
+
     function test_Tile_Image_draw (t) {
         t.plan( 7 );
 

Modified: sandbox/tschaub/canvas/tests/Util.html
===================================================================
--- sandbox/tschaub/canvas/tests/Util.html	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tests/Util.html	2010-10-13 19:07:54 UTC (rev 10826)
@@ -1,5 +1,6 @@
 <html>
 <head>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
   <script>
     var custom$ = function() {};
     window.$ = custom$;
@@ -894,7 +895,7 @@
     }
 
     function test_Util_getParameters(t) {
-        t.plan(13);
+        t.plan(17);
 
         t.eq(OpenLayers.Util.getParameters('http://www.example.com'), {},
              "getParameters works when args = ''");
@@ -952,6 +953,18 @@
         };
         var str = OpenLayers.Util.getParameterString(obj);
         t.eq(OpenLayers.Util.getParameters("?" + str), obj, "round tripped parameters");
+        
+        // try some oddly encoded strings
+        var url = "http://example.com/?C%E9sar=C%E9sar+Ch%E1vez";
+        var obj = OpenLayers.Util.getParameters(url);
+        t.ok("César" in obj, "got proper key from C%E9sar");
+        t.eq(obj["César"], "César Chávez", "got proper value from C%E9sar+Ch%E1vez");
+        
+        // try some properly encoded strings
+        var url = "http://example.com/?C%C3%A9sar=C%C3%A9sar+Ch%C3%A1vez";
+        var obj = OpenLayers.Util.getParameters(url);
+        t.ok("César" in obj, "got proper key from C%C3%A9sar");
+        t.eq(obj["César"], "César Chávez", "got proper value from C%E9sar+Ch%E1vez");
 
     }
 

Modified: sandbox/tschaub/canvas/tools/mergejs.py
===================================================================
--- sandbox/tschaub/canvas/tools/mergejs.py	2010-10-13 19:04:29 UTC (rev 10825)
+++ sandbox/tschaub/canvas/tools/mergejs.py	2010-10-13 19:07:54 UTC (rev 10826)
@@ -94,6 +94,7 @@
 
         [exclude]
         3rd/logger.js
+        exclude/this/dir
 
     All headings are required.
 
@@ -122,6 +123,20 @@
         self.include =  lines[lines.index("[include]") + 1:lines.index("[exclude]")]
         self.exclude =  lines[lines.index("[exclude]") + 1:]
 
+def undesired(filepath, excludes):
+    # exclude file if listed
+    exclude = filepath in excludes
+    if not exclude:
+        # check if directory is listed
+        for excludepath in excludes:
+            if not excludepath.endswith("/"):
+                excludepath += "/"
+            if filepath.startswith(excludepath):
+                exclude = True
+                break
+    return exclude
+            
+
 def run (sourceDirectory, outputFilename = None, configFile = None):
     cfg = None
     if configFile:
@@ -138,7 +153,7 @@
                 if cfg and cfg.include:
                     if filepath in cfg.include or filepath in cfg.forceFirst:
                         allFiles.append(filepath)
-                elif (not cfg) or (filepath not in cfg.exclude):
+                elif (not cfg) or (not undesired(filepath, cfg.exclude)):
                     allFiles.append(filepath)
 
     ## Header inserted at the start of each file in the output



More information about the Commits mailing list