Index: trunk/zoo-api/js/ZOO-api.js
===================================================================
--- trunk/zoo-api/js/ZOO-api.js	(revision 74)
+++ trunk/zoo-api/js/ZOO-api.js	(revision 81)
@@ -115,4 +115,67 @@
   },
   /**
+   * Function: rad
+   * 
+   * Parameters:
+   * x - {Float}
+   * 
+   * Returns:
+   * {Float}
+   */
+  rad: function(x) {return x*Math.PI/180;},
+  /**
+   * Function: distVincenty
+   * Given two objects representing points with geographic coordinates, this
+   *     calculates the distance between those points on the surface of an
+   *     ellipsoid.
+   * 
+   * Parameters:
+   * p1 - {<ZOO.Geometry.Point>} (or any object with both .x, .y properties)
+   * p2 - {<ZOO.Geometry.Point>} (or any object with both .x, .y 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.
+   */
+  distVincenty: function(p1, p2) {
+    var a = 6378137, b = 6356752.3142,  f = 1/298.257223563;
+    var L = ZOO.rad(p2.x - p1.y);
+    var U1 = Math.atan((1-f) * Math.tan(ZOO.rad(p1.y)));
+    var U2 = Math.atan((1-f) * Math.tan(ZOO.rad(p2.y)));
+    var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
+    var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
+    var lambda = L, lambdaP = 2*Math.PI;
+    var iterLimit = 20;
+    while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) {
+        var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
+        var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
+        (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));
+        if (sinSigma==0) {
+            return 0;  // co-incident points
+        }
+        var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
+        var sigma = Math.atan2(sinSigma, cosSigma);
+        var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);
+        var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);
+        var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
+        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
+        lambdaP = lambda;
+        lambda = L + (1-C) * f * Math.sin(alpha) *
+        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
+    }
+    if (iterLimit==0) {
+        return NaN;  // formula failed to converge
+    }
+    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 deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+        B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
+    var s = b*A*(sigma-deltaSigma);
+    var d = s.toFixed(3)/1000; // round to 1mm precision
+    return d;
+  },
+  /**
    * Function: Class
    * Method used to create ZOO classes. Includes support for
@@ -669,5 +732,5 @@
   projCode: null,
   /**
-   * Constructor: OpenLayers.Projection
+   * Constructor: ZOO.Projection
    * This class offers several methods for interacting with a wrapped 
    *     zoo-pro4js projection object. 
@@ -750,6 +813,6 @@
  * point - {{ZOO.Geometry.Point> | Object} An object with x and y
  *     properties representing coordinates in those dimensions.
- * sourceProj - {OpenLayers.Projection} Source map coordinate system
- * destProj - {OpenLayers.Projection} Destination map coordinate system
+ * sourceProj - {ZOO.Projection} Source map coordinate system
+ * destProj - {ZOO.Projection} Destination map coordinate system
  *
  * Returns:
@@ -973,4 +1036,5 @@
   },
   /**
+   * Property: extract
    * Object with properties corresponding to the geometry types.
    * Property values are functions that do the actual data extraction.
@@ -1057,12 +1121,17 @@
   },
   /**
+   * Property: parse
    * Object with properties corresponding to the geometry types.
-   * Property values are functions that do the actual parsing.
+   *     Property values are functions that do the actual parsing.
    */
   parse: {
     /**
+     * Method: parse.point
      * Return point feature given a point WKT fragment.
-     * @param {String} str A WKT fragment representing the point
-     * @returns {<ZOO.Feature>} A point feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the point
+     * Returns:
+     * {<ZOO.Feature>} A point feature
      */
     'point': function(str) {
@@ -1073,7 +1142,12 @@
     },
     /**
+     * Method: parse.multipoint
      * Return a multipoint feature given a multipoint WKT fragment.
-     * @param {String} A WKT fragment representing the multipoint
-     * @returns {<ZOO.Feature>} A multipoint feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multipoint
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multipoint feature
      */
     'multipoint': function(str) {
@@ -1088,7 +1162,12 @@
     },
     /**
+     * Method: parse.linestring
      * Return a linestring feature given a linestring WKT fragment.
-     * @param {String} A WKT fragment representing the linestring
-     * @returns {<ZOO.Feature>} A linestring feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the linestring
+     *
+     * Returns:
+     * {<ZOO.Feature>} A linestring feature
      */
     'linestring': function(str) {
@@ -1103,7 +1182,12 @@
     },
     /**
+     * Method: parse.multilinestring
      * Return a multilinestring feature given a multilinestring WKT fragment.
-     * @param {String} A WKT fragment representing the multilinestring
-     * @returns {<ZOO.Feature>} A multilinestring feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multilinestring
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multilinestring feature
      */
     'multilinestring': function(str) {
@@ -1120,7 +1204,12 @@
     },
     /**
+     * Method: parse.polygon
      * Return a polygon feature given a polygon WKT fragment.
-     * @param {String} A WKT fragment representing the polygon
-     * @returns {<ZOO.Feature>} A polygon feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the polygon
+     *
+     * Returns:
+     * {<ZOO.Feature>} A polygon feature
      */
     'polygon': function(str) {
@@ -1139,8 +1228,12 @@
     },
     /**
+     * Method: parse.multipolygon
      * Return a multipolygon feature given a multipolygon WKT fragment.
-     * @param {String} A WKT fragment representing the multipolygon
-     * @returns {<ZOO.Feature>} A multipolygon feature
-     * @private
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the multipolygon
+     *
+     * Returns:
+     * {<ZOO.Feature>} A multipolygon feature
      */
     'multipolygon': function(str) {
@@ -1157,7 +1250,12 @@
     },
     /**
+     * Method: parse.geometrycollection
      * Return an array of features given a geometrycollection WKT fragment.
-     * @param {String} A WKT fragment representing the geometrycollection
-     * @returns {Array} An array of ZOO.Feature
+     *
+     * Parameters:
+     * str - {String} A WKT fragment representing the geometrycollection
+     *
+     * Returns:
+     * {Array} An array of ZOO.Feature
      */
     'geometrycollection': function(str) {
@@ -1180,21 +1278,89 @@
  *
  * Inherits from:
- *  - <OpenLayers.Format>
+ *  - <ZOO.Format>
  */
 ZOO.Format.JSON = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: indent
+   * {String} For "pretty" printing, the indent string will be used once for
+   *     each indentation level.
+   */
   indent: "    ",
+  /**
+   * Property: space
+   * {String} For "pretty" printing, the space string will be used after
+   *     the ":" separating a name/value pair.
+   */
   space: " ",
+  /**
+   * Property: newline
+   * {String} For "pretty" printing, the newline string will be used at the
+   *     end of each name/value pair or array item.
+   */
   newline: "\n",
+  /**
+   * Property: level
+   * {Integer} For "pretty" printing, this is incremented/decremented during
+   *     serialization.
+   */
   level: 0,
+  /**
+   * Property: pretty
+   * {Boolean} Serialize with extra whitespace for structure.  This is set
+   *     by the <write> method.
+   */
   pretty: false,
+  /**
+   * Constructor: ZOO.Format.JSON
+   * Create a new parser for JSON.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
   initialize: function(options) {
     ZOO.Format.prototype.initialize.apply(this, [options]);
   },
+  /**
+   * Method: read
+   * Deserialize a json string.
+   *
+   * Parameters:
+   * json - {String} A JSON string
+   * filter - {Function} A function which will be called for every key and
+   *     value at every level of the final result. Each value will be
+   *     replaced by the result of the filter function. This can be used to
+   *     reform generic objects into instances of classes, or to transform
+   *     date strings into Date objects.
+   *     
+   * Returns:
+   * {Object} An object, array, string, or number .
+   */
   read: function(json, filter) {
+    /**
+     * Parsing happens in three stages. In the first stage, we run the text
+     *     against a regular expression which looks for non-JSON
+     *     characters. We are especially concerned with '()' and 'new'
+     *     because they can cause invocation, and '=' because it can cause
+     *     mutation. But just to be safe, we will reject all unexpected
+     *     characters.
+     */
     try {
       if (/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g, '@').
                           replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
                           replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+        /**
+         * In the second stage we use the eval function to compile the
+         *     text into a JavaScript structure. The '{' operator is
+         *     subject to a syntactic ambiguity in JavaScript - it can
+         *     begin a block or an object literal. We wrap the text in
+         *     parens to eliminate the ambiguity.
+         */
         var object = eval('(' + json + ')');
+        /**
+         * In the optional third stage, we recursively walk the new
+         *     structure, passing each name/value pair to a filter
+         *     function for possible transformation.
+         */
         if(typeof filter === 'function') {
           function walk(k, v) {
@@ -1220,4 +1386,17 @@
     return null;
   },
+  /**
+   * Method: write
+   * Serialize an object into a JSON string.
+   *
+   * Parameters:
+   * value - {String} The object, array, string, number, boolean or date
+   *     to be serialized.
+   * pretty - {Boolean} Structure the output with newlines and indentation.
+   *     Default is false.
+   *
+   * Returns:
+   * {String} The JSON string representation of the input value.
+   */
   write: function(value, pretty) {
     this.pretty = !!pretty;
@@ -1233,4 +1412,11 @@
     return json;
   },
+  /**
+   * Method: writeIndent
+   * Output an indentation string depending on the indentation level.
+   *
+   * Returns:
+   * {String} An appropriate indentation string.
+   */
   writeIndent: function() {
     var pieces = [];
@@ -1242,11 +1428,40 @@
     return pieces.join('');
   },
+  /**
+   * Method: writeNewline
+   * Output a string representing a newline if in pretty printing mode.
+   *
+   * Returns:
+   * {String} A string representing a new line.
+   */
   writeNewline: function() {
     return (this.pretty) ? this.newline : '';
   },
+  /**
+   * Method: writeSpace
+   * Output a string representing a space if in pretty printing mode.
+   *
+   * Returns:
+   * {String} A space.
+   */
   writeSpace: function() {
     return (this.pretty) ? this.space : '';
   },
+  /**
+   * Property: serialize
+   * Object with properties corresponding to the serializable data types.
+   *     Property values are functions that do the actual serializing.
+   */
   serialize: {
+    /**
+     * Method: serialize.object
+     * Transform an object into a JSON string.
+     *
+     * Parameters:
+     * object - {Object} The object to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the object.
+     */
     'object': function(object) {
        // three special objects that we want to treat differently
@@ -1282,4 +1497,14 @@
        return pieces.join('');
     },
+    /**
+     * Method: serialize.array
+     * Transform an array into a JSON string.
+     *
+     * Parameters:
+     * array - {Array} The array to be serialized
+     * 
+     * Returns:
+     * {String} A JSON string representing the array.
+     */
     'array': function(array) {
       var json;
@@ -1300,4 +1525,14 @@
       return pieces.join('');
     },
+    /**
+     * Method: serialize.string
+     * Transform a string into a JSON string.
+     *
+     * Parameters:
+     * string - {String} The string to be serialized
+     * 
+     * Returns:
+     * {String} A JSON string representing the string.
+     */
     'string': function(string) {
       var m = {
@@ -1323,10 +1558,40 @@
       return '"' + string + '"';
     },
+    /**
+     * Method: serialize.number
+     * Transform a number into a JSON string.
+     *
+     * Parameters:
+     * number - {Number} The number to be serialized.
+     *
+     * Returns:
+     * {String} A JSON string representing the number.
+     */
     'number': function(number) {
       return isFinite(number) ? String(number) : "null";
     },
+    /**
+     * Method: serialize.boolean
+     * Transform a boolean into a JSON string.
+     *
+     * Parameters:
+     * bool - {Boolean} The boolean to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the boolean.
+     */
     'boolean': function(bool) {
       return String(bool);
     },
+    /**
+     * Method: serialize.date
+     * Transform a date into a JSON string.
+     *
+     * Parameters:
+     * date - {Date} The date to be serialized.
+     * 
+     * Returns:
+     * {String} A JSON string representing the date.
+     */
     'date': function(date) {    
       function format(number) {
@@ -1344,8 +1609,49 @@
   CLASS_NAME: 'ZOO.Format.JSON'
 });
+/**
+ * Class: ZOO.Format.GeoJSON
+ * Read and write GeoJSON. Create a new parser with the
+ *     <ZOO.Format.GeoJSON> constructor.
+ *
+ * Inherits from:
+ *  - <ZOO.Format.JSON>
+ */
 ZOO.Format.GeoJSON = ZOO.Class(ZOO.Format.JSON, {
+  /**
+   * Constructor: ZOO.Format.GeoJSON
+   * Create a new parser for GeoJSON.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
   initialize: function(options) {
     ZOO.Format.JSON.prototype.initialize.apply(this, [options]);
   },
+  /**
+   * Method: read
+   * Deserialize a GeoJSON string.
+   *
+   * Parameters:
+   * json - {String} A GeoJSON string
+   * type - {String} Optional string that determines the structure of
+   *     the output.  Supported values are "Geometry", "Feature", and
+   *     "FeatureCollection".  If absent or null, a default of
+   *     "FeatureCollection" is assumed.
+   * filter - {Function} A function which will be called for every key and
+   *     value at every level of the final result. Each value will be
+   *     replaced by the result of the filter function. This can be used to
+   *     reform generic objects into instances of classes, or to transform
+   *     date strings into Date objects.
+   *
+   * Returns: 
+   * {Object} The return depends on the value of the type argument. If type
+   *     is "FeatureCollection" (the default), the return will be an array
+   *     of <ZOO.Feature>. If type is "Geometry", the input json
+   *     must represent a single geometry, and the return will be an
+   *     <ZOO.Geometry>.  If type is "Feature", the input json must
+   *     represent a single feature, and the return will be an
+   *     <ZOO.Feature>.
+   */
   read: function(json, type, filter) {
     type = (type) ? type : "FeatureCollection";
@@ -1357,7 +1663,7 @@
       obj = json;
     if(!obj) {
-      //OpenLayers.Console.error("Bad JSON: " + json);
+      //ZOO.Console.error("Bad JSON: " + json);
     } else if(typeof(obj.type) != "string") {
-      //OpenLayers.Console.error("Bad GeoJSON - no type: " + json);
+      //ZOO.Console.error("Bad GeoJSON - no type: " + json);
     } else if(this.isValidType(obj, type)) {
       switch(type) {
@@ -1366,5 +1672,5 @@
             results = this.parseGeometry(obj);
           } catch(err) {
-            //OpenLayers.Console.error(err);
+            //ZOO.Console.error(err);
           }
           break;
@@ -1374,5 +1680,5 @@
             results.type = "Feature";
           } catch(err) {
-            //OpenLayers.Console.error(err);
+            //ZOO.Console.error(err);
           }
           break;
@@ -1386,5 +1692,5 @@
               } catch(err) {
                 results = null;
-                //OpenLayers.Console.error(err);
+                //ZOO.Console.error(err);
               }
               break;
@@ -1395,5 +1701,5 @@
                 } catch(err) {
                   results = null;
-                  //OpenLayers.Console.error(err);
+                  //ZOO.Console.error(err);
                 }
               }
@@ -1405,5 +1711,5 @@
               } catch(err) {
                 results = null;
-                //OpenLayers.Console.error(err);
+                //ZOO.Console.error(err);
               }
           }
@@ -1413,4 +1719,11 @@
     return results;
   },
+  /**
+   * Method: isValidType
+   * Check if a GeoJSON object is a valid representative of the given type.
+   *
+   * Returns:
+   * {Boolean} The object is valid GeoJSON object of the given type.
+   */
   isValidType: function(obj, type) {
     var valid = false;
@@ -1422,5 +1735,5 @@
               obj.type) == -1) {
           // unsupported geometry type
-          //OpenLayers.Console.error("Unsupported geometry type: " +obj.type);
+          //ZOO.Console.error("Unsupported geometry type: " +obj.type);
         } else {
           valid = true;
@@ -1436,9 +1749,20 @@
           valid = true;
         } else {
-          //OpenLayers.Console.error("Cannot convert types from " +obj.type + " to " + type);
+          //ZOO.Console.error("Cannot convert types from " +obj.type + " to " + type);
         }
     }
     return valid;
   },
+  /**
+   * Method: parseFeature
+   * Convert a feature object from GeoJSON into an
+   *     <ZOO.Feature>.
+   *
+   * Parameters:
+   * obj - {Object} An object created from a GeoJSON object
+   *
+   * Returns:
+   * {<ZOO.Feature>} A feature.
+   */
   parseFeature: function(obj) {
     var feature, geometry, attributes, bbox;
@@ -1458,4 +1782,14 @@
     return feature;
   },
+  /**
+   * Method: parseGeometry
+   * Convert a geometry object from GeoJSON into an <ZOO.Geometry>.
+   *
+   * Parameters:
+   * obj - {Object} An object created from a GeoJSON object
+   *
+   * Returns: 
+   * {<ZOO.Geometry>} A geometry.
+   */
   parseGeometry: function(obj) {
     if (obj == null)
@@ -1499,5 +1833,21 @@
     return geometry;
   },
+  /**
+   * Property: parseCoords
+   * Object with properties corresponding to the GeoJSON geometry types.
+   *     Property values are functions that do the actual parsing.
+   */
   parseCoords: {
+    /**
+     * Method: parseCoords.point
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Point>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A geometry.
+     */
     "point": function(array) {
       if(array.length != 2) {
@@ -1506,4 +1856,15 @@
       return new ZOO.Geometry.Point(array[0], array[1]);
     },
+    /**
+     * Method: parseCoords.multipoint
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiPoint>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPoint>} A geometry.
+     */
     "multipoint": function(array) {
       var points = [];
@@ -1519,4 +1880,15 @@
       return new ZOO.Geometry.MultiPoint(points);
     },
+    /**
+     * Method: parseCoords.linestring
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.LineString>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A geometry.
+     */
     "linestring": function(array) {
       var points = [];
@@ -1532,4 +1904,15 @@
       return new ZOO.Geometry.LineString(points);
     },
+    /**
+     * Method: parseCoords.multilinestring
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiLineString>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiLineString>} A geometry.
+     */
     "multilinestring": function(array) {
       var lines = [];
@@ -1545,4 +1928,15 @@
       return new ZOO.Geometry.MultiLineString(lines);
     },
+    /**
+     * Method: parseCoords.polygon
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Polygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A geometry.
+     */
     "polygon": function(array) {
       var rings = [];
@@ -1559,4 +1953,15 @@
       return new ZOO.Geometry.Polygon(rings);
     },
+    /**
+     * Method: parseCoords.multipolygon
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.MultiPolygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPolygon>} A geometry.
+     */
     "multipolygon": function(array) {
       var polys = [];
@@ -1572,4 +1977,15 @@
       return new ZOO.Geometry.MultiPolygon(polys);
     },
+    /**
+     * Method: parseCoords.box
+     * Convert a coordinate array from GeoJSON into an
+     *     <ZOO.Geometry.Polygon>.
+     *
+     * Parameters:
+     * array - {Object} The coordinates array from the GeoJSON fragment.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A geometry.
+     */
     "box": function(array) {
       if(array.length != 2) {
@@ -1587,4 +2003,18 @@
     }
   },
+  /**
+   * Method: write
+   * Serialize a feature, geometry, array of features into a GeoJSON string.
+   *
+   * Parameters:
+   * obj - {Object} An <ZOO.Feature>, <ZOO.Geometry>,
+   *     or an array of features.
+   * pretty - {Boolean} Structure the output with newlines and indentation.
+   *     Default is false.
+   *
+   * Returns:
+   * {String} The GeoJSON string representation of the input geometry,
+   *     features, or array of features.
+   */
   write: function(obj, pretty) {
     var geojson = {
@@ -1617,4 +2047,15 @@
                                                  [geojson, pretty]);
   },
+  /**
+   * Method: createCRSObject
+   * Create the CRS object for an object.
+   *
+   * Parameters:
+   * object - {<ZOO.Feature>} 
+   *
+   * Returns:
+   * {Object} An object which can be assigned to the crs property
+   * of a GeoJSON object.
+   */
   createCRSObject: function(object) {
     //var proj = object.layer.projection.toString();
@@ -1641,5 +2082,20 @@
     return crs;
   },
+  /**
+   * Property: extract
+   * Object with properties corresponding to the GeoJSON types.
+   *     Property values are functions that do the actual value extraction.
+   */
   extract: {
+    /**
+     * Method: extract.feature
+     * Return a partial GeoJSON object representing a single feature.
+     *
+     * Parameters:
+     * feature - {<ZOO.Feature>}
+     *
+     * Returns:
+     * {Object} An object representing the point.
+     */
     'feature': function(feature) {
       var geom = this.extract.geometry.apply(this, [feature.geometry]);
@@ -1651,4 +2107,14 @@
       };
     },
+    /**
+     * Method: extract.geometry
+     * Return a GeoJSON object representing a single geometry.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry>}
+     *
+     * Returns:
+     * {Object} An object representing the geometry.
+     */
     'geometry': function(geometry) {
       if (geometry == null)
@@ -1674,7 +2140,28 @@
       return json;
     },
+    /**
+     * Method: extract.point
+     * Return an array of coordinates from a point.
+     *
+     * Parameters:
+     * point - {<ZOO.Geometry.Point>}
+     *
+     * Returns: 
+     * {Array} An array of coordinates representing the point.
+     */
     'point': function(point) {
       return [point.x, point.y];
     },
+    /**
+     * Method: extract.multipoint
+     * Return an array of coordinates from a multipoint.
+     *
+     * Parameters:
+     * multipoint - {<ZOO.Geometry.MultiPoint>}
+     *
+     * Returns: 
+     * {Array} An array of point coordinate arrays representing
+     *     the multipoint.
+     */
     'multipoint': function(multipoint) {
       var array = [];
@@ -1684,4 +2171,15 @@
       return array;
     },
+    /**
+     * Method: extract.linestring
+     * Return an array of coordinate arrays from a linestring.
+     *
+     * Parameters:
+     * linestring - {<ZOO.Geometry.LineString>}
+     *
+     * Returns:
+     * {Array} An array of coordinate arrays representing
+     *     the linestring.
+     */
     'linestring': function(linestring) {
       var array = [];
@@ -1691,4 +2189,15 @@
       return array;
     },
+    /**
+     * Method: extract.multilinestring
+     * Return an array of linestring arrays from a linestring.
+     * 
+     * Parameters:
+     * multilinestring - {<ZOO.Geometry.MultiLineString>}
+     * 
+     * Returns:
+     * {Array} An array of linestring arrays representing
+     *     the multilinestring.
+     */
     'multilinestring': function(multilinestring) {
       var array = [];
@@ -1698,4 +2207,14 @@
       return array;
     },
+    /**
+     * Method: extract.polygon
+     * Return an array of linear ring arrays from a polygon.
+     *
+     * Parameters:
+     * polygon - {<ZOO.Geometry.Polygon>}
+     * 
+     * Returns:
+     * {Array} An array of linear ring arrays representing the polygon.
+     */
     'polygon': function(polygon) {
       var array = [];
@@ -1705,4 +2224,15 @@
       return array;
     },
+    /**
+     * Method: extract.multipolygon
+     * Return an array of polygon arrays from a multipolygon.
+     * 
+     * Parameters:
+     * multipolygon - {<ZOO.Geometry.MultiPolygon>}
+     * 
+     * Returns:
+     * {Array} An array of polygon arrays representing
+     *     the multipolygon
+     */
     'multipolygon': function(multipolygon) {
       var array = [];
@@ -1712,4 +2242,15 @@
       return array;
     },
+    /**
+     * Method: extract.collection
+     * Return an array of geometries from a geometry collection.
+     * 
+     * Parameters:
+     * collection - {<ZOO.Geometry.Collection>}
+     * 
+     * Returns:
+     * {Array} An array of geometry objects representing the geometry
+     *     collection.
+     */
     'collection': function(collection) {
       var len = collection.components.length;
@@ -1725,10 +2266,49 @@
   CLASS_NAME: 'ZOO.Format.GeoJSON'
 });
+/**
+ * Class: ZOO.Format.KML
+ * Read/Write KML. Create a new instance with the <ZOO.Format.KML>
+ *     constructor. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
 ZOO.Format.KML = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: kmlns
+   * {String} KML Namespace to use. Defaults to 2.2 namespace.
+   */
   kmlns: "http://www.opengis.net/kml/2.2",
+  /** 
+   * Property: foldersName
+   * {String} Name of the folders.  Default is "ZOO export".
+   *          If set to null, no name element will be created.
+   */
   foldersName: "ZOO export",
+  /** 
+   * Property: foldersDesc
+   * {String} Description of the folders. Default is "Exported on [date]."
+   *          If set to null, no description element will be created.
+   */
   foldersDesc: "Created on " + new Date(),
+  /** 
+   * Property: placemarksDesc
+   * {String} Name of the placemarks.  Default is "No description available".
+   */
   placemarksDesc: "No description available",
+  /**
+   * Property: extractAttributes
+   * {Boolean} Extract attributes from KML.  Default is true.
+   *           Extracting styleUrls requires this to be set to true
+   */
   extractAttributes: true,
+  /**
+   * Constructor: ZOO.Format.KML
+   * Create a new parser for KML.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
   initialize: function(options) {
     // compile regular expressions once instead of every time they are used
@@ -1742,6 +2322,18 @@
            straightBracket: (/\$\[(.*?)\]/g)
     };
+    // KML coordinates are always in longlat WGS84
+    this.externalProjection = new ZOO.Projection("EPSG:4326");
     ZOO.Format.prototype.initialize.apply(this, [options]);
   },
+  /**
+   * APIMethod: read
+   * Read data from a string, and return a list of features. 
+   * 
+   * Parameters: 
+   * data    - {String} data to read/parse.
+   *
+   * Returns:
+   * {Array(<ZOO.Feature>)} List of features.
+   */
   read: function(data) {
     this.features = [];
@@ -1752,4 +2344,14 @@
     return this.features;
   },
+  /**
+   * Method: parseFeatures
+   * Loop through all Placemark nodes and parse them.
+   * Will create a list of features
+   * 
+   * Parameters: 
+   * nodes    - {Array} of {E4XElement} data to read/parse.
+   * options  - {Object} Hash of options
+   * 
+   */
   parseFeatures: function(nodes) {
     var features = new Array(nodes.length());
@@ -1761,5 +2363,18 @@
     this.features = this.features.concat(features);
   },
+  /**
+   * Method: parseFeature
+   * This function is the core of the KML parsing code in ZOO.
+   *     It creates the geometries that are then attached to the returned
+   *     feature, and calls parseAttributes() to get attribute data out.
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {<ZOO.Feature>} A vector feature.
+   */
   parseFeature: function(node) {
+    // only accept one geometry per feature - look for highest "order"
     var order = ["MultiGeometry", "Polygon", "LineString", "Point"];
     var type, nodeList, geometry, parser;
@@ -1776,7 +2391,9 @@
           }                       
         }
+        // stop looking for different geometry types
         break;
       }
     }
