Beispiel #1
0
long Set_Lambert_2_Parameters(double a,
                              double f,
                              double Origin_Latitude,
                              double Central_Meridian,
                              double Std_Parallel_1,
                              double Std_Parallel_2,
                              double False_Easting,
                              double False_Northing)

{ /* BEGIN Set_Lambert_2_Parameters */
/*
 * The function Set_Lambert_2_Parameters receives the ellipsoid parameters and
 * Lambert Conformal Conic (2 parallel) projection parameters as inputs, and sets the
 * corresponding state variables.  If any errors occur, the error code(s)
 * are returned by the function, otherwise LAMBERT_2_NO_ERROR is returned.
 *
 *   a                   : Semi-major axis of ellipsoid, in meters   (input)
 *   f                   : Flattening of ellipsoid				     (input)
 *   Central_Meridian    : Longitude of origin, in radians           (input)
 *   Std_Parallel_1      : First standard parallel, in radians       (input)
 *   Std_Parallel_2      : Second standard parallel, in radians      (input)
 *   False_Easting       : False easting, in meters                  (input)
 *   False_Northing      : False northing, in meters                 (input)
 *
 *   Note that when the two standard parallel parameters are both set to the 
 *   same latitude value, the result is a Lambert Conformal Conic projection 
 *   with one standard parallel at the specified latitude.
 */

  double es2;
  double es_sin;
  double t0;
  double t1;
  double t2;
  double t_olat;
  double m0;
  double m1;
  double m2;
  double m_olat;
  double n;                                /* Ratio of angle between meridians */
  double const_value;
  double inv_f = 1 / f;
  long Error_Code = LAMBERT_2_NO_ERROR;

  if (a <= 0.0)
  { /* Semi-major axis must be greater than zero */
    Error_Code |= LAMBERT_2_A_ERROR;
  }
  if ((inv_f < 250) || (inv_f > 350))
  { /* Inverse flattening must be between 250 and 350 */
    Error_Code |= LAMBERT_2_INV_F_ERROR;
  }
  if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
  { /* Origin Latitude out of range */
    Error_Code |= LAMBERT_2_ORIGIN_LAT_ERROR;
  }
  if ((Std_Parallel_1 < -MAX_LAT) || (Std_Parallel_1 > MAX_LAT))
  { /* First Standard Parallel out of range */
    Error_Code |= LAMBERT_2_FIRST_STDP_ERROR;
  }
  if ((Std_Parallel_2 < -MAX_LAT) || (Std_Parallel_2 > MAX_LAT))
  { /* Second Standard Parallel out of range */
    Error_Code |= LAMBERT_2_SECOND_STDP_ERROR;
  }
  if ((Std_Parallel_1 == 0) && (Std_Parallel_2 == 0))
  { /* First & Second Standard Parallels are both 0 */
    Error_Code |= LAMBERT_2_FIRST_SECOND_ERROR;
  }
  if (Std_Parallel_1 == -Std_Parallel_2)
  { /* Parallels are the negation of each other */
    Error_Code |= LAMBERT_2_HEMISPHERE_ERROR;
  }
  if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
  { /* Origin Longitude out of range */
    Error_Code |= LAMBERT_2_CENT_MER_ERROR;
  }

  if (!Error_Code)
  { /* no errors */

    Lambert_a = a;
    Lambert_f = f;
    Lambert_Origin_Lat = Origin_Latitude;
    Lambert_Std_Parallel_1 = Std_Parallel_1;
    Lambert_Std_Parallel_2 = Std_Parallel_2;
    if (Central_Meridian > PI)
      Central_Meridian -= TWO_PI;
    Lambert_Origin_Long = Central_Meridian;
    Lambert_False_Easting = False_Easting;
    Lambert_False_Northing = False_Northing;

    if (fabs(Lambert_Std_Parallel_1 - Lambert_Std_Parallel_2) > 1.0e-10)
    {
      es2 = 2 * Lambert_f - Lambert_f * Lambert_f;
      es = sqrt(es2);
      es_OVER_2 = es / 2.0;

      es_sin = ES_SIN(sin(Lambert_Origin_Lat));
      m_olat = LAMBERT_m(cos(Lambert_Origin_Lat), es_sin);
      t_olat = LAMBERT_t(Lambert_Origin_Lat, es_sin);

      es_sin = ES_SIN(sin(Lambert_Std_Parallel_1));
      m1 = LAMBERT_m(cos(Lambert_Std_Parallel_1), es_sin);
      t1 = LAMBERT_t(Lambert_Std_Parallel_1, es_sin);

      es_sin = ES_SIN(sin(Lambert_Std_Parallel_2));
      m2 = LAMBERT_m(cos(Lambert_Std_Parallel_2), es_sin);
      t2 = LAMBERT_t(Lambert_Std_Parallel_2, es_sin);

      n = log(m1 / m2) / log(t1 / t2);

      Lambert_lat0 = asin(n);
    
      es_sin = ES_SIN(sin(Lambert_lat0));
      m0 = LAMBERT_m(cos(Lambert_lat0), es_sin);
      t0 = LAMBERT_t(Lambert_lat0, es_sin);

      Lambert_k0 = (m1 / m0) * (pow(t0 / t1, n));

      const_value = ((Lambert_a * m2) / (n * pow(t2, n)));
      
      Lambert_false_northing = (const_value * pow(t_olat, n)) - (const_value * pow(t0, n)) + Lambert_False_Northing;
    }
    else
    {
      Lambert_lat0 = Lambert_Std_Parallel_1;
      Lambert_k0 = 1.0;
      Lambert_false_northing = Lambert_False_Northing;
    }

    Set_Lambert_1_Parameters(Lambert_a, Lambert_f, Lambert_lat0, Lambert_Origin_Long, Lambert_False_Easting, Lambert_false_northing, Lambert_k0);
  }
  return (Error_Code);
} /* END OF Set_Lambert_2_Parameters */
long ossimLambertConformalConicProjection::Convert_Geodetic_To_Lambert (double Latitude,
                                                                        double Longitude,
                                                                        double *Easting,
                                                                        double *Northing)const
   
