示例#1
0
文件: CS_pstro.c 项目: asir6/Colt
int EXP_LVL9 CSpstroI (Const struct cs_Pstro_ *pstro,double ll [2],Const double xy [2])
{
	extern double cs_Radian;			/*  57.29577..... */
	extern double cs_Two;				/* 2.0 */
	extern double cs_Pi_o_2;			/* PI over 2.0 */
	extern double cs_NPTest;			/* 0.001 seconds of arc
										   short of the north pole,
										   in radians. */

	int rtn_val;

	double x;
	double y;

	double c;
	double t;
	double chi;
	double rho;
	double cos_c;

	rtn_val = cs_CNVRT_NRML;

	/* Adjust for a non-standard quadrant. */

	if (pstro->quad == 0)
	{
		x = xy [XX] - pstro->x_off;
		y = xy [YY] - pstro->y_off;
	}
	else
	{
		CS_quadI (&x,&y,xy,pstro->x_off,pstro->y_off,pstro->quad);
	}

	/* If x and y are now both zero, or very close to it,
	   we must just set the result to the origin of the
	   projection.  We don't want to divide by rho if it's
	   zero. */

	rho = sqrt (x * x + y * y);
	if (rho <= pstro->one_mm)
	{
		/* The coordinate is essentially zero.  Return
		   the origin of the coordinate system. */

		ll [LNG] = pstro->org_lng * cs_Radian;
		ll [LAT] = pstro->org_lat * cs_Radian;
		return (rtn_val);
	}
		
	/* Now we can convert back to lat/longs. */

	if (pstro->ecent == 0.0)
	{
		/* Here for the sphere.  Note, we have already
		   filtered out cases where rho is zero (or very
		   close to zero).

		   Note, rho can approach infinity, although considering
		   values greater than two_ka out of the domain would
		   be generally acceptable. Read c as the angular distance
		   from the origin. */

		c = cs_Two * atan (rho / pstro->two_ka);
		cos_c = cos (c);

		switch (pstro->aspect) {

		default:
		case cs_STERO_NORTH:

			ll [LNG] = pstro->org_lng + atan2 (x,-y);
			ll [LAT] = asin (cos_c);
			break;

		case cs_STERO_SOUTH:

			ll [LNG] = -pstro->org_lng + atan2 (-x,y);
			ll [LAT] = -asin (cos_c);
			break;
		}
	}
	else
	{
		/* Here for the ellisoid. */

		switch (pstro->aspect) {

		default:
		case cs_STERO_NORTH:

			ll [LNG] = pstro->org_lng + atan2 (x,-y);
			t = rho * pstro->e_term / pstro->two_ka;
			chi = cs_Pi_o_2 - (cs_Two * atan (t));
			ll [LAT] = CSchiIcal (&pstro->chicofI,chi);
			break;

		case cs_STERO_SOUTH:

			ll [LNG] = pstro->org_lng - atan2 (-x,y);
			t = rho * pstro->e_term / pstro->two_ka;
			chi = (cs_Two * atan (t)) - cs_Pi_o_2;
			ll [LAT] = CSchiIcal (&pstro->chicofI,chi);
			break;
		}
	}
	if (fabs (ll [LAT]) > cs_NPTest && rtn_val == cs_CNVRT_NRML)	/*lint !e774 */
	{
		rtn_val = cs_CNVRT_INDF;
	}

	/* Convert the results to degrees. */

	ll [LNG] *= cs_Radian;
	ll [LAT] *= cs_Radian;

	return (rtn_val);
}
示例#2
0
文件: CS_mrcat.c 项目: auranet/csmap
int EXP_LVL9 CSmrcatI (Const struct cs_Mrcat_ *mrcat,double ll [2],Const double xy [2])
{
	extern double cs_Radian;			/* 57.29577... */
	extern double cs_Pi_o_2;			/* Pi / 2.0 */
	extern double cs_3Pi_o_2;			/* 3 Pi / 2.0 */
	extern double cs_Two;				/* 2.0 */

	int rtn_val;

	double xx;
	double yy;

	double chi;
	double lat;
	double del_lng;
	double tmp1;

	rtn_val = cs_CNVRT_NRML;

	/* Remove whatever offsets are active. */

	if (mrcat->quad == 0)
	{
		xx = xy [XX] - mrcat->x_off;
		yy = xy [YY] - mrcat->y_off;
	}
	else
	{
		CS_quadI (&xx,&yy,xy,mrcat->x_off,mrcat->y_off,mrcat->quad);
	}

	/* Check the Y value for range. */

	if (fabs (yy) > mrcat->yy_max)
	{
		rtn_val = cs_CNVRT_RNG;
		yy = (yy >= 0.0) ? mrcat->yy_max : -mrcat->yy_max;
	}

	/* The longitude calculation is the same for both the
	   spherical and ellipsoidal cases.  There may be a
	   slight difference if the standard parallel is not
	   the equator, but tis is taken care of during set up
	   and shows up in the Rfact variable. */

	del_lng = xx / mrcat->Rfact;
	if (fabs (del_lng) >= cs_3Pi_o_2)
	{
	    	rtn_val = cs_CNVRT_RNG;
		del_lng = CS_adj2pi (del_lng);
	}

	/* The following is used for sphere and ellipsoid. */

	tmp1 = exp (-yy / mrcat->Rfact);
	chi = cs_Pi_o_2 - cs_Two * atan (tmp1);

	/* Finish off the latitude as appropriate. */

	if (mrcat->ecent == 0.0)
	{
		/* Here for a sphere. */

		lat = chi;
	}
	else
	{
		/* Here for an ellipsoid.  This is a series
		   expansion used in other projections, so we
		   have a function to do this for us. */

		lat = CSchiIcal (&mrcat->chicofI,chi);
	}

	ll [LNG] = (del_lng + mrcat->cent_lng) * cs_Radian;
	ll [LAT] = lat * cs_Radian;
	return (rtn_val);
}