cdm/src/main/java/ucar/nc2/dataset/conv/WRFConvention.java
public void augmentDataset(NetcdfDataset ds, CancelTask cancelTask) {
    if (null != ds.findVariable("x")) return; // check if its already been done - aggregating enhanced datasets.

    Attribute att = ds.findGlobalAttribute("GRIDTYPE");
    gridE = att != null && att.getStringValue().equalsIgnoreCase("E");
    
    // kludge in fixing the units
    List<Variable> vlist = ds.getVariables();
    for (Variable v : vlist) {
      att = v.findAttributeIgnoreCase(CDM.UNITS);
      if (att != null) {
        String units = att.getStringValue();
        if (units != null)
          v.addAttribute(new Attribute(CDM.UNITS, normalize(units))); // removes the old
      }
    }

    // make projection transform
    att = ds.findGlobalAttribute("MAP_PROJ");
    int projType = att.getNumericValue().intValue();
    boolean isLatLon = false;

    if (projType == 203) {

      /* centerX = centralLon;
      centerY = centralLat;
      ds.addCoordinateAxis( makeLonCoordAxis( ds, "longitude", ds.findDimension("west_east")));
      ds.addCoordinateAxis( makeLatCoordAxis( ds, "latitude", ds.findDimension("south_north")));  */

      Variable glat = ds.findVariable("GLAT");
      if (glat == null) {
        parseInfo.format("Projection type 203 - expected GLAT variable not found%n");
      } else {
        glat.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
        if (gridE) glat.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        glat.setDimensions("south_north west_east");
        glat.setCachedData(convertToDegrees(glat), false);
        glat.addAttribute(new Attribute(CDM.UNITS, CDM.LAT_UNITS));
      }

      Variable glon = ds.findVariable("GLON");
      if (glon == null) {
        parseInfo.format("Projection type 203 - expected GLON variable not found%n");
      } else {
        glon.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
        if (gridE) glon.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        glon.setDimensions("south_north west_east");
        glon.setCachedData(convertToDegrees(glon), false);
        glon.addAttribute(new Attribute(CDM.UNITS, CDM.LON_UNITS));
      }

      VariableDS v = new VariableDS(ds, null, null, "LatLonCoordSys", DataType.CHAR, "", null, null);
      v.addAttribute(new Attribute(_Coordinate.Axes, "GLAT GLON Time"));
      Array data = Array.factory(DataType.CHAR, new int[]{}, new char[]{' '});
      v.setCachedData(data, true);
      ds.addVariable(null, v);

      Variable dataVar = ds.findVariable("LANDMASK");
      dataVar.addAttribute(new Attribute(_Coordinate.Systems, "LatLonCoordSys"));

    } else {
      double lat1 = findAttributeDouble(ds, "TRUELAT1");
      double lat2 = findAttributeDouble(ds, "TRUELAT2");
      double centralLat = findAttributeDouble(ds, "CEN_LAT");  // center of grid
      double centralLon = findAttributeDouble(ds, "CEN_LON");  // center of grid

      double standardLon = findAttributeDouble(ds, "STAND_LON"); // true longitude
      double standardLat = findAttributeDouble(ds, "MOAD_CEN_LAT");

      ProjectionImpl proj = null;
      switch (projType) {
        case 0: // for diagnostic runs with no georeferencing
          proj = new FlatEarth();
          projCT = new ProjectionCT("flat_earth", "FGDC", proj);
          // System.out.println(" using LC "+proj.paramsToString());
          break;
        case 1:
          proj = new LambertConformal(standardLat, standardLon, lat1, lat2, 0.0, 0.0, 6370);
          projCT = new ProjectionCT("Lambert", "FGDC", proj);
          // System.out.println(" using LC "+proj.paramsToString());
          break;
        case 2:
          // Thanks to Heiko Klein for figuring out WRF Stereographic
          double lon0 = (Double.isNaN(standardLon)) ? centralLon : standardLon;
          double lat0 = (Double.isNaN(centralLat)) ? lat2 : centralLat;  // ?? 7/20/2010
          double scaleFactor = (1 + Math.abs( Math.sin(Math.toRadians(lat1)))) / 2.;  // R Schmunk 9/10/07
          // proj = new Stereographic(lat2, lon0, scaleFactor);
          proj = new Stereographic(lat0, lon0, scaleFactor, 0.0, 0.0, 6370);
          projCT = new ProjectionCT("Stereographic", "FGDC", proj);
          break;
        case 3:
          proj = new Mercator(standardLon, lat1, 0.0, 0.0, 6370); // thanks to Robert Schmunk with edits for non-MOAD grids
          projCT = new ProjectionCT("Mercator", "FGDC", proj);
          // proj = new TransverseMercator(standardLat, standardLon, 1.0);
          //projCT = new ProjectionCT("TransverseMercator", "FGDC", proj);
          break;
        case 6:
          // version 3 "lat-lon", including global
          // http://www.mmm.ucar.edu/wrf/users/workshops/WS2008/presentations/1-2.pdf
          // use 2D XLAT, XLONG
          isLatLon = true;
          for (Variable v : vlist) {
            if (v.getShortName().startsWith("XLAT")) {
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
              removeConstantTimeDim(ds, v);

            } else if (v.getShortName().startsWith("XLONG")) {
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
              removeConstantTimeDim(ds, v);

            } else if (v.getShortName().equals("T")) { // ANOTHER MAJOR KLUDGE to pick up 4D fields
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT XLONG z"));
            } else if (v.getShortName().equals("U")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT_U XLONG_U z"));
            } else if (v.getShortName().equals("V")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT_V XLONG_V z"));
            } else if (v.getShortName().equals("W")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT XLONG z_stag"));
            }
          }
          break;
        default:
          parseInfo.format("ERROR: unknown projection type = %s%n", projType);
          break;
      }

      if (proj != null) {
        LatLonPointImpl lpt1 = new LatLonPointImpl(centralLat, centralLon); // center of the grid
        ProjectionPoint ppt1 = proj.latLonToProj(lpt1, new ProjectionPointImpl());
        centerX = ppt1.getX();
        centerY = ppt1.getY();
        if (debug) {
          System.out.println("centerX=" + centerX);
          System.out.println("centerY=" + centerY);
        }
      }

      // make axes
      if (!isLatLon) {
        ds.addCoordinateAxis(makeXCoordAxis(ds, "x", ds.findDimension("west_east")));
        ds.addCoordinateAxis(makeXCoordAxis(ds, "x_stag", ds.findDimension("west_east_stag")));
        ds.addCoordinateAxis(makeYCoordAxis(ds, "y", ds.findDimension("south_north")));
        ds.addCoordinateAxis(makeYCoordAxis(ds, "y_stag", ds.findDimension("south_north_stag")));
      }
      ds.addCoordinateAxis(makeZCoordAxis(ds, "z", ds.findDimension("bottom_top")));
      ds.addCoordinateAxis(makeZCoordAxis(ds, "z_stag", ds.findDimension("bottom_top_stag")));

      if (projCT != null) {
        VariableDS v = makeCoordinateTransformVariable(ds, projCT);
        v.addAttribute(new Attribute(_Coordinate.AxisTypes, "GeoX GeoY"));
        if (gridE) v.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        ds.addVariable(null, v);
      }
    }

    // time coordinate variations
    if (ds.findVariable("Time") == null) { // Can skip this if its already there, eg from NcML
      CoordinateAxis taxis = makeTimeCoordAxis(ds, "Time", ds.findDimension("Time"));
      if (taxis == null)
        taxis = makeTimeCoordAxis(ds, "Time", ds.findDimension("Times"));
      if (taxis != null)
        ds.addCoordinateAxis(taxis);
    }

    ds.addCoordinateAxis(makeSoilDepthCoordAxis(ds, "ZS"));

    ds.finish();
  }
