visad/src/main/java/ucar/nc2/iosp/grid/GridHorizCoordSys.java
private void makeSpaceViewOrOthographic() {
    double Lat0 = gds.getDouble(GridDefRecord.LAP);  // sub-satellite point lat
    double Lon0 = gds.getDouble(GridDefRecord.LOP);  // sub-satellite point lon

    double xp = gds.getDouble(GridDefRecord.XP);  // sub-satellite point in grid lengths
    double yp = gds.getDouble(GridDefRecord.YP);

    double dx = gds.getDouble(GridDefRecord.DX);  // apparent diameter in units of grid lengths
    double dy = gds.getDouble(GridDefRecord.DY);
    // have to check both names because Grib1 and Grib2 used different names
    double major_axis = gds.getDouble(GridDefRecord.MAJOR_AXIS_EARTH);  // km
    if (Double.isNaN(major_axis) )
       major_axis = gds.getDouble("major_axis_earth");

    double minor_axis = gds.getDouble(GridDefRecord.MINOR_AXIS_EARTH);  // km
    if (Double.isNaN(minor_axis) )
       minor_axis = gds.getDouble("minor_axis_earth");
    // Nr = altitude of camera from center, in units of radius
    double nr = gds.getDouble(GridDefRecord.NR) * 1e-6;
    double apparentDiameter = 2 * Math.sqrt((nr - 1) / (nr + 1));  // apparent diameter, units of radius (see Snyder p 173)

    // app diameter kmeters / app diameter grid lengths = m per grid length
    double gridLengthX = major_axis * apparentDiameter / dx;
    double gridLengthY = minor_axis * apparentDiameter / dy;
    // have to add to both for consistency
    gds.addParam(GridDefRecord.DX, String.valueOf(1000 * gridLengthX));  // meters
    gds.addParam(GridDefRecord.DX, new Double(1000 * gridLengthX));
    gds.addParam(GridDefRecord.DY, String.valueOf(1000 * gridLengthY));  // meters
    gds.addParam(GridDefRecord.DY, new Double(1000 * gridLengthY));
    startx = -gridLengthX * xp;  // km
    starty = -gridLengthY * yp;

    double radius = Earth.getRadius() / 1000.0;  // km

    if (nr == 1111111111.0) {  // LOOK: not sure how all ones will appear as a double, need example
      proj = new Orthographic(Lat0, Lon0, radius);

      attributes.add(new Attribute(GridCF.GRID_MAPPING_NAME, "orthographic"));
      attributes.add(new Attribute(GridCF.LONGITUDE_OF_PROJECTION_ORIGIN, Lon0));
      attributes.add(new Attribute(GridCF.LATITUDE_OF_PROJECTION_ORIGIN, Lat0));

    } else {  // "space view perspective"

      double height = (nr - 1.0) * radius;  // height = the height of the observing camera in km
      proj = new VerticalPerspectiveView(Lat0, Lon0, radius, height);

      attributes.add(new Attribute(GridCF.GRID_MAPPING_NAME, "vertical_perspective"));
      attributes.add(new Attribute(GridCF.LONGITUDE_OF_PROJECTION_ORIGIN, Lon0));
      attributes.add(new Attribute(GridCF.LATITUDE_OF_PROJECTION_ORIGIN, Lat0));
      attributes.add(new Attribute("height_above_earth", height));
    }

    if (GridServiceProvider.debugProj) {

      double Lo2 = gds.getDouble(GridDefRecord.LO2) + 360.0;
      double La2 = gds.getDouble(GridDefRecord.LA2);
      LatLonPointImpl endLL = new LatLonPointImpl(La2, Lo2);
      System.out.println(
          "GridHorizCoordSys.makeOrthographic end at latlon "+ endLL);

      ProjectionPointImpl endPP =
          (ProjectionPointImpl) proj.latLonToProj(endLL);
      System.out.println("   end at proj coord " + endPP);

      double endx = startx + getNx() * getDxInKm();
      double endy = starty + getNy() * getDyInKm();
      System.out.println("   should be x=" + endx + " y=" + endy);
    }
  }
