[fusion-commits] r2226 - trunk/lib/OpenLayers

svn_fusion at osgeo.org svn_fusion at osgeo.org
Fri Sep 10 14:35:41 EDT 2010


Author: madair
Date: 2010-09-10 18:35:41 +0000 (Fri, 10 Sep 2010)
New Revision: 2226

Modified:
   trunk/lib/OpenLayers/OpenLayers.js
Log:
closes #406: Update OpenLayers to v2.10

Modified: trunk/lib/OpenLayers/OpenLayers.js
===================================================================
--- trunk/lib/OpenLayers/OpenLayers.js	2010-09-10 17:12:53 UTC (rev 2225)
+++ trunk/lib/OpenLayers/OpenLayers.js	2010-09-10 18:35:41 UTC (rev 2226)
@@ -1,101 +1,102 @@
-/*
-
-  OpenLayers.js -- OpenLayers Map Viewer Library
-
-  Copyright 2005-2008 MetaCarta, Inc., released under the Clear BSD license.
-  Please see http://svn.openlayers.org/trunk/openlayers/license.txt
-  for the full text of the license.
-
-  Includes compressed code under the following licenses:
-
-  (For uncompressed versions of the code used please see the
-  OpenLayers SVN repository: <http://openlayers.org/>)
-
-*/
-
-/* Contains portions of Prototype.js:
- *
- * Prototype JavaScript framework, version 1.4.0
- *  (c) 2005 Sam Stephenson <sam at conio.net>
- *
- *  Prototype is freely distributable under the terms of an MIT-style license.
- *  For details, see the Prototype web site: http://prototype.conio.net/
- *
- *--------------------------------------------------------------------------*/
-
-/**  
-*  
-*  Contains portions of Rico <http://openrico.org/>
-* 
-*  Copyright 2005 Sabre Airline Solutions  
-*  
-*  Licensed under the Apache License, Version 2.0 (the "License"); you
-*  may not use this file except in compliance with the License. You
-*  may obtain a copy of the License at
-*  
-*         http://www.apache.org/licenses/LICENSE-2.0  
-*  
-*  Unless required by applicable law or agreed to in writing, software
-*  distributed under the License is distributed on an "AS IS" BASIS,
-*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-*  implied. See the License for the specific language governing
-*  permissions and limitations under the License. 
-*
-**/
-
-/**
- * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
- * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- */
-
-/**
- * Contains portions of Gears <http://code.google.com/apis/gears/>
- *
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. Neither the name of Google Inc. nor the names of its contributors may be
- *     used to endorse or promote products derived from this software without
- *     specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Sets up google.gears.*, which is *the only* supported way to access Gears.
- *
- * Circumvent this file at your own risk!
- *
- * In the future, Gears may automatically define google.gears.* without this
- * file. Gears may use these objects to transparently fix bugs and compatibility
- * issues. Applications that use the code below will continue to work seamlessly
- * when that happens.
- */
+/*
+
+  OpenLayers.js -- OpenLayers Map Viewer Library
+
+  Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
+  license. Please see http://svn.openlayers.org/trunk/openlayers/license.txt
+  for the full text of the license.
+
+  Includes compressed code under the following licenses:
+
+  (For uncompressed versions of the code used please see the
+  OpenLayers SVN repository: <http://openlayers.org/>)
+
+*/
+
+/* Contains portions of Prototype.js:
+ *
+ * Prototype JavaScript framework, version 1.4.0
+ *  (c) 2005 Sam Stephenson <sam at conio.net>
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+ *--------------------------------------------------------------------------*/
+
+/**  
+*  
+*  Contains portions of Rico <http://openrico.org/>
+* 
+*  Copyright 2005 Sabre Airline Solutions  
+*  
+*  Licensed under the Apache License, Version 2.0 (the "License"); you
+*  may not use this file except in compliance with the License. You
+*  may obtain a copy of the License at
+*  
+*         http://www.apache.org/licenses/LICENSE-2.0  
+*  
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+*  implied. See the License for the specific language governing
+*  permissions and limitations under the License. 
+*
+**/
+
+/**
+ * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
+ * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+/**
+ * Contains portions of Gears <http://code.google.com/apis/gears/>
+ *
+ * Copyright 2007, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *  3. Neither the name of Google Inc. nor the names of its contributors may be
+ *     used to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sets up google.gears.*, which is *the only* supported way to access Gears.
+ *
+ * Circumvent this file at your own risk!
+ *
+ * In the future, Gears may automatically define google.gears.* without this
+ * file. Gears may use these objects to transparently fix bugs and compatibility
+ * issues. Applications that use the code below will continue to work seamlessly
+ * when that happens.
+ */
 /* ======================================================================
     OpenLayers/SingleFile.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 var OpenLayers = {
@@ -107,8 +108,9 @@
     OpenLayers.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /* 
@@ -216,6 +218,7 @@
             "OpenLayers/Layer/EventPane.js",
             "OpenLayers/Layer/FixedZoomLevels.js",
             "OpenLayers/Layer/Google.js",
+            "OpenLayers/Layer/Google/v3.js",
             "OpenLayers/Layer/VirtualEarth.js",
             "OpenLayers/Layer/Yahoo.js",
             "OpenLayers/Layer/HTTPRequest.js",
@@ -233,6 +236,7 @@
             "OpenLayers/Layer/WMS.js",
             "OpenLayers/Layer/WMS/Untiled.js",
             "OpenLayers/Layer/WMS/Post.js",
+            "OpenLayers/Layer/WMTS.js",
             "OpenLayers/Layer/ArcIMS.js",
             "OpenLayers/Layer/GeoRSS.js",
             "OpenLayers/Layer/Boxes.js",
@@ -287,8 +291,10 @@
             "OpenLayers/Control/NavigationHistory.js",
             "OpenLayers/Control/Measure.js",
             "OpenLayers/Control/WMSGetFeatureInfo.js",
+            "OpenLayers/Control/WMTSGetFeatureInfo.js",
             "OpenLayers/Control/Graticule.js",
             "OpenLayers/Control/TransformFeature.js",
+            "OpenLayers/Control/SLDSelect.js",
             "OpenLayers/Geometry.js",
             "OpenLayers/Geometry/Rectangle.js",
             "OpenLayers/Geometry/Collection.js",
@@ -309,6 +315,7 @@
             "OpenLayers/Layer/Vector.js",
             "OpenLayers/Layer/Vector/RootContainer.js",
             "OpenLayers/Strategy.js",
+            "OpenLayers/Strategy/Filter.js",
             "OpenLayers/Strategy/Fixed.js",
             "OpenLayers/Strategy/Cluster.js",
             "OpenLayers/Strategy/Paging.js",
@@ -333,10 +340,12 @@
             "OpenLayers/Layer/PointTrack.js",
             "OpenLayers/Layer/GML.js",
             "OpenLayers/Style.js",
+            "OpenLayers/Style2.js",
             "OpenLayers/StyleMap.js",
             "OpenLayers/Rule.js",
             "OpenLayers/Format.js",
             "OpenLayers/Format/XML.js",
+            "OpenLayers/Format/Context.js",
             "OpenLayers/Format/ArcXML.js",
             "OpenLayers/Format/ArcXML/Features.js",
             "OpenLayers/Format/GML.js",
@@ -364,6 +373,9 @@
             "OpenLayers/Format/SLD.js",
             "OpenLayers/Format/SLD/v1.js",
             "OpenLayers/Format/SLD/v1_0_0.js",
+            "OpenLayers/Format/OWSCommon/v1.js",
+            "OpenLayers/Format/OWSCommon/v1_0_0.js",
+            "OpenLayers/Format/OWSCommon/v1_1_0.js",
             "OpenLayers/Format/CSWGetDomain.js",
             "OpenLayers/Format/CSWGetDomain/v2_0_2.js",
             "OpenLayers/Format/CSWGetRecords.js",
@@ -387,11 +399,14 @@
             "OpenLayers/Format/WMSCapabilities/v1_3.js",
             "OpenLayers/Format/WMSCapabilities/v1_3_0.js",
             "OpenLayers/Format/WMSGetFeatureInfo.js",
-            "OpenLayers/Format/OWSCommon/v1_1_0.js",
             "OpenLayers/Format/SOSCapabilities.js",
             "OpenLayers/Format/SOSCapabilities/v1_0_0.js",
             "OpenLayers/Format/SOSGetObservation.js",
             "OpenLayers/Format/SOSGetFeatureOfInterest.js",
+            "OpenLayers/Format/OWSContext.js",
+            "OpenLayers/Format/OWSContext/v0_3_1.js",
+            "OpenLayers/Format/WMTSCapabilities.js",
+            "OpenLayers/Format/WMTSCapabilities/v1_0_0.js",
             "OpenLayers/Layer/WFS.js",
             "OpenLayers/Control/GetFeature.js",
             "OpenLayers/Control/MouseToolbar.js",
@@ -402,6 +417,12 @@
             "OpenLayers/Control/ZoomOut.js",
             "OpenLayers/Control/ZoomPanel.js",
             "OpenLayers/Control/EditingToolbar.js",
+            "OpenLayers/Symbolizer.js",
+            "OpenLayers/Symbolizer/Point.js",
+            "OpenLayers/Symbolizer/Line.js",
+            "OpenLayers/Symbolizer/Polygon.js",
+            "OpenLayers/Symbolizer/Text.js",
+            "OpenLayers/Symbolizer/Raster.js",
             "OpenLayers/Lang.js",
             "OpenLayers/Lang/en.js"
         ); // etc.
@@ -434,13 +455,14 @@
 /**
  * Constant: VERSION_NUMBER
  */
-OpenLayers.VERSION_NUMBER="$Revision$";
+OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision$";
 /* ======================================================================
     OpenLayers/Util.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -490,7 +512,7 @@
  * Maintain existing definition of $.
  */
 if(typeof window.$  === "undefined") {
-    window.$ = OpenLayers.Util.getElement;
+    //window.$ = OpenLayers.Util.getElement;
 }
 
 /**
@@ -1333,22 +1355,45 @@
 OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};
 
 /**
- * Function: distVincenty
+ * Function: deg
+ *
+ * Parameters:
+ * x - {Float}
+ *
+ * Returns:
+ * {Float}
+ */
+OpenLayers.Util.deg = function(x) {return x*180/Math.PI;};
+
+/**
+ * Property: VincentyConstants
+ * {Object} Constants for Vincenty functions.
+ */
+OpenLayers.Util.VincentyConstants = {
+    a: 6378137,
+    b: 6356752.3142,
+    f: 1/298.257223563
+};
+
+/**
+ * APIFunction: distVincenty
  * Given two objects representing points with geographic coordinates, this
  *     calculates the distance between those points on the surface of an
  *     ellipsoid.
- * 
+ *
  * Parameters:
  * p1 - {<OpenLayers.LonLat>} (or any object with both .lat, .lon properties)
  * p2 - {<OpenLayers.LonLat>} (or any object with both .lat, .lon properties)
- * 
+ *
  * Returns:
  * {Float} The distance (in km) between the two input points as measured on an
  *     ellipsoid.  Note that the input point objects must be in geographic
  *     coordinates (decimal degrees) and the return distance is in kilometers.
  */
-OpenLayers.Util.distVincenty=function(p1, p2) {
-    var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;
+OpenLayers.Util.distVincenty = function(p1, p2) {
+    var ct = OpenLayers.Util.VincentyConstants;
+    var a = ct.a, b = ct.b, f = ct.f;
+
     var L = OpenLayers.Util.rad(p2.lon - p1.lon);
     var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));
     var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));
@@ -1387,6 +1432,68 @@
 };
 
 /**
+ * APIFunction: destinationVincenty
+ * Calculate destination point given start point lat/long (numeric degrees),
+ * bearing (numeric degrees) & distance (in m).
+ * Adapted from Chris Veness work, see
+ * http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html
+ *
+ * Parameters:
+ * lonlat  - {<OpenLayers.LonLat>} (or any object with both .lat, .lon
+ *     properties) The start point.
+ * brng     - {Float} The bearing (degrees).
+ * distance - {Float} The ground distance (meters).
+ *
+ * Returns:
+ * {<OpenLayers.LonLat>} The destination point.
+ */
+OpenLayers.Util.destinationVincenty = function(lonlat, brng, dist) {
+    var u = OpenLayers.Util;
+    var ct = u.VincentyConstants;
+    var a = ct.a, b = ct.b, f = ct.f;
+
+    var lon1 = lonlat.lon;
+    var lat1 = lonlat.lat;
+
+    var s = dist;
+    var alpha1 = u.rad(brng);
+    var sinAlpha1 = Math.sin(alpha1);
+    var cosAlpha1 = Math.cos(alpha1);
+
+    var tanU1 = (1-f) * Math.tan(u.rad(lat1));
+    var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
+    var sigma1 = Math.atan2(tanU1, cosAlpha1);
+    var sinAlpha = cosU1 * sinAlpha1;
+    var cosSqAlpha = 1 - sinAlpha*sinAlpha;
+    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
+    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
+    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
+
+    var sigma = s / (b*A), sigmaP = 2*Math.PI;
+    while (Math.abs(sigma-sigmaP) > 1e-12) {
+        var cos2SigmaM = Math.cos(2*sigma1 + sigma);
+        var sinSigma = Math.sin(sigma);
+        var cosSigma = Math.cos(sigma);
+        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+            B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
+        sigmaP = sigma;
+        sigma = s / (b*A) + deltaSigma;
+    }
+
+    var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
+    var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
+        (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
+    var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
+    var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
+    var L = lambda - (1-C) * f * sinAlpha *
+        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
+
+    var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing
+
+    return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));
+};
+
+/**
  * Function: getParameters
  * Parse the parameters from a URL or from the current page itself into a 
  *     JavaScript Object. Note that parameter values with commas are separated
@@ -2126,7 +2233,7 @@
     if( coordinatedegrees < 10 ) {
         coordinatedegrees = "0" + coordinatedegrees;
     }
-    var str = coordinatedegrees + " ";  //get degree symbol here somehow for SVG/VML labelling
+    var str = coordinatedegrees + "\u00B0";
 
     if (dmsOption.indexOf('dm') >= 0) {
         if( coordinateminutes < 10 ) {
@@ -2154,8 +2261,9 @@
     OpenLayers/Console.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -2403,8 +2511,9 @@
     OpenLayers/BaseTypes.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -2924,7 +3033,7 @@
      *     Array.prototype.filter extension to the ECMA-262 standard.  Where
      *     available, Array.prototype.filter will be used.
      *
-     * Based on well known example from http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter
+     * Based on well known example from http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter
      *
      * Parameters:
      * array - {Array} The array to be filtered.  This array is not mutated.
@@ -2964,12 +3073,133 @@
     }
     
 };
+
+/**
+ * Namespace: OpenLayers.Date
+ * Contains implementations of Date.parse and date.toISOString that match the 
+ *     ECMAScript 5 specification for parsing RFC 3339 dates.
+ *     http://tools.ietf.org/html/rfc3339
+ */
+OpenLayers.Date = {
+    
+    /**
+     * APIMethod: toISOString
+     * Generates a string representing a date.  The format of the string follows 
+     *     the profile of ISO 8601 for date and time on the Internet (see 
+     *     http://tools.ietf.org/html/rfc3339).  If the toISOString method is 
+     *     available on the Date prototype, that is used.  The toISOString
+     *     method for Date instances is defined in ECMA-262.
+     *
+     * Parameters:
+     * date - {Date} A date object.
+     *
+     * Returns:
+     * {String} A string representing the date (e.g. 
+     *     "2010-08-07T16:58:23.123Z").  If the date does not have a valid time
+     *     (i.e. isNaN(date.getTime())) this method returns the string "Invalid
+     *     Date".  The ECMA standard says the toISOString method should throw
+     *     RangeError in this case, but Firefox returns a string instead.  For
+     *     best results, use isNaN(date.getTime()) to determine date validity
+     *     before generating date strings.  
+     */
+    toISOString: (function() {
+        if ("toISOString" in Date.prototype) {
+            return function(date) {
+                return date.toISOString();
+            }
+        } else {
+            function pad(num, len) {
+                var str = num + "";
+                while (str.length < len) {
+                    str = "0" + str;
+                }
+                return str;
+            }
+            return function(date) {
+                var str;
+                if (isNaN(date.getTime())) {
+                    // ECMA-262 says throw RangeError, Firefox returns 
+                    // "Invalid Date"
+                    str = "Invalid Date";
+                } else {
+                    str = 
+                        date.getUTCFullYear() + "-" +
+                        pad(date.getUTCMonth() + 1, 2) + "-" +
+                        pad(date.getUTCDate(), 2) + "T" +
+                        pad(date.getUTCHours(), 2) + ":" +
+                        pad(date.getUTCMinutes(), 2) + ":" +
+                        pad(date.getUTCSeconds(), 2) + "." +
+                        pad(date.getUTCMilliseconds(), 3) + "Z";
+                }
+                return str;
+            }
+        }
+
+    })(),
+    
+    /**
+     * APIMethod: parse
+     * Generate a date object from a string.  The format for the string follows
+     *     the profile of ISO 8601 for date and time on the Internet (see 
+     *     http://tools.ietf.org/html/rfc3339).  If the parse method on 
+     *     the Date constructor returns a valid date for the given string,
+     *     that method is used.
+     *
+     * Parameters:
+     * str - {String} A string representing the date (e.g. 
+     *     "2010", "2010-08", "2010-08-07", "2010-08-07T16:58:23.123Z",
+     *     "2010-08-07T11:58:23.123-06").
+     * 
+     * Returns:
+     * {Date} A date object.  If the string could not be parsed, an invalid
+     *     date is returned (i.e. isNaN(date.getTime())).
+     */
+    parse: function(str) {
+        var date;
+        // first check if the native parse method can parse it
+        var elapsed = Date.parse(str);
+        if (!isNaN(elapsed)) {
+            date = new Date(elapsed);
+        } else {
+            var match = str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);
+            var date;
+            if (match && (match[1] || match[7])) { // must have at least year or time
+                var year = parseInt(match[1], 10) || 0;
+                var month = (parseInt(match[2], 10) - 1) || 0;
+                var day = parseInt(match[3], 10) || 1;
+                date = new Date(Date.UTC(year, month, day));
+                // optional time
+                var type = match[7];
+                if (type) {
+                    var hours = parseInt(match[4], 10);
+                    var minutes = parseInt(match[5], 10);
+                    var secFrac = parseFloat(match[6]);
+                    var seconds = secFrac | 0;
+                    var milliseconds = Math.round(1000 * (secFrac - seconds));
+                    date.setUTCHours(hours, minutes, seconds, milliseconds);
+                    // check offset
+                    if (type !== "Z") {
+                        var hoursOffset = parseInt(type, 10);
+                        var minutesOffset = parseInt(match[8]) || 0;
+                        var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);
+                        date = new Date(date.getTime() + offset);
+                    }
+                }
+            } else {
+                date = new Date("invalid");
+            }
+        }
+        return date;
+    }
+
+};
 /* ======================================================================
     OpenLayers/BaseTypes/Class.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -3005,30 +3235,31 @@
         }
     };
     var extended = {};
-    var parent, initialize;
+    var parent, initialize, Type;
     for(var i=0, len=arguments.length; i<len; ++i) {
-        if(typeof arguments[i] == "function") {
+        Type = arguments[i];
+        if(typeof Type == "function") {
             // make the class passed as the first argument the superclass
             if(i == 0 && len > 1) {
-                initialize = arguments[i].prototype.initialize;
+                initialize = Type.prototype.initialize;
                 // replace the initialize method with an empty function,
                 // because we do not want to create a real instance here
-                arguments[i].prototype.initialize = function() {};
+                Type.prototype.initialize = function() {};
                 // the line below makes sure that the new class has a
                 // superclass
-                extended = new arguments[i];
+                extended = new Type();
                 // restore the original initialize method
                 if(initialize === undefined) {
-                    delete arguments[i].prototype.initialize;
+                    delete Type.prototype.initialize;
                 } else {
-                    arguments[i].prototype.initialize = initialize;
+                    Type.prototype.initialize = initialize;
                 }
             }
             // get the prototype of the superclass
-            parent = arguments[i].prototype;
+            parent = Type.prototype;
         } else {
             // in this case we're extending with the prototype
-            parent = arguments[i];
+            parent = Type;
         }
         OpenLayers.Util.extend(extended, parent);
     }
@@ -3086,8 +3317,9 @@
     OpenLayers/BaseTypes/Size.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -3174,8 +3406,9 @@
     OpenLayers/BaseTypes/Bounds.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -3653,7 +3886,7 @@
      * 
      * bounds - {<OpenLayers.Bounds>} The target bounds.
      * partial - {Boolean} If any of the target corners is within this bounds
-     *     consider the bounds contained.  Default is false.  If true, the
+     *     consider the bounds contained.  Default is false.  If false, the
      *     entire target bounds must be contained within this bounds.
      * inclusive - {Boolean} Treat shared edges as contained.  Default is
      *     true.
@@ -3858,8 +4091,9 @@
     OpenLayers/BaseTypes/Element.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -3907,7 +4141,9 @@
     hide: function() {
         for (var i=0, len=arguments.length; i<len; i++) {
             var element = OpenLayers.Util.getElement(arguments[i]);
-            element.style.display = 'none';
+            if (element) {
+                element.style.display = 'none';
+            }
         }
     },
 
@@ -3921,7 +4157,9 @@
     show: function() {
         for (var i=0, len=arguments.length; i<len; i++) {
             var element = OpenLayers.Util.getElement(arguments[i]);
-            element.style.display = '';
+            if (element) {
+                element.style.display = '';
+            }
         }
     },
 
@@ -4108,8 +4346,9 @@
     OpenLayers/BaseTypes/LonLat.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -4202,7 +4441,8 @@
             OpenLayers.Console.error(msg);
             return null;
         }
-        return new OpenLayers.LonLat(this.lon + lon, this.lat + lat);
+        return new OpenLayers.LonLat(this.lon + OpenLayers.Util.toFloat(lon), 
+                                     this.lat + OpenLayers.Util.toFloat(lat));
     },
 
     /** 
@@ -4294,15 +4534,15 @@
  */
 OpenLayers.LonLat.fromString = function(str) {
     var pair = str.split(",");
-    return new OpenLayers.LonLat(parseFloat(pair[0]), 
-                                 parseFloat(pair[1]));
+    return new OpenLayers.LonLat(pair[0], pair[1]);
 };
 /* ======================================================================
     OpenLayers/BaseTypes/Pixel.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -4429,11 +4669,11 @@
     OpenLayers/Icon.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
-
 /**
  * Class: OpenLayers.Icon
  * 
@@ -4660,8 +4900,9 @@
     OpenLayers/Popup.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -5715,8 +5956,9 @@
     OpenLayers/Protocol.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -5774,20 +6016,18 @@
      * filter - {OpenLayers.Filter}
      */
     mergeWithDefaultFilter: function(filter) {
-        if(filter) {
-            if(this.defaultFilter) {
-                filter = new OpenLayers.Filter.Logical({
-                    type: OpenLayers.Filter.Logical.AND,
-                    filters: [this.defaultFilter, filter]
-                });
-            }
+        var merged;
+        if (filter && this.defaultFilter) {
+            merged = new OpenLayers.Filter.Logical({
+                type: OpenLayers.Filter.Logical.AND,
+                filters: [this.defaultFilter, filter]
+            });
         } else {
-            filter = this.defaultFilter;
+            merged = filter || this.defaultFilter || undefined;
         }
-        return filter;
+        return merged;
     },
 
-
     /**
      * APIMethod: destroy
      * Clean up the protocol.
@@ -5992,8 +6232,9 @@
     OpenLayers/Renderer.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -6259,8 +6500,9 @@
             features = [features];
         }
         for(var i=0, len=features.length; i<len; ++i) {
-            this.eraseGeometry(features[i].geometry);
-            this.removeText(features[i].id);
+            var feature = features[i];
+            this.eraseGeometry(feature.geometry, feature.id);
+            this.removeText(feature.id);
         }
     },
     
@@ -6271,8 +6513,9 @@
      * 
      * Parameters:
      * geometry - {<OpenLayers.Geometry>} 
+     * featureId - {String}
      */
-    eraseGeometry: function(geometry) {},
+    eraseGeometry: function(geometry, featureId) {},
     
     /**
      * Method: moveRoot
@@ -6297,15 +6540,67 @@
     getRenderLayerId: function() {
         return this.container.id;
     },
+    
+    /**
+     * Method: applyDefaultSymbolizer
+     * 
+     * Parameters:
+     * symbolizer - {Object}
+     * 
+     * Returns:
+     * {Object}
+     */
+    applyDefaultSymbolizer: function(symbolizer) {
+        var result = OpenLayers.Util.extend({},
+            OpenLayers.Renderer.defaultSymbolizer);
+        if(symbolizer.stroke === false) {
+            delete result.strokeWidth;
+            delete result.strokeColor;
+        }
+        if(symbolizer.fill === false) {
+            delete result.fillColor;
+        }
+        OpenLayers.Util.extend(result, symbolizer);
+        return result;
+    },
 
     CLASS_NAME: "OpenLayers.Renderer"
 });
