int EXP_LVL9 CSunityF (Const struct cs_Unity_ *unity,double xy [2],Const double ll [2]) { extern double cs_Zero; /* 0.0 */ extern double cs_K90; /* 90.0 */ extern double cs_Km90; /* -90.0 */ extern double cs_K270; /* 270.0 */ extern double cs_Km270; /* -270.0 */ int rtn_val; double lng; rtn_val = cs_CNVRT_NRML; /* If the lat/long we have been provided are not within internal standards, we have a domain problem. This should only happen if we are called directly by an application program. */ xy [XX] = ll [LNG]; xy [YY] = ll [LAT]; if (xy [XX] <= cs_Km270 || xy [XX] > cs_K270) { rtn_val = cs_CNVRT_DOMN; xy [XX] = CS_adj270 (xy [XX]); } if (xy [YY] < cs_Km90 || xy [YY] > cs_K90) { rtn_val = cs_CNVRT_DOMN; xy [YY] = CS_adj90 (xy [YY]); } /* Convert to user form. */ xy [XX] = (xy [XX] - unity->gwo_lng) * unity->unit_s; xy [YY] = xy [YY] * unity->unit_s; /* Normalize longitude, if necessary, to acheive the user's desired range. */ if (xy [XX] < unity->usr_min || xy [XX] > unity->usr_max) { lng = xy [XX] - unity->usr_min; lng = fmod (lng,unity->usr_2pi); if (lng < 0.0) lng += unity->usr_2pi; if (lng > unity->usr_rng) lng -= unity->usr_2pi; xy [XX] = unity->usr_min + lng; } if (unity->quad != 0) { CS_quadF (xy,xy [XX],xy [YY],cs_Zero,cs_Zero,unity->quad); } return (rtn_val); }
int EXP_LVL9 CSnzlndI (Const struct cs_Nzlnd_ *nzlnd,double ll [2],Const double xy [2]) { extern double cs_Radian; /* 57.29577..... */ extern double cs_Zero; /* 0.0 */ extern double cs_One; /* 1.0 */ extern double cs_K90; /* 90.0 */ int ii; int rtn_val; double xx; double yy; double rho; double lat; double del_psi,del_lat; struct cs_Cmplx_ zz; struct cs_Cmplx_ theta; struct cs_Cmplx_ theta1; struct cs_Cmplx_ theta2; rtn_val = cs_CNVRT_NRML; if (nzlnd->quad == 0) { xx = xy [XX] - nzlnd->x_off; yy = xy [YY] - nzlnd->y_off; } else { CS_quadI (&xx,&yy,xy,nzlnd->x_off,nzlnd->y_off,nzlnd->quad); } xx /= nzlnd->ka; yy /= nzlnd->ka; if (fabs (xx) > cs_One || fabs (yy) > cs_One) { rtn_val = cs_CNVRT_RNG; rho = sqrt (xx * xx + yy * yy); xx /= rho; yy /= rho; } zz.real = yy; zz.img = xx; CS_iisrs (&zz,nzlnd->C_ary,6,&theta); for (ii = 0;ii < 2;ii++) { CS_iisrs1 (&theta,nzlnd->B_ary,6,&theta1); CS_iisrs0 (&theta,nzlnd->B_ary,6,&theta2); CS_iiadd (&zz,&theta2,&theta2); CS_iidiv (&theta2,&theta1,&theta); } del_psi = theta.real; del_lat = cs_Zero; for (ii = 8;ii >= 0;ii--) { del_lat = (del_lat + nzlnd->D_ary [ii]) * del_psi; } ll [LNG] = CS_adj180 (theta.img * cs_Radian) + nzlnd->org_lng; lat = CS_adj90 (del_lat / nzlnd->lat_kk) + nzlnd->org_lat; if (fabs (lat) > cs_K90) { rtn_val = cs_CNVRT_RNG; lat = CS_adj90 (lat); } ll [LAT] = lat; return (rtn_val); }
int EXP_LVL9 CSunityI (Const struct cs_Unity_ *unity,double ll [2],Const double xy [2]) { extern double cs_Zero; /* 0.0 */ extern double cs_K90; /* 90.0 */ extern double cs_Km90; /* -90.0 */ int rtn_val; double lcl_xy [2]; rtn_val = cs_CNVRT_NRML; /* Apply the quadrant processing. This is usually used to make west longitude positive. */ if (unity->quad == 0) { lcl_xy [XX] = xy [XX]; lcl_xy [YY] = xy [YY]; } else { CS_quadI (&lcl_xy [XX],&lcl_xy [YY],xy,cs_Zero,cs_Zero,unity->quad); } /* See if the user supplied values are with the user's specified range. If not, we have a domain error, and we normalize to the user's specified range before proceeding. */ if (lcl_xy [XX] < unity->usr_min || lcl_xy [XX] > unity->usr_max) { rtn_val = cs_CNVRT_DOMN; lcl_xy [XX] -= unity->usr_min; lcl_xy [XX] = fmod (lcl_xy [XX],unity->usr_2pi); lcl_xy [XX] += unity->usr_min; } /* Convert the supplied values to internal units and referencing. */ ll [LNG] = unity->gwo_lng + (lcl_xy [XX] / unity->unit_s); ll [LAT] = lcl_xy [YY] / unity->unit_s; /* Normalize the longitude to internal standards. */ ll [LNG] = CS_adj270 (ll [LNG]); /* If the resulting latitude is out of range, we do have a problem. */ if (ll [LAT] < cs_Km90 || ll [LAT] > cs_K90) { /* Not within the user's expected range. */ rtn_val = cs_CNVRT_RNG; ll [LAT] = CS_adj90 (ll [LAT]); } return (rtn_val); }