+    // construct feature (optionally with attributes)
     var attributes;
     if(this.extractAttributes) {
@@ -1789,5 +2406,21 @@
     return feature;
   },
+  /**
+   * Property: parseGeometry
+   * Properties of this object are the functions that parse geometries based
+   *     on their type.
+   */
   parseGeometry: {
+    /**
+     * Method: parseGeometry.point
+     * Given a KML node representing a point geometry, create a ZOO
+     *     point geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML Point node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A point geometry.
+     */
     'point': function(node) {
       var coordString = node.*::coordinates.toString();
@@ -1804,4 +2437,15 @@
       return point;
     },
+    /**
+     * Method: parseGeometry.linestring
+     * Given a KML node representing a linestring geometry, create a
+     *     ZOO linestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML LineString node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A linestring geometry.
+     */
     'linestring': function(node, ring) {
       var line = null;
@@ -1838,4 +2482,15 @@
       return line;
     },
+    /**
+     * Method: parseGeometry.polygon
+     * Given a KML node representing a polygon geometry, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML Polygon node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
     'polygon': function(node) {
       var nodeList = node..*::LinearRing;
@@ -1857,5 +2512,16 @@
       return new ZOO.Geometry.Polygon(components);
     },
-    multigeometry: function(node) {
+    /**
+     * Method: parseGeometry.multigeometry
+     * Given a KML node representing a multigeometry, create a
+     *     ZOO geometry collection.
+     *
+     * Parameters:
+     * node - {E4XElement} A KML MultiGeometry node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Collection>} A geometry collection.
+     */
+    'multigeometry': function(node) {
       var child, parser;
       var parts = [];
@@ -1872,4 +2538,13 @@
     }
   },