+
+/**
+ * Constant: OpenLayers.Renderer.defaultSymbolizer
+ * {Object} Properties from this symbolizer will be applied to symbolizers
+ *     with missing properties. This can also be used to set a global
+ *     symbolizer default in OpenLayers. To be SLD 1.x compliant, add the
+ *     following code before rendering any vector features:
+ * (code)
+ * OpenLayers.Renderer.defaultSymbolizer = {
+ *     fillColor: "#808080",
+ *     fillOpacity: 1,
+ *     strokeColor: "#000000",
+ *     strokeOpacity: 1,
+ *     strokeWidth: 1,
+ *     pointRadius: 3,
+ *     graphicName: "square"
+ * };
+ * (end)
+ */
+OpenLayers.Renderer.defaultSymbolizer = {
+    fillColor: "#000000",
+    strokeColor: "#000000",
+    strokeWidth: 2,
+    fillOpacity: 1,
+    strokeOpacity: 1,
+    pointRadius: 0
+};
+    
 /* ======================================================================
     OpenLayers/Strategy.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -6421,11 +6716,67 @@
     CLASS_NAME: "OpenLayers.Strategy" 
 });
 /* ======================================================================
+    OpenLayers/Symbolizer.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * Class: OpenLayers.Symbolizer
+ * Base class representing a symbolizer used for feature rendering.
+ */
+OpenLayers.Symbolizer = OpenLayers.Class({
+    
+
+    /**
+     * APIProperty: zIndex
+     * {Number} The zIndex determines the rendering order for a symbolizer.
+     *     Symbolizers with larger zIndex values are rendered over symbolizers
+     *     with smaller zIndex values.  Default is 0.
+     */
+    zIndex: 0,
+    
+    /**
+     * Constructor: OpenLayers.Symbolizer
+     * Instances of this class are not useful.  See one of the subclasses.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Util.extend(this, config);
+    },
+    
+    /** 
+     * APIMethod: clone
+     * Create a copy of this symbolizer.
+     *
+     * Returns a symbolizer of the same type with the same properties.
+     */
+    clone: function() {
+        var Type = eval(this.CLASS_NAME);
+        return new Type(OpenLayers.Util.extend({}, this));
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer"
+    
+});
+
+/* ======================================================================
     OpenLayers/Control.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -6502,9 +6853,9 @@
 
     /** 
      * Property: type 
-     * {OpenLayers.Control.TYPES} Controls can have a 'type'. The type
-     * determines the type of interactions which are possible with them when
-     * they are placed into a toolbar. 
+     * {Number} Controls can have a 'type'. The type determines the type of
+     * interactions which are possible with them when they are placed in an
+     * <OpenLayers.Control.Panel>. 
      */
     type: null, 
 
@@ -6777,15 +7128,27 @@
     CLASS_NAME: "OpenLayers.Control"
 });
 
+/**
+ * Constant: OpenLayers.Control.TYPE_BUTTON
+ */
 OpenLayers.Control.TYPE_BUTTON = 1;
+
+/**
+ * Constant: OpenLayers.Control.TYPE_TOGGLE
+ */
 OpenLayers.Control.TYPE_TOGGLE = 2;
+
+/**
+ * Constant: OpenLayers.Control.TYPE_TOOL
+ */
 OpenLayers.Control.TYPE_TOOL   = 3;
 /* ======================================================================
     OpenLayers/Lang.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -6920,8 +7283,9 @@
     OpenLayers/Popup/Anchored.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -7107,10 +7471,10 @@
         var size = this.size || this.contentSize;
 
         var top = (this.relativePosition.charAt(0) == 't');
-        newPx.y += (top) ? -size.h : this.anchor.size.h;
+        newPx.y += (top) ? -(size.h + this.anchor.size.h) : this.anchor.size.h;
         
         var left = (this.relativePosition.charAt(1) == 'l');
-        newPx.x += (left) ? -size.w : this.anchor.size.w;
+        newPx.x += (left) ? -(size.w + this.anchor.size.w) : this.anchor.size.w;
 
         return newPx;   
     },
@@ -7121,8 +7485,9 @@
     OpenLayers/Renderer/Canvas.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -7151,14 +7516,6 @@
     features: null, 
    
     /**
-     * Property: geometryMap
-     * {Object} Geometry -> Feature lookup table. Used by eraseGeometry to
-     *     lookup features to remove from our internal table (this.features)
-     *     when erasing geoms.
-     */
-    geometryMap: null,
- 
-    /**
      * Constructor: OpenLayers.Renderer.Canvas
      *
      * Parameters:
@@ -7170,7 +7527,6 @@
         this.container.appendChild(this.root);
         this.canvas = this.root.getContext("2d");
         this.features = {};
-        this.geometryMap = {};
     },
     
     /** 
@@ -7181,9 +7537,10 @@
      * 
      * Parameters:
      * geometry - {<OpenLayers.Geometry>}
+     * featureId - {String}
      */
-    eraseGeometry: function(geometry) {
-        this.eraseFeatures(this.features[this.geometryMap[geometry.id]][0]);
+    eraseGeometry: function(geometry, featureId) {
+        this.eraseFeatures(this.features[featureId][0]);
     },
 
     /**
@@ -7241,20 +7598,10 @@
      * style - {<Object>} 
      */
     drawFeature: function(feature, style) {
-        if(style == null) {
-            style = feature.style;
-        }
-        style = OpenLayers.Util.extend({
-          'fillColor': '#000000',
-          'strokeColor': '#000000',
-          'strokeWidth': 2,
-          'fillOpacity': 1,
-          'strokeOpacity': 1
-        }, style);  
+        style = style || feature.style;
+        style = this.applyDefaultSymbolizer(style);  
+        
         this.features[feature.id] = [feature, style]; 
-        if (feature.geometry) { 
-            this.geometryMap[feature.geometry.id] = feature.id;
-        }    
         this.redraw();
     },
 
@@ -7278,7 +7625,7 @@
                 this.drawGeometry(geometry.components[i], style);
             }
             return;
