Cartography-Projection-GCTP
view release on metacpan or search on metacpan
gctpc/tminv.c view on Meta::CPAN
double r_maj; /* major axis */
double r_min; /* minor axis */
double scale_fact; /* scale factor */
double center_lon; /* center longitude */
double center_lat; /* center latitude */
double false_east; /* x offset in meters */
double false_north; /* y offset in meters */
{
double temp; /* temporary variable */
/* Place parameters in static storage for common use
-------------------------------------------------*/
r_major = r_maj;
r_minor = r_min;
scale_factor = scale_fact;
lon_center = center_lon;
lat_origin = center_lat;
false_northing = false_north;
false_easting = false_east;
temp = r_minor / r_major;
es = 1.0 - SQUARE(temp);
e = sqrt(es);
e0 = e0fn(es);
e1 = e1fn(es);
e2 = e2fn(es);
e3 = e3fn(es);
ml0 = r_major * mlfn(e0, e1, e2, e3, lat_origin);
esp = es / (1.0 - es);
if (es < .00001)
ind = 1;
/* Report parameters to the user
-----------------------------*/
ptitle("TRANSVERSE MERCATOR (TM)");
radius2(r_major, r_minor);
genrpt(scale_factor,"Scale Factor at C. Meridian: ");
cenlonmer(lon_center);
origin(lat_origin);
offsetp(false_easting,false_northing);
return(OK);
}
/* Transverse Mercator inverse equations--mapping x,y to lat,long
Note: The algorithm for UTM is exactly the same as TM and therefore
if a change is implemented, also make the change to UTMINV.c
--------------------------------------------------------------*/
long tminv(x, y, lon, lat)
double x; /* (I) X projection coordinate */
double y; /* (I) Y projection coordinate */
double *lon; /* (O) Longitude */
double *lat; /* (O) Latitude */
{
double con,phi; /* temporary angles */
double delta_phi; /* difference between longitudes */
long i; /* counter variable */
double sin_phi, cos_phi, tan_phi; /* sin cos and tangent values */
double c, cs, t, ts, n, r, d, ds; /* temporary variables */
double f, h, g, temp; /* temporary variables */
long max_iter = 6; /* maximun number of iterations */
/* fortran code for spherical form
--------------------------------*/
if (ind != 0)
{
f = exp(x/(r_major * scale_factor));
g = .5 * (f - 1/f);
temp = lat_origin + y/(r_major * scale_factor);
h = cos(temp);
con = sqrt((1.0 - h * h)/(1.0 + g * g));
*lat = asinz(con);
if (temp < 0)
*lat = -*lat;
if ((g == 0) && (h == 0))
{
*lon = lon_center;
return(OK);
}
else
{
*lon = adjust_lon(atan2(g,h) + lon_center);
return(OK);
}
}
/* Inverse equations
-----------------*/
x = x - false_easting;
y = y - false_northing;
con = (ml0 + y / scale_factor) / r_major;
phi = con;
for (i=0;;i++)
{
delta_phi = ((con + e1 * sin(2.0*phi) - e2 * sin(4.0*phi) + e3 * sin(6.0*phi))
/ e0) - phi;
/*
delta_phi = ((con + e1 * sin(2.0*phi) - e2 * sin(4.0*phi)) / e0) - phi;
*/
phi += delta_phi;
if (fabs(delta_phi) <= EPSLN) break;
if (i >= max_iter)
{
p_error("Latitude failed to converge","TM-INVERSE");
return(95);
}
}
if (fabs(phi) < HALF_PI)
{
sincos(phi, &sin_phi, &cos_phi);
tan_phi = tan(phi);
c = esp * SQUARE(cos_phi);
cs = SQUARE(c);
t = SQUARE(tan_phi);
ts = SQUARE(t);
con = 1.0 - es * SQUARE(sin_phi);
n = r_major / sqrt(con);
r = n * (1.0 - es) / con;
d = x / (n * scale_factor);
ds = SQUARE(d);
( run in 0.672 second using v1.01-cache-2.11-cpan-71847e10f99 )