+  /**
+   * Method: parseAttributes
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
   parseAttributes: function(node) {
     var attributes = {};
@@ -1894,4 +2569,16 @@
     return attributes;
   },
+  /**
+   * Method: parseExtendedData
+   * Parse ExtendedData from KML. Limited support for schemas/datatypes.
+   *     See http://code.google.com/apis/kml/documentation/kmlreference.html#extendeddata
+   *     for more information on extendeddata.
+   *
+   * Parameters:
+   * node - {E4XElement}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
   parseExtendedData: function(node) {
     var attributes = {};
@@ -1911,4 +2598,14 @@
     return attributes;
   },
+  /**
+   * Method: write
+   * Accept Feature Collection, and return a string. 
+   * 
+   * Parameters:
+   * features - {Array(<ZOO.Feature>} An array of features.
+   *
+   * Returns:
+   * {String} A KML string.
+   */
   write: function(features) {
     if(!(features instanceof Array))
@@ -1919,9 +2616,18 @@
     folder.description = this.foldersDesc;
     for(var i=0, len=features.length; i<len; ++i) {
-      //folder.appendChild(this.createPlacemarkXML(features[i]));
       folder.Placemark[i] = this.createPlacemark(features[i]);
     }
     return kml.toXMLString();
   },
+  /**
+   * Method: createPlacemark
+   * Creates and returns a KML placemark node representing the given feature. 
+   * 
+   * Parameters:
+   * feature - {<ZOO.Feature>}
+   * 
+   * Returns:
+   * {E4XElement}
+   */
   createPlacemark: function(feature) {
     var placemark = new XML('<Placemark xmlns="'+this.kmlns+'"></Placemark>');
@@ -1935,4 +2641,14 @@
     return placemark;
   },
+  /**
+   * Method: buildGeometryNode
+   * Builds and returns a KML geometry node with the given geometry.
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   * 
+   * Returns:
+   * {E4XElement}
+   */
   buildGeometryNode: function(geometry) {
     if (this.internalProjection && this.externalProjection) {
@@ -1950,5 +2666,20 @@
     return node;
   },
+  /**
+   * Property: buildGeometry
+   * Object containing methods to do the actual geometry node building
+   *     based on geometry type.
+   */
   buildGeometry: {
+    /**
+     * Method: buildGeometry.point
+     * Given a ZOO point geometry, create a KML point.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A point geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML point node.
+     */
     'point': function(geometry) {
       var kml = new XML('<Point xmlns="'+this.kmlns+'"></Point>');
@@ -1956,7 +2687,28 @@
       return kml;
     },
+    /**
+     * Method: buildGeometry.multipoint
+     * Given a ZOO multipoint geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
     'multipoint': function(geometry) {
       return this.buildGeometry.collection.apply(this, [geometry]);
     },
+    /**
+     * Method: buildGeometry.linestring
+     * Given a ZOO linestring geometry, create a KML linestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LineString>} A linestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML linestring node.
+     */
     'linestring': function(geometry) {
       var kml = new XML('<LineString xmlns="'+this.kmlns+'"></LineString>');
@@ -1964,7 +2716,28 @@
       return kml;
     },
+    /**
+     * Method: buildGeometry.multilinestring
+     * Given a ZOO multilinestring geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiLineString>} A multilinestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
     'multilinestring': function(geometry) {
       return this.buildGeometry.collection.apply(this, [geometry]);
     },
+    /**
+     * Method: buildGeometry.linearring
+     * Given a ZOO linearring geometry, create a KML linearring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LinearRing>} A linearring geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML linearring node.
+     */
     'linearring': function(geometry) {
       var kml = new XML('<LinearRing xmlns="'+this.kmlns+'"></LinearRing>');
@@ -1972,4 +2745,14 @@
       return kml;
     },
+    /**
+     * Method: buildGeometry.polygon
+     * Given a ZOO polygon geometry, create a KML polygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Polygon>} A polygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML polygon node.
+     */
     'polygon': function(geometry) {
       var kml = new XML('<Polygon xmlns="'+this.kmlns+'"></Polygon>');
@@ -1984,7 +2767,28 @@
       return kml;
     },
+    /**
+     * Method: buildGeometry.multipolygon
+     * Given a ZOO multipolygon geometry, create a KML
+     *     GeometryCollection.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A multipolygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A KML GeometryCollection node.
+     */
     'multipolygon': function(geometry) {
       return this.buildGeometry.collection.apply(this, [geometry]);
     },
+    /**
+     * Method: buildGeometry.collection
+     * Given a ZOO geometry collection, create a KML MultiGeometry.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Collection>} A geometry collection.
+     *
+     * Returns:
+     * {E4XElement} A KML MultiGeometry node.
+     */
     'collection': function(geometry) {
       var kml = new XML('<MultiGeometry xmlns="'+this.kmlns+'"></MultiGeometry>');
@@ -1996,4 +2800,15 @@
     }
   },
+  /**
+   * Method: buildCoordinatesNode
+   * Builds and returns the KML coordinates node with the given geometry
+   *     <coordinates>...</coordinates>
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   * 
+   * Return:
+   * {E4XElement}
+   */
   buildCoordinatesNode: function(geometry) {
     var cooridnates = new XML('<coordinates xmlns="'+this.kmlns+'"></coordinates>');
@@ -2017,6 +2832,22 @@
   CLASS_NAME: 'ZOO.Format.KML'
 });