-        };
+        }
         switch (geometry.CLASS_NAME) {
             case "OpenLayers.Geometry.Point":
                 this.drawPoint(geometry, style);
@@ -7307,7 +7654,6 @@
      */ 
     drawExternalGraphic: function(pt, style) {
        var img = new Image();
-       img.src = style.externalGraphic;
        
        if(style.graphicTitle) {
            img.title=style.graphicTitle;           
@@ -7321,19 +7667,21 @@
            style.graphicXOffset : -(0.5 * width);
        var yOffset = (style.graphicYOffset != undefined) ?
            style.graphicYOffset : -(0.5 * height);
-       var opacity = style.graphicOpacity || style.fillOpacity;
        
        var context = { img: img, 
                        x: (pt[0]+xOffset), 
                        y: (pt[1]+yOffset), 
                        width: width, 
                        height: height, 
+                       opacity: style.graphicOpacity || style.fillOpacity,
                        canvas: this.canvas };
 
        img.onload = OpenLayers.Function.bind( function() {
+           this.canvas.globalAlpha = this.opacity;
            this.canvas.drawImage(this.img, this.x, 
                                  this.y, this.width, this.height);
-       }, context);   
+       }, context);
+       img.src = style.externalGraphic;
     },
 
     /**
@@ -7436,7 +7784,6 @@
         }
         
         if(style.stroke !== false) {
-            var oldWidth = this.canvas.lineWidth; 
             this.setCanvasStyle("stroke", style);
             this.canvas.beginPath();
             var start = this.getLocalXY(geometry.components[0]);
@@ -7535,14 +7882,14 @@
         var y = ((extent.top / resolution) - point.y / resolution);
         return [x, y];
     },
-        
+
     /**
      * Method: clear
      * Clear all vectors from the renderer.
-     * virtual function.
      */    
     clear: function() {
         this.canvas.clearRect(0, 0, this.root.width, this.root.height);
+        this.features = {};
     },
 
     /**
@@ -7600,7 +7947,7 @@
      */
     redraw: function() {
         if (!this.locked) {
-            this.clear();
+            this.canvas.clearRect(0, 0, this.root.width, this.root.height);
             var labelMap = [];
             var feature, style;
             for (var id in this.features) {
@@ -7614,7 +7961,7 @@
                 }
             }
             var item;
-            for (var i=0; len=labelMap.length, i<len; ++i) {
+            for (var i=0, len=labelMap.length; i<len; ++i) {
                 item = labelMap[i];
                 this.drawText(item[0].geometry.getCentroid(), item[1]);
             }
@@ -7636,8 +7983,9 @@
     OpenLayers/Renderer/Elements.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -8033,18 +8381,6 @@
     LABEL_ID_SUFFIX: "_label",
     
     /**
-     * Property: minimumSymbolizer
-     * {Object}
-     */
-    minimumSymbolizer: {
-        strokeLinecap: "round",
-        strokeOpacity: 1,
-        strokeDashstyle: "solid",
-        fillOpacity: 1,
-        pointRadius: 0
-    },
-    
-    /**
      * Constructor: OpenLayers.Renderer.Elements
      * 
      * Parameters:
@@ -8092,14 +8428,17 @@
      * Remove all the elements from the root
      */    
     clear: function() {
-        if (this.vectorRoot) {
-            while (this.vectorRoot.childNodes.length > 0) {
-                this.vectorRoot.removeChild(this.vectorRoot.firstChild);
+        var child;
+        var root = this.vectorRoot;
+        if (root) {
+            while (child = root.firstChild) {
+                root.removeChild(child);
             }
         }
-        if (this.textRoot) {
-            while (this.textRoot.childNodes.length > 0) {
-                this.textRoot.removeChild(this.textRoot.firstChild);
+        root = this.textRoot;
+        if (root) {
+            while (child = root.firstChild) {
+                root.removeChild(child);
             }
         }
         if (this.indexer) {
@@ -8190,6 +8529,7 @@
      *     the geometry could not be drawn, false otherwise
      */
     redrawNode: function(id, geometry, style, featureId) {
+        style = this.applyDefaultSymbolizer(style);
         // Get the node if it's already on the map.
         var node = this.nodeFactory(id, this.getNodeType(geometry, style));
         
@@ -8293,7 +8633,6 @@
      */
     drawGeometryNode: function(node, geometry, style) {
         style = style || node._style;
-        OpenLayers.Util.applyDefaults(style, this.minimumSymbolizer);
 
         var options = {
             'isFilled': style.fill === undefined ?
@@ -8505,14 +8844,15 @@
      * 
      * Parameters:
      * geometry - {<OpenLayers.Geometry>}
+     * featureId - {String}
      */
-    eraseGeometry: function(geometry) {
+    eraseGeometry: function(geometry, featureId) {
         if ((geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") ||
             (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString") ||
             (geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon") ||
             (geometry.CLASS_NAME == "OpenLayers.Geometry.Collection")) {
             for (var i=0, len=geometry.components.length; i<len; i++) {
-                this.eraseGeometry(geometry.components[i]);
+                this.eraseGeometry(geometry.components[i], featureId);
             }
         } else {    
             var element = OpenLayers.Util.getElement(geometry.id);
@@ -8657,8 +8997,9 @@
     OpenLayers/Strategy/Fixed.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -8795,11 +9136,422 @@
     CLASS_NAME: "OpenLayers.Strategy.Fixed"
 });
 /* ======================================================================
+    OpenLayers/Symbolizer/Line.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Line
+ * A symbolizer used to render line features.
+ */
+OpenLayers.Symbolizer.Line = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+    /**
+     * APIProperty: strokeColor
+     * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
+     *     for red).
+     */
+    strokeColor: null,
+    
+    /**
+     * APIProperty: strokeOpacity
+     * {Number} Stroke opacity (0-1).
+     */
+    strokeOpacity: null,
+    
+    /**
+     * APIProperty: strokeWidth
+     * {Number} Pixel stroke width.
+     */
+    strokeWidth: null,
+    
+    /**
+     * APIProperty: strokeLinecap
+     * {String} Stroke cap type ("butt", "round", or "square").
+     */
+    strokeLinecap: null,
+    
+    /**
+     * Property: strokeDashstyle
+     * {String} Stroke dash style according to the SLD spec. Note that the
+     *     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.
+     */
+    strokeDashstyle: null,
+
+    /**
+     * Constructor: OpenLayers.Symbolizer.Line
+     * Create a symbolizer for rendering lines.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new line symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer.Line"
+    
+});
+
+/* ======================================================================
+    OpenLayers/Symbolizer/Point.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Point
+ * A symbolizer used to render point features.
+ */
+OpenLayers.Symbolizer.Point = OpenLayers.Class(OpenLayers.Symbolizer, {
+    
+    /**
+     * APIProperty: strokeColor
+     * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
+     *     for red).
+     */
+    strokeColor: null,
+    
+    /**
+     * APIProperty: strokeOpacity
+     * {Number} Stroke opacity (0-1).
+     */
+    strokeOpacity: null,
+    
+    /**
+     * APIProperty: strokeWidth
+     * {Number} Pixel stroke width.
+     */
+    strokeWidth: null,
+    
+    /**
+     * APIProperty: strokeLinecap
+     * {String} Stroke cap type ("butt", "round", or "square").
+     */
+    strokeLinecap: null,
+    
+    /**
+     * Property: strokeDashstyle
+     * {String} Stroke dash style according to the SLD spec. Note that the
+     *     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.
+     */
+    strokeDashstyle: null,
+
+    /**
+     * APIProperty: fillColor
+     * {String} RGB hex fill color (e.g. "#ff0000" for red).
+     */
+    fillColor: null,
+    
+    /**
+     * APIProperty: fillOpacity
+     * {Number} Fill opacity (0-1).
+     */
+    fillOpacity: null, 
+
+    /**
+     * APIProperty: pointRadius
+     * {Number} Pixel point radius.
+     */
+    pointRadius: null,
+
+    /**
+     * APIProperty: externalGraphic
+     * {String} Url to an external graphic that will be used for rendering 
+     *     points.
+     */
+    externalGraphic: null,
+    
+    /**
+     * APIProperty: graphicWidth
+     * {Number} Pixel width for sizing an external graphic.
+     */
+    graphicWidth: null,
+    
+    /**
+     * APIProperty: graphicHeight
+     * {Number} Pixel height for sizing an external graphic.
+     */
+    graphicHeight: null,
+    
+    /**
+     * APIProperty: graphicOpacity
+     * {Number} Opacity (0-1) for an external graphic.
+     */
+    graphicOpacity: null,
+    
+    /**
+     * APIProperty: graphicXOffset
+     * {Number} Pixel offset along the positive x axis for displacing an 
+     *     external graphic.
+     */
+    graphicXOffset: null,
+    
+    /**
+     * APIProperty: graphicYOffset
+     * {Number} Pixel offset along the positive y axis for displacing an 
+     *     external graphic.
+     */
+    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>).
+     */
+    rotation: null,
+    
+    /**
+     * APIProperty: graphicName
+     * {String} Named graphic to use when rendering points.  Supported values 
+     *     include "circle", "square", "star", "x", "cross", and "triangle".
+     */
+    graphicName: null,
+    
+    /**
+     * Constructor: OpenLayers.Symbolizer.Point
+     * Create a symbolizer for rendering points.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new point symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer.Point"
+    
+});
+
+/* ======================================================================
+    OpenLayers/Symbolizer/Polygon.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Polygon
+ * A symbolizer used to render line features.
+ */
+OpenLayers.Symbolizer.Polygon = OpenLayers.Class(OpenLayers.Symbolizer, {
+    
+    /**
+     * APIProperty: strokeColor
+     * {String} Color for line stroke.  This is a RGB hex value (e.g. "#ff0000"
+     *     for red).
+     */
+    strokeColor: null,
+    
+    /**
+     * APIProperty: strokeOpacity
+     * {Number} Stroke opacity (0-1).
+     */
+    strokeOpacity: null,
+    
+    /**
+     * APIProperty: strokeWidth
+     * {Number} Pixel stroke width.
+     */
+    strokeWidth: null,
+    
+    /**
+     * APIProperty: strokeLinecap
+     * {String} Stroke cap type ("butt", "round", or "square").
+     */
+    strokeLinecap: null,
+    
+    /**
+     * Property: strokeDashstyle
+     * {String} Stroke dash style according to the SLD spec. Note that the
+     *     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.
+     */
+    strokeDashstyle: null,
+
+    /**
+     * APIProperty: fillColor
+     * {String} RGB hex fill color (e.g. "#ff0000" for red).
+     */
+    fillColor: null,
+    
+    /**
+     * APIProperty: fillOpacity
+     * {Number} Fill opacity (0-1).
+     */
+    fillOpacity: null, 
+
+    /**
+     * Constructor: OpenLayers.Symbolizer.Polygon
+     * Create a symbolizer for rendering polygons.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new polygon symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer.Polygon"
+    
+});
+
+/* ======================================================================
+    OpenLayers/Symbolizer/Raster.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Raster
+ * A symbolizer used to render raster images.
+ */
+OpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, {
+    
+    /**
+     * Constructor: OpenLayers.Symbolizer.Raster
+     * Create a symbolizer for rendering rasters.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new raster symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer.Raster"
+    
+});
+/* ======================================================================
+    OpenLayers/Symbolizer/Text.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Text
+ * A symbolizer used to render text labels for features.
+ */
+OpenLayers.Symbolizer.Text = OpenLayers.Class(OpenLayers.Symbolizer, {
+    
+    /** 
+     * APIProperty: label
+     * {String} The text for the label.
+     */
+    label: null,
+    
+    /** 
+     * APIProperty: fontFamily
+     * {String} The font family for the label.
+     */
+    fontFamily: null,
+
+    /** 
+     * APIProperty: fontSize
+     * {String} The font size for the label.
+     */
+    fontSize: null,
+
+    /** 
+     * APIProperty: fontWeight
+     * {String} The font weight for the label.
+     */
+    fontWeight: null,
+    
+    /**
+     * Property: fontStyle
+     * {String} The font style for the label.
+     */
+    fontStyle: null,
+
+    /**
+     * Constructor: OpenLayers.Symbolizer.Text
+     * Create a symbolizer for rendering text labels.
+     *
+     * Parameters:
+     * config - {Object} An object containing properties to be set on the 
+     *     symbolizer.  Any documented symbolizer property can be set at 
+     *     construction.
+     *
+     * Returns:
+     * A new text symbolizer.
+     */
+    initialize: function(config) {
+        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+    },
+    
+    CLASS_NAME: "OpenLayers.Symbolizer.Text"
+    
+});
+
+/* ======================================================================
     OpenLayers/Tween.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -8948,12 +9700,7 @@
         }
         
         if (this.time > this.duration) {
-            if (this.callbacks && this.callbacks.done) {
-                this.callbacks.done.call(this, this.finish);
-                this.playing = false;
-            }
-            window.clearInterval(this.interval);
-            this.interval = null;
+            this.stop();
         }
     },
     
@@ -9124,8 +9871,9 @@
     OpenLayers/Control/ArgParser.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -9293,8 +10041,9 @@
     OpenLayers/Control/PanZoom.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -9542,9 +10291,10 @@
     OpenLayers/Control/ScaleLine.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Control.js
@@ -9608,7 +10358,10 @@
     
     /**
      * APIProperty: geodesic
-     * {Boolean} Use geodesic measurement. Default is false.
+     * {Boolean} Use geodesic measurement. Default is false. The recommended
+     * setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
+     * true, the scale will be calculated based on the horizontal size of the
+     * pixel in the center of the map viewport.
      */
     geodesic: false,
 
@@ -9709,7 +10462,8 @@
         var maxSizeData = this.maxWidth * res * inches[curMapUnits];
         var geodesicRatio = 1;
         if(this.geodesic === true) {
-            var maxSizeGeodesic = this.getGeodesicLength(this.maxWidth);
+            var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||
+                0.000001) * this.maxWidth;
             var maxSizeKilometers = maxSizeData / inches["km"];
             geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
             maxSizeData *= geodesicRatio;
@@ -9757,26 +10511,6 @@
         
     }, 
 
-    /**
-     * Method: getGeodesicLength
-     * 
-     * Parameters:
-     * pixels - {Number} the pixels to get the geodesic length in meters for.
-     */
-    getGeodesicLength: function(pixels) {
-        var map = this.map;
-        var centerPx = map.getPixelFromLonLat(map.getCenter());
-        var bottom = map.getLonLatFromPixel(centerPx.add(0, -pixels / 2));
-        var top = map.getLonLatFromPixel(centerPx.add(0, pixels / 2));
-        var source = map.getProjectionObject();
-        var dest = new OpenLayers.Projection("EPSG:4326");
-        if(!source.equals(dest)) {
-            bottom.transform(source, dest);
-            top.transform(source, dest);
-        }
-        return OpenLayers.Util.distVincenty(bottom, top);
-    },
-
     CLASS_NAME: "OpenLayers.Control.ScaleLine"
 });
 
@@ -9784,8 +10518,9 @@
     OpenLayers/Events.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -10642,8 +11377,9 @@
     OpenLayers/Format.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -10768,10 +11504,6 @@
     OpenLayers/Lang/en.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
 /**
  * @requires OpenLayers/Lang.js
  */
@@ -10857,6 +11589,7 @@
     'E': 'E',
     'N': 'N',
     'S': 'S',
+    'graticule': 'Graticule',
 
     // console message
     'layerAlreadyAdded':
@@ -10891,18 +11624,21 @@
     // console message
     'pagePositionFailed':
         "OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",
-                    
-    'end': '',
 
     // console message
-    'filterEvaluateNotImplemented': "evaluate is not implemented for this filter type."
+    'filterEvaluateNotImplemented': "evaluate is not implemented for this filter type.",
+
+    // **** end ****
+    'end': ''
+    
 };
 /* ======================================================================
     OpenLayers/Popup/AnchoredBubble.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -11094,9 +11830,10 @@
     OpenLayers/Projection.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Util.js
@@ -11275,8 +12012,9 @@
     OpenLayers/Renderer/SVG.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -11550,7 +12288,7 @@
             } else if (style.externalGraphic) {
                 pos = this.getPosition(node);
                 
-        		if (style.graphicTitle) {
+                if (style.graphicTitle) {
                     node.setAttributeNS(null, "title", style.graphicTitle);
                 }
                 if (style.graphicWidth && style.graphicHeight) {
@@ -11625,7 +12363,7 @@
                         "rotate(" + rotation + " " + pos.x + " " +
                         pos.y + ")");
                 } else {
-                     var metrics = this.symbolMetrics[id]
+                     var metrics = this.symbolMetrics[id];
                      node.firstChild.setAttributeNS(null, "transform",
                      "rotate(" + style.rotation + " " + metrics[1] +
                          " " +  metrics[2] + ")");
@@ -11644,12 +12382,12 @@
             node.setAttributeNS(null, "stroke", style.strokeColor);
             node.setAttributeNS(null, "stroke-opacity", style.strokeOpacity);
             node.setAttributeNS(null, "stroke-width", style.strokeWidth * widthFactor);
-            node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap);
+            node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap || "round");
             // Hard-coded linejoin for now, to make it look the same as in VML.
             // There is no strokeLinejoin property yet for symbolizers.
             node.setAttributeNS(null, "stroke-linejoin", "round");
-            node.setAttributeNS(null, "stroke-dasharray", this.dashStyle(style,
-                widthFactor));
+            style.strokeDashstyle && node.setAttributeNS(null,
+                "stroke-dasharray", this.dashStyle(style, widthFactor));
         } else {
             node.setAttributeNS(null, "stroke", "none");
         }
@@ -11657,7 +12395,7 @@
         if (style.pointerEvents) {
             node.setAttributeNS(null, "pointer-events", style.pointerEvents);
         }
-		        
+                
         if (style.cursor != null) {
             node.setAttributeNS(null, "cursor", style.cursor);
         }
@@ -12044,7 +12782,7 @@
         var complete = true;
         var len = components.length;
         var strings = [];
-        var str, component, j;
+        var str, component;
         for(var i=0; i<len; i++) {
             component = components[i];
             renderCmp.push(component);
@@ -12183,7 +12921,6 @@
         var symbol = OpenLayers.Renderer.symbol[graphicName];
         if (!symbol) {
             throw new Error(graphicName + ' is not a valid symbol name');
-            return;
         }
 
         var symbolNode = this.nodeFactory(id, "symbol");
@@ -12192,7 +12929,7 @@
         var symbolExtent = new OpenLayers.Bounds(
                                     Number.MAX_VALUE, Number.MAX_VALUE, 0, 0);
 
-        var points = "";
+        var points = [];
         var x,y;
         for (var i=0; i<symbol.length; i=i+2) {
             x = symbol[i];
@@ -12201,10 +12938,10 @@
             symbolExtent.bottom = Math.min(symbolExtent.bottom, y);
             symbolExtent.right = Math.max(symbolExtent.right, x);
             symbolExtent.top = Math.max(symbolExtent.top, y);
-            points += " " + x + "," + y;
+            points.push(x, ",", y);
         }
         
-        node.setAttributeNS(null, "points", points);
+        node.setAttributeNS(null, "points", points.join(" "));
         
         var width = symbolExtent.getWidth();
         var height = symbolExtent.getHeight();
@@ -12274,8 +13011,9 @@
     OpenLayers/Renderer/VML.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -12490,12 +13228,11 @@
     setStyle: function(node, style, options, geometry) {
         style = style  || node._style;
         options = options || node._options;
-        var widthFactor = 1;
         var fillColor = style.fillColor;
 
         if (node._geometryClass === "OpenLayers.Geometry.Point") {
             if (style.externalGraphic) {
-        		if (style.graphicTitle) {
+                if (style.graphicTitle) {
                     node.title=style.graphicTitle;
                 } 
                 var width = style.graphicWidth || style.graphicHeight;
@@ -12571,7 +13308,7 @@
 
         // additional rendering for rotated graphics or symbols
         var rotation = style.rotation;
-        if (rotation !== node._rotation) {
+        if ((rotation !== undefined || node._rotation !== undefined)) {
             node._rotation = rotation;
             if (style.externalGraphic) {
                 this.graphicRotate(node, xOffset, yOffset, style);
@@ -12586,26 +13323,27 @@
         }
 
         // stroke 
-        if (options.isStroked) { 
-            node.strokecolor = style.strokeColor; 
-            node.strokeweight = style.strokeWidth + "px"; 
-        } else { 
-            node.stroked = false; 
-        }
         var strokes = node.getElementsByTagName("stroke");
         var stroke = (strokes.length == 0) ? null : strokes[0];
         if (!options.isStroked) {
+            node.stroked = false;
             if (stroke) {
-                node.removeChild(stroke);
+                stroke.on = false;
             }
         } else {
             if (!stroke) {
                 stroke = this.createNode('olv:stroke', node.id + "_stroke");
                 node.appendChild(stroke);
             }
+            stroke.on = true;
+            stroke.color = style.strokeColor; 
+            stroke.weight = style.strokeWidth + "px"; 
             stroke.opacity = style.strokeOpacity;
-            stroke.endcap = !style.strokeLinecap || style.strokeLinecap == 'butt' ? 'flat' : style.strokeLinecap;
-            stroke.dashstyle = this.dashStyle(style);
+            stroke.endcap = style.strokeLinecap == 'butt' ? 'flat' :
+                (style.strokeLinecap || 'round');
+            if (style.strokeDashstyle) {
+                stroke.dashstyle = this.dashStyle(style);
+            }
         }
         
         if (style.cursor != "inherit" && style.cursor != null) {
@@ -12636,7 +13374,6 @@
      */
     graphicRotate: function(node, xOffset, yOffset, style) {
         var style = style || node._style;
-        var options = node._options;
         var rotation = style.rotation || 0;
         
         var aspectRatio, size;
@@ -13123,10 +13860,13 @@
         }
 
         var align = style.labelAlign || "cm";
+        if (align.length == 1) {
+            align += "m";
+        }
         var xshift = textbox.clientWidth *
-            (OpenLayers.Renderer.VML.LABEL_SHIFT[align[0] || "c"]);
+            (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);
         var yshift = textbox.clientHeight *
-            (OpenLayers.Renderer.VML.LABEL_SHIFT[align[1] || "m"]);
+            (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);
         label.style.left = parseInt(label.style.left)-xshift-1+"px";
         label.style.top = parseInt(label.style.top)+yshift+"px";
         
@@ -13212,7 +13952,6 @@
         var symbol = OpenLayers.Renderer.symbol[graphicName];
         if (!symbol) {
             throw new Error(graphicName + ' is not a valid symbol name');
-            return;
         }
 
         var symbolExtent = new OpenLayers.Bounds(
@@ -13275,8 +14014,9 @@
     OpenLayers/Tile.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -13559,8 +14299,9 @@
     OpenLayers/Format/XML.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -13804,6 +14545,9 @@
      */
     createTextNode: function(text) {
         var node;
+        if (typeof text !== "string") {
+            text = String(text);
+        }
         if(this.xmldom) {
             node = this.xmldom.createTextNode(text);
         } else {
@@ -14129,9 +14873,6 @@
         }
         var value = options.value;
         if(value != null) {
-            if(typeof value == "boolean") {
-                value = String(value);
-            }
             node.appendChild(this.createTextNode(value));
         }
         return node;
@@ -14443,8 +15184,9 @@
     OpenLayers/Handler.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -14536,7 +15278,8 @@
      * Parameters:
      * control - {<OpenLayers.Control>} The control that initialized this
      *     handler.  The control is assumed to have a valid map property; that
-     *     map is used in the handler's own setMap method.
+     *     map is used in the handler's own setMap method.  If a map property
+     *     is present in the options argument it will be used instead.
      * callbacks - {Object} An object whose properties correspond to abstracted
      *     events or sequences of browser events.  The values for these
      *     properties are functions defined by the control that get called by
@@ -14548,11 +15291,11 @@
         OpenLayers.Util.extend(this, options);
         this.control = control;
         this.callbacks = callbacks;
-        if (control.map) {
-            this.setMap(control.map); 
+
+        var map = this.map || control.map;
+        if (map) {
+            this.setMap(map); 
         }
-
-        OpenLayers.Util.extend(this, options);
         
         this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
     },
@@ -14732,8 +15475,9 @@
     OpenLayers/Map.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -14806,15 +15550,9 @@
      *  - *move* triggered after each drag, pan, or zoom
      *  - *moveend* triggered after a drag, pan, or zoom completes
      *  - *zoomend* triggered after a zoom completes
-     *  - *addmarker* triggered after a marker has been added
-     *  - *removemarker* triggered after a marker has been removed
-     *  - *clearmarkers* triggered after markers have been cleared
      *  - *mouseover* triggered after mouseover the map
      *  - *mouseout* triggered after mouseout the map
      *  - *mousemove* triggered after mousemove the map
-     *  - *dragstart* Does not work.  Register for movestart instead.
-     *  - *drag* Does not work.  Register for move instead.
-     *  - *dragend* Does not work.  Register for moveend instead.
      *  - *changebaselayer* triggered after the base layer changes
      */
     EVENT_TYPES: [ 
@@ -15381,8 +16119,9 @@
         }
         
         // make sure panning doesn't continue after destruction
-        if(this.panTween && this.panTween.playing) {
+        if(this.panTween) {
             this.panTween.stop();
+            this.panTween = null;
         }
 
         // map has been destroyed. dont do it again!
@@ -17021,6 +17760,39 @@
         px.y = Math.round(px.y);
         return px;
     },
+    
+    /**
+     * Method: getGeodesicPixelSize
+     * 
+     * Parameters:
+     * px - {<OpenLayers.Pixel>} The pixel to get the geodesic length for. If
+     *     not provided, the center pixel of the map viewport will be used.
+     * 
+     * Returns:
+     * {<OpenLayers.Size>} The geodesic size of the pixel in kilometers.
+     */
+    getGeodesicPixelSize: function(px) {
+        var lonlat = px ? this.getLonLatFromPixel(px) : (this.getCenter() ||
+            new OpenLayers.LonLat(0, 0));
+        var res = this.getResolution();
+        var left = lonlat.add(-res / 2, 0);
+        var right = lonlat.add(res / 2, 0);
+        var bottom = lonlat.add(0, -res / 2);
+        var top = lonlat.add(0, res / 2);
+        var dest = new OpenLayers.Projection("EPSG:4326");
+        var source = this.getProjectionObject() || dest;
+        if(!source.equals(dest)) {
+            left.transform(source, dest);
+            right.transform(source, dest);
+            bottom.transform(source, dest);
+            top.transform(source, dest);
+        }
+        
+        return new OpenLayers.Size(
+            OpenLayers.Util.distVincenty(left, right),
+            OpenLayers.Util.distVincenty(bottom, top)
+        );
+    },
 
 
 
@@ -17124,8 +17896,9 @@
     OpenLayers/Marker.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -17147,9 +17920,9 @@
  * var markers = new OpenLayers.Layer.Markers( "Markers" );
  * map.addLayer(markers);
  *
- * var size = new OpenLayers.Size(10,17);
+ * var size = new OpenLayers.Size(21,25);
  * var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
- * var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png',size,offset);
+ * var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
  * markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon));
  * markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon.clone()));
  *
@@ -17369,8 +18142,9 @@
     OpenLayers/Request.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -17539,7 +18313,9 @@
             request.send(config.data);
         } else {
             window.setTimeout(function(){
-                request.send(config.data);
+                if (request._aborted !== true) {
+                    request.send(config.data);
+                }
             }, 0);
         }
         return request;
@@ -17728,8 +18504,9 @@
     OpenLayers/Tile/Image.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -17913,7 +18690,8 @@
         }
         var drawTile = OpenLayers.Tile.prototype.draw.apply(this, arguments);
         
-        if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) {
+        if ((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) || 
+            this.layer.singleTile) {
             if (drawTile) {
                 //we use a clone of this tile to create a double buffer for visual
                 //continuity.  The backBufferTile is used to create transition
@@ -18047,9 +18825,9 @@
      positionImage: function() {
         // if the this layer doesn't exist at the point the image is
         // returned, do not attempt to use it for size computation
-        if ( this.layer == null )
+        if (this.layer === null) {
             return;
-        
+        }
         // position the frame 
         OpenLayers.Util.modifyDOMElement(this.frame, 
                                           null, this.position, this.size);   
@@ -18308,8 +19086,9 @@
     OpenLayers/Control/OverviewMap.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /** 
@@ -18431,6 +19210,12 @@
     resolutionFactor: 1,
 
     /**
+     * APIProperty: maximized
+     * {Boolean} Start as maximized (visible). Defaults to false.
+     */
+    maximized: false,
+
+    /**
      * Constructor: OpenLayers.Control.OverviewMap
      * Create a new overview map
      *
@@ -18598,7 +19383,10 @@
         }
         
         this.map.events.register('moveend', this, this.update);
-
+        
+        if (this.maximized) {
+            this.maximizeControl();
+        }
         return this.div;
     },
     
@@ -19022,8 +19810,9 @@
     OpenLayers/Feature.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -19252,9 +20041,10 @@
     OpenLayers/Handler/Click.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Handler.js
@@ -19580,8 +20370,9 @@
     OpenLayers/Handler/Drag.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -19782,8 +20573,8 @@
             
             if(!this.oldOnselectstart) {
                 this.oldOnselectstart = (document.onselectstart) ? document.onselectstart : OpenLayers.Function.True;
-                document.onselectstart = OpenLayers.Function.False;
             }
+            document.onselectstart = OpenLayers.Function.False;
             
             propagate = !this.stopDown;
         } else {
@@ -20003,8 +20794,9 @@
     OpenLayers/Handler/Feature.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -20394,9 +21186,10 @@
     OpenLayers/Handler/Hover.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Handler.js
@@ -20580,8 +21373,9 @@
     OpenLayers/Handler/MouseWheel.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -20866,8 +21660,9 @@
     OpenLayers/Layer.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -20950,8 +21745,20 @@
      */
     EVENT_TYPES: ["loadstart", "loadend", "loadcancel", "visibilitychanged",
                   "move", "moveend"],
-        
+
     /**
+     * Constant: RESOLUTION_PROPERTIES
+     * {Array} The properties that are used for calculating resolutions
+     *     information.
+     */
+    RESOLUTION_PROPERTIES: [
+        'scales', 'resolutions',
+        'maxScale', 'minScale',
+        'maxResolution', 'minResolution',
+        'numZoomLevels', 'maxZoomLevel'
+    ],
+
+    /**
      * APIProperty: events
      * {<OpenLayers.Events>}
      */
@@ -21168,6 +21975,13 @@
      *     transitionEffect values.
      */
     SUPPORTED_TRANSITIONS: ['resize'],
+
+    /**
+     * Property: metadata
+     * {Object} This object can be used to store additional information on a
+     *     layer object.
+     */
+    metadata: {},
     
     /**
      * Constructor: OpenLayers.Layer
@@ -21305,18 +22119,46 @@
     * newOptions - {Object}
     */
     addOptions: function (newOptions) {
-        
+
         if (this.options == null) {
             this.options = {};
         }
-        
+
         // update our copy for clone
         OpenLayers.Util.extend(this.options, newOptions);
 
         // add new options to this
         OpenLayers.Util.extend(this, newOptions);
+
+        // make sure this.projection references a projection object
+        if(typeof this.projection == "string") {
+            this.projection = new OpenLayers.Projection(this.projection);
+        }
+
+        // get the units from the projection, if we have a projection
+        // and it it has units
+        if(this.projection && this.projection.getUnits()) {
+            this.units = this.projection.getUnits();
+        }
+
+        // re-initialize resolutions if necessary, i.e. if any of the
+        // properties of the "properties" array defined below is set
+        // in the new options
+        if(this.map) {
+            var properties = this.RESOLUTION_PROPERTIES.concat(
+                ["projection", "units", "minExtent", "maxExtent"]
+            );
+            for(var o in newOptions) {
+                if(newOptions.hasOwnProperty(o) &&
+                   OpenLayers.Util.indexOf(properties, o) >= 0) {
+
+                    this.initResolutions();
+                    break;
+                }
+            }
+        }
     },
-    
+
     /**
      * APIMethod: onMapResize
      * This function can be implemented by subclasses
@@ -21390,12 +22232,13 @@
             // grab some essential layer data from the map if it hasn't already
             //  been set
             this.maxExtent = this.maxExtent || this.map.maxExtent;
+            this.minExtent = this.minExtent || this.map.minExtent;
+
             this.projection = this.projection || this.map.projection;
-            
-            if (this.projection && typeof this.projection == "string") {
+            if (typeof this.projection == "string") {
                 this.projection = new OpenLayers.Projection(this.projection);
             }
-            
+
             // Check the projection to see if we can get units -- if not, refer
             // to properties.
             this.units = this.projection.getUnits() ||
@@ -21595,184 +22438,242 @@
      */
     initResolutions: function() {
 
-        // These are the relevant options which are used for calculating 
-        //  resolutions information.
+        // ok we want resolutions, here's our strategy:
         //
-        var props = new Array(
-          'projection', 'units',
-          'scales', 'resolutions',
-          'maxScale', 'minScale', 
-          'maxResolution', 'minResolution', 
-          'minExtent', 'maxExtent',
-          'numZoomLevels', 'maxZoomLevel'
-        );
+        // 1. if resolutions are defined in the layer config, use them
+        // 2. else, if scales are defined in the layer config then derive
+        //    resolutions from these scales
+        // 3. else, attempt to calculate resolutions from maxResolution,
+        //    minResolution, numZoomLevels, maxZoomLevel set in the
+        //    layer config
+        // 4. if we still don't have resolutions, and if resolutions
+        //    are defined in the same, use them
+        // 5. else, if scales are defined in the map then derive
+        //    resolutions from these scales
+        // 6. else, attempt to calculate resolutions from maxResolution,
+        //    minResolution, numZoomLevels, maxZoomLevel set in the
+        //    map
+        // 7. hope for the best!
 
-        //these are the properties which do *not* imply that user wishes 
-        // this layer to be scale-dependant
-        var notScaleProps = ['projection', 'units'];    
+        var i, len;
+        var props = {}, alwaysInRange = true;
 
-        //should the layer be scale-dependant? default is false -- this will 
-        // only be set true if we find that the user has specified a property
-        // from the 'props' array that is not in 'notScaleProps'
-        var useInRange = false;
-
-        // First we create a new object where we will store all of the 
-        //  resolution-related properties that we find in either the layer's
-        //  'options' array or from the map.
-        //
-        var confProps = {};        
-        for(var i=0, len=props.length; i<len; i++) {
-            var property = props[i];
-            
-            // If the layer had one of these properties set *and* it is 
-            // a scale property (is not a non-scale property), then we assume
-            // the user did intend to use scale-dependant display (useInRange).
-            if (this.options[property] && 
-                OpenLayers.Util.indexOf(notScaleProps, property) == -1) {
-                useInRange = true;
+        // get resolution data from layer config
+        // (we also set alwaysInRange in the layer as appropriate)
+        for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
+            var p = this.RESOLUTION_PROPERTIES[i];
+            props[p] = this.options[p];
+            if(alwaysInRange && this.options[p]) {
+                alwaysInRange = false;
             }
-                   
-            confProps[property] = this.options[property] || this.map[property];
         }
+        if(this.alwaysInRange == null) {
+            this.alwaysInRange = alwaysInRange;
+        }
 
-        //only automatically set 'alwaysInRange' if the user hasn't already 
-        // set it (to true or false, since the default is null). If user did
-        // not intend to use scale-dependant display then we set they layer
-        // as alwaysInRange. This means calculateInRange() will always return 
-        // true and the layer will never be turned off due to scale changes.
-        //
-        if (this.alwaysInRange == null) {
-            this.alwaysInRange = !useInRange;
+        // if we don't have resolutions then attempt to derive them from scales
+        if(props.resolutions == null) {
+            props.resolutions = this.resolutionsFromScales(props.scales);
         }
 
-        // Do not use the scales array set at the map level if 
-        // either minScale or maxScale or both are set at the
-        // layer level
-        if ((this.options.minScale != null ||
-             this.options.maxScale != null) &&
-            this.options.scales == null) {
+        // if we still don't have resolutions then attempt to calculate them
+        if(props.resolutions == null) {
+            props.resolutions = this.calculateResolutions(props);
+        }
 
-            confProps.scales = null;
+        // if we couldn't calculate resolutions then we look at we have
+        // in the map
+        if(props.resolutions == null) {
+            for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
+                var p = this.RESOLUTION_PROPERTIES[i];
+                props[p] = this.options[p] != null ?
+                    this.options[p] : this.map[p];
+            }
+            if(props.resolutions == null) {
+                props.resolutions = this.resolutionsFromScales(props.scales);
+            }
+            if(props.resolutions == null) {
+                props.resolutions = this.calculateResolutions(props);
+            }
         }
-        // Do not use the resolutions array set at the map level if 
-        // either minResolution or maxResolution or both are set at the
-        // layer level
-        if ((this.options.minResolution != null ||
-             this.options.maxResolution != null) &&
-            this.options.resolutions == null) {
 
-            confProps.resolutions = null;
+        // ok, we new need to set properties in the instance
+
+        // get maxResolution from the config if it's defined there
+        var maxResolution;
+        if(this.options.maxResolution &&
+           this.options.maxResolution !== "auto") {
+            maxResolution = this.options.maxResolution;
         }
+        if(this.options.minScale) {
+            maxResolution = OpenLayers.Util.getResolutionFromScale(
+                this.options.minScale, this.units);
+        }
 
-        // If numZoomLevels hasn't been set and the maxZoomLevel *has*, 
-        //  then use maxZoomLevel to calculate numZoomLevels
-        //
-        if ( (!confProps.numZoomLevels) && (confProps.maxZoomLevel) ) {
-            confProps.numZoomLevels = confProps.maxZoomLevel + 1;
+        // get minResolution from the config if it's defined there
+        var minResolution;
+        if(this.options.minResolution &&
+           this.options.minResolution !== "auto") {
+            minResolution = this.options.minResolution;
         }
+        if(this.options.maxScale) {
+            minResolution = OpenLayers.Util.getResolutionFromScale(
+                this.options.maxScale, this.units);
+        }
 
-        // First off, we take whatever hodge-podge of values we have and 
-        //  calculate/distill them down into a resolutions[] array
-        //
-        if ((confProps.scales != null) || (confProps.resolutions != null)) {
-          //preset levels
-            if (confProps.scales != null) {
-                confProps.resolutions = [];
-                for(var i=0, len=confProps.scales.length; i<len; i++) {
-                    var scale = confProps.scales[i];
-                    confProps.resolutions[i] = 
-                       OpenLayers.Util.getResolutionFromScale(scale, 
-                                                              confProps.units);
-                }
+        if(props.resolutions) {
+
+            //sort resolutions array descendingly
+            props.resolutions.sort(function(a, b) {
+                return (b - a);
+            });
+
+            // if we still don't have a maxResolution get it from the
+            // resolutions array
+            if(!maxResolution) {
+                maxResolution = props.resolutions[0];
             }
-            confProps.numZoomLevels = confProps.resolutions.length;
 
-        } else {
-          //maxResolution and numZoomLevels based calculation
+            // if we still don't have a minResolution get it from the
+            // resolutions array
+            if(!minResolution) {
+                var lastIdx = props.resolutions.length - 1;
+                minResolution = props.resolutions[lastIdx];
+            }
+        }
 
-            // determine maxResolution
-            if (confProps.minScale) {
-                confProps.maxResolution = 
-                    OpenLayers.Util.getResolutionFromScale(confProps.minScale, 
-                                                           confProps.units);
-            } else if (confProps.maxResolution == "auto") {
-                var viewSize = this.map.getSize();
-                var wRes = confProps.maxExtent.getWidth() / viewSize.w;
-                var hRes = confProps.maxExtent.getHeight()/ viewSize.h;
-                confProps.maxResolution = Math.max(wRes, hRes);
-            } 
+        this.resolutions = props.resolutions;
+        if(this.resolutions) {
+            len = this.resolutions.length;
+            this.scales = new Array(len);
+            for(i=0; i<len; i++) {
+                this.scales[i] = OpenLayers.Util.getScaleFromResolution(
+                    this.resolutions[i], this.units);
+            }
+            this.numZoomLevels = len;
+        }
+        this.minResolution = minResolution;
+        if(minResolution) {
+            this.maxScale = OpenLayers.Util.getScaleFromResolution(
+                minResolution, this.units);
+        }
+        this.maxResolution = maxResolution;
+        if(maxResolution) {
+            this.minScale = OpenLayers.Util.getScaleFromResolution(
+                maxResolution, this.units);
+        }
+    },
 
-            // determine minResolution
-            if (confProps.maxScale != null) {           
-                confProps.minResolution = 
-                    OpenLayers.Util.getResolutionFromScale(confProps.maxScale, 
-                                                           confProps.units);
-            } else if ( (confProps.minResolution == "auto") && 
-                        (confProps.minExtent != null) ) {
-                var viewSize = this.map.getSize();
-                var wRes = confProps.minExtent.getWidth() / viewSize.w;
-                var hRes = confProps.minExtent.getHeight()/ viewSize.h;
-                confProps.minResolution = Math.max(wRes, hRes);
-            } 
+    /**
+     * Method: resolutionsFromScales
+     * Derive resolutions from scales.
+     *
+     * Parameters:
+     * scales - {Array(Number)} Scales
+     *
+     * Returns
+     * {Array(Number)} Resolutions
+     */
+    resolutionsFromScales: function(scales) {
+        if(scales == null) {
+            return;
+        }
+        var resolutions, i, len;
+        len = scales.length;
+        resolutions = new Array(len);
+        for(i=0; i<len; i++) {
+            resolutions[i] = OpenLayers.Util.getResolutionFromScale(
+                scales[i], this.units);
+        }
+        return resolutions;
+    },
 
-            // determine numZoomLevels if not already set on the layer
-            // this gives numZoomLevels assuming approximately base 2 scaling
-            if (confProps.minResolution != null &&
-                this.options.numZoomLevels == undefined) {
-                var ratio = confProps.maxResolution / confProps.minResolution;
-                confProps.numZoomLevels = 
-                    Math.floor(Math.log(ratio) / Math.log(2)) + 1;
+    /**
+     * Method: calculateResolutions
+     * Calculate resolutions based on the provided properties.
+     *
+     * Parameters:
+     * props - {Object} Properties
+     *
+     * Return:
+     * {Array({Number})} Array of resolutions.
+     */
+    calculateResolutions: function(props) {
+
+        // determine maxResolution
+        var maxResolution = props.maxResolution;
+        if(props.minScale != null) {
+            maxResolution =
+                OpenLayers.Util.getResolutionFromScale(props.minScale,
+                                                       this.units);
+        } else if(maxResolution == "auto" && this.maxExtent != null) {
+            var viewSize = this.map.getSize();
+            var wRes = this.maxExtent.getWidth() / viewSize.w;
+            var hRes = this.maxExtent.getHeight() / viewSize.h;
+            maxResolution = Math.max(wRes, hRes);
+        }
+
+        // determine minResolution
+        var minResolution = props.minResolution;
+        if(props.maxScale != null) {
+            minResolution =
+                OpenLayers.Util.getResolutionFromScale(props.maxScale,
+                                                       this.units);
+        } else if(props.minResolution == "auto" && this.minExtent != null) {
+            var viewSize = this.map.getSize();
+            var wRes = this.minExtent.getWidth() / viewSize.w;
+            var hRes = this.minExtent.getHeight()/ viewSize.h;
+            minResolution = Math.max(wRes, hRes);
+        }
+
+        // determine numZoomLevels
+        var maxZoomLevel = props.maxZoomLevel;
+        var numZoomLevels = props.numZoomLevels;
+        if(typeof minResolution === "number" &&
+           typeof maxResolution === "number" && numZoomLevels === undefined) {
+            var ratio = maxResolution / minResolution;
+            numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;
+        } else if(numZoomLevels === undefined && maxZoomLevel != null) {
+            numZoomLevels = maxZoomLevel + 1;
+        }
+
+        // are we able to calculate resolutions?
+        if(typeof numZoomLevels !== "number" || numZoomLevels <= 0 ||
+           (typeof maxResolution !== "number" &&
+                typeof minResolution !== "number")) {
+            return;
+        }
+
+        // now we have numZoomLevels and at least one of maxResolution
+        // or minResolution, we can populate the resolutions array
+
+        var resolutions = new Array(numZoomLevels);
+        var base = 2;
+        if(typeof minResolution == "number" &&
+           typeof maxResolution == "number") {
+            // if maxResolution and minResolution are set, we calculate
+            // the base for exponential scaling that starts at
+            // maxResolution and ends at minResolution in numZoomLevels
+            // steps.
+            base = Math.pow(
+                    (maxResolution / minResolution),
+                (1 / (numZoomLevels - 1))
+            );
+        }
+
+        var i;
+        if(typeof maxResolution === "number") {
+            for(i=0; i<numZoomLevels; i++) {
+                resolutions[i] = maxResolution / Math.pow(base, i);
             }
-            
-            // now we have numZoomLevels and maxResolution, 
-            //  we can populate the resolutions array
-            confProps.resolutions = new Array(confProps.numZoomLevels);
-            var base = 2;
-            if(typeof confProps.minResolution == "number" &&
-               confProps.numZoomLevels > 1) {
-                /**
-                 * If maxResolution and minResolution are set (or related
-                 * scale properties), we calculate the base for exponential
-                 * scaling that starts at maxResolution and ends at
-                 * minResolution in numZoomLevels steps.
-                 */
-                base = Math.pow(
-                    (confProps.maxResolution / confProps.minResolution),
-                    (1 / (confProps.numZoomLevels - 1))
-                );
+        } else {
+            for(i=0; i<numZoomLevels; i++) {
+                resolutions[numZoomLevels - 1 - i] =
+                    minResolution * Math.pow(base, i);
             }
-            for (var i=0; i < confProps.numZoomLevels; i++) {
-                var res = confProps.maxResolution / Math.pow(base, i);
-                confProps.resolutions[i] = res;
-            }
         }
-        
-        //sort resolutions array ascendingly
-        //
-        confProps.resolutions.sort( function(a, b) { return(b-a); } );
 
-        // now set our newly calculated values back to the layer 
-        //  Note: We specifically do *not* set them to layer.options, which we 
-        //        will preserve as it was when we added this layer to the map. 
-        //        this way cloned layers reset themselves to new map div 
-        //        dimensions)
-        //
-
-        this.resolutions = confProps.resolutions;
-        this.maxResolution = confProps.resolutions[0];
-        var lastIndex = confProps.resolutions.length - 1;
-        this.minResolution = confProps.resolutions[lastIndex];
-        
-        this.scales = [];
-        for(var i=0, len=confProps.resolutions.length; i<len; i++) {
-            this.scales[i] = 
-               OpenLayers.Util.getScaleFromResolution(confProps.resolutions[i], 
-                                                      confProps.units);
-        }
-        this.minScale = this.scales[0];
-        this.maxScale = this.scales[this.scales.length - 1];
-        
-        this.numZoomLevels = confProps.numZoomLevels;
+        return resolutions;
     },
 
     /**
@@ -22067,8 +22968,9 @@
     OpenLayers/Marker/Box.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -22190,7 +23092,7 @@
     OpenLayers/Request/XMLHttpRequest.js
    ====================================================================== */
 
-// Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+// XMLHttpRequest.js Copyright (C) 2010 Sergey Ilinsky (http://www.ilinsky.com)
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -22215,11 +23117,13 @@
 
     // Define on browser type
     var bGecko    = !!window.controllers,
-        bIE        = window.document.all && !window.opera;
+        bIE        = window.document.all && !window.opera,
+        bIE7    = bIE && window.navigator.userAgent.match(/MSIE ([\.0-9]+)/) && RegExp.$1 == 7;
 
     // Constructor
     function cXMLHttpRequest() {
-        this._object    = oXMLHttpRequest ? new oXMLHttpRequest : new window.ActiveXObject('Microsoft.XMLHTTP');
+        this._object    = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
+        this._listeners    = [];
     };
 
     // BUGFIX: Firefox with Firebug installed would break pages if not executed
@@ -22235,10 +23139,10 @@
 
     // Public Properties
     cXMLHttpRequest.prototype.readyState    = cXMLHttpRequest.UNSENT;
-    cXMLHttpRequest.prototype.responseText    = "";
+    cXMLHttpRequest.prototype.responseText    = '';
     cXMLHttpRequest.prototype.responseXML    = null;
     cXMLHttpRequest.prototype.status        = 0;
-    cXMLHttpRequest.prototype.statusText    = "";
+    cXMLHttpRequest.prototype.statusText    = '';
 
     // Instance-level Events Handlers
     cXMLHttpRequest.prototype.onreadystatechange    = null;
@@ -22251,24 +23155,50 @@
 
     // Public Methods
     cXMLHttpRequest.prototype.open    = function(sMethod, sUrl, bAsync, sUser, sPassword) {
+        // Delete headers, required when object is reused
+        delete this._headers;
 
+        // When bAsync parameter value is omitted, use true as default
+        if (arguments.length < 3)
+            bAsync    = true;
+
         // Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
         this._async        = bAsync;
 
         // Set the onreadystatechange handler
         var oRequest    = this,
-            nState        = this.readyState;
+            nState        = this.readyState,
+            fOnUnload;
 
         // BUGFIX: IE - memory leak on page unload (inter-page leak)
-        if (bIE) {
-            var fOnUnload    = function() {
-                if (oRequest._object.readyState != cXMLHttpRequest.DONE)
+        if (bIE && bAsync) {
+            fOnUnload = function() {
+                if (nState != cXMLHttpRequest.DONE) {
                     fCleanTransport(oRequest);
+                    // Safe to abort here since onreadystatechange handler removed
+                    oRequest.abort();
+                }
             };
-            if (bAsync)
                 window.attachEvent("onunload", fOnUnload);
         }
 
+        // Add method sniffer
+        if (cXMLHttpRequest.onopen)
+            cXMLHttpRequest.onopen.apply(this, arguments);
+
+        if (arguments.length > 4)
+            this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
+        else
+        if (arguments.length > 3)
+            this._object.open(sMethod, sUrl, bAsync, sUser);
+        else
+            this._object.open(sMethod, sUrl, bAsync);
+
+        if (!bGecko && !bIE) {
+            this.readyState    = cXMLHttpRequest.OPENED;
+            fReadyStateChange(this);
+        }
+
         this._object.onreadystatechange    = function() {
             if (bGecko && !bAsync)
                 return;
@@ -22279,7 +23209,7 @@
             //
             fSynchronizeValues(oRequest);
 
-            // BUGFIX: Firefox fires unneccesary DONE when aborting
+            // BUGFIX: Firefox fires unnecessary DONE when aborting
             if (oRequest._aborted) {
                 // Reset readyState to UNSENT
                 oRequest.readyState    = cXMLHttpRequest.UNSENT;
@@ -22302,7 +23232,14 @@
                     cXMLHttpRequest.call(oRequest);
 
                     // Re-send request
+                    if (sUser) {
+                         if (sPassword)
                     oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
+                        else
+                            oRequest._object.open(sMethod, sUrl, bAsync, sUser);
+                    }
+                    else
+                        oRequest._object.open(sMethod, sUrl, bAsync);
                     oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
                     // Copy headers set
                     if (oRequest._headers)
@@ -22346,7 +23283,7 @@
                     };
                     oRequest._object.send(null);
 
-                    // Return now - wait untill re-sent request is finished
+                    // Return now - wait until re-sent request is finished
                     return;
                 };
 */
@@ -22360,19 +23297,6 @@
                 fReadyStateChange(oRequest);
 
             nState    = oRequest.readyState;
-        };
-
-        // Add method sniffer
-        if (cXMLHttpRequest.onopen)
-            cXMLHttpRequest.onopen.apply(this, arguments);
-
-        this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
-
-        // BUGFIX: Gecko - missing readystatechange calls in synchronous requests
-        if (!bAsync && bGecko) {
-            this.readyState    = cXMLHttpRequest.OPENED;
-
-            fReadyStateChange(this);
         }
     };
     cXMLHttpRequest.prototype.send    = function(vData) {
@@ -22413,7 +23337,7 @@
         if (cXMLHttpRequest.onabort)
             cXMLHttpRequest.onabort.apply(this, arguments);
 
-        // BUGFIX: Gecko - unneccesary DONE when aborting
+        // BUGFIX: Gecko - unnecessary DONE when aborting
         if (this.readyState > cXMLHttpRequest.UNSENT)
             this._aborted    = true;
 
@@ -22436,34 +23360,86 @@
 
         return this._object.setRequestHeader(sName, sValue);
     };
+
+    // EventTarget interface implementation
+    cXMLHttpRequest.prototype.addEventListener    = function(sName, fHandler, bUseCapture) {
+        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
+                return;
+        // Add listener
+        this._listeners.push([sName, fHandler, bUseCapture]);
+    };
+
+    cXMLHttpRequest.prototype.removeEventListener    = function(sName, fHandler, bUseCapture) {
+        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
+                break;
+        // Remove listener
+        if (oListener)
+            this._listeners.splice(nIndex, 1);
+    };
+
+    cXMLHttpRequest.prototype.dispatchEvent    = function(oEvent) {
+        var oEventPseudo    = {
+            'type':            oEvent.type,
+            'target':        this,
+            'currentTarget':this,
+            'eventPhase':    2,
+            'bubbles':        oEvent.bubbles,
+            'cancelable':    oEvent.cancelable,
+            'timeStamp':    oEvent.timeStamp,
+            'stopPropagation':    function() {},    // There is no flow
+            'preventDefault':    function() {},    // There is no default action
+            'initEvent':        function() {}    // Original event object should be initialized
+        };
+
+        // Execute onreadystatechange
+        if (oEventPseudo.type == "readystatechange" && this.onreadystatechange)
+            (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
+
+        // Execute listeners
+        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+            if (oListener[0] == oEventPseudo.type && !oListener[2])
+                (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
+    };
+
+    //
     cXMLHttpRequest.prototype.toString    = function() {
         return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
     };
+
     cXMLHttpRequest.toString    = function() {
         return '[' + "XMLHttpRequest" + ']';
     };
 
     // Helper function
     function fReadyStateChange(oRequest) {
-        // Execute onreadystatechange
-        if (oRequest.onreadystatechange)
-            oRequest.onreadystatechange.apply(oRequest);
-
         // Sniffing code
         if (cXMLHttpRequest.onreadystatechange)
             cXMLHttpRequest.onreadystatechange.apply(oRequest);
+
+        // Fake event
+        oRequest.dispatchEvent({
+            'type':            "readystatechange",
+            'bubbles':        false,
+            'cancelable':    false,
+            'timeStamp':    new Date + 0
+        });
     };
 
     function fGetDocument(oRequest) {
-        var oDocument    = oRequest.responseXML;
+        var oDocument    = oRequest.responseXML,
+            sResponse    = oRequest.responseText;
         // Try parsing responseText
-        if (bIE && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
-            oDocument    = new ActiveXObject('Microsoft.XMLDOM');
-            oDocument.loadXML(oRequest.responseText);
+        if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
+            oDocument    = new window.ActiveXObject("Microsoft.XMLDOM");
+            oDocument.async                = false;
+            oDocument.validateOnParse    = false;
+            oDocument.loadXML(sResponse);
         }
         // Check if there is no error in document
         if (oDocument)
-            if ((bIE && oDocument.parseError != 0) || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
+            if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
                 return null;
         return oDocument;
     };
@@ -22478,9 +23454,6 @@
     function fCleanTransport(oRequest) {
         // BUGFIX: IE - memory leak (on-page leak)
         oRequest._object.onreadystatechange    = new window.Function;
-
-        // Delete private properties
-        delete oRequest._headers;
     };
 
     // Internet Explorer 5.0 (missing apply)
@@ -22507,8 +23480,9 @@
     OpenLayers/Ajax.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -23188,8 +24162,9 @@
     OpenLayers/Control/DragPan.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -23285,8 +24260,9 @@
     OpenLayers/Feature/Vector.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 // TRASH THIS
@@ -23329,8 +24305,8 @@
 
     /** 
      * APIProperty: attributes 
-     * {Object} This object holds arbitrary properties that describe the
-     *     feature.
+     * {Object} This object holds arbitrary, serializable properties that
+     *     describe the feature.
      */
     attributes: null,
 
@@ -23742,8 +24718,9 @@
     OpenLayers/Handler/Box.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -23805,6 +24782,17 @@
     },
 
     /**
+     * Method: destroy
+     */
+    destroy: function() {
+        if (this.dragHandler) {
+            this.dragHandler.destroy();
+            this.dragHandler = null;
+        }            
+        OpenLayers.Handler.prototype.destroy.apply(this, arguments);
+    },
+
+    /**
      * Method: setMap
      */
     setMap: function (map) {
@@ -23955,8 +24943,9 @@
     OpenLayers/Handler/RegularPolygon.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -24013,6 +25002,12 @@
     snapToggle: 'shiftKey',
     
     /**
+     * Property: layerOptions
+     * {Object} Any optional properties to be set on the sketch layer.
+     */
+    layerOptions: null,
+
+    /**
      * APIProperty: persist
      * {Boolean} Leave the feature rendered until clear is called.  Default
      *     is false.  If set to true, the feature remains rendered until
@@ -24087,11 +25082,13 @@
      *     cancel callback will receive a geometry.
      */
     initialize: function(control, callbacks, options) {
-        this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
+        if(!(options && options.layerOptions && options.layerOptions.styleMap)) {
+            this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
+        }
 
         OpenLayers.Handler.prototype.initialize.apply(this,
                                                 [control, callbacks, options]);
-        this.options = (options) ? options : new Object();
+        this.options = (options) ? options : {};
     },
     
     /**
@@ -24116,14 +25113,14 @@
         var activated = false;
         if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
             // create temporary vector layer for rendering geometry sketch
-            var options = {
+            var options = OpenLayers.Util.extend({
                 displayInLayerSwitcher: false,
                 // indicate that the temp vector layer will never be out of range
                 // without this, resolution properties must be specified at the
                 // map-level for this temporary layer to init its resolutions
                 // correctly
                 calculateInRange: OpenLayers.Function.True
-            };
+            }, this.layerOptions);
             this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
             this.map.addLayer(this.layer);
             activated = true;
@@ -24275,7 +25272,7 @@
      * Modify the polygon geometry in place.
      */
     modifyGeometry: function() {
-        var angle, dx, dy, point;
+        var angle, point;
         var ring = this.feature.geometry.components[0];
         // if the number of sides ever changes, create a new geometry
         if(ring.components.length != (this.sides + 1)) {
@@ -24336,8 +25333,10 @@
      *     is true).
      */
     clear: function() {
-        this.layer.renderer.clear();
-        this.layer.destroyFeatures();
+        if (this.layer) {
+            this.layer.renderer.clear();
+            this.layer.destroyFeatures();
+        }
     },
     
     /**
@@ -24369,8 +25368,9 @@
     OpenLayers/Layer/EventPane.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -24790,8 +25790,9 @@
     OpenLayers/Layer/FixedZoomLevels.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -25108,8 +26109,9 @@
     OpenLayers/Layer/HTTPRequest.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -25341,8 +26343,9 @@
     OpenLayers/Layer/Markers.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -25531,6 +26534,11 @@
     OpenLayers/Layer/SphericalMercator.js
    ====================================================================== */
 
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
 /**
  * @requires OpenLayers/Layer.js
  * @requires OpenLayers/Projection.js
@@ -25583,6 +26591,38 @@
         return extent;
     },
 
+    /**
+     * Method: getLonLatFromViewPortPx
+     * Get a map location from a pixel location
+     * 
+     * Parameters:
+     * viewPortPx - {<OpenLayers.Pixel>}
+     *
+     * Returns:
+     *  {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in view
+     *  port OpenLayers.Pixel, translated into lon/lat by map lib
+     *  If the map lib is not loaded or not centered, returns null
+     */
+    getLonLatFromViewPortPx: function (viewPortPx) {
+        return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this, arguments);
+    },
+    
+    /**
+     * Method: getViewPortPxFromLonLat
+     * Get a pixel location from a map location
+     *
+     * Parameters:
+     * lonlat - {<OpenLayers.LonLat>}
+     *
+     * Returns:
+     * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
+     * OpenLayers.LonLat, translated into view port pixels by map lib
+     * If map lib is not loaded or not centered, returns null
+     */
+    getViewPortPxFromLonLat: function (lonlat) {
+        return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this, arguments);
+    },
+
     /** 
      * Method: initMercatorParameters 
      * Set up the mercator parameters on the layer: resolutions,
@@ -25596,7 +26636,7 @@
             this.RESOLUTIONS[zoom] = maxResolution / Math.pow(2, zoom);
         }
         this.units = "m";
-        this.projection = "EPSG:900913";
+        this.projection = this.projection || "EPSG:900913";
     },
 
     /**
@@ -25694,8 +26734,9 @@
     OpenLayers/Control/DrawFeature.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -25823,8 +26864,9 @@
     OpenLayers/Control/Measure.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -26004,12 +27046,15 @@
      * geometry - {<OpenLayers.Geometry>} The sketch geometry.
      */
     measurePartial: function(point, geometry) {
-        this.delayedTrigger = window.setTimeout(
-            OpenLayers.Function.bind(function() {
-                this.measure(geometry, "measurepartial");
-            }, this),
-            this.partialDelay
-        );
+        if (geometry.getLength() > 0) {
+            geometry = geometry.clone();
+            this.delayedTrigger = window.setTimeout(
+                OpenLayers.Function.bind(function() {
+                    this.measure(geometry, "measurepartial");
+                }, this),
+                this.partialDelay
+            );
+        }
     },
 
     /**
@@ -26144,8 +27189,9 @@
     OpenLayers/Control/ZoomBox.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -26242,8 +27288,9 @@
     OpenLayers/Format/WKT.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -26395,7 +27442,9 @@
         'multipoint': function(multipoint) {
             var array = [];
             for(var i=0, len=multipoint.components.length; i<len; ++i) {
-                array.push(this.extract.point.apply(this, [multipoint.components[i]]));
+                array.push('(' +
+                           this.extract.point.apply(this, [multipoint.components[i]]) +
+                           ')');
             }
             return array.join(',');
         },
@@ -26488,10 +27537,12 @@
          * @private
          */
         'multipoint': function(str) {
-            var points = OpenLayers.String.trim(str).split(',');
+            var point;
+            var points = OpenLayers.String.trim(str).split(this.regExes.parenComma);
             var components = [];
             for(var i=0, len=points.length; i<len; ++i) {
-                components.push(this.parse.point.apply(this, [points[i]]).geometry);
+                point = points[i].replace(this.regExes.trimParens, '$1');
+                components.push(this.parse.point.apply(this, [point]).geometry);
             }
             return new OpenLayers.Feature.Vector(
                 new OpenLayers.Geometry.MultiPoint(components)
@@ -26599,8 +27650,9 @@
     OpenLayers/Layer/Google.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -26608,7 +27660,6 @@
  * @requires OpenLayers/Layer/SphericalMercator.js
  * @requires OpenLayers/Layer/EventPane.js
  * @requires OpenLayers/Layer/FixedZoomLevels.js
- * @requires OpenLayers/Console.js
  */
 
 /**
@@ -26672,6 +27723,14 @@
     type: null,
 
     /**
+     * APIProperty: wrapDateLine
+     * {Boolean} Allow user to pan forever east/west.  Default is true.  
+     *     Setting this to false only restricts panning if 
+     *     <sphericalMercator> is true. 
+     */
+    wrapDateLine: true,
+
+    /**
      * APIProperty: sphericalMercator
      * {Boolean} Should the map act as a mercator-projected map? This will
      *     cause all interactions with the map to be in the actual map 
@@ -26681,24 +27740,11 @@
     sphericalMercator: false, 
     
     /**
-     * Property: dragObject
-     * {GDraggableObject} Since 2.93, Google has exposed the ability to get
-     *     the maps GDraggableObject. We can now use this for smooth panning
+     * Property: version
+     * {Number} The version of the Google Maps API
      */
-    dragObject: null, 
+    version: null,
 
-    /**
-     * Property: termsOfUse
-     * {DOMElement} Div for Google's copyright and terms of use link
-     */
-    termsOfUse: null, 
-
-    /**
-     * Property: poweredBy
-     * {DOMElement} Div for Google's powered by logo and link
-     */
-    poweredBy: null, 
-
     /** 
      * Constructor: OpenLayers.Layer.Google
      * 
@@ -26708,16 +27754,34 @@
      *     on the layer.
      */
     initialize: function(name, options) {
-        OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);
+        options = options || {};
+        if(!options.version) {
+            options.version = typeof GMap2 === "function" ? "2" : "3";
+        }
+        var mixin = OpenLayers.Layer.Google["v" +
+            options.version.replace(/\./g, "_")];
+        if (mixin) {
+            OpenLayers.Util.applyDefaults(options, mixin);
+        } else {
+            throw "Unsupported Google Maps API version: " + options.version;
+        }
+
+        OpenLayers.Util.applyDefaults(options, mixin.DEFAULTS);
+        if (options.maxExtent) {
+            options.maxExtent = options.maxExtent.clone();
+        }
+
+        OpenLayers.Layer.EventPane.prototype.initialize.apply(this,
+            [name, options]);
         OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, 
-                                                                    arguments);
-        this.addContainerPxFunction();
+            [name, options]);
+
         if (this.sphericalMercator) {
             OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);
             this.initMercatorParameters();
         }    
     },
-    
+
     /**
      * Method: clone
      * Create a clone of this layer
@@ -26736,118 +27800,8 @@
             this.name, this.getOptions()
         );
     },
-    
-    /** 
-     * Method: loadMapObject
-     * Load the GMap and register appropriate event listeners. If we can't 
-     *     load GMap2, then display a warning message.
-     */
-    loadMapObject:function() {
-        if (!this.type) {
-            this.type = G_NORMAL_MAP;
-        }
-        var mapObject, termsOfUse, poweredBy;
-        var cache = OpenLayers.Layer.Google.cache[this.map.id];
-        if (cache) {
-            // there are already Google layers added to this map
-            mapObject = cache.mapObject;
-            termsOfUse = cache.termsOfUse;
-            poweredBy = cache.poweredBy;
-            // increment the layer count
-            ++cache.count;
-        } else {
-            // this is the first Google layer for this map
 
-            var container = this.map.viewPortDiv;
-            var div = document.createElement("div");
-            div.id = this.map.id + "_GMap2Container";
-            div.style.position = "absolute";
-            div.style.width = "100%";
-            div.style.height = "100%";
-            container.appendChild(div);
-
-            // create GMap and shuffle elements
-            try {
-                mapObject = new GMap2(div);
-                
-                // move the ToS and branding stuff up to the container div
-                termsOfUse = div.lastChild;
-                container.appendChild(termsOfUse);
-                termsOfUse.style.zIndex = "1100";
-                termsOfUse.style.right = "";
-                termsOfUse.style.bottom = "";
-                termsOfUse.className = "olLayerGoogleCopyright";
-
-                poweredBy = div.lastChild;
-                container.appendChild(poweredBy);
-                poweredBy.style.zIndex = "1100";
-                poweredBy.style.right = "";
-                poweredBy.style.bottom = "";
-                poweredBy.className = "olLayerGooglePoweredBy gmnoprint";
-                
-            } catch (e) {
-                OpenLayers.Console.error(e);
-                return;
-            }
-            // cache elements for use by any other google layers added to
-            // this same map
-            OpenLayers.Layer.Google.cache[this.map.id] = {
-                mapObject: mapObject,
-                termsOfUse: termsOfUse,
-                poweredBy: poweredBy,
-                count: 1
-            };
-        }
-
-        this.mapObject = mapObject;
-        this.termsOfUse = termsOfUse;
-        this.poweredBy = poweredBy;
-        
-        // ensure this layer type is one of the mapObject types
-        if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),
-                                    this.type) === -1) {
-            this.mapObject.addMapType(this.type);
-        }
-
-        //since v 2.93 getDragObject is now available.
-        if(typeof mapObject.getDragObject == "function") {
-            this.dragObject = mapObject.getDragObject();
-        } else {
-            this.dragPanMapObject = null;
-        }
-        
-        if(this.isBaseLayer === false) {
-            this.setGMapVisibility(this.div.style.display !== "none");
-        }
-
-    },
-
     /**
-     * APIMethod: onMapResize
-     */
-    onMapResize: function() {
-        // workaround for resizing of invisible or not yet fully loaded layers
-        // where GMap2.checkResize() does not work. We need to load the GMap
-        // for the old div size, then checkResize(), and then call
-        // layer.moveTo() to trigger GMap.setCenter() (which will finish
-        // the GMap initialization).
-        if(this.visibility && this.mapObject.isLoaded()) {
-            this.mapObject.checkResize();
-        } else {
-            if(!this._resized) {
-                var layer = this;
-                var handle = GEvent.addListener(this.mapObject, "load", function() {
-                    GEvent.removeListener(handle);
-                    delete layer._resized;
-                    layer.mapObject.checkResize();
-                    layer.moveTo(layer.map.getCenter(), layer.map.getZoom());
-                });
-            }
-            this._resized = true;
-        }
-    },
-
-    /**
      * APIMethod: setVisibility
      * Set the visibility flag for the layer and hide/show & redraw 
      *     accordingly. Fire event unless otherwise specified
@@ -26863,51 +27817,42 @@
      * visible - {Boolean} Display the layer (if in range)
      */
     setVisibility: function(visible) {
-        this.setGMapVisibility(visible);
         // sharing a map container, opacity has to be set per layer
         var opacity = this.opacity == null ? 1 : this.opacity;
         OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this, arguments);
         this.setOpacity(opacity);
     },
     
-    /**
-     * Method: setGMapVisibility
-     * Display the GMap container and associated elements.
+    /** 
+     * APIMethod: display
+     * Hide or show the Layer
      * 
      * Parameters:
-     * visible - {Boolean} Display the GMap elements.
+     * display - {Boolean}
      */
-    setGMapVisibility: function(visible) {
-        var cache = OpenLayers.Layer.Google.cache[this.map.id];
-        if (cache) {
-            var container = this.mapObject.getContainer();
-            if (visible === true) {
-                this.mapObject.setMapType(this.type);
-                container.style.display = "";
-                this.termsOfUse.style.left = "";
-                this.termsOfUse.style.display = "";
-                this.poweredBy.style.display = "";            
-                cache.displayed = this.id;
-            } else {
-                if (cache.displayed === this.id) {
-                    delete cache.displayed;
-                }
-                if (!cache.displayed) {
-                    container.style.display = "none";
-                    this.termsOfUse.style.display = "none";
-                    // move ToU far to the left in addition to setting display
-                    // to "none", because at the end of the GMap2 load
-                    // sequence, display: none will be unset and ToU would be
-                    // visible after loading a map with a google layer that is
-                    // initially hidden. 
-                    this.termsOfUse.style.left = "-9999px";
-                    this.poweredBy.style.display = "none";
-                }
-            }
+    display: function(visible) {
+        if (!this._dragging) {
+            this.setGMapVisibility(visible);
         }
+        OpenLayers.Layer.EventPane.prototype.display.apply(this, arguments);
     },
     
     /**
+     * Method: moveTo
+     * 
+     * Parameters:
+     * bound - {<OpenLayers.Bounds>}
+     * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to
+     *     do some init work in that case.
+     * dragging - {Boolean}
+     */
+    moveTo: function(bounds, zoomChanged, dragging) {
+        this._dragging = dragging;
+        OpenLayers.Layer.EventPane.prototype.moveTo.apply(this, arguments);
+        delete this._dragging;
+    },
+    
+    /**
      * APIMethod: setOpacity
      * Sets the opacity for the entire layer (all images)
      * 
@@ -26927,7 +27872,7 @@
         // Though this layer's opacity may not change, we're sharing a container
         // and need to update the opacity for the entire container.
         if (this.getVisibility()) {
-            var container = this.mapObject.getContainer();
+            var container = this.getMapContainer();
             OpenLayers.Util.modifyDOMElement(
                 container, null, null, null, null, null, null, opacity
             );
@@ -26948,7 +27893,7 @@
             this.setGMapVisibility(false);
             var cache = OpenLayers.Layer.Google.cache[this.map.id];
             if (cache && cache.count <= 1) {
-                this.removeGMapElements(false);
+                this.removeGMapElements();
             }            
         }
         OpenLayers.Layer.EventPane.prototype.destroy.apply(this, arguments);
@@ -26963,7 +27908,7 @@
         var cache = OpenLayers.Layer.Google.cache[this.map.id];
         if (cache) {
             // remove shared elements from dom
-            var container = this.mapObject && this.mapObject.getContainer();                
+            var container = this.mapObject && this.getMapContainer();                
             if (container && container.parentNode) {
                 container.parentNode.removeChild(container);
             }
@@ -27009,33 +27954,6 @@
         OpenLayers.Layer.EventPane.prototype.removeMap.apply(this, arguments);
     },
     
-    /**
-     * APIMethod: getZoomForExtent
-     * 
-     * Parameters:
-     * bounds - {<OpenLayers.Bounds>}
-     *  
-     * Returns:
-     * {Integer} Corresponding zoom level for a specified Bounds. 
-     *           If mapObject is not loaded or not centered, returns null
-     *
-    getZoomForExtent: function (bounds) {
-        var zoom = null;
-        if (this.mapObject != null) {
-            var moBounds = this.getMapObjectBoundsFromOLBounds(bounds);
-            var moZoom = this.getMapObjectZoomFromMapObjectBounds(moBounds);
-
-            //make sure zoom is within bounds    
-            var moZoom = Math.min(Math.max(moZoom, this.minZoomLevel), 
-                                 this.maxZoomLevel);
-
-            zoom = this.getOLZoomFromMapObjectZoom(moZoom);
-        }
-        return zoom;
-    },
-    
-    */
-    
   //
   // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds
   //
@@ -27071,7 +27989,313 @@
         return olBounds;
     },
 
+    /** 
+     * APIMethod: getWarningHTML
+     * 
+     * Returns: 
+     * {String} String with information on why layer is broken, how to get
+     *          it working.
+     */
+    getWarningHTML:function() {
+        return OpenLayers.i18n("googleWarning");
+    },
+
+
+    /************************************
+     *                                  *
+     *   MapObject Interface Controls   *
+     *                                  *
+     ************************************/
+
+
+  // Get&Set Center, Zoom
+
     /**
+     * APIMethod: getMapObjectCenter
+     * 
+     * Returns: 
+     * {Object} The mapObject's current center in Map Object format
+     */
+    getMapObjectCenter: function() {
+        return this.mapObject.getCenter();
+    },
+
+    /** 
+     * APIMethod: getMapObjectZoom
+     * 
+     * Returns:
+     * {Integer} The mapObject's current zoom, in Map Object format
+     */
+    getMapObjectZoom: function() {
+        return this.mapObject.getZoom();
+    },
+
+  
+    /************************************
+     *                                  *
+     *       MapObject Primitives       *
+     *                                  *
+     ************************************/
+
+
+  // LonLat
+    
+    /**
+     * APIMethod: getLongitudeFromMapObjectLonLat
+     * 
+     * Parameters:
+     * moLonLat - {Object} MapObject LonLat format
+     * 
+     * Returns:
+     * {Float} Longitude of the given MapObject LonLat
+     */
+    getLongitudeFromMapObjectLonLat: function(moLonLat) {
+        return this.sphericalMercator ? 
+          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon :
+          moLonLat.lng();  
+    },
+
+    /**
+     * APIMethod: getLatitudeFromMapObjectLonLat
+     * 
+     * Parameters:
+     * moLonLat - {Object} MapObject LonLat format
+     * 
+     * Returns:
+     * {Float} Latitude of the given MapObject LonLat
+     */
+    getLatitudeFromMapObjectLonLat: function(moLonLat) {
+        var lat = this.sphericalMercator ? 
+          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat :
+          moLonLat.lat(); 
+        return lat;  
+    },
+    
+  // Pixel
+    
+    /**
+     * APIMethod: getXFromMapObjectPixel
+     * 
+     * Parameters:
+     * moPixel - {Object} MapObject Pixel format
+     * 
+     * Returns:
+     * {Integer} X value of the MapObject Pixel
+     */
+    getXFromMapObjectPixel: function(moPixel) {
+        return moPixel.x;
+    },
+
+    /**
+     * APIMethod: getYFromMapObjectPixel
+     * 
+     * Parameters:
+     * moPixel - {Object} MapObject Pixel format
+     * 
+     * Returns:
+     * {Integer} Y value of the MapObject Pixel
+     */
+    getYFromMapObjectPixel: function(moPixel) {
+        return moPixel.y;
+    },
+    
+    CLASS_NAME: "OpenLayers.Layer.Google"
+});
+
+/**
+ * Property: OpenLayers.Layer.Google.cache
+ * {Object} Cache for elements that should only be created once per map.
+ */
+OpenLayers.Layer.Google.cache = {};
+
+
+/**
+ * Constant: OpenLayers.Layer.Google.v2
+ * 
+ * Mixin providing functionality specific to the Google Maps API v2.
+ */
+OpenLayers.Layer.Google.v2 = {
+    
+    /**
+     * Property: termsOfUse
+     * {DOMElement} Div for Google's copyright and terms of use link
+     */
+    termsOfUse: null, 
+
+    /**
+     * Property: poweredBy
+     * {DOMElement} Div for Google's powered by logo and link
+     */
+    poweredBy: null, 
+
+    /**
+     * Property: dragObject
+     * {GDraggableObject} Since 2.93, Google has exposed the ability to get
+     *     the maps GDraggableObject. We can now use this for smooth panning
+     */
+    dragObject: null, 
+    
+    /** 
+     * Method: loadMapObject
+     * Load the GMap and register appropriate event listeners. If we can't 
+     *     load GMap2, then display a warning message.
+     */
+    loadMapObject:function() {
+        if (!this.type) {
+            this.type = G_NORMAL_MAP;
+        }
+        var mapObject, termsOfUse, poweredBy;
+        var cache = OpenLayers.Layer.Google.cache[this.map.id];
+        if (cache) {
+            // there are already Google layers added to this map
+            mapObject = cache.mapObject;
+            termsOfUse = cache.termsOfUse;
+            poweredBy = cache.poweredBy;
+            // increment the layer count
+            ++cache.count;
+        } else {
+            // this is the first Google layer for this map
+
+            var container = this.map.viewPortDiv;
+            var div = document.createElement("div");
+            div.id = this.map.id + "_GMap2Container";
+            div.style.position = "absolute";
+            div.style.width = "100%";
+            div.style.height = "100%";
+            container.appendChild(div);
+
+            // create GMap and shuffle elements
+            try {
+                mapObject = new GMap2(div);
+                
+                // move the ToS and branding stuff up to the container div
+                termsOfUse = div.lastChild;
+                container.appendChild(termsOfUse);
+                termsOfUse.style.zIndex = "1100";
+                termsOfUse.style.right = "";
+                termsOfUse.style.bottom = "";
+                termsOfUse.className = "olLayerGoogleCopyright";
+
+                poweredBy = div.lastChild;
+                container.appendChild(poweredBy);
+                poweredBy.style.zIndex = "1100";
+                poweredBy.style.right = "";
+                poweredBy.style.bottom = "";
+                poweredBy.className = "olLayerGooglePoweredBy gmnoprint";
+                
+            } catch (e) {
+                throw(e);
+            }
+            // cache elements for use by any other google layers added to
+            // this same map
+            OpenLayers.Layer.Google.cache[this.map.id] = {
+                mapObject: mapObject,
+                termsOfUse: termsOfUse,
+                poweredBy: poweredBy,
+                count: 1
+            };
+        }
+
+        this.mapObject = mapObject;
+        this.termsOfUse = termsOfUse;
+        this.poweredBy = poweredBy;
+        
+        // ensure this layer type is one of the mapObject types
+        if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),
+                                    this.type) === -1) {
+            this.mapObject.addMapType(this.type);
+        }
+
+        //since v 2.93 getDragObject is now available.
+        if(typeof mapObject.getDragObject == "function") {
+            this.dragObject = mapObject.getDragObject();
+        } else {
+            this.dragPanMapObject = null;
+        }
+        
+        if(this.isBaseLayer === false) {
+            this.setGMapVisibility(this.div.style.display !== "none");
+        }
+
+    },
+
+    /**
+     * APIMethod: onMapResize
+     */
+    onMapResize: function() {
+        // workaround for resizing of invisible or not yet fully loaded layers
+        // where GMap2.checkResize() does not work. We need to load the GMap
+        // for the old div size, then checkResize(), and then call
+        // layer.moveTo() to trigger GMap.setCenter() (which will finish
+        // the GMap initialization).
+        if(this.visibility && this.mapObject.isLoaded()) {
+            this.mapObject.checkResize();
+        } else {
+            if(!this._resized) {
+                var layer = this;
+                var handle = GEvent.addListener(this.mapObject, "load", function() {
+                    GEvent.removeListener(handle);
+                    delete layer._resized;
+                    layer.mapObject.checkResize();
+                    layer.moveTo(layer.map.getCenter(), layer.map.getZoom());
+                });
+            }
+            this._resized = true;
+        }
+    },
+
+    /**
+     * Method: setGMapVisibility
+     * Display the GMap container and associated elements.
+     * 
+     * Parameters:
+     * visible - {Boolean} Display the GMap elements.
+     */
+    setGMapVisibility: function(visible) {
+        var cache = OpenLayers.Layer.Google.cache[this.map.id];
+        if (cache) {
+            var container = this.mapObject.getContainer();
+            if (visible === true) {
+                this.mapObject.setMapType(this.type);
+                container.style.display = "";
+                this.termsOfUse.style.left = "";
+                this.termsOfUse.style.display = "";
+                this.poweredBy.style.display = "";            
+                cache.displayed = this.id;
+            } else {
+                if (cache.displayed === this.id) {
+                    delete cache.displayed;
+                }
+                if (!cache.displayed) {
+                    container.style.display = "none";
+                    this.termsOfUse.style.display = "none";
+                    // move ToU far to the left in addition to setting display
+                    // to "none", because at the end of the GMap2 load
+                    // sequence, display: none will be unset and ToU would be
+                    // visible after loading a map with a google layer that is
+                    // initially hidden. 
+                    this.termsOfUse.style.left = "-9999px";
+                    this.poweredBy.style.display = "none";
+                }
+            }
+        }
+    },
+    
+    /**
+     * Method: getMapContainer
+     * 
+     * Returns:
+     * {DOMElement} the GMap container's div
+     */
+    getMapContainer: function() {
+        return this.mapObject.getContainer();
+    },
+
+  //
+  // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds
+  //
+
+    /**
      * APIMethod: getMapObjectBoundsFromOLBounds
      * 
      * Parameters:
@@ -27096,49 +28320,7 @@
         return moBounds;
     },
 
-    /** 
-     * Method: addContainerPxFunction
-     * Hack-on function because GMAPS does not give it to us
-     * 
-     * Parameters: 
-     * gLatLng - {GLatLng}
-     * 
-     * Returns:
-     * {GPoint} A GPoint specifying gLatLng translated into "Container" coords
-     */
-    addContainerPxFunction: function() {
-        if ( (typeof GMap2 != "undefined") && 
-             !GMap2.prototype.fromLatLngToContainerPixel) {
-          
-            GMap2.prototype.fromLatLngToContainerPixel = function(gLatLng) {
-          
-                // first we translate into "DivPixel"
-                var gPoint = this.fromLatLngToDivPixel(gLatLng);
-      
-                // locate the sliding "Div" div
-                var div = this.getContainer().firstChild.firstChild;
-  
-                // adjust by the offset of "Div" and voila!
-                gPoint.x += div.offsetLeft;
-                gPoint.y += div.offsetTop;
-    
-                return gPoint;
-            };
-        }
-    },
 
-    /** 
-     * APIMethod: getWarningHTML
-     * 
-     * Returns: 
-     * {String} String with information on why layer is broken, how to get
-     *          it working.
-     */
-    getWarningHTML:function() {
-        return OpenLayers.i18n("googleWarning");
-    },
-
-
     /************************************
      *                                  *
      *   MapObject Interface Controls   *
@@ -27171,27 +28353,7 @@
         this.dragObject.moveBy(new GSize(-dX, dY));
     },
 
-    /**
-     * APIMethod: getMapObjectCenter
-     * 
-     * Returns: 
-     * {Object} The mapObject's current center in Map Object format
-     */
-    getMapObjectCenter: function() {
-        return this.mapObject.getCenter();
-    },
 
-    /** 
-     * APIMethod: getMapObjectZoom
-     * 
-     * Returns:
-     * {Integer} The mapObject's current zoom, in Map Object format
-     */
-    getMapObjectZoom: function() {
-        return this.mapObject.getZoom();
-    },
-
-
   // LonLat - Pixel Translation
   
     /**
@@ -27246,37 +28408,6 @@
   // LonLat
     
     /**
-     * APIMethod: getLongitudeFromMapObjectLonLat
-     * 
-     * Parameters:
-     * moLonLat - {Object} MapObject LonLat format
-     * 
-     * Returns:
-     * {Float} Longitude of the given MapObject LonLat
-     */
-    getLongitudeFromMapObjectLonLat: function(moLonLat) {
-        return this.sphericalMercator ? 
-          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon :
-          moLonLat.lng();  
-    },
-
-    /**
-     * APIMethod: getLatitudeFromMapObjectLonLat
-     * 
-     * Parameters:
-     * moLonLat - {Object} MapObject LonLat format
-     * 
-     * Returns:
-     * {Float} Latitude of the given MapObject LonLat
-     */
-    getLatitudeFromMapObjectLonLat: function(moLonLat) {
-        var lat = this.sphericalMercator ? 
-          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat :
-          moLonLat.lat(); 
-        return lat;  
-    },
-    
-    /**
      * APIMethod: getMapObjectLonLatFromLonLat
      * 
      * Parameters:
@@ -27300,32 +28431,6 @@
   // Pixel
     
     /**
-     * APIMethod: getXFromMapObjectPixel
-     * 
-     * Parameters:
-     * moPixel - {Object} MapObject Pixel format
-     * 
-     * Returns:
-     * {Integer} X value of the MapObject Pixel
-     */
-    getXFromMapObjectPixel: function(moPixel) {
-        return moPixel.x;
-    },
-
-    /**
-     * APIMethod: getYFromMapObjectPixel
-     * 
-     * Parameters:
-     * moPixel - {Object} MapObject Pixel format
-     * 
-     * Returns:
-     * {Integer} Y value of the MapObject Pixel
-     */
-    getYFromMapObjectPixel: function(moPixel) {
-        return moPixel.y;
-    },
-
-    /**
      * APIMethod: getMapObjectPixelFromXY
      * 
      * Parameters:
@@ -27337,22 +28442,16 @@
      */
     getMapObjectPixelFromXY: function(x, y) {
         return new GPoint(x, y);
-    },
-
-    CLASS_NAME: "OpenLayers.Layer.Google"
-});
-
-/**
- * Property: OpenLayers.Layer.Google.cache
- * {Object} Cache for elements that should only be created once per map.
- */
-OpenLayers.Layer.Google.cache = {};
+    }
+    
+};
 /* ======================================================================
     OpenLayers/Layer/Grid.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -27560,7 +28659,7 @@
      */
     setTileSize: function(size) { 
         if (this.singleTile) {
-            size = this.map.getSize().clone();
+            size = this.map.getSize();
             size.h = parseInt(size.h * this.ratio);
             size.w = parseInt(size.w * this.ratio);
         } 
@@ -27707,7 +28806,7 @@
         var minCols = Math.ceil(viewSize.w/this.tileSize.w) +
                       Math.max(1, 2 * this.buffer);
         
-        var extent = this.maxExtent;
+        var extent = this.getMaxExtent();
         var resolution = this.map.getResolution();
         
         var tileLayout = this.calculateGridLayout(bounds, extent, resolution);
@@ -27782,6 +28881,18 @@
         //now actually draw the tiles
         this.spiralTileLoad();
     },
+
+    /**
+     * Method: getMaxExtent
+     * Get this layer's maximum extent. (Implemented as a getter for
+     *     potential specific implementations in sub-classes.)
+     *
+     * Returns:
+     * {OpenLayers.Bounds}
+     */
+    getMaxExtent: function() {
+        return this.maxExtent;
+    },
     
     /**
      * Method: spiralTileLoad
@@ -28097,8 +29208,9 @@
     OpenLayers/Layer/VirtualEarth.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -28165,6 +29277,14 @@
     type: null,
 
     /**
+     * APIProperty: wrapDateLine
+     * {Boolean} Allow user to pan forever east/west.  Default is true.  
+     *     Setting this to false only restricts panning if 
+     *     <sphericalMercator> is true. 
+     */
+    wrapDateLine: true,
+
+    /**
      * APIProperty: sphericalMercator
      * {Boolean} Should the map act as a mercator-projected map? This will
      *     cause all interactions with the map to be in the actual map
@@ -28225,8 +29345,6 @@
                 this.mapObject.AttachEvent("onmousedown", OpenLayers.Function.True);
 
             } catch (e) { }
-            this.mapObject.AttachEvent("onresize",
-                OpenLayers.Function.bindAsEventListener(this.redrawDependentLayers, this));
             this.mapObject.HideDashboard();
             if(typeof this.mapObject.SetAnimationEnabled == "function") {
                 this.mapObject.SetAnimationEnabled(this.animationEnabled);
@@ -28245,20 +29363,6 @@
 
     },
 
-     /**
-     * Method: redrawDependentLayers
-     */
-    redrawDependentLayers: function(event) {
-        if(this.isBaseLayer) {
-            for(var i=0, len=this.map.layers.length; i<len; i++) {
-                var otherLayer = this.map.layers[i];
-                if (otherLayer != this) {
-                    otherLayer.redraw();
-                }
-            }
-        }
-    },
-
     /**
      * Method: onMapResize
      */
@@ -28476,8 +29580,9 @@
     OpenLayers/Layer/Yahoo.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -28542,6 +29647,14 @@
     type: null,
     
     /**
+     * APIProperty: wrapDateLine
+     * {Boolean} Allow user to pan forever east/west.  Default is true.  
+     *     Setting this to false only restricts panning if 
+     *     <sphericalMercator> is true. 
+     */
+    wrapDateLine: true,
+
+    /**
      * APIProperty: sphericalMercator
      * {Boolean} Should the map act as a mercator-projected map? This will
      * cause all interactions with the map to be in the actual map projection,
@@ -28901,9 +30014,10 @@
     OpenLayers/Style.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
-  * full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 
 /**
@@ -28919,6 +30033,12 @@
 OpenLayers.Style = OpenLayers.Class({
 
     /**
+     * Property: id
+     * {String} A unique id for this session.
+     */
+    id: null,
+    
+    /**
      * APIProperty: name
      * {String}
      */
@@ -29022,6 +30142,7 @@
         this.setDefaultStyle(style ||
                              OpenLayers.Feature.Vector.style["default"]);
 
+        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
     },
 
     /** 
@@ -29236,7 +30357,7 @@
      * rules - {Array(<OpenLayers.Rule>)}
      */
     addRules: function(rules) {
-        this.rules = this.rules.concat(rules);
+        Array.prototype.push.apply(this.rules, rules);
         this.propertyStyles = this.findPropertyStyles();
     },
     
@@ -29272,6 +30393,29 @@
         }
     },
     
+    /**
+     * APIMethod: clone
+     * Clones this style.
+     * 
+     * Returns:
+     * {<OpenLayers.Style>} Clone of this style.
+     */
+    clone: function() {
+        var options = OpenLayers.Util.extend({}, this);
+        // clone rules
+        if(this.rules) {
+            options.rules = [];
+            for(var i=0, len=this.rules.length; i<len; ++i) {
+                options.rules.push(this.rules[i].clone());
+            }
+        }
+        // clone context
+        options.context = this.context && OpenLayers.Util.extend({}, this.context);
+        //clone default style
+        var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);
+        return new OpenLayers.Style(defaultStyle, options);
+    },
+    
     CLASS_NAME: "OpenLayers.Style"
 });
 
@@ -29311,13 +30455,15 @@
  * {Array} prefixes of the sld symbolizers. These are the
  * same as the main geometry types
  */
-OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text'];
+OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',
+    'Raster'];
 /* ======================================================================
     OpenLayers/Control/Navigation.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -29622,9 +30768,10 @@
     OpenLayers/Filter.js
    ====================================================================== */
 
-/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 
 /**
@@ -29666,7 +30813,8 @@
      *     subclasses.
      * 
      * Parameters:
-     * context - {Object} Context to use in evaluating the filter.
+     * context - {Object} Context to use in evaluating the filter.  If a vector
+     *     feature is provided, the feature.attributes will be used as context.
      * 
      * Returns:
      * {Boolean} The filter applies.
@@ -29692,8 +30840,9 @@
     OpenLayers/Geometry.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
  
 /**
@@ -30151,8 +31300,9 @@
     OpenLayers/Layer/MapGuide.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * licence.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -30506,7 +31656,7 @@
         allParams = OpenLayers.Util.extend(allParams, newParams);
         // ignore parameters that are already in the url search string
         var urlParams = OpenLayers.Util.upperCaseObject(
-                            OpenLayers.Util.getArgs(url));
+                            OpenLayers.Util.getParameters(url));
         for(var key in allParams) {
             if(key.toUpperCase() in urlParams) {
                 delete allParams[key];
@@ -30643,8 +31793,9 @@
     OpenLayers/Layer/MapServer.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -30845,8 +31996,9 @@
     OpenLayers/Layer/WMS.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -30913,11 +32065,11 @@
     
     /**
      * Property: yx
-     * {Array} Array of strings with the EPSG codes for which the axis order
-     *     is to be reversed (yx instead of xy, LatLon instead of LonLat). This
-     *     is only relevant for WMS versions >= 1.3.0.
+     * {Object} Keys in this object are EPSG codes for which the axis order
+     *     is to be reversed (yx instead of xy, LatLon instead of LonLat), with
+     *     true as value. This is only relevant for WMS versions >= 1.3.0.
      */
-    yx: ['EPSG:4326'],
+    yx: {'EPSG:4326': true},
     
     /**
      * Constructor: OpenLayers.Layer.WMS
@@ -30942,6 +32094,9 @@
         var newArguments = [];
         //uppercase params
         params = OpenLayers.Util.upperCaseObject(params);
+        if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) {
+            params.EXCEPTIONS = "INIMAGE";
+        } 
         newArguments.push(name, url, params, options);
         OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
         OpenLayers.Util.applyDefaults(
@@ -31013,8 +32168,7 @@
      */
     reverseAxisOrder: function() {
         return (parseFloat(this.params.VERSION) >= 1.3 && 
-            OpenLayers.Util.indexOf(this.yx, 
-            this.map.getProjectionObject().getCode()) !== -1)
+            !!this.yx[this.map.getProjectionObject().getCode()]);
     },
     
     /**
@@ -31111,17 +32265,223 @@
     CLASS_NAME: "OpenLayers.Layer.WMS"
 });
 /* ======================================================================
+    OpenLayers/Layer/XYZ.js
+   ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Layer/Grid.js
+ * @requires OpenLayers/Tile/Image.js
+ */
+
+/** 
+ * Class: OpenLayers.Layer.XYZ
+ * The XYZ class is designed to make it easier for people who have tiles
+ * arranged by a standard XYZ grid. 
+ * 
+ * Inherits from:
+ *  - <OpenLayers.Layer.Grid>
+ */
+OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {
+    
+    /**
+     * APIProperty: isBaseLayer
+     * Default is true, as this is designed to be a base tile source. 
+     */
+    isBaseLayer: true,
+    
+    /**
+     * APIProperty: sphericalMecator
+     * Whether the tile extents should be set to the defaults for 
+     *    spherical mercator. Useful for things like OpenStreetMap.
+     *    Default is false, except for the OSM subclass.
+     */
+    sphericalMercator: false,
+
+    /**
+     * APIProperty: zoomOffset
+     * {Number} If your cache has more zoom levels than you want to provide
+     *     access to with this layer, supply a zoomOffset.  This zoom offset
+     *     is added to the current map zoom level to determine the level
+     *     for a requested tile.  For example, if you supply a zoomOffset
+     *     of 3, when the map is at the zoom 0, tiles will be requested from
+     *     level 3 of your cache.  Default is 0 (assumes cache level and map
+     *     zoom are equivalent).
+     */
+    zoomOffset: 0,
+    
+    /**
+     * Constructor: OpenLayers.Layer.XYZ
+     *
+     * Parameters:
+     * name - {String}
+     * url - {String}
+     * options - {Object} Hashtable of extra options to tag onto the layer
+     */
+    initialize: function(name, url, options) {
+        if (options && options.sphericalMercator || this.sphericalMercator) {
+            options = OpenLayers.Util.extend({
+                maxExtent: new OpenLayers.Bounds(
+                    -128 * 156543.0339,
+                    -128 * 156543.0339,
+                    128 * 156543.0339,
+                    128 * 156543.0339
+                ),
+                maxResolution: 156543.0339,
+                numZoomLevels: 19,
+                units: "m",
+                projection: "EPSG:900913"
+            }, options);
+        }
+        url = url || this.url;
+        name = name || this.name;
+        var newArguments = [name, url, {}, options];
+        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
+    },
+    
+    /**
+     * APIMethod: clone
+     * Create a clone of this layer
+     *
+     * Parameters:
+     * obj - {Object} Is this ever used?
+     * 
+     * Returns:
+     * {<OpenLayers.Layer.XYZ>} An exact clone of this OpenLayers.Layer.XYZ
+     */
+    clone: function (obj) {
+        
+        if (obj == null) {
+            obj = new OpenLayers.Layer.XYZ(this.name,
+                                            this.url,
+                                            this.getOptions());
+        }
+
+        //get all additions from superclasses
+        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
+
+        return obj;
+    },    
+
+    /**
+     * Method: getUrl
+     *
+     * Parameters:
+     * bounds - {<OpenLayers.Bounds>}
+     *
+     * Returns:
+     * {String} A string with the layer's url and parameters and also the
+     *          passed-in bounds and appropriate tile size specified as
+     *          parameters
+     */
+    getURL: function (bounds) {
+        var res = this.map.getResolution();
+        var x = Math.round((bounds.left - this.maxExtent.left) 
+            / (res * this.tileSize.w));
+        var y = Math.round((this.maxExtent.top - bounds.top) 
+            / (res * this.tileSize.h));
+        var z = this.map.getZoom() + this.zoomOffset;
+
+        var url = this.url;
+        var s = '' + x + y + z;
+        if (url instanceof Array)
+        {
+            url = this.selectUrl(s, url);
+        }
+        
+        var path = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z});
+
+        return path;
+    },
+    
+    /**
+     * Method: addTile
+     * addTile creates a tile, initializes it, and adds it to the layer div. 
+     * 
+     * Parameters:
+     * bounds - {<OpenLayers.Bounds>}
+     * position - {<OpenLayers.Pixel>}
+     * 
+     * Returns:
+     * {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
+     */
+    addTile:function(bounds,position) {
+        return new OpenLayers.Tile.Image(this, position, bounds, 
+                                         null, this.tileSize);
+    },
+     
+    /* APIMethod: setMap
+     * When the layer is added to a map, then we can fetch our origin 
+     *    (if we don't have one.) 
+     * 
+     * Parameters:
+     * map - {<OpenLayers.Map>}
+     */
+    setMap: function(map) {
+        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
+        if (!this.tileOrigin) { 
+            this.tileOrigin = new OpenLayers.LonLat(this.maxExtent.left,
+                                                this.maxExtent.bottom);
+        }                                       
+    },
+
+    CLASS_NAME: "OpenLayers.Layer.XYZ"
+});
+
+
+/**
+ * Class: OpenLayers.Layer.OSM
+ * A class to access OpenStreetMap tiles. By default, uses the OpenStreetMap
+ *    hosted tile.openstreetmap.org 'Mapnik' tileset. If you wish to use
+ *    tiles at home / osmarender layer instead, you can pass a layer like:
+ * 
+ * (code)
+ *     new OpenLayers.Layer.OSM("t at h", 
+ *       "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"); 
+ * (end)
+ *
+ * This layer defaults to Spherical Mercator.
+ * 
+ * Inherits from:
+ *  - <OpenLayers.Layer.XYZ>
+ */
+OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
+     name: "OpenStreetMap",
+     attribution: "Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",
+     sphericalMercator: true,
+     url: 'http://tile.openstreetmap.org/${z}/${x}/${y}.png',
+     clone: function(obj) {
+         if (obj == null) {
+             obj = new OpenLayers.Layer.OSM(
+                 this.name, this.url, this.getOptions());
+         }
+         obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
+         return obj;
+     },
+     CLASS_NAME: "OpenLayers.Layer.OSM"
+});
+/* ======================================================================
     OpenLayers/Rule.js
    ====================================================================== */
 