{ /* BEGIN Convert_Geodetic_To_Lambert */
/*
 * The function Convert_Geodetic_To_Lambert converts Geodetic (latitude and
 * longitude) coordinates to Lambert Conformal Conic projection (easting
 * and northing) coordinates, according to the current ellipsoid and
 * Lambert Conformal Conic projection parameters.  If any errors occur, the
 * error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR is
 * returned.
 *
 *    Latitude         : Latitude, in radians                         (input)
 *    Longitude        : Longitude, in radians                        (input)
 *    Easting          : Easting (X), in meters                       (output)
 *    Northing         : Northing (Y), in meters                      (output)
 */

  double slat;
  double es_sin;
  double t;
  double rho;
  double dlam;
  double theta;
  long  Error_Code = LAMBERT_NO_ERROR;

//   if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
//   {  /* Latitude out of range */
//     Error_Code|= LAMBERT_LAT_ERROR;
//   }
//   if ((Longitude < -PI) || (Longitude > TWO_PI))
//   {  /* Longitude out of range */
//     Error_Code|= LAMBERT_LON_ERROR;
//   }

  if (!Error_Code)
  { /* no errors */

    if (fabs(fabs(Latitude) - PI_OVER_2) > 1.0e-10)
    {
      slat = sin(Latitude);
      es_sin = ES_SIN(slat);
      t = LAMBERT_t(Latitude, es_sin);
      rho = Lambert_aF * pow(t, n);
    }
    else
    {
      if ((Latitude * n) <= 0)
      { /* Point can not be projected */
        Error_Code |= LAMBERT_LAT_ERROR;
        return (Error_Code);
      }
      rho = 0.0;
    }

    dlam = Longitude - Lambert_Origin_Long;

//     if (dlam > PI)
//     {
//       dlam -= TWO_PI;
//     }
//     if (dlam < -PI)
//     {
//       dlam += TWO_PI;
//     }

    theta = n * dlam;

    *Easting = rho * sin(theta) + Lambert_False_Easting;
    *Northing = rho0 - rho * cos(theta) + Lambert_False_Northing;

  }
  return (Error_Code);
} /* END OF Convert_Geodetic_To_Lambert */
long ossimLambertConformalConicProjection::Convert_Lambert_To_Geodetic (double Easting,
                                                                        double Northing,
                                                                        double *Latitude,
                                                                        double *Longitude)const