public void augmentDataset(NetcdfDataset ds, CancelTask cancelTask) {
    if (null != ds.findVariable("x")) return; // check if its already been done - aggregating enhanced datasets.

    Attribute att = ds.findGlobalAttribute("GRIDTYPE");
    gridE = att != null && att.getStringValue().equalsIgnoreCase("E");
    
    // kludge in fixing the units
    List<Variable> vlist = ds.getVariables();
    for (Variable v : vlist) {
      att = v.findAttributeIgnoreCase(CDM.UNITS);
      if (att != null) {
        String units = att.getStringValue();
        if (units != null)
          v.addAttribute(new Attribute(CDM.UNITS, normalize(units))); // removes the old
      }
    }

    // make projection transform
    att = ds.findGlobalAttribute("MAP_PROJ");
    int projType = att.getNumericValue().intValue();
    boolean isLatLon = false;

    if (projType == 203) {

      /* centerX = centralLon;
      centerY = centralLat;
      ds.addCoordinateAxis( makeLonCoordAxis( ds, "longitude", ds.findDimension("west_east")));
      ds.addCoordinateAxis( makeLatCoordAxis( ds, "latitude", ds.findDimension("south_north")));  */

      Variable glat = ds.findVariable("GLAT");
      if (glat == null) {
        parseInfo.format("Projection type 203 - expected GLAT variable not found%n");
      } else {
        glat.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
        if (gridE) glat.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        glat.setDimensions("south_north west_east");
        glat.setCachedData(convertToDegrees(glat), false);
        glat.addAttribute(new Attribute(CDM.UNITS, CDM.LAT_UNITS));
      }

      Variable glon = ds.findVariable("GLON");
      if (glon == null) {
        parseInfo.format("Projection type 203 - expected GLON variable not found%n");
      } else {
        glon.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
        if (gridE) glon.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        glon.setDimensions("south_north west_east");
        glon.setCachedData(convertToDegrees(glon), false);
        glon.addAttribute(new Attribute(CDM.UNITS, CDM.LON_UNITS));
      }

      VariableDS v = new VariableDS(ds, null, null, "LatLonCoordSys", DataType.CHAR, "", null, null);
      v.addAttribute(new Attribute(_Coordinate.Axes, "GLAT GLON Time"));
      Array data = Array.factory(DataType.CHAR, new int[]{}, new char[]{' '});
      v.setCachedData(data, true);
      ds.addVariable(null, v);

      Variable dataVar = ds.findVariable("LANDMASK");
      dataVar.addAttribute(new Attribute(_Coordinate.Systems, "LatLonCoordSys"));

    } else {
      double lat1 = findAttributeDouble(ds, "TRUELAT1");
      double lat2 = findAttributeDouble(ds, "TRUELAT2");
      double centralLat = findAttributeDouble(ds, "CEN_LAT");  // center of grid
      double centralLon = findAttributeDouble(ds, "CEN_LON");  // center of grid

      double standardLon = findAttributeDouble(ds, "STAND_LON"); // true longitude
      double standardLat = findAttributeDouble(ds, "MOAD_CEN_LAT");

      ProjectionImpl proj = null;
      switch (projType) {
        case 0: // for diagnostic runs with no georeferencing
          proj = new FlatEarth();
          projCT = new ProjectionCT("flat_earth", "FGDC", proj);
          // System.out.println(" using LC "+proj.paramsToString());
          break;
        case 1:
          proj = new LambertConformal(standardLat, standardLon, lat1, lat2, 0.0, 0.0, 6370);
          projCT = new ProjectionCT("Lambert", "FGDC", proj);
          // System.out.println(" using LC "+proj.paramsToString());
          break;
        case 2:
          // Thanks to Heiko Klein for figuring out WRF Stereographic
          double lon0 = (Double.isNaN(standardLon)) ? centralLon : standardLon;
          double lat0 = (Double.isNaN(centralLat)) ? lat2 : centralLat;  // ?? 7/20/2010
          double scaleFactor = (1 + Math.abs( Math.sin(Math.toRadians(lat1)))) / 2.;  // R Schmunk 9/10/07
          // proj = new Stereographic(lat2, lon0, scaleFactor);
          proj = new Stereographic(lat0, lon0, scaleFactor, 0.0, 0.0, 6370);
          projCT = new ProjectionCT("Stereographic", "FGDC", proj);
          break;
        case 3:
          proj = new Mercator(standardLon, lat1, 0.0, 0.0, 6370); // thanks to Robert Schmunk with edits for non-MOAD grids
          projCT = new ProjectionCT("Mercator", "FGDC", proj);
          // proj = new TransverseMercator(standardLat, standardLon, 1.0);
          //projCT = new ProjectionCT("TransverseMercator", "FGDC", proj);
          break;
        case 6:
          // version 3 "lat-lon", including global
          // http://www.mmm.ucar.edu/wrf/users/workshops/WS2008/presentations/1-2.pdf
          // use 2D XLAT, XLONG
          isLatLon = true;
          for (Variable v : vlist) {
            if (v.getShortName().startsWith("XLAT")) {
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lat.toString()));
              removeConstantTimeDim(ds, v);

            } else if (v.getShortName().startsWith("XLONG")) {
              v.addAttribute(new Attribute(_Coordinate.AxisType, AxisType.Lon.toString()));
              removeConstantTimeDim(ds, v);

            } else if (v.getShortName().equals("T")) { // ANOTHER MAJOR KLUDGE to pick up 4D fields
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT XLONG z"));
            } else if (v.getShortName().equals("U")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT_U XLONG_U z"));
            } else if (v.getShortName().equals("V")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT_V XLONG_V z"));
            } else if (v.getShortName().equals("W")) {
              v.addAttribute(new Attribute(_Coordinate.Axes, "Time XLAT XLONG z_stag"));
            }
          }
          break;
        default:
          parseInfo.format("ERROR: unknown projection type = %s%n", projType);
          break;
      }

      if (proj != null) {
        LatLonPointImpl lpt1 = new LatLonPointImpl(centralLat, centralLon); // center of the grid
        ProjectionPoint ppt1 = proj.latLonToProj(lpt1, new ProjectionPointImpl());
        centerX = ppt1.getX();
        centerY = ppt1.getY();
        if (debug) {
          System.out.println("centerX=" + centerX);
          System.out.println("centerY=" + centerY);
        }
      }

      // make axes
      if (!isLatLon) {
        ds.addCoordinateAxis(makeXCoordAxis(ds, "x", ds.findDimension("west_east")));
        ds.addCoordinateAxis(makeXCoordAxis(ds, "x_stag", ds.findDimension("west_east_stag")));
        ds.addCoordinateAxis(makeYCoordAxis(ds, "y", ds.findDimension("south_north")));
        ds.addCoordinateAxis(makeYCoordAxis(ds, "y_stag", ds.findDimension("south_north_stag")));
      }
      ds.addCoordinateAxis(makeZCoordAxis(ds, "z", ds.findDimension("bottom_top")));
      ds.addCoordinateAxis(makeZCoordAxis(ds, "z_stag", ds.findDimension("bottom_top_stag")));

      if (projCT != null) {
        VariableDS v = makeCoordinateTransformVariable(ds, projCT);
        v.addAttribute(new Attribute(_Coordinate.AxisTypes, "GeoX GeoY"));
        if (gridE) v.addAttribute(new Attribute(_Coordinate.Stagger, CDM.ARAKAWA_E));
        ds.addVariable(null, v);
      }
    }

    // time coordinate variations
    if (ds.findVariable("Time") == null) { // Can skip this if its already there, eg from NcML
      CoordinateAxis taxis = makeTimeCoordAxis(ds, "Time", ds.findDimension("Time"));
      if (taxis == null)
        taxis = makeTimeCoordAxis(ds, "Time", ds.findDimension("Times"));
      if (taxis != null)
        ds.addCoordinateAxis(taxis);
    }

    ds.addCoordinateAxis(makeSoilDepthCoordAxis(ds, "ZS"));

    ds.finish();
  }