private void makeSpaceViewOrOthographic() {
    double Lat0 = gds.getDouble(GridDefRecord.LAP);  // sub-satellite point lat
    double Lon0 = gds.getDouble(GridDefRecord.LOP);  // sub-satellite point lon

    double xp = gds.getDouble(GridDefRecord.XP);  // sub-satellite point in grid lengths
    double yp = gds.getDouble(GridDefRecord.YP);

    double dx = gds.getDouble(GridDefRecord.DX);  // apparent diameter in units of grid lengths
    double dy = gds.getDouble(GridDefRecord.DY);
    // have to check both names because Grib1 and Grib2 used different names
    double major_axis = gds.getDouble(GridDefRecord.MAJOR_AXIS_EARTH);  // km
    if (Double.isNaN(major_axis) )
       major_axis = gds.getDouble("major_axis_earth");

    double minor_axis = gds.getDouble(GridDefRecord.MINOR_AXIS_EARTH);  // km
    if (Double.isNaN(minor_axis) )
       minor_axis = gds.getDouble("minor_axis_earth");
    // Nr = altitude of camera from center, in units of radius
    double nr = gds.getDouble(GridDefRecord.NR) * 1e-6;
    double apparentDiameter = 2 * Math.sqrt((nr - 1) / (nr + 1));  // apparent diameter, units of radius (see Snyder p 173)

    // app diameter kmeters / app diameter grid lengths = m per grid length
    double gridLengthX = major_axis * apparentDiameter / dx;
    double gridLengthY = minor_axis * apparentDiameter / dy;
    // have to add to both for consistency
    gds.addParam(GridDefRecord.DX, String.valueOf(1000 * gridLengthX));  // meters
    gds.addParam(GridDefRecord.DX, new Double(1000 * gridLengthX));
    gds.addParam(GridDefRecord.DY, String.valueOf(1000 * gridLengthY));  // meters
    gds.addParam(GridDefRecord.DY, new Double(1000 * gridLengthY));
    startx = -gridLengthX * xp;  // km
    starty = -gridLengthY * yp;

    double radius = Earth.getRadius() / 1000.0;  // km

    if (nr == 1111111111.0) {  // LOOK: not sure how all ones will appear as a double, need example
      proj = new Orthographic(Lat0, Lon0, radius);

      attributes.add(new Attribute(GridCF.GRID_MAPPING_NAME, "orthographic"));
      attributes.add(new Attribute(GridCF.LONGITUDE_OF_PROJECTION_ORIGIN, Lon0));
      attributes.add(new Attribute(GridCF.LATITUDE_OF_PROJECTION_ORIGIN, Lat0));

    } else {  // "space view perspective"

      double height = (nr - 1.0) * radius;  // height = the height of the observing camera in km
      proj = new VerticalPerspectiveView(Lat0, Lon0, radius, height);

      attributes.add(new Attribute(GridCF.GRID_MAPPING_NAME, "vertical_perspective"));
      attributes.add(new Attribute(GridCF.LONGITUDE_OF_PROJECTION_ORIGIN, Lon0));
      attributes.add(new Attribute(GridCF.LATITUDE_OF_PROJECTION_ORIGIN, Lat0));
      attributes.add(new Attribute("height_above_earth", height));
    }

    if (GridServiceProvider.debugProj) {

      double Lo2 = gds.getDouble(GridDefRecord.LO2) + 360.0;
      double La2 = gds.getDouble(GridDefRecord.LA2);
      LatLonPointImpl endLL = new LatLonPointImpl(La2, Lo2);
      System.out.println(
          "GridHorizCoordSys.makeOrthographic end at latlon "+ endLL);

      ProjectionPointImpl endPP =
          (ProjectionPointImpl) proj.latLonToProj(endLL);
      System.out.println("   end at proj coord " + endPP);

      double endx = startx + getNx() * getDxInKm();
      double endy = starty + getNy() * getDyInKm();
      System.out.println("   should be x=" + endx + " y=" + endy);
    }
  }
Make a Space View Orthographic projection