{ /* BEGIN Convert_Lambert_To_Geodetic */
/*
 * The function Convert_Lambert_To_Geodetic converts Lambert Conformal
 * Conic projection (easting and northing) coordinates to Geodetic
 * (latitude and longitude) coordinates, according to the current ellipsoid
 * and Lambert Conformal Conic projection parameters.  If any errors occur,
 * the error code(s) are returned by the function, otherwise LAMBERT_NO_ERROR
 * is returned.
 *
 *    Easting          : Easting (X), in meters                       (input)
 *    Northing         : Northing (Y), in meters                      (input)
 *    Latitude         : Latitude, in radians                         (output)
 *    Longitude        : Longitude, in radians                        (output)
 */


  double dy, dx;
  double rho, rho0_MINUS_dy;
  double t;
  double PHI;
  double tempPHI = 0.0;
  double sin_PHI;
  double es_sin;
  double theta = 0.0;
  double tolerance = 4.85e-10;
  long Error_Code = LAMBERT_NO_ERROR;

//   if ((Easting < (Lambert_False_Easting - Lambert_Delta_Easting))
//       ||(Easting > (Lambert_False_Easting + Lambert_Delta_Easting)))
//   { /* Easting out of range  */
//     Error_Code |= LAMBERT_EASTING_ERROR;
//   }
//   if ((Northing < (Lambert_False_Northing - Lambert_Delta_Northing))
//       || (Northing > (Lambert_False_Northing + Lambert_Delta_Northing)))
//   { /* Northing out of range */
//     Error_Code |= LAMBERT_NORTHING_ERROR;
//   }

  if (!Error_Code)
  { /* no errors */

    dy = Northing - Lambert_False_Northing;
    dx = Easting - Lambert_False_Easting;
    rho0_MINUS_dy = rho0 - dy;
    rho = sqrt(dx * dx + (rho0_MINUS_dy) * (rho0_MINUS_dy));

    if (n < 0.0)
    {
      rho *= -1.0;
      dy *= -1.0;
      dx *= -1.0;
      rho0_MINUS_dy *= -1.0;
    }

    if (rho != 0.0)
    {
      theta = atan2(dx, rho0_MINUS_dy);
      t = pow(rho / (Lambert_aF) , 1.0 / n);
      PHI = PI_OVER_2 - 2.0 * atan(t);
      while (fabs(PHI - tempPHI) > tolerance)
      {
        tempPHI = PHI;
        sin_PHI = sin(PHI);
        es_sin = ES_SIN(sin_PHI);
        PHI = PI_OVER_2 - 2.0 * atan(t * pow((1.0 - es_sin) / (1.0 + es_sin), es_OVER_2));
      }
      *Latitude = PHI;
      *Longitude = theta / n + Lambert_Origin_Long;

      if (fabs(*Latitude) < 2.0e-7)  /* force lat to 0 to avoid -0 degrees */
        *Latitude = 0.0;
      if (*Latitude > PI_OVER_2)  /* force distorted values to 90, -90 degrees */
        *Latitude = PI_OVER_2;
      else if (*Latitude < -PI_OVER_2)
        *Latitude = -PI_OVER_2;

      if (*Longitude > M_PI)
      {
        if (*Longitude - M_PI < 3.5e-6) 
          *Longitude = M_PI;
//         else
//           *Longitude -= TWO_PI;
      }
      if (*Longitude < -M_PI)
      {
        if (fabs(*Longitude + M_PI) < 3.5e-6)
          *Longitude = -M_PI;
//         else
//           *Longitude += TWO_PI;
      }

      if (fabs(*Longitude) < 2.0e-7)  /* force lon to 0 to avoid -0 degrees */
        *Longitude = 0.0;
      if (*Longitude > M_PI)  /* force distorted values to 180, -180 degrees */
        *Longitude = M_PI;
      else if (*Longitude < -M_PI)
        *Longitude = -M_PI;
    }
    else
    {
      if (n > 0.0)
        *Latitude = PI_OVER_2;
      else
        *Latitude = -PI_OVER_2;
      *Longitude = Lambert_Origin_Long;
    }
  }
  return (Error_Code);
} /* END OF Convert_Lambert_To_Geodetic */
long ossimLambertConformalConicProjection::Set_Lambert_Parameters(double a,
                                                                  double f,
                                                                  double Origin_Latitude,
                                                                  double Central_Meridian,
                                                                  double Std_Parallel_1,
                                                                  double Std_Parallel_2,
                                                                  double False_Easting,
                                                                  double False_Northing)

