rspfDpt rspfTransCylEquAreaProjection::forward(const rspfGpt &latLon)const
{
   double easting  = 0.0;
   double northing = 0.0;
   rspfGpt gpt = latLon;
   
   if (theDatum)
   {
      if (theDatum->code() != latLon.datum()->code())
      {
         gpt.changeDatum(theDatum); // Shift to our datum.
      }
   }
   Convert_Geodetic_To_Trans_Cyl_Eq_Area(gpt.latr(),
                                         gpt.lonr(),
                                         &easting,
                                         &northing);
   
   return rspfDpt(easting, northing);
}
Example #2
0
long Set_Trans_Cyl_Eq_Area_Parameters(double a,
                                      double f,
                                      double Origin_Latitude,
                                      double Central_Meridian,
                                      double False_Easting,
                                      double False_Northing,
                                      double Scale_Factor)
{ /* BEGIN Set_Trans_Cyl_Eq_Area_Parameters */
/*
 * The function Set_Trans_Cyl_Eq_Area_Parameters receives the ellipsoid parameters and
 * Transverse Cylindrical Equal Area projection parameters as inputs, and sets the
 * corresponding state variables.  If any errors occur, the error code(s) are returned
 * by the function, otherwise TCEA_NO_ERROR is returned.
 *
 *    a                 : Semi-major axis of ellipsoid, in meters   (input)
 *    f                 : Flattening of ellipsoid                   (input)
 *    Origin_Latitude   : Latitude in radians at which the          (input)
 *                          point scale factor is 1.0
 *    Central_Meridian  : Longitude in radians at the center of     (input)
 *                          the projection
 *    False_Easting     : A coordinate value in meters assigned to the
 *                          central meridian of the projection.     (input)
 *    False_Northing    : A coordinate value in meters assigned to the
 *                          origin latitude of the projection       (input)
 *    Scale_Factor      : Multiplier which reduces distances in the
 *                          projection to the actual distance on the
 *                          ellipsoid                               (input)
 */

  double sin_lat_90 = sin(PI_OVER_2);
  double x, j, three_es4;
  double Sqrt_One_MINUS_es2;
  double e1, e2, e3, e4;
  double lat, sin2lat, sin4lat, sin6lat;
  double temp, temp_northing;
  double inv_f = 1 / f;
  long Error_Code = TCEA_NO_ERROR;

  if (a <= 0.0)
  { /* Semi-major axis must be greater than zero */
    Error_Code |= TCEA_A_ERROR;
  }
  if ((inv_f < 250) || (inv_f > 350))
  { /* Inverse flattening must be between 250 and 350 */
    Error_Code |= TCEA_INV_F_ERROR;
  }
  if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
  { /* origin latitude out of range */
    Error_Code |= TCEA_ORIGIN_LAT_ERROR;
  }
  if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
  { /* origin longitude out of range */
    Error_Code |= TCEA_CENT_MER_ERROR;
  }
  if ((Scale_Factor < MIN_SCALE_FACTOR) || (Scale_Factor > MAX_SCALE_FACTOR))
  {
    Error_Code |= TCEA_SCALE_FACTOR_ERROR;
  }

  if (!Error_Code)
  { /* no errors */
    Tcea_a = a;
    Tcea_f = f;
    Tcea_Origin_Lat = Origin_Latitude;
    if (Central_Meridian > PI)
      Central_Meridian -= TWO_PI;
    Tcea_Origin_Long = Central_Meridian;
    Tcea_False_Northing = False_Northing;
    Tcea_False_Easting = False_Easting;
    Tcea_Scale_Factor = Scale_Factor;

    es2 = 2 * Tcea_f - Tcea_f * Tcea_f;
    es = sqrt(es2);
    One_MINUS_es2 = 1.0 - es2;
    Sqrt_One_MINUS_es2 = sqrt(One_MINUS_es2);
    One_OVER_2es = 1.0 / (2.0 * es);
    es4 = es2 * es2;
    es6 = es4 * es2;
    x = es * sin_lat_90;
    qp = TCEA_Q(sin_lat_90,x);

    a0 = es2 / 3.0 + 31.0 * es4 / 180.0 + 517.0 * es6 / 5040.0;
    a1 = 23.0 * es4 / 360.0 + 251.0 * es6 / 3780.0;
    a2 = 761.0 * es6 / 45360.0;

    e1 = (1.0 - Sqrt_One_MINUS_es2) / (1.0 + Sqrt_One_MINUS_es2);
    e2 = e1 * e1;
    e3 = e2 * e1;
    e4 = e3 * e1;
    b0 = 3.0 * e1 / 2.0 - 27.0 * e3 / 32.0;
    b1 = 21.0 * e2 / 16.0 - 55.0 * e4 / 32.0;
    b2 = 151.0 * e3 / 96.0;
    b3 = 1097.0 * e4 / 512.0;

    j = 45.0 * es6 / 1024.0;
    three_es4 = 3.0 * es4;
    c0 = 1.0 - es2 / 4.0 - three_es4 / 64.0 - 5.0 * es6 / 256.0;
    c1 = 3.0 * es2 / 8.0 + three_es4 / 32.0 + j;
    c2 = 15.0 * es4 / 256.0 + j;
    c3 = 35.0 * es6 / 3072.0;
    lat = c0 * Tcea_Origin_Lat;
    sin2lat = TCEA_COEFF_TIMES_SIN(c1, 2.0, Tcea_Origin_Lat);
    sin4lat = TCEA_COEFF_TIMES_SIN(c2, 4.0, Tcea_Origin_Lat);
    sin6lat = TCEA_COEFF_TIMES_SIN(c3, 6.0, Tcea_Origin_Lat);
    M0 = TCEA_M(lat, sin2lat, sin4lat, sin6lat);
    Convert_Geodetic_To_Trans_Cyl_Eq_Area(PI_OVER_2, PI, &temp, &temp_northing);
    if (temp_northing > 0)
    {
      Tcea_Min_Northing = temp_northing - 20003931.458986;
      Tcea_Max_Northing = temp_northing;

      if(Tcea_False_Northing)
      {
        Tcea_Min_Northing -= Tcea_False_Northing;
        Tcea_Max_Northing -= Tcea_False_Northing;
      }
    }
    else if (temp_northing < 0)
    {
      Tcea_Max_Northing = temp_northing + 20003931.458986;
      Tcea_Min_Northing = temp_northing;

      if(Tcea_False_Northing)
      {
        Tcea_Min_Northing -= Tcea_False_Northing;
        Tcea_Max_Northing -= Tcea_False_Northing;
      }
    }

  } /* END OF if(!Error_Code) */
  return (Error_Code);
} /* END OF Set_Trans_Cyl_Eq_Area_Parameters */