Cartography-Projection-GCTP
view release on metacpan or search on metacpan
gctpc/sominv.c view on Meta::CPAN
sumc1=sumc1+4.0*fc1;
sumc3=sumc3+4.0*fc3;
}
for(i=18; i<=72; i+=18)
{
dlam=i;
som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam);
suma2=suma2+2.0*fa2;
suma4=suma4+2.0*fa4;
sumb=sumb+2.0*fb;
sumc1=sumc1+2.0*fc1;
sumc3=sumc3+2.0*fc3;
}
dlam=90.0;
som_series(&fb,&fa2,&fa4,&fc1,&fc3,&dlam);
suma2=suma2+fa2;
suma4=suma4+fa4;
sumb=sumb+fb;
sumc1=sumc1+fc1;
sumc3=sumc3+fc3;
a2=suma2/30.0;
a4=suma4/60.0;
b=sumb/30.0;
c1=sumc1/15.0;
c3=sumc3/45.0;
return(OK);
}
long sominv(y, x, lon, lat)
double x; /* (I) X projection coordinate */
double y; /* (I) Y projection coordinate */
double *lon; /* (O) Longitude */
double *lat; /* (O) Latitude */
{
double tlon,conv,sav,sd,sdsq,blon,dif,st,defac,actan,tlat,dd,bigk,bigk2,xlamt;
double sl,scl,dlat,dlon,temp;
long inumb;
/* Inverse equations. Begin inverse computation with approximation for tlon.
Solve for transformed long.
---------------------------*/
temp=y; y=x - false_easting; x= temp - false_northing;
tlon= x/(a*b);
conv=1.e-9;
for(inumb=0;inumb<50;inumb++)
{
sav=tlon;
sd=sin(tlon);
sdsq=sd*sd;
s=p21*sa*cos(tlon)*sqrt((1.0+t*sdsq)/((1.0+w*sdsq)*(1.0+q*sdsq)));
blon=(x/a)+(y/a)*s/xj-a2*sin(2.0*tlon)-a4*sin(4.0*tlon)-(s/xj)*(c1*
sin(tlon)+c3*sin(3.0*tlon));
tlon=blon/b;
dif=tlon-sav;
if(fabs(dif)<conv)break;
}
if(inumb>=50)
{
p_error("50 iterations without convergence","som-inverse");
return(214);
}
/* Compute transformed lat.
------------------------*/
st=sin(tlon);
defac=exp(sqrt(1.0+s*s/xj/xj)*(y/a-c1*st-c3*sin(3.0*tlon)));
actan=atan(defac);
tlat=2.0*(actan-(PI/4.0));
/* Compute geodetic longitude
--------------------------*/
dd=st*st;
if(fabs(cos(tlon))<1.e-7) tlon=tlon-1.e-7;
bigk=sin(tlat);
bigk2=bigk*bigk;
xlamt=atan(((1.0-bigk2/(1.0-es))*tan(tlon)*ca-bigk*sa*sqrt((1.0+q*dd)
*(1.0-bigk2)-bigk2*u)/cos(tlon))/(1.0-bigk2*(1.0+u)));
/* Correct inverse quadrant
------------------------*/
if(xlamt>=0.0) sl=1.0;
if(xlamt<0.0) sl= -1.0;
if(cos(tlon)>=0.0) scl=1.0;
if(cos(tlon)<0.0) scl= -1.0;
xlamt=xlamt-((PI/2.0)*(1.0-scl)*sl);
dlon=xlamt-p21*tlon;
/* Compute geodetic latitude
-------------------------*/
if(fabs(sa)<1.e-7)dlat=asin(bigk/sqrt((1.0-es)*(1.0-es)+es*bigk2));
if(fabs(sa)>=1.e-7)dlat=atan((tan(tlon)*cos(xlamt)-ca*sin(xlamt))/((1.0-es)*sa));
*lon = adjust_lon(dlon+lon_center);
*lat = dlat;
return(OK);
}
/* Series to calculate a,b,c coefficients to convert from transform
latitude,longitude to Space Oblique Mercator (SOM) rectangular coordinates
Mathematical analysis by John Snyder 6/82
--------------------------------------------------------------------------*/
static double som_series(fb,fa2,fa4,fc1,fc3,dlam)
double *fb,*fa2,*fa4,*fc1,*fc3,*dlam;
{
double sd,sdsq,h,sq,fc;
*dlam= *dlam*0.0174532925; /* Convert dlam to radians */
sd=sin(*dlam);
sdsq=sd*sd;
s=p21*sa*cos(*dlam)*sqrt((1.0+t*sdsq)/((1.0+w*sdsq)*(1.0+q*sdsq)));
h=sqrt((1.0+q*sdsq)/(1.0+w*sdsq))*(((1.0+w*sdsq)/((1.0+q*sdsq)*(1.0+
q*sdsq)))-p21*ca);
sq=sqrt(xj*xj+s*s);
*fb=(h*xj-s*s)/sq;
*fa2= *fb*cos(2.0* *dlam);
*fa4= *fb*cos(4.0* *dlam);
( run in 0.603 second using v1.01-cache-2.11-cpan-71847e10f99 )