+/**
+ * Class: ZOO.Format.GML
+ * Read/Write GML. Create a new instance with the <ZOO.Format.GML>
+ *     constructor.  Supports the GML simple features profile.
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
 ZOO.Format.GML = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: schemaLocation
+   * {String} Schema location for a particular minor version.
+   */
   schemaLocation: "http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",
+  /**
+   * Property: namespaces
+   * {Object} Mapping of namespace aliases to namespace URIs.
+   */
   namespaces: {
     ogr: "http://ogr.maptools.org/",
@@ -2026,9 +2857,37 @@
     wfs: "http://www.opengis.net/wfs" // this is a convenience for reading wfs:FeatureCollection
   },
+  /**
+   * Property: defaultPrefix
+   */
   defaultPrefix: 'ogr',
+  /** 
+   * Property: collectionName
+   * {String} Name of featureCollection element.
+   */
   collectionName: "FeatureCollection",
+  /*
+   * Property: featureName
+   * {String} Element name for features. Default is "sql_statement".
+   */
   featureName: "sql_statement",
+  /**
+   * Property: geometryName
+   * {String} Name of geometry element.  Defaults to "geometryProperty".
+   */
   geometryName: "geometryProperty",
+  /**
+   * Property: xy
+   * {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
+   * Changing is not recommended, a new Format should be instantiated.
+   */
   xy: true,
+  /**
+   * Constructor: ZOO.Format.GML
+   * Create a new parser for GML.
+   *
+   * Parameters:
+   * options - {Object} An optional object whose properties will be set on
+   *     this instance.
+   */
   initialize: function(options) {
     // compile regular expressions once instead of every time they are used
@@ -2041,4 +2900,14 @@
     ZOO.Format.prototype.initialize.apply(this, [options]);
   },
+  /**
+   * Method: read
+   * Read data from a string, and return a list of features. 
+   * 
+   * Parameters:
+   * data - {String} data to read/parse.
+   *
+   * Returns:
+   * {Array(<ZOO.Feature>)} An array of features.
+   */
   read: function(data) {
     this.features = [];
@@ -2057,4 +2926,13 @@
     return features;
   },
+  /**
+   * Method: parseFeature
+   * This function is the core of the GML parsing code in ZOO.
+   *    It creates the geometries that are then attached to the returned
+   *    feature, and calls parseAttributes() to get attribute data out.
+   *    
+   * Parameters:
+   * node - {E4XElement} A GML feature node. 
+   */
   parseFeature: function(node) {
     // only accept one geometry per feature - look for highest "order"
@@ -2076,4 +2954,5 @@
           }                       
         }
+        // stop looking for different geometry types
         break;
       }
@@ -2081,10 +2960,26 @@
     var attributes;
     if(this.extractAttributes) {
-      //attributes = this.parseAttributes(node);
+      attributes = this.parseAttributes(node);
     }
     var feature = new ZOO.Feature(geometry, attributes);
     return feature;
   },