/* ARW Users Guide p 3-19
<pre>
7. MAP_PROJ_NAME: Character string specifying type of map projection. Valid entries are:
"polar" -> Polar stereographic
"lambert" -> Lambert conformal (secant and tangent)
"mercator" -> Mercator

8. MOAD_KNOWN_LAT/MOAD_KNOWN_LON (= CEN_LAT, CEN_LON):
Real latitude and longitude of the center point in the grid.

9. MOAD_STAND_LATS (= TRUE_LAT1/2):
2 real values for the "true" latitudes (where grid spacing is exact).
Must be between -90 and 90, and the values selected depend on projection:
Polar-stereographic: First value must be the latitude at which the grid
spacing is true. Most users will set this equal to their center latitude.
Second value must be +/-90. for NH/SH grids.
Lambert Conformal: Both values should have the same sign as the center
latitude. For a tangential lambert conformal, set both to the same value
(often equal to the center latitude). For a secant Lambert Conformal, they
may be set to different values.
Mercator: The first value should be set to the latitude you wish your grid
spacing to be true (often your center latitude). Second value is not used.

10. MOAD_STAND_LONS (=STAND_LON): This is one entry specifying the longitude in degrees East (-
180->180) that is parallel to the y-axis of your grid, (sometimes referred to as the
orientation of the grid). This should be set equal to the center longitude in most cases.

---------------------------------
version 3.1
http://www.mmm.ucar.edu/wrf/users/docs/user_guide_V3.1/users_guide_chap5.htm

The definition for map projection options:

map_proj =  1: Lambert Conformal
2: Polar Stereographic
3: Mercator
6: latitude and longitude (including global)