-/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt 
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 
 /**
  * @requires OpenLayers/Util.js
  * @requires OpenLayers/Style.js
+ * @requires OpenLayers/Symbolizer/Point.js
+ * @requires OpenLayers/Symbolizer/Line.js
+ * @requires OpenLayers/Symbolizer/Polygon.js
+ * @requires OpenLayers/Symbolizer/Text.js
+ * @requires OpenLayers/Symbolizer/Raster.js
  */
 
 /**
@@ -31140,7 +32500,7 @@
      * APIProperty: name
      * {String} name of this rule
      */
-    name: 'default',
+    name: null,
     
     /**
      * Property: title
@@ -31190,6 +32550,17 @@
     symbolizer: null,
     
     /**
+     * Property: symbolizers
+     * {Array} Collection of symbolizers associated with this rule.  If 
+     *     provided at construction, the symbolizers array has precedence
+     *     over the deprecated symbolizer property.  Note that multiple 
+     *     symbolizers are not currently supported by the vector renderers.
+     *     Rules with multiple symbolizers are currently only useful for
+     *     maintaining elements in an SLD document.
+     */
+    symbolizers: null,
+    
+    /**
      * APIProperty: minScaleDenominator
      * {Number} or {String} minimum scale at which to draw the feature.
      * In the case of a String, this can be a combination of text and
@@ -31219,6 +32590,9 @@
     initialize: function(options) {
         this.symbolizer = {};
         OpenLayers.Util.extend(this, options);
+        if (this.symbolizers) {
+            delete this.symbolizer;
+        }
         this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
     },
 
@@ -31231,6 +32605,7 @@
             this.symbolizer[i] = null;
         }
         this.symbolizer = null;
+        delete this.symbolizers;
     },
     
     /**
@@ -31303,16 +32678,26 @@
      */
     clone: function() {
         var options = OpenLayers.Util.extend({}, this);
-        // clone symbolizer
-        options.symbolizer = {};
-        for(var key in this.symbolizer) {
-            value = this.symbolizer[key];
-            type = typeof value;
-            if(type === "object") {
-                options.symbolizer[key] = OpenLayers.Util.extend({}, value);
-            } else if(type === "string") {
-                options.symbolizer[key] = value;
+        if (this.symbolizers) {
+            // clone symbolizers
+            var len = this.symbolizers.length;
+            options.symbolizers = new Array(len);
+            for (var i=0; i<len; ++i) {
+                options.symbolizers[i] = this.symbolizers[i].clone();
             }
+        } else {
+            // clone symbolizer
+            options.symbolizer = {};
+            var value, type;
+            for(var key in this.symbolizer) {
+                value = this.symbolizer[key];
+                type = typeof value;
+                if(type === "object") {
+                    options.symbolizer[key] = OpenLayers.Util.extend({}, value);
+                } else if(type === "string") {
+                    options.symbolizer[key] = value;
+                }
+            }
         }
         // clone filter
         options.filter = this.filter && this.filter.clone();
@@ -31327,8 +32712,9 @@
     OpenLayers/StyleMap.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -31490,9 +32876,10 @@
     OpenLayers/Filter/Comparison.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
-  * full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Filter.js
@@ -31585,20 +32972,23 @@
 
     /**
      * APIMethod: evaluate
-     * Evaluates this filter in a specific context.  Should be implemented by
-     *     subclasses.
+     * Evaluates this filter in a specific context.
      * 
      * Parameters:
-     * context - {Object} Context to use in evaluating the filter.
+     * context - {Object} Context to use in evaluating the filter.  If a vector
+     *     feature is provided, the feature.attributes will be used as context.
      * 
      * Returns:
      * {Boolean} The filter applies.
      */
     evaluate: function(context) {
+        if (context instanceof OpenLayers.Feature.Vector) {
+            context = context.attributes;
+        }
         var result = false;
+        var got = context[this.property];
         switch(this.type) {
             case OpenLayers.Filter.Comparison.EQUAL_TO:
-                var got = context[this.property];
                 var exp = this.value;
                 if(!this.matchCase &&
                    typeof got == "string" && typeof exp == "string") {
@@ -31608,7 +32998,6 @@
                 }
                 break;
             case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:
-                var got = context[this.property];
                 var exp = this.value;
                 if(!this.matchCase &&
                    typeof got == "string" && typeof exp == "string") {
@@ -31618,24 +33007,24 @@
                 }
                 break;
             case OpenLayers.Filter.Comparison.LESS_THAN:
-                result = context[this.property] < this.value;
+                result = got < this.value;
                 break;
             case OpenLayers.Filter.Comparison.GREATER_THAN:
-                result = context[this.property] > this.value;
+                result = got > this.value;
                 break;
             case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:
-                result = context[this.property] <= this.value;
+                result = got <= this.value;
                 break;
             case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:
-                result = context[this.property] >= this.value;
+                result = got >= this.value;
                 break;
             case OpenLayers.Filter.Comparison.BETWEEN:
-                result = (context[this.property] >= this.lowerBoundary) &&
-                    (context[this.property] <= this.upperBoundary);
+                result = (got >= this.lowerBoundary) &&
+                    (got <= this.upperBoundary);
                 break;
             case OpenLayers.Filter.Comparison.LIKE:
                 var regexp = new RegExp(this.value, "gi");
-                result = regexp.test(context[this.property]);
+                result = regexp.test(got);
                 break;
         }
         return result;
@@ -31749,9 +33138,10 @@
     OpenLayers/Filter/Logical.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
-  * full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 
 /**
@@ -31809,11 +33199,12 @@
 
     /**
      * APIMethod: evaluate
-     * Evaluates this filter in a specific context.  Should be implemented by
-     *     subclasses.
+     * Evaluates this filter in a specific context.
      * 
      * Parameters:
-     * context - {Object} Context to use in evaluating the filter.
+     * context - {Object} Context to use in evaluating the filter.  A vector
+     *     feature may also be provided to evaluate feature attributes in 
+     *     comparison filters or geometries in spatial filters.
      * 
      * Returns:
      * {Boolean} The filter applies.
@@ -31870,9 +33261,10 @@
     OpenLayers/Filter/Spatial.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
-  * full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
 /**
  * @requires OpenLayers/Filter.js
@@ -32001,8 +33393,9 @@
     OpenLayers/Geometry/Collection.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -32066,6 +33459,7 @@
     destroy: function () {
         this.components.length = 0;
         this.components = null;
+        OpenLayers.Geometry.prototype.destroy.apply(this, arguments);
     },
 
     /**
@@ -32263,22 +33657,67 @@
     /**
      * APIMethod: getCentroid
      *
+     * Compute the centroid for this geometry collection.
+     *
+     * Parameters:
+     * weighted - {Boolean} Perform the getCentroid computation recursively,
+     * returning an area weighted average of all geometries in this collection.
+     *
      * Returns:
      * {<OpenLayers.Geometry.Point>} The centroid of the collection
      */
-    getCentroid: function() {
-        return this.components.length && this.components[0].getCentroid();
-        /*
-        var centroid;
-        for (var i=0, len=this.components.length; i<len; i++) {
-            if (!centroid) {
-                centroid = this.components[i].getCentroid();
-            } else {
-                centroid.resize(this.components[i].getCentroid(), 0.5);
+    getCentroid: function(weighted) {
+        if (!weighted) {
+            return this.components.length && this.components[0].getCentroid();
+        }
+        var len = this.components.length;
+        if (!len) {
+            return false;
+        }
+        
+        var areas = [];
+        var centroids = [];
+        var areaSum = 0;
+        var minArea = Number.MAX_VALUE;
+        var component;
+        for (var i=0; i<len; ++i) {
+            component = this.components[i];
+            var area = component.getArea();
+            var centroid = component.getCentroid(true);
+            if (isNaN(area) || isNaN(centroid.x) || isNaN(centroid.y)) {
+                continue;
             }
+            areas.push(area);
+            areaSum += area;
+            minArea = (area < minArea && area > 0) ? area : minArea;
+            centroids.push(centroid);
         }
-        return centroid;
-        */
+        len = areas.length;
+        if (areaSum === 0) {
+            // all the components in this collection have 0 area
+            // probably a collection of points -- weight all the points the same
+            for (var i=0; i<len; ++i) {
+                areas[i] = 1;
+            }
+            areaSum = areas.length;
+        } else {
+            // normalize all the areas where the smallest area will get
+            // a value of 1
+            for (var i=0; i<len; ++i) {
+                areas[i] /= minArea;
+            }
+            areaSum /= minArea;
+        }
+        
+        var xSum = 0, ySum = 0, centroid, area;
+        for (var i=0; i<len; ++i) {
+            centroid = centroids[i];
+            area = areas[i];
+            xSum += centroid.x * area;
+            ySum += centroid.y * area;
+        }
+        
+        return new OpenLayers.Geometry.Point(xSum/areaSum, ySum/areaSum);
     },
 
     /**
@@ -32504,8 +33943,9 @@
     OpenLayers/Geometry/Point.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -32790,8 +34230,9 @@
     OpenLayers/Layer/Vector.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -32846,6 +34287,9 @@
      * beforefeatureremoved - Triggered before a feature is removed. Listeners
      *      will receive an object with a *feature* property referencing the
      *      feature to be removed.
+     * beforefeaturesremoved - Triggered before multiple features are removed. 
+     *      Listeners will receive an object with a *features* property
+     *      referencing the features to be removed.
      * featureremoved - Triggerd after a feature is removed. The event
      *      object passed to listeners will have a *feature* property with a
      *      reference to the removed feature.
@@ -32889,8 +34333,8 @@
      *      for a new set of features.
      */
     EVENT_TYPES: ["beforefeatureadded", "beforefeaturesadded",
-                  "featureadded", "featuresadded",
-                  "beforefeatureremoved", "featureremoved", "featuresremoved",
+                  "featureadded", "featuresadded", "beforefeatureremoved",
+                  "beforefeaturesremoved", "featureremoved", "featuresremoved",
                   "beforefeatureselected", "featureselected", "featureunselected", 
                   "beforefeaturemodified", "featuremodified", "afterfeaturemodified",
                   "vertexmodified", "sketchstarted", "sketchmodified",
@@ -33146,10 +34590,12 @@
      */    
     assignRenderer: function()  {
         for (var i=0, len=this.renderers.length; i<len; i++) {
-            var rendererClass = OpenLayers.Renderer[this.renderers[i]];
-            if (rendererClass && rendererClass.prototype.supported()) {
-                this.renderer = new rendererClass(this.div,
-                    this.rendererOptions);
+            var rendererClass = this.renderers[i];
+            var renderer = (typeof rendererClass == "function") ?
+                rendererClass :
+                OpenLayers.Renderer[rendererClass];
+            if (renderer && renderer.prototype.supported()) {
+                this.renderer = new renderer(this.div, this.rendererOptions);
                 break;
             }  
         }  
@@ -33213,6 +34659,7 @@
      * map - {<OpenLayers.Map>}
      */
     removeMap: function(map) {
+        this.drawn = false;
         if(this.strategies) {
             var strategy, i, len;
             for(i=0, len=this.strategies.length; i<len; i++) {
@@ -33330,7 +34777,9 @@
             features = event.features;
         }
         
-
+        // Track successfully added features for featuresadded event, since
+        // beforefeatureadded can veto single features.
+        var featuresAdded = [];
         for (var i=0, len=features.length; i<len; i++) {
             if (i != (features.length - 1)) {
                 this.renderer.locked = true;
@@ -33346,8 +34795,6 @@
                 throw throwStr;
               }
 
-            this.features.push(feature);
-            
             //give feature reference to its layer
             feature.layer = this;
 
@@ -33363,6 +34810,8 @@
                 this.preFeatureInsert(feature);
             }
 
+            featuresAdded.push(feature);
+            this.features.push(feature);
             this.drawFeature(feature);
             
             if (notify) {
@@ -33374,7 +34823,7 @@
         }
         
         if(notify) {
-            this.events.triggerEvent("featuresadded", {features: features});
+            this.events.triggerEvent("featuresadded", {features: featuresAdded});
         }
     },
 
@@ -33400,14 +34849,23 @@
         if(!features || features.length === 0) {
             return;
         }
+        if (features === this.features) {
+            return this.removeAllFeatures(options);
+        }
         if (!(features instanceof Array)) {
             features = [features];
         }
-        if (features === this.features || features === this.selectedFeatures) {
+        if (features === this.selectedFeatures) {
             features = features.slice();
         }
 
         var notify = !options || !options.silent;
+        
+        if (notify) {
+            this.events.triggerEvent(
+                "beforefeaturesremoved", {features: features}
+            );
+        }
 
         for (var i = features.length - 1; i >= 0; i--) {
             // We remain locked so long as we're not at 0
@@ -33458,6 +34916,49 @@
             this.events.triggerEvent("featuresremoved", {features: features});
         }
     },
+    
+    /** 
+     * APIMethod: removeAllFeatures
+     * Remove all features from the layer.
+     *
+     * Parameters:
+     * options - {Object} Optional properties for changing behavior of the
+     *     removal.
+     *
+     * Valid options:
+     * silent - {Boolean} Supress event triggering.  Default is false.
+     */
+    removeAllFeatures: function(options) {
+        var notify = !options || !options.silent;
+        var features = this.features;
+        if (notify) {
+            this.events.triggerEvent(
+                "beforefeaturesremoved", {features: features}
+            );
+        }
+        var feature;
+        for (var i = features.length-1; i >= 0; i--) {
+            feature = features[i];
+            if (notify) {
+                this.events.triggerEvent("beforefeatureremoved", {
+                    feature: feature
+                });
+            }
+            feature.layer = null;
+            if (notify) {
+                this.events.triggerEvent("featureremoved", {
+                    feature: feature
+                });
+            }
+        }
+        this.renderer.clear();
+        this.features = [];
+        this.unrenderedFeatures = {};
+        this.selectedFeatures = [];
+        if (notify) {
+            this.events.triggerEvent("featuresremoved", {features: features});
+        }
+    },
 
     /**
      * APIMethod: destroyFeatures
@@ -33499,7 +35000,7 @@
      *
      * Parameters: 
      * feature - {<OpenLayers.Feature.Vector>} 
-     * style - {Object} Symbolizer hash or {String} renderIntent
+     * style - {String | Object} Named render intent or full symbolizer object.
      */
     drawFeature: function(feature, style) {
         // don't try to draw the feature with the renderer if the layer is not 
@@ -33555,31 +35056,62 @@
         var featureId = this.renderer.getFeatureIdFromEvent(evt);
         return this.getFeatureById(featureId);
     },
-    
+
     /**
-     * APIMethod: getFeatureById
-     * Given a feature id, return the feature if it exists in the features array
+     * APIMethod: getFeatureBy
+     * Given a property value, return the feature if it exists in the features array
      *
      * Parameters:
-     * featureId - {String} 
+     * property - {String}
+     * value - {String}
      *
      * Returns:
      * {<OpenLayers.Feature.Vector>} A feature corresponding to the given
-     * featureId
+     * property value or null if there is no such feature.
      */
-    getFeatureById: function(featureId) {
+    getFeatureBy: function(property, value) {
         //TBD - would it be more efficient to use a hash for this.features?
         var feature = null;
         for(var i=0, len=this.features.length; i<len; ++i) {
-            if(this.features[i].id == featureId) {
+            if(this.features[i][property] == value) {
                 feature = this.features[i];
                 break;
             }
         }
         return feature;
     },
-    
+
     /**
+     * APIMethod: getFeatureById
+     * Given a feature id, return the feature if it exists in the features array
+     *
+     * Parameters:
+     * featureId - {String}
+     *
+     * Returns:
+     * {<OpenLayers.Feature.Vector>} A feature corresponding to the given
+     * featureId or null if there is no such feature.
+     */
+    getFeatureById: function(featureId) {
+        return this.getFeatureBy('id', featureId);
+    },
+
+    /**
+     * APIMethod: getFeatureByFid
+     * Given a feature fid, return the feature if it exists in the features array
+     *
+     * Parameters:
+     * featureFid - {String}
+     *
+     * Returns:
+     * {<OpenLayers.Feature.Vector>} A feature corresponding to the given
+     * featureFid or null if there is no such feature.
+     */
+    getFeatureByFid: function(featureFid) {
+        return this.getFeatureBy('fid', featureFid);
+    },
+
+    /**
      * Unselect the selected features
      * i.e. clears the featureSelection array
      * change the style back
@@ -33649,8 +35181,9 @@
     OpenLayers/Geometry/MultiPoint.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -33722,8 +35255,9 @@
     OpenLayers/Handler/Point.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -34098,8 +35632,9 @@
     OpenLayers/Protocol/HTTP.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -34108,6 +35643,7 @@
  * @requires OpenLayers/Filter/Spatial.js
  * @requires OpenLayers/Filter/Comparison.js
  * @requires OpenLayers/Filter/Logical.js
+ * @requires OpenLayers/Request/XMLHttpRequest.js
  */
 
 /**
@@ -34755,8 +36291,9 @@
     OpenLayers/Geometry/Curve.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -34851,8 +36388,9 @@
     OpenLayers/Geometry/LineString.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -35406,8 +36944,9 @@
     OpenLayers/Geometry/LinearRing.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -35826,8 +37365,9 @@
     OpenLayers/Geometry/MultiLineString.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -36091,8 +37631,9 @@
     OpenLayers/Handler/Path.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -36396,8 +37937,9 @@
     OpenLayers/Geometry/Polygon.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -36658,8 +38200,9 @@
     OpenLayers/Geometry/MultiPolygon.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -36707,8 +38250,9 @@
     OpenLayers/Handler/Polygon.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 
@@ -36854,8 +38398,9 @@
     OpenLayers/Format/GML.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -36996,7 +38541,9 @@
         // only accept one geometry per feature - look for highest "order"
         var order = ["MultiPolygon", "Polygon",
                      "MultiLineString", "LineString",
-                     "MultiPoint", "Point", "Envelope", "Box"];
+                     "MultiPoint", "Point", "Envelope"];
+        // FIXME: In case we parse a feature with no geometry, but boundedBy an Envelope,
+        // this code creates a geometry derived from the Envelope. This is not correct.
         var type, nodeList, geometry, parser;
         for(var i=0; i<order.length; ++i) {
             type = order[i];
@@ -37018,6 +38565,21 @@
                 break;
             }
         }
+
+        var bounds;
+        var boxNodes = this.getElementsByTagNameNS(node, this.gmlns, "Box");
+        for(i=0; i<boxNodes.length; ++i) {
+            var boxNode = boxNodes[i];
+            var box = this.parseGeometry["box"].apply(this, [boxNode]);
+            var parentNode = boxNode.parentNode;
+            var parentName = parentNode.localName ||
+                             parentNode.nodeName.split(":").pop();
+            if(parentName === "boundedBy") {
+                bounds = box;
+            } else {
+                geometry = box.toGeometry();
+            }
+        }
         
         // construct feature (optionally with attributes)
         var attributes;
@@ -37025,6 +38587,7 @@
             attributes = this.parseAttributes(node);
         }
         var feature = new OpenLayers.Feature.Vector(geometry, attributes);
+        feature.bounds = bounds;
         
         feature.gml = {
             featureType: node.firstChild.nodeName.split(":")[1],
@@ -37032,14 +38595,6 @@
             featureNSPrefix: node.firstChild.prefix
         };
                 
-        var boundedByNodes = this.getElementsByTagNameNS(node, this.gmlns, 'boundedBy');
-        if (boundedByNodes.length === 1) {
-            parser = this.parseGeometry['box']; 
-            if (parser) { 
-                feature.bounds = parser.apply(this, [boundedByNodes[0]]);
-            }            
-        }
-                
         // assign fid - this can come from a "fid" or "id" attribute
         var childNode = node.firstChild;
         var fid;
@@ -37771,8 +39326,9 @@
     OpenLayers/Format/GML/Base.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -38352,8 +39908,9 @@
     OpenLayers/Format/GML/v2.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**
@@ -38548,8 +40105,9 @@
     OpenLayers/Format/GML/v3.js
    ====================================================================== */
 
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
 
 /**



More information about the fusion-commits mailing list