+  /**
+   * Property: parseGeometry
+   * Properties of this object are the functions that parse geometries based
+   *     on their type.
+   */
   parseGeometry: {
+    /**
+     * Method: parseGeometry.point
+     * Given a GML node representing a point geometry, create a ZOO
+     *     point geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Point>} A point geometry.
+     */
     'point': function(node) {
       /**
@@ -2131,4 +3026,15 @@
         return new ZOO.Geometry.Point(coords[1],coords[0],coords[2]);
     },
+    /**
+     * Method: parseGeometry.multipoint
+     * Given a GML node representing a multipoint geometry, create a
+     *     ZOO multipoint geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     */
     'multipoint': function(node) {
       var nodeList = node..*::Point;
@@ -2144,4 +3050,15 @@
       return new ZOO.Geometry.MultiPoint(components);
     },
+    /**
+     * Method: parseGeometry.linestring
+     * Given a GML node representing a linestring geometry, create a
+     *     ZOO linestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.LineString>} A linestring geometry.
+     */
     'linestring': function(node, ring) {
       /**
@@ -2200,4 +3117,15 @@
       return line;
     },
+    /**
+     * Method: parseGeometry.multilinestring
+     * Given a GML node representing a multilinestring geometry, create a
+     *     ZOO multilinestring geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiLineString>} A multilinestring geometry.
+     */
     'multilinestring': function(node) {
       var nodeList = node..*::LineString;
@@ -2213,4 +3141,15 @@
       return new ZOO.Geometry.MultiLineString(components);
     },
+    /**
+     * Method: parseGeometry.polygon
+     * Given a GML node representing a polygon geometry, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
     'polygon': function(node) {
       nodeList = node..*::LinearRing;
@@ -2227,4 +3166,15 @@
       return new ZOO.Geometry.Polygon(components);
     },
+    /**
+     * Method: parseGeometry.multipolygon
+     * Given a GML node representing a multipolygon geometry, create a
+     *     ZOO multipolygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.MultiPolygon>} A multipolygon geometry.
+     */
     'multipolygon': function(node) {
       var nodeList = node..*::Polygon;
@@ -2240,4 +3190,15 @@
       return new ZOO.Geometry.MultiPolygon(components);
     },
+    /**
+     * Method: parseGeometry.polygon
+     * Given a GML node representing an envelope, create a
+     *     ZOO polygon geometry.
+     *
+     * Parameters:
+     * node - {E4XElement} A GML node.
+     *
+     * Returns:
+     * {<ZOO.Geometry.Polygon>} A polygon geometry.
+     */
     'envelope': function(node) {
       var components = [];
@@ -2286,4 +3247,45 @@
     }
   },
+  /**
+   * Method: parseAttributes
+   *
+   * Parameters:
+   * node - {<E4XElement>}
+   *
+   * Returns:
+   * {Object} An attributes object.
+   */
+  parseAttributes: function(node) {
+    var attributes = {};
+    // assume attributes are children of the first type 1 child
+    var childNode = node.*::*[0];
+    var child, grandchildren;
+    var children = childNode.*::*;
+    for(var i=0, len=children.length(); i<len; ++i) {
+      child = children[i];
+      grandchildren = child..*::*;
+      if(grandchildren.length() == 1) {
+        var name = child.localName();
+        var value = child.toString();
+        if (value) {
+          value = value.replace(this.regExes.trimSpace, "");
+          attributes[name] = value;
+        } else
+          attributes[name] = null;
+      }
+    }
+    return attributes;
+  },
+  /**
+   * Method: write
+   * Generate a GML document string given a list of features. 
+   * 
+   * Parameters:
+   * features - {Array(<ZOO.Feature>)} List of features to
+   *     serialize into a string.
+   *
+   * Returns:
+   * {String} A string representing the GML document.
+   */
   write: function(features) {
     if(!(features instanceof Array)) {
@@ -2294,9 +3296,19 @@
     var gml = new XML('<'+name+' xmlns:'+pfx+'="'+this.namespaces[pfx]+'" xmlns:gml="'+this.namespaces['gml']+'" xmlns:xsi="'+this.namespaces['xsi']+'" xsi:schemaLocation="'+this.schemaLocation+'"></'+name+'>');
     for(var i=0; i<features.length; i++) {
-      gml.*::*[i] = this.createFeatureXML(features[i]);
+      gml.*::*[i] = this.createFeature(features[i]);
     }
     return gml.toXMLString();
   },
-  createFeatureXML: function(feature) {
+  /** 
+   * Method: createFeature
+   * Accept an ZOO.Feature, and build a GML node for it.
+   *
+   * Parameters:
+   * feature - {<ZOO.Feature>} The feature to be built as GML.
+   *
+   * Returns:
+   * {E4XElement} A node reprensting the feature in GML.
+   */
+  createFeature: function(feature) {
     var pfx = this.defaultPrefix;
     var name = pfx+':'+this.featureName;
@@ -2311,4 +3323,13 @@
     return gml;
   },
+  /**
+   * Method: buildGeometryNode
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} The geometry to be built as GML.
+   *
+   * Returns:
+   * {E4XElement} A node reprensting the geometry in GML.
+   */
   buildGeometryNode: function(geometry) {
     if (this.externalProjection && this.internalProjection) {
@@ -2327,5 +3348,20 @@
     return gml;
   },
+  /**
+   * Property: buildGeometry
+   * Object containing methods to do the actual geometry node building
+   *     based on geometry type.
+   */
   buildGeometry: {
+    /**
+     * Method: buildGeometry.point
+     * Given a ZOO point geometry, create a GML point.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Point>} A point geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML point node.
+     */
     'point': function(geometry) {
       var gml = new XML('<gml:Point xmlns:gml="'+this.namespaces['gml']+'"></gml:Point>');
@@ -2333,4 +3369,14 @@
       return gml;
     },
+    /**
+     * Method: buildGeometry.multipoint
+     * Given a ZOO multipoint geometry, create a GML multipoint.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPoint>} A multipoint geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multipoint node.
+     */
     'multipoint': function(geometry) {
       var gml = new XML('<gml:MultiPoint xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiPoint>');
@@ -2344,4 +3390,14 @@
       return gml;            
     },
+    /**
+     * Method: buildGeometry.linestring
+     * Given a ZOO linestring geometry, create a GML linestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LineString>} A linestring geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML linestring node.
+     */
     'linestring': function(geometry) {
       var gml = new XML('<gml:LineString xmlns:gml="'+this.namespaces['gml']+'"></gml:LineString>');
@@ -2349,4 +3405,16 @@
       return gml;
     },
+    /**
+     * Method: buildGeometry.multilinestring
+     * Given a ZOO multilinestring geometry, create a GML
+     *     multilinestring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiLineString>} A multilinestring
+     *     geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multilinestring node.
+     */
     'multilinestring': function(geometry) {
       var gml = new XML('<gml:MultiLineString xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiLineString>');
@@ -2360,4 +3428,14 @@
       return gml;            
     },
+    /**
+     * Method: buildGeometry.linearring
+     * Given a ZOO linearring geometry, create a GML linearring.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.LinearRing>} A linearring geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML linearring node.
+     */
     'linearring': function(geometry) {
       var gml = new XML('<gml:LinearRing xmlns:gml="'+this.namespaces['gml']+'"></gml:LinearRing>');
@@ -2365,4 +3443,14 @@
       return gml;
     },
+    /**
+     * Method: buildGeometry.polygon
+     * Given an ZOO polygon geometry, create a GML polygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.Polygon>} A polygon geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML polygon node.
+     */
     'polygon': function(geometry) {
       var gml = new XML('<gml:Polygon xmlns:gml="'+this.namespaces['gml']+'"></gml:Polygon>');
@@ -2377,4 +3465,15 @@
       return gml;
     },
+    /**
+     * Method: buildGeometry.multipolygon
+     * Given a ZOO multipolygon geometry, create a GML multipolygon.
+     *
+     * Parameters:
+     * geometry - {<ZOO.Geometry.MultiPolygon>} A multipolygon
+     *     geometry.
+     *
+     * Returns:
+     * {E4XElement} A GML multipolygon node.
+     */
     'multipolygon': function(geometry) {
       var gml = new XML('<gml:MultiPolygon xmlns:gml="'+this.namespaces['gml']+'"></gml:MultiPolygon>');
@@ -2387,11 +3486,18 @@
       }
       return gml;            
-    },
-    'bounds': function(bounds) {
-      var gml = new XML('<gml:Box xmlns:gml="'+this.namespaces['gml']+'"></gml:Box>');
-      gml.*::*[0] = this.buildCoordinatesNode(bounds);
-      return gml;
-    }
-  },
+    }
+  },
+  /**
+   * Method: buildCoordinatesNode
+   * builds the coordinates XmlNode
+   * (code)
+   * <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
+   * (end)
+   * Parameters: 
+   * geometry - {<ZOO.Geometry>} 
+   *
+   * Returns:
+   * {E4XElement} created E4XElement
+   */
   buildCoordinatesNode: function(geometry) {
     var parts = [];
@@ -2409,6 +3515,22 @@
   CLASS_NAME: 'ZOO.Format.GML'
 });
+/**
+ * Class: ZOO.Format.WPS
+ * Read/Write WPS. Create a new instance with the <ZOO.Format.WPS>
+ *     constructor. Supports only parseExecuteResponse.
+ * 
+ * Inherits from:
+ *  - <ZOO.Format>
+ */
 ZOO.Format.WPS = ZOO.Class(ZOO.Format, {
+  /**
+   * Property: schemaLocation
+   * {String} Schema location for a particular minor version.
+   */
   schemaLocation: "http://www.opengis.net/wps/1.0.0/../wpsExecute_request.xsd",
+  /**
+   * Property: namespaces
+   * {Object} Mapping of namespace aliases to namespace URIs.
+   */
   namespaces: {
     ows: "http://www.opengis.net/ows/1.1",
@@ -2417,4 +3539,13 @@
     xsi: "http://www.w3.org/2001/XMLSchema-instance",
   },
+  /**
+   * Method: read
+   *
+   * Parameters:
+   * data - {String} A WPS xml document
+   *
+   * Returns:
+   * {Object} Execute response.
+   */
   read:function(data) {
     data = data.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "");
@@ -2427,4 +3558,13 @@
     }
   },
+  /**
+   * Method: parseExecuteResponse
+   *
+   * Parameters:
+   * node - {E4XElement} A WPS ExecuteResponse document
+   *
+   * Returns:
+   * {Object} Execute response.
+   */
   parseExecuteResponse: function(node) {
     var outputs = node.*::ProcessOutputs.*::Output;
@@ -2439,5 +3579,19 @@
       return null;
   },
+  /**
+   * Property: parseData
+   * Object containing methods to analyse data response.
+   */
   parseData: {
+    /**
+     * Method: parseData.complexdata
+     * Given an Object representing the WPS complex data response.
+     *
+     * Parameters:
+     * node - {E4XElement} A WPS node.
+     *
+     * Returns:
+     * {Object} A WPS complex data response.
+     */
     'complexdata': function(node) {
       var result = {value:node.toString()};
@@ -2450,4 +3604,14 @@
       return result;
     },
+    /**
+     * Method: parseData.literaldata
+     * Given an Object representing the WPS literal data response.
+     *
+     * Parameters:
+     * node - {E4XElement} A WPS node.
+     *
+     * Returns:
+     * {Object} A WPS literal data response.
+     */
     'literaldata': function(node) {
       var result = {value:node.toString()};
@@ -2462,10 +3626,44 @@
 });
 
-
+/**
+ * Class: ZOO.Feature
+ * Vector features use the ZOO.Geometry classes as geometry description.
+ * They have an 'attributes' property, which is the data object
+ */
 ZOO.Feature = ZOO.Class({
+  /** 
+   * Property: fid 
+   * {String} 
+   */
   fid: null,
+  /** 
+   * Property: geometry 
+   * {<ZOO.Geometry>} 
+   */
   geometry: null,
+  /** 
+   * Property: attributes 
+   * {Object} This object holds arbitrary properties that describe the
+   *     feature.
+   */
   attributes: null,
+  /**
+   * Property: bounds
+   * {<ZOO.Bounds>} The box bounding that feature's geometry, that
+   *     property can be set by an <ZOO.Format> object when
+   *     deserializing the feature, so in most cases it represents an
+   *     information set by the server. 
+   */
   bounds: null,
+  /** 
+   * Constructor: ZOO.Feature
+   * Create a vector feature. 
+   * 
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} The geometry that this feature
+   *     represents.
+   * attributes - {Object} An optional object that will be mapped to the
+   *     <attributes> property. 
+   */
   initialize: function(geometry, attributes) {
     this.geometry = geometry ? geometry : null;
@@ -2474,11 +3672,31 @@
       this.attributes = ZOO.extend(this.attributes,attributes);
   },
+  /** 
+   * Method: destroy
+   * nullify references to prevent circular references and memory leaks
+   */
   destroy: function() {
     this.geometry = null;
   },
+  /**
+   * Method: clone
+   * Create a clone of this vector feature.  Does not set any non-standard
+   *     properties.
+   *
+   * Returns:
+   * {<ZOO.Feature>} An exact clone of this vector feature.
+   */
   clone: function () {
     return new ZOO.Feature(this.geometry ? this.geometry.clone() : null,
             this.attributes);
   },
+  /**
+   * Method: move
+   * Moves the feature and redraws it at its new location
+   *
+   * Parameters:
+   * x - {Float}
+   * y - {Float}
+   */
   move: function(x, y) {
     if(!this.geometry.move)
@@ -2491,18 +3709,61 @@
 });
 
+/**
+ * Class: ZOO.Geometry
+ * A Geometry is a description of a geographic object. Create an instance
+ * of this class with the <ZOO.Geometry> constructor. This is a base class,
+ * typical geometry types are described by subclasses of this class.
+ */
 ZOO.Geometry = ZOO.Class({
+  /**
+   * Property: id
+   * {String} A unique identifier for this geometry.
+   */
   id: null,
+  /**
+   * Property: parent
+   * {<ZOO.Geometry>}This is set when a Geometry is added as component
+   * of another geometry
+   */
   parent: null,
+  /**
+   * Property: bounds 
+   * {<ZOO.Bounds>} The bounds of this geometry
+   */
   bounds: null,
+  /**
+   * Constructor: ZOO.Geometry
+   * Creates a geometry object.  
+   */
   initialize: function() {
     //generate unique id
   },
+  /**
+   * Method: destroy
+   * Destroy this geometry.
+   */
   destroy: function() {
     this.id = null;
     this.bounds = null;
   },
+  /**
+   * Method: clone
+   * Create a clone of this geometry.  Does not set any non-standard
+   *     properties of the cloned geometry.
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} An exact clone of this geometry.
+   */
   clone: function() {
     return new ZOO.Geometry();
   },
+  /**
+   * Method: extendBounds
+   * Extend the existing bounds to include the new bounds. 
+   * If geometry's bounds is not yet set, then set a new Bounds.
+   * 
+   * Parameters:
+   * newBounds - {<ZOO.Bounds>} 
+   */
   extendBounds: function(newBounds){
     var bounds = this.getBounds();
@@ -2512,8 +3773,18 @@
       this.bounds.extend(newBounds);
   },
+  /**
+   * Set the bounds for this Geometry.
+   * 
+   * Parameters:
+   * bounds - {<ZOO.Bounds>} 
+   */
   setBounds: function(bounds) {
     if (bounds)
       this.bounds = bounds.clone();
   },
+  /**
+   * Method: clearBounds
+   * Nullify this components bounds and that of its parent as well.
+   */
   clearBounds: function() {
     this.bounds = null;
@@ -2521,4 +3792,12 @@
       this.parent.clearBounds();
   },
+  /**
+   * Method: getBounds
+   * Get the bounds for this Geometry. If bounds is not set, it 
+   * is calculated again, this makes queries faster.
+   * 
+   * Returns:
+   * {<ZOO.Bounds>}
+   */
   getBounds: function() {
     if (this.bounds == null) {
@@ -2527,6 +3806,11 @@
     return this.bounds;
   },
+  /** 
+   * Method: calculateBounds
+   * Recalculate the bounds for the geometry. 
+   */
   calculateBounds: function() {
-    return this.bounds = null;
+    // This should be overridden by subclasses.
+    return this.bounds;
   },
   distanceTo: function(geometry, options) {
@@ -2543,4 +3827,11 @@
     return null;
   },
+  /**
+   * Method: toString
+   * Returns the Well-Known Text representation of a geometry
+   *
+   * Returns:
+   * {String} Well-Known Text
+   */
   toString: function() {
     return ZOO.Format.WKT.prototype.write(
@@ -2550,4 +3841,14 @@
   CLASS_NAME: 'ZOO.Geometry'
 });
+/**
+ * Function: OpenLayers.Geometry.fromWKT
+ * Generate a geometry given a Well-Known Text string.
+ *
+ * Parameters:
+ * wkt - {String} A string representing the geometry in Well-Known Text.
+ *
+ * Returns:
+ * {<ZOO.Geometry>} A geometry of the appropriate class.
+ */
 ZOO.Geometry.fromWKT = function(wkt) {
   var format = arguments.callee.format;
@@ -2683,7 +3984,43 @@
   };
 };
+/**
+ * Class: OpenLayers.Geometry.Collection
+ * A Collection is exactly what it sounds like: A collection of different 
+ * Geometries. These are stored in the local parameter <components> (which
+ * can be passed as a parameter to the constructor). 
+ * 
+ * As new geometries are added to the collection, they are NOT cloned. 
+ * When removing geometries, they need to be specified by reference (ie you 
+ * have to pass in the *exact* geometry to be removed).
+ * 
+ * The <getArea> and <getLength> functions here merely iterate through
+ * the components, summing their respective areas and lengths.
+ *
+ * Create a new instance with the <ZOO.Geometry.Collection> constructor.
+ *
+ * Inerhits from:
+ *  - <ZOO.Geometry> 
+ */
 ZOO.Geometry.Collection = ZOO.Class(ZOO.Geometry, {
+  /**
+   * Property: components
+   * {Array(<ZOO.Geometry>)} The component parts of this geometry
+   */
   components: null,
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of
+   * components that the collection can include.  A null value means the
+   * component types are not restricted.
+   */
   componentTypes: null,
+  /**
+   * Constructor: ZOO.Geometry.Collection
+   * Creates a Geometry Collection -- a list of geoms.
+   *
+   * Parameters: 
+   * components - {Array(<ZOO.Geometry>)} Optional array of geometries
+   *
+   */
   initialize: function (components) {
     ZOO.Geometry.prototype.initialize.apply(this, arguments);
@@ -2693,8 +4030,19 @@
     }
   },
+  /**
+   * Method: destroy
+   * Destroy this geometry.
+   */
   destroy: function () {
     this.components.length = 0;
     this.components = null;
   },
+  /**
+   * Method: clone
+   * Clone this geometry.
+   *
+   * Returns:
+   * {<ZOO.Geometry.Collection>} An exact clone of this collection
+   */
   clone: function() {
     var geometry = eval("new " + this.CLASS_NAME + "()");
@@ -2704,4 +4052,11 @@
     return geometry;
   },
+  /**
+   * Method: getComponentsString
+   * Get a string representing the components for this collection
+   * 
+   * Returns:
+   * {String} A string representation of the components of this geometry
+   */
   getComponentsString: function(){
     var strings = [];
@@ -2711,4 +4066,9 @@
     return strings.join(",");
   },
+  /**
+   * Method: calculateBounds
+   * Recalculate the bounds by iterating through the components and 
+   * calling calling extendBounds() on each item.
+   */
   calculateBounds: function() {
     this.bounds = null;
@@ -2721,4 +4081,11 @@
     return this.bounds
   },
+  /**
+   * APIMethod: addComponents
+   * Add components to this geometry.
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry>)} An array of geometries to add
+   */
   addComponents: function(components){
     if(!(components instanceof Array))
@@ -2728,4 +4095,18 @@
     }
   },
+  /**
+   * Method: addComponent
+   * Add a new component (geometry) to the collection.  If this.componentTypes
+   * is set, then the component class name must be in the componentTypes array.
+   *
+   * The bounds cache is reset.
+   * 
+   * Parameters:
+   * component - {<ZOO.Geometry>} A geometry to add
+   * index - {int} Optional index into the array to insert the component
+   *
+   * Returns:
+   * {Boolean} The component geometry was successfully added
+   */
   addComponent: function(component, index) {
     var added = false;
@@ -2750,4 +4131,11 @@
     return added;
   },
+  /**
+   * Method: removeComponents
+   * Remove components from this geometry.
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry>)} The components to be removed
+   */
   removeComponents: function(components) {
     if(!(components instanceof Array))
@@ -2757,4 +4145,11 @@
     }
   },
+  /**
+   * Method: removeComponent
+   * Remove a component from this geometry.
+   *
+   * Parameters:
+   * component - {<ZOO.Geometry>} 
+   */
   removeComponent: function(component) {      
     ZOO.removeItem(this.components, component);
@@ -2763,4 +4158,11 @@
     this.clearBounds();
   },
+  /**
+   * Method: getLength
+   * Calculate the length of this geometry
+   *
+   * Returns:
+   * {Float} The length of the geometry
+   */
   getLength: function() {
     var length = 0.0;
@@ -2770,4 +4172,12 @@
     return length;
   },
+  /**
+   * APIMethod: getArea
+   * Calculate the area of this geometry. Note how this function is 
+   * overridden in <ZOO.Geometry.Polygon>.
+   *
+   * Returns:
+   * {Float} The area of the collection by summing its parts
+   */
   getArea: function() {
     var area = 0.0;
@@ -2777,7 +4187,67 @@
     return area;
   },
+  /** 
+   * APIMethod: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate geodesic area of the geometry in square meters.
+   */
+  getGeodesicArea: function(projection) {
+    var area = 0.0;
+    for(var i=0, len=this.components.length; i<len; i++) {
+      area += this.components[i].getGeodesicArea(projection);
+    }
+    return area;
+  },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the collection
+   */
   getCentroid: function() {
     return this.components.length && this.components[0].getCentroid();
   },
+  /**
+   * Method: getGeodesicLength
+   * Calculate the approximate length of the geometry were it projected onto
+   *     the earth.
+   *
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Returns:
+   * {Float} The appoximate geodesic length of the geometry in meters.
+   */
+  getGeodesicLength: function(projection) {
+    var length = 0.0;
+    for(var i=0, len=this.components.length; i<len; i++) {
+      length += this.components[i].getGeodesicLength(projection);
+    }
+    return length;
+  },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
   move: function(x, y) {
     for(var i=0, len=this.components.length; i<len; i++) {
@@ -2785,4 +4255,13 @@
     }
   },
+  /**
+   * Method: rotate
+   * Rotate a geometry around some origin
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
   rotate: function(angle, origin) {
     for(var i=0, len=this.components.length; i<len; ++i) {
@@ -2790,4 +4269,20 @@
     }
   },
+  /**
+   * Method: resize
+   * Resize a geometry relative to some origin.  Use this method to apply
+   *     a uniform scaling to a geometry.
+   *
+   * Parameters:
+   * scale - {Float} Factor by which to scale the geometry.  A scale of 2
+   *                 doubles the size of the geometry in each dimension
+   *                 (lines, for example, will be twice as long, and polygons
+   *                 will have four times the area).
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
   resize: function(scale, origin, ratio) {
     for(var i=0; i<this.components.length; ++i) {
@@ -2813,4 +4308,15 @@
     return best;
   },
+  /** 
+   * Method: equals
+   * Determine whether another geometry is equivalent to this one.  Geometries
+   *     are considered equivalent if all components have the same coordinates.
+   * 
+   * Parameters:
+   * geom - {<ZOO.Geometry>} The geometry to test. 
+   *
+   * Returns:
+   * {Boolean} The supplied geometry is equivalent to this geometry.
+   */
   equals: function(geometry) {
     var equivalent = true;
@@ -2830,4 +4336,15 @@
     return equivalent;
   },
+  /**
+   * Method: transform
+   * Reproject the components geometry from source to dest.
+   * 
+   * Parameters:
+   * source - {<ZOO.Projection>} 
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
   transform: function(source, dest) {
     if (source && dest) {
@@ -2840,4 +4357,14 @@
     return this;
   },
+  /**
+   * Method: intersects
+   * Determine if the input geometry intersects this one.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} Any type of geometry.
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this one.
+   */
   intersects: function(geometry) {
     var intersect = false;
@@ -2849,4 +4376,17 @@
     return intersect;
   },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
   getVertices: function(nodes) {
     var vertices = [];
@@ -2860,7 +4400,31 @@
   CLASS_NAME: 'ZOO.Geometry.Collection'
 });
+/**
+ * Class: ZOO.Geometry.Point
+ * Point geometry class. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry> 
+ */
 ZOO.Geometry.Point = ZOO.Class(ZOO.Geometry, {
+  /** 
+   * Property: x 
+   * {float} 
+   */
   x: null,
+  /** 
+   * Property: y 
+   * {float} 
+   */
   y: null,
+  /**
+   * Constructor: ZOO.Geometry.Point
+   * Construct a point geometry.
+   *
+   * Parameters:
+   * x - {float} 
+   * y - {float}
+   * 
+   */
   initialize: function(x, y) {
     ZOO.Geometry.prototype.initialize.apply(this, arguments);
@@ -2868,11 +4432,21 @@
     this.y = parseFloat(y);
   },
+  /**
+   * Method: clone
+   * 
+   * Returns:
+   * {<ZOO.Geometry.Point>} An exact clone of this ZOO.Geometry.Point
+   */
   clone: function(obj) {
     if (obj == null)
       obj = new ZOO.Geometry.Point(this.x, this.y);
     // catch any randomly tagged-on properties
-    //OpenLayers.Util.applyDefaults(obj, this);
+    // ZOO.Util.applyDefaults(obj, this);
     return obj;
   },
+  /** 
+   * Method: calculateBounds
+   * Create a new Bounds based on the x/y
+   */
   calculateBounds: function () {
     this.bounds = new ZOO.Bounds(this.x, this.y,
@@ -2904,4 +4478,15 @@
     return result;
   },
+  /** 
+   * Method: equals
+   * Determine whether another geometry is equivalent to this one.  Geometries
+   *     are considered equivalent if all components have the same coordinates.
+   * 
+   * Parameters:
+   * geom - {<ZOO.Geometry.Point>} The geometry to test. 
+   *
+   * Returns:
+   * {Boolean} The supplied geometry is equivalent to this geometry.
+   */
   equals: function(geom) {
     var equals = false;
@@ -2911,7 +4496,24 @@
     return equals;
   },
+  /**
+   * Method: toShortString
+   *
+   * Returns:
+   * {String} Shortened String representation of Point object. 
+   *         (ex. <i>"5, 42"</i>)
+   */
   toShortString: function() {
     return (this.x + ", " + this.y);
   },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
   move: function(x, y) {
     this.x = this.x + x;
@@ -2919,4 +4521,13 @@
     this.clearBounds();
   },
+  /**
+   * Method: rotate
+   * Rotate a point around another.
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
   rotate: function(angle, origin) {
         angle *= Math.PI / 180;
@@ -2927,7 +4538,29 @@
         this.clearBounds();
   },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the collection
+   */
   getCentroid: function() {
     return new ZOO.Geometry.Point(this.x, this.y);
   },
+  /**
+   * Method: resize
+   * Resize a point relative to some origin.  For points, this has the effect
+   *     of scaling a vector (from the origin to the point).  This method is
+   *     more useful on geometry collection subclasses.
+   *
+   * Parameters:
+   * scale - {Float} Ratio of the new distance from the origin to the old
+   *                 distance from the origin.  A scale of 2 doubles the
+   *                 distance between the point and origin.
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
   resize: function(scale, origin, ratio) {
     ratio = (ratio == undefined) ? 1 : ratio;
@@ -2937,4 +4570,14 @@
     return this;
   },
+  /**
+   * Method: intersects
+   * Determine if the input geometry intersects this one.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} Any type of geometry.
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this one.
+   */
   intersects: function(geometry) {
     var intersect = false;
@@ -2946,4 +4589,15 @@
     return intersect;
   },
+  /**
+   * Method: transform
+   * Translate the x,y properties of the point from source to dest.
+   * 
+   * Parameters:
+   * source - {<ZOO.Projection>} 
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
   transform: function(source, dest) {
     if ((source && dest)) {
@@ -2954,4 +4608,17 @@
     return this;
   },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
   getVertices: function(nodes) {
     return [this];
@@ -2959,4 +4626,11 @@
   CLASS_NAME: 'ZOO.Geometry.Point'
 });
+/**
+ * Class: ZOO.Geometry.Surface
+ * Surface geometry class. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry> 
+ */
 ZOO.Geometry.Surface = ZOO.Class(ZOO.Geometry, {
   initialize: function() {
@@ -2965,13 +4639,52 @@
   CLASS_NAME: "ZOO.Geometry.Surface"
 });
+/**
+ * Class: ZOO.Geometry.MultiPoint
+ * MultiPoint is a collection of Points. Create a new instance with the
+ * <ZOO.Geometry.MultiPoint> constructor.
+ *
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
 ZOO.Geometry.MultiPoint = ZOO.Class(
   ZOO.Geometry.Collection, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of
+   * components that the collection can include.  A null value means the
+   * component types are not restricted.
+   */
   componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: ZOO.Geometry.MultiPoint
+   * Create a new MultiPoint Geometry
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.Point>)} 
+   *
+   * Returns:
+   * {<ZOO.Geometry.MultiPoint>}
+   */
   initialize: function(components) {
     ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
   },
+  /**
+   * Method: addPoint
+   * Wrapper for <ZOO.Geometry.Collection.addComponent>
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>} Point to be added
+   * index - {Integer} Optional index
+   */
   addPoint: function(point, index) {
     this.addComponent(point, index);
   },
+  /**
+   * Method: removePoint
+   * Wrapper for <ZOO.Geometry.Collection.removeComponent>
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>} Point to be removed
+   */
   removePoint: function(point){
     this.removeComponent(point);
@@ -2979,9 +4692,36 @@
   CLASS_NAME: "ZOO.Geometry.MultiPoint"
 });
+/**
+ * Class: ZOO.Geometry.Curve
+ * A Curve is a MultiPoint, whose points are assumed to be connected. To 
+ * this end, we provide a "getLength()" function, which iterates through 
+ * the points, summing the distances between them. 
+ * 
+ * Inherits: 
+ *  - <ZOO.Geometry.MultiPoint>
+ */
 ZOO.Geometry.Curve = ZOO.Class(ZOO.Geometry.MultiPoint, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of 
+   *                 components that the collection can include.  A null 
+   *                 value means the component types are not restricted.
+   */
   componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: ZOO.Geometry.Curve
+   * 
+   * Parameters:
+   * point - {Array(<ZOO.Geometry.Point>)}
+   */
   initialize: function(points) {
     ZOO.Geometry.MultiPoint.prototype.initialize.apply(this,arguments);
   },
+  /**
+   * Method: getLength
+   * 
+   * Returns:
+   * {Float} The length of the curve
+   */
   getLength: function() {
     var length = 0.0;
@@ -2993,14 +4733,87 @@
     return length;
   },
+  /**
+     * APIMethod: getGeodesicLength
+     * Calculate the approximate length of the geometry were it projected onto
+     *     the earth.
+     *
+     * projection - {<ZOO.Projection>} The spatial reference system
+     *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+     *     assumed.
+     * 
+     * Returns:
+     * {Float} The appoximate geodesic length of the geometry in meters.
+     */
+    getGeodesicLength: function(projection) {
+      var geom = this;  // so we can work with a clone if needed
+      if(projection) {
+        var gg = new ZOO.Projection("EPSG:4326");
+        if(!gg.equals(projection)) {
+          geom = this.clone().transform(projection, gg);
+       }
+     }
+     var length = 0.0;
+     if(geom.components && (geom.components.length > 1)) {
+       var p1, p2;
+       for(var i=1, len=geom.components.length; i<len; i++) {
+         p1 = geom.components[i-1];
+         p2 = geom.components[i];
+        // this returns km and requires x/y properties
+        length += ZOO.distVincenty(p1,p2);
+      }
+    }
+    // convert to m
+    return length * 1000;
+  },
   CLASS_NAME: "ZOO.Geometry.Curve"
 });
+/**
+ * Class: ZOO.Geometry.LineString
+ * A LineString is a Curve which, once two points have been added to it, can 
+ * never be less than two points long.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Curve>
+ */
 ZOO.Geometry.LineString = ZOO.Class(ZOO.Geometry.Curve, {
+  /**
+   * Constructor: ZOO.Geometry.LineString
+   * Create a new LineString geometry
+   *
+   * Parameters:
+   * points - {Array(<ZOO.Geometry.Point>)} An array of points used to
+   *          generate the linestring
+   *
+   */
   initialize: function(points) {
     ZOO.Geometry.Curve.prototype.initialize.apply(this, arguments);        
   },
+  /**
+   * Method: removeComponent
+   * Only allows removal of a point if there are three or more points in 
+   * the linestring. (otherwise the result would be just a single point)
+   *
+   * Parameters: 
+   * point - {<ZOO.Geometry.Point>} The point to be removed
+   */
   removeComponent: function(point) {
     if ( this.components && (this.components.length > 2))
       ZOO.Geometry.Collection.prototype.removeComponent.apply(this,arguments);
   },
+  /**
+   * Method: intersects
+   * Test for instersection between two geometries.  This is a cheapo
+   *     implementation of the Bently-Ottmann algorigithm.  It doesn't
+   *     really keep track of a sweep line data structure.  It is closer
+   *     to the brute force method, except that segments are sorted and
+   *     potential intersections are only calculated when bounding boxes
+   *     intersect.
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>}
+   *
+   * Returns:
+   * {Boolean} The input geometry intersects this geometry.
+   */
   intersects: function(geometry) {
     var intersect = false;
@@ -3050,4 +4863,13 @@
     return intersect;
   },
+  /**
+   * Method: getSortedSegments
+   *
+   * Returns:
+   * {Array} An array of segment objects.  Segment objects have properties
+   *     x1, y1, x2, and y2.  The start point is represented by x1 and y1.
+   *     The end point is represented by x2 and y2.  Start and end are
+   *     ordered so that x1 < x2.
+   */
   getSortedSegments: function() {
     var numSeg = this.components.length - 1;
@@ -3077,4 +4899,29 @@
     return segments.sort(byX1);
   },
+  /**
+   * Method: splitWithSegment
+   * Split this geometry with the given segment.
+   *
+   * Parameters:
+   * seg - {Object} An object with x1, y1, x2, and y2 properties referencing
+   *     segment endpoint coordinates.
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source segment must be within the
+   *     tolerance distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of one of the source segment's
+   *     endpoints will be assumed to occur at the endpoint.
+   *
+   * Returns:
+   * {Object} An object with *lines* and *points* properties.  If the given
+   *     segment intersects this linestring, the lines array will reference
+   *     geometries that result from the split.  The points array will contain
+   *     all intersection points.  Intersection points are sorted along the
+   *     segment (in order from x1,y1 to x2,y2).
+   */
   splitWithSegment: function(seg, options) {
     var edge = !(options && options.edge === false);
@@ -3137,4 +4984,33 @@
     return result;
   },
+  /**
+   * Method: split
+   * Use this geometry (the source) to attempt to split a target geometry.
+   * 
+   * Parameters:
+   * target - {<ZOO.Geometry>} The target geometry.
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * mutual - {Boolean} Split the source geometry in addition to the target
+   *     geometry.  Default is false.
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source must be within the tolerance
+   *     distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of an existing vertex on the source
+   *     will be assumed to occur at the vertex.
+   * 
+   * Returns:
+   * {Array} A list of geometries (of this same type as the target) that
+   *     result from splitting the target with the source geometry.  The
+   *     source and target geometry will remain unmodified.  If no split
+   *     results, null will be returned.  If mutual is true and a split
+   *     results, return will be an array of two arrays - the first will be
+   *     all geometries that result from splitting the source geometry and
+   *     the second will be all geometries that result from splitting the
+   *     target geometry.
+   */
   split: function(target, options) {
     var results = null;
@@ -3205,7 +5081,50 @@
     return results;
   },
+  /**
+   * Method: splitWith
+   * Split this geometry (the target) with the given geometry (the source).
+   *
+   * Parameters:
+   * geometry - {<ZOO.Geometry>} A geometry used to split this
+   *     geometry (the source).
+   * options - {Object} Properties of this object will be used to determine
+   *     how the split is conducted.
+   *
+   * Valid options:
+   * mutual - {Boolean} Split the source geometry in addition to the target
+   *     geometry.  Default is false.
+   * edge - {Boolean} Allow splitting when only edges intersect.  Default is
+   *     true.  If false, a vertex on the source must be within the tolerance
+   *     distance of the intersection to be considered a split.
+   * tolerance - {Number} If a non-null value is provided, intersections
+   *     within the tolerance distance of an existing vertex on the source
+   *     will be assumed to occur at the vertex.
+   * 
+   * Returns:
+   * {Array} A list of geometries (of this same type as the target) that
+   *     result from splitting the target with the source geometry.  The
+   *     source and target geometry will remain unmodified.  If no split
+   *     results, null will be returned.  If mutual is true and a split
+   *     results, return will be an array of two arrays - the first will be
+   *     all geometries that result from splitting the source geometry and
+   *     the second will be all geometries that result from splitting the
+   *     target geometry.
+   */
   splitWith: function(geometry, options) {
     return geometry.split(this, options);
   },
+  /**
+   * Method: getVertices
+   * Return a list of all points in this geometry.
+   *
+   * Parameters:
+   * nodes - {Boolean} For lines, only return vertices that are
+   *     endpoints.  If false, for lines, only vertices that are not
+   *     endpoints will be returned.  If not provided, all vertices will
+   *     be returned.
+   *
+   * Returns:
+   * {Array} A list of all vertices in the geometry.
+   */
   getVertices: function(nodes) {
     var vertices;
@@ -3323,10 +5242,57 @@
   CLASS_NAME: "ZOO.Geometry.LineString"
 });
+/**
+ * Class: ZOO.Geometry.LinearRing
+ * 
+ * A Linear Ring is a special LineString which is closed. It closes itself 
+ * automatically on every addPoint/removePoint by adding a copy of the first
+ * point as the last point. 
+ * 
+ * Also, as it is the first in the line family to close itself, a getArea()
+ * function is defined to calculate the enclosed area of the linearRing
+ * 
+ * Inherits:
+ *  - <OpenLayers.Geometry.LineString>
+ */
 ZOO.Geometry.LinearRing = ZOO.Class(
   ZOO.Geometry.LineString, {
+  /**
+   * Property: componentTypes
+   * {Array(String)} An array of class names representing the types of 
+   *                 components that the collection can include.  A null 
+   *                 value means the component types are not restricted.
+   */
   componentTypes: ["ZOO.Geometry.Point"],
+  /**
+   * Constructor: OpenLayers.Geometry.LinearRing
+   * Linear rings are constructed with an array of points.  This array
+   *     can represent a closed or open ring.  If the ring is open (the last
+   *     point does not equal the first point), the constructor will close
+   *     the ring.  If the ring is already closed (the last point does equal
+   *     the first point), it will be left closed.
+   * 
+   * Parameters:
+   * points - {Array(<ZOO.Geometry.Point>)} points
+   */
   initialize: function(points) {
     ZOO.Geometry.LineString.prototype.initialize.apply(this,arguments);
   },
+  /**
+   * Method: addComponent
+   * Adds a point to geometry components.  If the point is to be added to
+   *     the end of the components array and it is the same as the last point
+   *     already in that array, the duplicate point is not added.  This has 
+   *     the effect of closing the ring if it is not already closed, and 
+   *     doing the right thing if it is already closed.  This behavior can 
+   *     be overridden by calling the method with a non-null index as the 
+   *     second argument.
+   *
+   * Parameter:
+   * point - {<ZOO.Geometry.Point>}
+   * index - {Integer} Index into the array to insert the component
+   * 
+   * Returns:
+   * {Boolean} Was the Point successfully added?
+   */
   addComponent: function(point, index) {
     var added = false;
@@ -3342,4 +5308,11 @@
     return added;
   },
+  /**
+   * APIMethod: removeComponent
+   * Removes a point from geometry components.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   */
   removeComponent: function(point) {
     if (this.components.length > 4) {
@@ -3353,4 +5326,14 @@
     }
   },
+  /**
+   * Method: move
+   * Moves a geometry by the given displacement along positive x and y axes.
+   *     This modifies the position of the geometry and clears the cached
+   *     bounds.
+   *
+   * Parameters:
+   * x - {Float} Distance to move geometry in positive x direction. 
+   * y - {Float} Distance to move geometry in positive y direction.
+   */
   move: function(x, y) {
     for(var i = 0, len=this.components.length; i<len - 1; i++) {
@@ -3358,4 +5341,13 @@
     }
   },
+  /**
+   * Method: rotate
+   * Rotate a geometry around some origin
+   *
+   * Parameters:
+   * angle - {Float} Rotation angle in degrees (measured counterclockwise
+   *                 from the positive x-axis)
+   * origin - {<ZOO.Geometry.Point>} Center point for the rotation
+   */
   rotate: function(angle, origin) {
     for(var i=0, len=this.components.length; i<len - 1; ++i) {
@@ -3363,4 +5355,20 @@
     }
   },
+  /**
+   * Method: resize
+   * Resize a geometry relative to some origin.  Use this method to apply
+   *     a uniform scaling to a geometry.
+   *
+   * Parameters:
+   * scale - {Float} Factor by which to scale the geometry.  A scale of 2
+   *                 doubles the size of the geometry in each dimension
+   *                 (lines, for example, will be twice as long, and polygons
+   *                 will have four times the area).
+   * origin - {<ZOO.Geometry.Point>} Point of origin for resizing
+   * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
+   * 
+   * Returns:
+   * {ZOO.Geometry} - The current geometry. 
+   */
   resize: function(scale, origin, ratio) {
     for(var i=0, len=this.components.length; i<len - 1; ++i) {
@@ -3369,4 +5377,15 @@
     return this;
   },
+  /**
+   * Method: transform
+   * Reproject the components geometry from source to dest.
+   *
+   * Parameters:
+   * source - {<ZOO.Projection>}
+   * dest - {<ZOO.Projection>}
+   * 
+   * Returns:
+   * {<ZOO.Geometry>} 
+   */
   transform: function(source, dest) {
     if (source && dest) {
@@ -3379,4 +5398,10 @@
     return this;
   },
+  /**
+   * Method: getCentroid
+   *
+   * Returns:
+   * {<ZOO.Geometry.Point>} The centroid of the ring
+   */
   getCentroid: function() {
     if ( this.components && (this.components.length > 2)) {
@@ -3395,4 +5420,12 @@
     return new ZOO.Geometry.Point(x, y);
   },
+  /**
+   * Method: getArea
+   * Note - The area is positive if the ring is oriented CW, otherwise
+   *         it will be negative.
+   * 
+   * Returns:
+   * {Float} The signed area for a ring.
+   */
   getArea: function() {
     var area = 0.0;
@@ -3408,4 +5441,60 @@
     return area;
   },
+  /**
+   * Method: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.  Note that this area will be positive if ring is oriented
+   *     clockwise, otherwise it will be negative.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate signed geodesic area of the polygon in square
+   *     meters.
+   */
+  getGeodesicArea: function(projection) {
+    var ring = this;  // so we can work with a clone if needed
+    if(projection) {
+      var gg = new ZOO.Projection("EPSG:4326");
+      if(!gg.equals(projection)) {
+        ring = this.clone().transform(projection, gg);
+      }
+    }
+    var area = 0.0;
+    var len = ring.components && ring.components.length;
+    if(len > 2) {
+      var p1, p2;
+      for(var i=0; i<len-1; i++) {
+        p1 = ring.components[i];
+        p2 = ring.components[i+1];
+        area += ZOO.rad(p2.x - p1.x) *
+                (2 + Math.sin(ZOO.rad(p1.y)) +
+                Math.sin(ZOO.rad(p2.y)));
+      }
+      area = area * 6378137.0 * 6378137.0 / 2.0;
+    }
+    return area;
+  },
+  /**
+   * Method: containsPoint
+   * Test if a point is inside a linear ring.  For the case where a point
+   *     is coincident with a linear ring edge, returns 1.  Otherwise,
+   *     returns boolean.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   *
+   * Returns:
+   * {Boolean | Number} The point is inside the linear ring.  Returns 1 if
+   *     the point is coincident with an edge.  Returns boolean otherwise.
+   */
   containsPoint: function(point) {
     var approx = OpenLayers.Number.limitSigDigs;
@@ -3506,7 +5595,23 @@
   CLASS_NAME: "ZOO.Geometry.LinearRing"
 });
+/**
+ * Class: ZOO.Geometry.MultiLineString
+ * A MultiLineString is a geometry with multiple <ZOO.Geometry.LineString>
+ * components.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
 ZOO.Geometry.MultiLineString = ZOO.Class(
   ZOO.Geometry.Collection, {
   componentTypes: ["ZOO.Geometry.LineString"],
+  /**
+   * Constructor: ZOO.Geometry.MultiLineString
+   * Constructor for a MultiLineString Geometry.
+   *
+   * Parameters: 
+   * components - {Array(<ZOO.Geometry.LineString>)} 
+   *
+   */
   initialize: function(components) {
     ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);        
@@ -3663,10 +5768,35 @@
   CLASS_NAME: "ZOO.Geometry.MultiLineString"
 });
+/**
+ * Class: ZOO.Geometry.Polygon 
+ * Polygon is a collection of <ZOO.Geometry.LinearRing>. 
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection> 
+ */
 ZOO.Geometry.Polygon = ZOO.Class(
   ZOO.Geometry.Collection, {
   componentTypes: ["ZOO.Geometry.LinearRing"],
+  /**
+   * Constructor: OpenLayers.Geometry.Polygon
+   * Constructor for a Polygon geometry. 
+   * The first ring (this.component[0])is the outer bounds of the polygon and 
+   * all subsequent rings (this.component[1-n]) are internal holes.
+   *
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.LinearRing>)} 
+   */
   initialize: function(components) {
     ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
   },
+  /** 
+   * Method: getArea
+   * Calculated by subtracting the areas of the internal holes from the 
+   *   area of the outer hole.
+   * 
+   * Returns:
+   * {float} The area of the geometry
+   */
   getArea: function() {
     var area = 0.0;
@@ -3679,4 +5809,44 @@
     return area;
   },
+  /** 
+   * APIMethod: getGeodesicArea
+   * Calculate the approximate area of the polygon were it projected onto
+   *     the earth.
+   *
+   * Parameters:
+   * projection - {<ZOO.Projection>} The spatial reference system
+   *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
+   *     assumed.
+   * 
+   * Reference:
+   * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
+   *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
+   *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
+   *
+   * Returns:
+   * {float} The approximate geodesic area of the polygon in square meters.
+   */
+  getGeodesicArea: function(projection) {
+    var area = 0.0;
+    if(this.components && (this.components.length > 0)) {
+      area += Math.abs(this.components[0].getGeodesicArea(projection));
+      for(var i=1, len=this.components.length; i<len; i++) {
+          area -= Math.abs(this.components[i].getGeodesicArea(projection));
+      }
+    }
+    return area;
+  },
+  /**
+   * Method: containsPoint
+   * Test if a point is inside a polygon.  Points on a polygon edge are
+   *     considered inside.
+   *
+   * Parameters:
+   * point - {<ZOO.Geometry.Point>}
+   *
+   * Returns:
+   * {Boolean | Number} The point is inside the polygon.  Returns 1 if the
+   *     point is on an edge.  Returns boolean otherwise.
+   */
   containsPoint: function(point) {
     var numRings = this.components.length;
@@ -3760,7 +5930,52 @@
   CLASS_NAME: "ZOO.Geometry.Polygon"
 });
+/**
+ * Method: createRegularPolygon
+ * Create a regular polygon around a radius. Useful for creating circles 
+ * and the like.
+ *
+ * Parameters:
+ * origin - {<ZOO.Geometry.Point>} center of polygon.
+ * radius - {Float} distance to vertex, in map units.
+ * sides - {Integer} Number of sides. 20 approximates a circle.
+ * rotation - {Float} original angle of rotation, in degrees.
+ */
+OpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {  
+    var angle = Math.PI * ((1/sides) - (1/2));
+    if(rotation) {
+        angle += (rotation / 180) * Math.PI;
+    }
+    var rotatedAngle, x, y;
+    var points = [];
+    for(var i=0; i<sides; ++i) {
+        rotatedAngle = angle + (i * 2 * Math.PI / sides);
+        x = origin.x + (radius * Math.cos(rotatedAngle));
+        y = origin.y + (radius * Math.sin(rotatedAngle));
+        points.push(new ZOO.Geometry.Point(x, y));
+    }
+    var ring = new ZOO.Geometry.LinearRing(points);
+    return new ZOO.Geometry.Polygon([ring]);
+};
+/**
+ * Class: ZOO.Geometry.MultiPolygon
+ * MultiPolygon is a geometry with multiple <ZOO.Geometry.Polygon>
+ * components.  Create a new instance with the <ZOO.Geometry.MultiPolygon>
+ * constructor.
+ * 
+ * Inherits from:
+ *  - <ZOO.Geometry.Collection>
+ */
 ZOO.Geometry.MultiPolygon = ZOO.Class(
   ZOO.Geometry.Collection, {
   componentTypes: ["ZOO.Geometry.Polygon"],
+  /**
+   * Constructor: OpenLayers.Geometry.MultiPolygon
+   * Create a new MultiPolygon geometry
+   *
+   * Parameters:
+   * components - {Array(<ZOO.Geometry.Polygon>)} An array of polygons
+   *              used to generate the MultiPolygon
+   *
+   */
   initialize: function(components) {
     ZOO.Geometry.Collection.prototype.initialize.apply(this,arguments);