{ /* BEGIN Set_Lambert_Parameters */
/*
 * The function Set_Lambert_Parameters receives the ellipsoid parameters and
 * Lambert Conformal Conic projection parameters as inputs, and sets the
 * corresponding state variables.  If any errors occur, the error code(s)
 * are returned by the function, otherwise LAMBERT_NO_ERROR is returned.
 *
 *   a                   : Semi-major axis of ellipsoid, in meters   (input)
 *   f                   : Flattening of ellipsoid						       (input)
 *   Origin_Latitude     : Latitude of origin, in radians            (input)
 *   Central_Meridian    : Longitude of origin, in radians           (input)
 *   Std_Parallel_1      : First standard parallel, in radians       (input)
 *   Std_Parallel_2      : Second standard parallel, in radians      (input)
 *   False_Easting       : False easting, in meters                  (input)
 *   False_Northing      : False northing, in meters                 (input)
 */

  double slat, slat1, clat;
  double es_sin;
  double t0, t1, t2;
  double m1, m2;
//  double inv_f = 1 / f;
  long Error_Code = LAMBERT_NO_ERROR;

//   if (a <= 0.0)
//   { /* Semi-major axis must be greater than zero */
//     Error_Code |= LAMBERT_A_ERROR;
//   }
//   if ((inv_f < 250) || (inv_f > 350))
//   { /* Inverse flattening must be between 250 and 350 */
//     Error_Code |= LAMBERT_INV_F_ERROR;
//   }
//   if ((Origin_Latitude < -MAX_LAT) || (Origin_Latitude > MAX_LAT))
//   { /* Origin Latitude out of range */
//     Error_Code |= LAMBERT_ORIGIN_LAT_ERROR;
//   }
//   if ((Std_Parallel_1 < -MAX_LAT) || (Std_Parallel_1 > MAX_LAT))
//   { /* First Standard Parallel out of range */
//     Error_Code |= LAMBERT_FIRST_STDP_ERROR;
//   }
//   if ((Std_Parallel_2 < -MAX_LAT) || (Std_Parallel_2 > MAX_LAT))
//   { /* Second Standard Parallel out of range */
//     Error_Code |= LAMBERT_SECOND_STDP_ERROR;
//   }
//   if ((Std_Parallel_1 == 0) && (Std_Parallel_2 == 0))
//   { /* First & Second Standard Parallels are both 0 */
//     Error_Code |= LAMBERT_FIRST_SECOND_ERROR;
//   }
//   if (Std_Parallel_1 == -Std_Parallel_2)
//   { /* Parallels are the negation of each other */
//     Error_Code |= LAMBERT_HEMISPHERE_ERROR;
//   }
//   if ((Central_Meridian < -PI) || (Central_Meridian > TWO_PI))
//   { /* Origin Longitude out of range */
//     Error_Code |= LAMBERT_CENT_MER_ERROR;
//   }

  if (!Error_Code)
  { /* no errors */

    Lambert_a = a;
    Lambert_f = f;
    Lambert_Origin_Lat = Origin_Latitude;
    Lambert_Std_Parallel_1 = Std_Parallel_1;
    Lambert_Std_Parallel_2 = Std_Parallel_2;
//     if (Central_Meridian > PI)
//       Central_Meridian -= TWO_PI;
    Lambert_Origin_Long = Central_Meridian;
    Lambert_False_Easting = False_Easting;
    Lambert_False_Northing = False_Northing;

    es2 = 2 * Lambert_f - Lambert_f * Lambert_f;
    es = sqrt(es2);
    es_OVER_2 = es / 2.0;

    slat = sin(Lambert_Origin_Lat);
    es_sin = ES_SIN(slat);
    t0 = LAMBERT_t(Lambert_Origin_Lat, es_sin);

    slat1 = sin(Lambert_Std_Parallel_1);
    clat = cos(Lambert_Std_Parallel_1);
    es_sin = ES_SIN(slat1);
    m1 = LAMBERT_m(clat, es_sin);
    t1 = LAMBERT_t(Lambert_Std_Parallel_1, es_sin);


    if (fabs(Lambert_Std_Parallel_1 - Lambert_Std_Parallel_2) > 1.0e-10)
    {
      slat = sin(Lambert_Std_Parallel_2);
      clat = cos(Lambert_Std_Parallel_2);
      es_sin = ES_SIN(slat);
      m2 = LAMBERT_m(clat, es_sin);
      t2 = LAMBERT_t(Lambert_Std_Parallel_2, es_sin);
      n = log(m1 / m2) / log(t1 / t2);
    }
    else
      n = slat1;
    F = m1 / (n * pow(t1, n));
    Lambert_aF = Lambert_a * F;
    if ((t0 == 0) && (n < 0))
      rho0 = 0.0;
    else
      rho0 = Lambert_aF * pow(t0, n);

  }
  return (Error_Code);
} /* END OF Set_Lambert_Parameters */