docs: function() {
          //wait for the map to be initialized before proceeding
          var mapBounds = this.map.getExtent();
          if (!mapBounds) {
              return;
          }
          
          //clear out the old grid
          this.gratLayer.destroyFeatures();
          
          //get the projection objects required
          var llProj = new OpenLayers.Projection("EPSG:4326");
          var mapProj = this.map.getProjectionObject();
          var mapRes = this.map.getResolution();
          
          //if the map is in lon/lat, then the lines are straight and only one
          //point is required
          if (mapProj.proj && mapProj.proj.projName == "longlat") {
              this.numPoints = 1;
          }
          
          //get the map center in EPSG:4326
          var mapCenter = this.map.getCenter(); //lon and lat here are really map x and y
          var mapCenterLL = new OpenLayers.Pixel(mapCenter.lon, mapCenter.lat);
          OpenLayers.Projection.transform(mapCenterLL, mapProj, llProj);
          
          /* This block of code determines the lon/lat interval to use for the
           * grid by calculating the diagonal size of one grid cell at the map
           * center.  Iterates through the intervals array until the diagonal
           * length is less than the targetSize option.
           */
          //find lat/lon interval that results in a grid of less than the target size
          var testSq = this.targetSize*mapRes;
          testSq *= testSq;   //compare squares rather than doing a square root to save time
          var llInterval;
          for (var i=0; i<this.intervals.length; ++i) {
              llInterval = this.intervals[i];   //could do this for both x and y??
              var delta = llInterval/2;  
              var p1 = mapCenterLL.offset({x: -delta, y: -delta});  //test coords in EPSG:4326 space
              var p2 = mapCenterLL.offset({x: delta, y: delta});
              OpenLayers.Projection.transform(p1, llProj, mapProj); // convert them back to map projection
              OpenLayers.Projection.transform(p2, llProj, mapProj);
              var distSq = (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
              if (distSq <= testSq) {
                  break;
              }
          }
          //alert(llInterval);
          
          //round the LL center to an even number based on the interval
          mapCenterLL.x = Math.floor(mapCenterLL.x/llInterval)*llInterval;
          mapCenterLL.y = Math.floor(mapCenterLL.y/llInterval)*llInterval;
          //TODO adjust for minutses/seconds?
          
          /* The following 2 blocks calculate the nodes of the grid along a 
           * line of constant longitude (then latitiude) running through the
           * center of the map until it reaches the map edge.  The calculation
           * goes from the center in both directions to the edge.
           */
          //get the central longitude line, increment the latitude
          var iter = 0;
          var centerLonPoints = [mapCenterLL.clone()];
          var newPoint = mapCenterLL.clone();
          var mapXY;
          do {
              newPoint = newPoint.offset({x: 0, y: llInterval});
              mapXY = OpenLayers.Projection.transform(newPoint.clone(), llProj, mapProj);
              centerLonPoints.unshift(newPoint);
          } while (mapBounds.containsPixel(mapXY) && ++iter<1000);
          newPoint = mapCenterLL.clone();
          do {          
              newPoint = newPoint.offset({x: 0, y: -llInterval});
              mapXY = OpenLayers.Projection.transform(newPoint.clone(), llProj, mapProj);
              centerLonPoints.push(newPoint);
          } while (mapBounds.containsPixel(mapXY) && ++iter<1000);
          
          //get the central latitude line, increment the longitude
          iter = 0;
          var centerLatPoints = [mapCenterLL.clone()];
          newPoint = mapCenterLL.clone();
          do {
              newPoint = newPoint.offset({x: -llInterval, y: 0});
              mapXY = OpenLayers.Projection.transform(newPoint.clone(), llProj, mapProj);
              centerLatPoints.unshift(newPoint);
          } while (mapBounds.containsPixel(mapXY) && ++iter<1000);
          newPoint = mapCenterLL.clone();
          do {          
              newPoint = newPoint.offset({x: llInterval, y: 0});
              mapXY = OpenLayers.Projection.transform(newPoint.clone(), llProj, mapProj);
              centerLatPoints.push(newPoint);
          } while (mapBounds.containsPixel(mapXY) && ++iter<1000);
          
          //now generate a line for each node in the central lat and lon lines
          //first loop over constant longitude
          var lines = [];
          for(var i=0; i < centerLatPoints.length; ++i) {
              var lon = centerLatPoints[i].x;
              var pointList = [];
              var labelPoint = null;
              var latEnd = Math.min(centerLonPoints[0].y, 90);
              var latStart = Math.max(centerLonPoints[centerLonPoints.length - 1].y, -90);
              var latDelta = (latEnd - latStart)/this.numPoints;
              var lat = latStart;
              for(var j=0; j<= this.numPoints; ++j) {
                  var gridPoint = new OpenLayers.Geometry.Point(lon,lat);
                  gridPoint.transform(llProj, mapProj);
                  pointList.push(gridPoint);
                  lat += latDelta;
                  if (gridPoint.y >= mapBounds.bottom && !labelPoint) {
                      labelPoint = gridPoint;
                  }
              }
              if (this.labelled) {
                  //keep track of when this grid line crosses the map bounds to set
                  //the label position
                  //labels along the bottom, add 10 pixel offset up into the map
                  //TODO add option for labels on top
                  var labelPos = new OpenLayers.Geometry.Point(labelPoint.x,mapBounds.bottom);
                  var labelAttrs = {
                      value: lon,
                      label: this.labelled?OpenLayers.Util.getFormattedLonLat(lon, "lon", this.labelFormat):"",
                      labelAlign: "cb",
                      xOffset: 0,
                      yOffset: 2
                  }; 
                  this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));
              }
              var geom = new OpenLayers.Geometry.LineString(pointList);
              lines.push(new OpenLayers.Feature.Vector(geom));
          }
          
          //now draw the lines of constant latitude
          for (var j=0; j < centerLonPoints.length; ++j) {
              lat = centerLonPoints[j].y;
              if (lat<-90 || lat>90) {  //latitudes only valid between -90 and 90
                  continue;
              }
              var pointList = [];
              var lonStart = centerLatPoints[0].x;
              var lonEnd = centerLatPoints[centerLatPoints.length - 1].x;
              var lonDelta = (lonEnd - lonStart)/this.numPoints;
              var lon = lonStart;
              var labelPoint = null;
              for(var i=0; i <= this.numPoints ; ++i) {
                  var gridPoint = new OpenLayers.Geometry.Point(lon,lat);
                  gridPoint.transform(llProj, mapProj);
                  pointList.push(gridPoint);
                  lon += lonDelta;
                  if (gridPoint.x < mapBounds.right) {
                      labelPoint = gridPoint;
                  }
              }
              if (this.labelled) {
                  //keep track of when this grid line crosses the map bounds to set
                  //the label position
                  //labels along the right, 30 pixel offset left into the map
                  //TODO add option for labels on left
                  var labelPos = new OpenLayers.Geometry.Point(mapBounds.right, labelPoint.y); 
                  var labelAttrs = {
                      value: lat,
                      label: this.labelled?OpenLayers.Util.getFormattedLonLat(lat, "lat", this.labelFormat):"",
                      labelAlign: "rb",
                      xOffset: -2,
                      yOffset: 2
                  }; 
                  this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));
              }
              var geom = new OpenLayers.Geometry.LineString(pointList);
              lines.push(new OpenLayers.Feature.Vector(geom));
            }
            this.gratLayer.addFeatures(lines);
      }