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 */