Beispiel #1
0
/******************************************************************************
	What we call the Frame/Wolfe tranformation is an approximation of the
	Seven Parameter transformation.  The following approximations apply:

	1> The cosine of all rotation angles is one.
	2> The sine of all rotation angles is equal to the angle itself.
	3> The product of two sine terms is zero.
*/
int EXP_LVL9 CSframeS (struct cs_GxXform_* gxXfrm)
{
	extern double cs_One;				/* 1.0 */
	extern double cs_Sec2Rad;			/* 4.848...E-06 */

	double trgScale;
	struct csFrame_ *frame;

	frame = &gxXfrm->xforms.frame;
	
	frame->srcERad = gxXfrm->srcDatum.e_rad;
	frame->srcESqr = gxXfrm->srcDatum.ecent * gxXfrm->srcDatum.ecent;

	frame->trgERad = gxXfrm->trgDatum.e_rad;
	frame->trgESqr = gxXfrm->trgDatum.ecent * gxXfrm->trgDatum.ecent;

	frame->deltaX = gxXfrm->gxDef.parameters.geocentricParameters.deltaX;
	frame->deltaY = gxXfrm->gxDef.parameters.geocentricParameters.deltaY;
	frame->deltaZ = gxXfrm->gxDef.parameters.geocentricParameters.deltaZ;
	frame->rotX   = gxXfrm->gxDef.parameters.geocentricParameters.rotateX * cs_Sec2Rad;
	frame->rotY   = gxXfrm->gxDef.parameters.geocentricParameters.rotateY * cs_Sec2Rad;
	frame->rotZ   = gxXfrm->gxDef.parameters.geocentricParameters.rotateZ * cs_Sec2Rad;

	trgScale = cs_One + (gxXfrm->gxDef.parameters.geocentricParameters.scale * 1.0E-06);
	if (fabs (trgScale) < 1.0E-06)
	{
		// An actual scale factor of zero would produce a floating point
		// exception.  Can't allow that.
		CS_erpt (cs_ISER);
	}
	else
	{
		frame->scale = cs_One + (gxXfrm->gxDef.parameters.geocentricParameters.scale * 1.0E-06);
	}

	frame->errorValue    = gxXfrm->errorValue;
	frame->cnvrgValue    = gxXfrm->cnvrgValue;
	frame->maxIterations = gxXfrm->maxIterations;

	gxXfrm->frwrd2D = (cs_FRWRD2D_CAST)CSframeF2;
	gxXfrm->frwrd3D = (cs_FRWRD3D_CAST)CSframeF3;
	gxXfrm->invrs2D = (cs_INVRS2D_CAST)CSframeI2;
	gxXfrm->invrs3D = (cs_INVRS3D_CAST)CSframeI3;
	gxXfrm->inRange = (cs_INRANGE_CAST)CSframeL;
	gxXfrm->release = (cs_RELEASE_CAST)CSframeR;
	gxXfrm->destroy = (cs_DESTROY_CAST)CSframeD;

	return 0;
}
Beispiel #2
0
Const char * EXP_LVL7 CSnad27ToAts77Log (Const double ll_27 [2])
{
	Const char *cp;

	cp = NULL;
	/* Make sure we have been initialized. */
	if (csNad27ToAts77 == NULL)
	{
		CS_erpt (cs_DTC_NO_SETUP);
	}
	else
	{
		cp = CSsourceNad27ToAts77 (csNad27ToAts77,ll_27);
	}
	return (cp == NULL || *cp == '\0') ? "<unavailable>" : cp;
}
Beispiel #3
0
Const char * EXP_LVL7 CSdhdnToEtrf89Log (Const double ll_50 [2])
{
	Const char *cp;

	cp = NULL;
	/* Make sure we have been initialized. */
	if (csDhdnToEtrf89 == NULL)
	{
		CS_erpt (cs_DTC_NO_SETUP);
	}
	else
	{
		cp = CSsourceDhdnToEtrf89 (csDhdnToEtrf89,ll_50);
	}
	return (cp == NULL || *cp == '\0') ? "<unavailable>" : cp;
}
Beispiel #4
0
int EXP_LVL1 CS_llFromMgrs (double latLng [2],const char* mgrsString)
{
	extern struct cs_Mgrs_ *cs_MgrsPtr;


	int status;


	if (cs_MgrsPtr == NULL)
	{
		CS_erpt (cs_MGRS_NOSET);
		status = -1;
	}
	else
	{
		status = CScalcLlFromMgrs (cs_MgrsPtr,latLng,mgrsString);
	}
	return status;
}
Beispiel #5
0
/******************************************************************************
	Calculation function.  Calculates the conversion from Ats77 to NAD83.
*/
int CScalcAts77ToCsrsEntry (struct csAts77ToCsrsEntry_* __This,double* ll_csrs,Const double *ll_ats77,struct csLLGridCellCache_ *cachePtr)
{
	extern char csErrnam [];

	int status;

	switch (__This->type){
	case dtAts77ToCsrsC2:
		status = CScalcDatumShiftCa2 (__This->pointers.c2DatumPtr,ll_csrs,ll_ats77,cachePtr);
		break;
	case dtAts77ToCsrsNoneYet:
	default:
		/* Minus one indicates a fatal error.  In this case, it is an internal
		   software error. */
		CS_stncp (csErrnam,"CS_dtAts77ToCsrs:1",MAXPATH);
		CS_erpt (cs_ISER);
		status = -1;
		break;
	}
	return status;
}
Beispiel #6
0
/*
	The following function returns the mesh code appropriate for the given
	geographic coordinates provided.  Note, it is expected that the calling
	module deals with the rounding to the appropriate grid point.

	This function returns a zero to indicate an error.  Zero is not, under
	any circumstances, a valid mesh code.
*/
ulong32_t EXP_LVL9 CSjpnLlToMeshCode (const double ll [2])
{
	extern char csErrnam [];

	ulong32_t mesh;
	ulong32_t iLat, iLng;

	/* Verify that we are in the proper range.  This prevents many nasty
	   situations such as overflow. */
	if (ll [0] < 120.0 || ll [0] > 160.0 || ll [1] <  20.0 || ll [1] >  60.0)
	{
		CS_stncp (csErrnam,"CS_jpnMeshCode:1",MAXPATH);
		CS_erpt (cs_ISER);
		return 0;
	}

	/* Compute the mesh numbers for each value. */
	iLat = ((ulong32_t)CS_degToSec (ll [1])) / 30;
	iLng = ((ulong32_t)CS_degToSec (ll [0] - 100.0)) / 45;

	/* We do the last two digits; these range from 0 thru 9.  Each increment in
	   longitude represents 45 seconds of longitude.  Each increment in
	   latitude represents 30 seconds of latitude. */
	mesh  =  iLng % 10;
	mesh += (iLat % 10) * 10;

	/* Next two digits, range from 0 thru 7.  Each increment of longitude represents
	   7.5 minutes (450 seconds).  Each increment of latitude represents 5 minutes
	   (300 seconds). */
	mesh += ((iLng / 10) % 8) * 100;
	mesh += ((iLat / 10) % 8) * 1000;

	/* Now for the last set of four digits.  Each increment of latitude represents
	   40 minutes (2400 sceonds) and each increment of longitude repsents 12 degree
	   (3600 seconds) of longitude.  Note that we biased the longitude by 100 degrees
	   above. */
	mesh += ((iLng / 80) % 100) *   10000;
	mesh += ((iLat / 80) % 100) * 1000000;
	return mesh;
}
Beispiel #7
0
int EXP_LVL1 CS_cs2WktEx (char *bufr,size_t bufrSize,const char *csKeyName,int flavor,unsigned short flags)
{
	int rtnValue = -1;
	struct cs_Dtdef_ *dtDefPtr = 0;
	struct cs_Eldef_ *elDefPtr = 0;
	struct cs_Csdef_ *csDefPtr = 0;
	
	if (bufrSize > 0)
	{
		*bufr = '\0';
		csDefPtr = CS_csdef (csKeyName);
		if (csDefPtr != 0)
		{
			if (csDefPtr->dat_knm [0] == '\0')
			{
				CS_erpt (cs_WKT_NODTREF);
			}
			else
			{
				dtDefPtr = CS_dtdef (csDefPtr->dat_knm);
				if (dtDefPtr != 0)
				{
					elDefPtr = CS_eldef (dtDefPtr->ell_knm);
					if (elDefPtr != 0)
					{
						rtnValue = CScs2WktEx (bufr,bufrSize,flavor,csDefPtr,dtDefPtr,elDefPtr,flags);	/*lint !e64 */
						CS_free (elDefPtr);
						elDefPtr = 0;
					}
					CS_free (dtDefPtr);
					dtDefPtr = 0;
				}
			}
			CS_free (csDefPtr);
			csDefPtr = 0;
		}
	}
	return rtnValue;		
}
Beispiel #8
0
int EXP_LVL1 CS_mgrsFromLl (char* result,double latLng [2],int prec)
{
	extern struct cs_Mgrs_ *cs_MgrsPtr;

	int size;
	int status;

	size = 6 + prec + prec;


	if (cs_MgrsPtr == NULL)
	{
		CS_erpt (cs_MGRS_NOSET);
		status = -1;
	}
	else
	{
		size = 6 + prec + prec;
		status = CScalcMgrsFromLl (cs_MgrsPtr,result,size,latLng,prec);
	}
	return status;
}
Beispiel #9
0
/******************************************************************************
Constructor */
struct csDatumShiftCa1_* CSnewDatumShiftCa1 (Const char *path,long bufferSize,unsigned long flags,double density)
{
	struct csDatumShiftCa1_ *__This = NULL;

	__This = (struct csDatumShiftCa1_ *)CS_malc (sizeof (struct csDatumShiftCa1_));
	if (__This == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}
	__This->gridPtr = NULL;

	__This->gridPtr = CSnewGridFileCa1 (path,bufferSize,flags,density);
	if (__This->gridPtr == NULL) goto error;
	return __This;
error:
	if (__This != NULL)
	{
		if (__This->gridPtr != NULL) CSdeleteGridFileCa1 (__This->gridPtr);
		CS_free (__This);
	}
	return NULL;
}
Beispiel #10
0
/**********************************************************************
**	status = CSvrtcon29To88 (deltaHgt,ll_83);
**
**	double *deltaHgt;			the calculated change in orthometric height
**								is returned here. 
**	double ll_83 [3];			the longitude ([0]) and the latitude ([1]) of
**								the point at which the change in orthometric
**								height is to be determined.
**	int status;					returns zero if conversion took place as expected,
**								+1 if conversion failed due to out of range
**								error, -1 for all other errors.
**
**	In the event of a +1 return value, deltaHgt is set to zero.
**********************************************************************/
int EXP_LVL7 CSvrtcon29To88 (double* deltaHgt,Const double ll_83 [3])
{
	extern double cs_Zero;

	int status;
	double result;

	result = cs_Zero;
	/* Make sure we have been initialized. */
	if (csVertconUS == NULL)
	{
		CS_erpt (cs_DTC_NO_SETUP);
		status = -1;
	}
	else
	{
		/* Note, this function returns the shift in millimeters. */
		status = CScalcVertconUS (csVertconUS,&result,ll_83);
		if (status == 0) result *= 0.001;
	}
	*deltaHgt = result;
	return status;
}
Beispiel #11
0
/******************************************************************************
	Constructor.  Can't have an object of this type without a data file.  Thus
	this constructor requires a data file and returns NULL in the event of a
	failure.  Currently, there is no use of the flags value.
*/
struct cs_NTv2_* CSnewNTv2 (Const char *filePath,long32_t bufferSize,ulong32_t flags,double density)
{
	int st;

	struct cs_NTv2_* thisPtr;

	/* Allocate and initialize the basic structure. */
	thisPtr = (struct cs_NTv2_ *)CS_malc (sizeof (struct cs_NTv2_));
	if (thisPtr == NULL)
	{
		CS_erpt (cs_NO_MEM);
	}
	else
	{
		st = CSinitNTv2 (thisPtr,filePath,bufferSize,flags,density);
		if (st != 0)
		{
			CSdeleteNTv2 (thisPtr);
			thisPtr = NULL;
		}
	}
	return thisPtr;
}
Beispiel #12
0
/******************************************************************************
	Calculation function.  Calculates the conversion from RGF93 to NTF.
*/
int CScalcRgf93ToNtfEntry (struct csRgf93ToNtfEntry_* __This,double* llNtf,Const double *llRgf93,struct csLLGridCellCache_ *cachePtr)
{
	extern char csErrnam [];

	int status;

	switch (__This->type){
	case dtRgf93ToNtfTxt:
		status = CScalcRgf93ToNtfTxt (__This->pointers.txtDatumPtr,llNtf,llRgf93);
		break;
	case dtRgf93ToNtfC2:
		status = CScalcDatumShiftCa2 (__This->pointers.c2DatumPtr,llNtf,llRgf93,cachePtr);
		break;
	case dtRgf93ToNtfNone:
	default:
		/* Minus one indicates a fatal error.  In this case, it is an internal
		   software error. */
		CS_stncp (csErrnam,"CS_dtRgf93ToNtf:1",MAXPATH);
		CS_erpt (cs_ISER);
		status = -1;
		break;
	}
	return status;
}
Beispiel #13
0
/******************************************************************************
	Calculate the geoid height, given the specific "Entry" item which is to
	be used.
*/
int CScalcGeoidHeightEntry (struct csGeoidHeightEntry_* __This,double* geoidHgt,Const double *ll84)
{
	extern char csErrnam [];

	int status;

	status = -1;
	if (__This != NULL)
	{
		switch (__This->type) {
		case csGeoidHgtTypeGeoid96:
			status = CScalcGeoid96GridFile (__This->pointers.geoid96Ptr,geoidHgt,ll84);
			break;
		case csGeoidHgtTypeGeoid99:
			status = CScalcGeoid99GridFile (__This->pointers.geoid99Ptr,geoidHgt,ll84);
			break;
		case csGeoidHgtTypeOsgm91:
			status = CScalcOsgm91 (__This->pointers.osgm91Ptr,geoidHgt,ll84);
			break;
		case csGeoidHgtTypeBynGridFile:
			status = CScalcBynGridFile (__This->pointers.bynGridFilePtr,geoidHgt,ll84);
			break;
      case csGeoidHgtTypeEgm96:
         status = CScalcEgm96 (__This->pointers.egm96Ptr,geoidHgt,ll84);
         break;
		case csGeoidHgtTypeWorld:
		case csGeoidHgtTypeAustralia:
		case csGeoidHgtTypeNone:
		default:
			CS_stncp (csErrnam,"CS_usGridFile:3",MAXPATH);
			CS_erpt (cs_ISER);
			break;
		}
	}
	return status;
}
Beispiel #14
0
int EXP_LVL9 CSazmedI (Const struct cs_Azmed_ *azmed,double ll [2],Const double xy [2])
{
	extern char csErrnam [];

	extern double cs_Radian;			/*  57.29577..... */
	extern double cs_Zero;				/* 0.0 */
	extern double cs_Half;				/* 0.5 */
	extern double cs_One;				/* 1.0 */
	extern double cs_Mone;				/*-1.0 */
	extern double cs_Three;				/* 3.0 */
	extern double cs_Six;				/* 6.0 */
	extern double cs_AnglTest;			/* 0.001 seconds of arc,
										   in radians. */
	extern double cs_NPTest;			/* 0.001 seconds of arc
										   short of the north pole,
										   in radians. */

	int rtn_val;
	int itr_cnt;

	double x = 0.0;			/* initialized to keep the gcc compiler happy */
	double y = 0.0;			/* initialized to keep the gcc compiler happy */
	double c;
	double lat = 0.0;		/* initialized to keep the gcc compiler happy */
	double del_lng;
	double rho;
	double sin_c;
	double cos_c;
	double Az;
	double sin_Az;
	double cos_Az;
	double cos_psi;
	double last_lat;
	double A;
	double B;
	double D;
	double D_third;
	double D_fourth;
	double E;
	double E_sq;
	double E_third;
	double sin_E;
	double F;
	double M;
	double psi;
	double tmp1;
	double tmp2;

	double my_xy [2];

	rtn_val = cs_CNVRT_NRML;

	/* There are two formulae, one for the sphere and
	   one for the ellipsoid.  If the ecentricity of the
	   datum in use is 0.0 exactly, we shall use the
	   spherical formulae.

	   The calculations which immediately follow are required
	   by both cases.  First, we remove the false origin, return
	   to the normal X/Y quadrant, and unrotate the coordinates. */

	if (azmed->quad == 0)
	{
		my_xy [XX] = xy [XX] - azmed->x_off;
		my_xy [YY] = xy [YY] - azmed->y_off;
	}
	else
	{
		CS_quadI (&my_xy [XX],&my_xy [YY],xy,azmed->x_off,
						     azmed->y_off,
						     azmed->quad);
	}
	x = azmed->cos_Az * my_xy [XX] + azmed->sin_Az * my_xy [YY];
	y = azmed->cos_Az * my_xy [YY] - azmed->sin_Az * my_xy [XX];

	/* Rho is the radius of the circle whose center is at the
	   origin and goes thorugh the current point. */

	rho = sqrt (x * x + y * y);
	if (rho < azmed->one_mm)
	{
		/* The coordinate is essentially the origin.  We
		   do the following to avoid a atan2(0,0).

		   If the origin is either pole, the longitude
		   will be undefined. */

		if (azmed->aspect == cs_AZMED_NORTH ||
		    azmed->aspect == cs_AZMED_SOUTH)
		{
			rtn_val = cs_CNVRT_INDF;
		}
		ll [LNG] = azmed->org_lng * cs_Radian;
		ll [LAT] = azmed->org_lat * cs_Radian;
		return (rtn_val);
	}
	if (rho >= azmed->max_rho)
	{
		/* Opps!!! The x and/or y is so large it is outside
		   the circle which defines the extent of the
		   coordinate system.  Convert xy to lie on the
		   bounding circle at the apropriate azimuth. */

		rtn_val = cs_CNVRT_RNG;
		x *= azmed->max_rho / rho;
		y *= azmed->max_rho / rho;
		rho = azmed->max_rho;
	}

	/* Now we can convert back to lat/longs.  We know that rho
	   is not zero which implies that at least one of x and y is
	   not zero. */

	del_lng = cs_Zero;
	if (azmed->ecent == 0.0)
	{
		/* Here for the sphere.  The sine and cosine functions
		   shouldnever return a value greater than one.  Thus,
		   the asin ()'s here should be OK without any checking. */

		c = rho / azmed->ka;
		sin_c = sin (c);
		cos_c = cos (c);

		switch (azmed->aspect) {

		case cs_AZMED_NORTH:

			del_lng = atan2 (x,-y);
			lat     = asin  (cos_c);
			break;

		case cs_AZMED_SOUTH:

			del_lng =  atan2 (x,y);
			lat     = -asin  (cos_c);
			break;

		case cs_AZMED_EQUATOR:

			c = rho / azmed->ka;
			tmp1 = x * sin (c);
			tmp2 = rho * cos (c);
			del_lng = atan2 (tmp1,tmp2);
			tmp1  = (y / rho) * sin_c;
			if (fabs (tmp1) > cs_One)
			{
				tmp1 = (tmp1 >= 0.0) ? cs_One : cs_Mone;
			}
			lat = asin (tmp1);
			break;

		case cs_AZMED_GUAM:

			lat = azmed->org_lat;
			itr_cnt = 16;
			for (;;)
			{
				last_lat = lat;
				tmp1 = x * x * tan (lat) / azmed->two_ka;
				lat = azmed->org_lat + (y - tmp1) / azmed->ka;
				if (fabs (lat - last_lat) < cs_AnglTest)
				{
					break;
				}
				if (--itr_cnt <= 0)
				{
					rtn_val = cs_CNVRT_RNG;
					break;
				}
			}

			/* Longitude is undefined at the poles. */

			if (fabs (lat) < cs_NPTest)
			{
				del_lng = x / (azmed->ka * cos (lat));
			}
			break;

		case cs_AZMED_OBLIQUE:

			tmp1  = cos_c * azmed->sin_org_lat;
			tmp1 += (y / rho) * sin_c * azmed->cos_org_lat;
			if (fabs (tmp1) > cs_One)
			{
				tmp1 = (tmp1 >= 0.0) ? cs_One : cs_Mone;
			}
			lat = asin (tmp1);

			tmp1  = x * sin_c;
			tmp2  = rho * cos_c * azmed->cos_org_lat;
			tmp2 -= y * sin_c * azmed->sin_org_lat;
			del_lng = atan2 (tmp1,tmp2);
			break;

		default:
			CS_stncp (csErrnam,"CS_azmed:3",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}
	}
	else
	{
		/* Here for the ellisoid.  We've already dealt
		   with x and y == 0. */

		switch (azmed->aspect) {

		case cs_AZMED_NORTH:

			del_lng = atan2 (x,-y);
			lat = CSmmIcal (&azmed->mmcofI,(azmed->Mp - rho));
			break;

		case cs_AZMED_SOUTH:

			del_lng = atan2 (x,y);
			lat = CSmmIcal (&azmed->mmcofI,(rho - azmed->Mp));
			break;

		case cs_AZMED_GUAM:

			itr_cnt = 16;
			lat = azmed->org_lat;
			for (;;)
			{
				last_lat = lat;
				tmp1 = sin (lat);
				tmp1 = cs_One - azmed->e_sq * tmp1 * tmp1;
				tmp1 = x * x * tan (lat) * sqrt (tmp1);
				tmp1 = y - tmp1 / azmed->two_ka;
				M = azmed->M1 + tmp1;
				lat = CSmmIcal (&azmed->mmcofI,M);
				if (fabs (lat - last_lat) < cs_AnglTest)
				{
					break;
				}
				if (--itr_cnt <= 0)
				{
					rtn_val = cs_CNVRT_RNG;
					break;
				}
			}

			/* Longitude is undefined at the poles. */

			if (fabs (lat) < cs_NPTest)
			{
				tmp1 = sin (lat);
				tmp1 = cs_One - azmed->e_sq * tmp1 * tmp1;
				del_lng = x * sqrt (tmp1) / (azmed->ka * cos (lat));
			}
			break;

		case cs_AZMED_EQUATOR:
		case cs_AZMED_OBLIQUE:

			Az = atan2 (x,y);
			sin_Az = sin (Az);
			cos_Az = cos (Az);
			A = -azmed->e_sq_cos_sq * cos_Az * cos_Az / azmed->one_esq;
			B = cs_Three * azmed->e_sq * (cs_One - A) * azmed->sin_cos *
						cos_Az / azmed->one_esq;
			D = rho / azmed->N1;
			D_third = D * D * D;
			D_fourth = D_third * D;
			E = D;
			E -= A * (cs_One + A) * D_third / cs_Six;
			E -= B * (cs_One + cs_Three * A) * D_fourth / 24.0;
			E_sq = E * E;
			E_third = E_sq * E;
			sin_E = sin (E);
			F = cs_One - (A * E_sq * cs_Half) - (B * E_third / cs_Six);		/*lint !e834 */
			tmp1 = azmed->sin_org_lat * cos (E);
			tmp2 = azmed->cos_org_lat * sin_E * cos_Az;
			psi = asin (tmp1 + tmp2);

			/* Psi is essentially the latitude of the point
			   adjusted for the affect of the ellipsoid.  Thus,
			   it can be zero, and it can be the equivalent of
			   +-90 degrees.

			   In analyzing the following, note that:
			   1) E is the ellipsoidally adjusted angular
			      distance from the origin to the point;
			   2) the formula is actually equation 5-4 of Synder,
			      reorganized to produce the delta longitude.

			   Thus, I conclude that delta longitude goes to
			   zero as cos(psi) approaches zero. */

			cos_psi = cos (psi);
			if (fabs (cos_psi) > cs_AnglTest)
			{
				del_lng = asin (sin_Az * sin_E / cos (psi));
			}

			/* Now, the latitude.  We have a similar problem,
			   but now with sin (psi) == 0. As psi approaches
			   zero, this whole mess reduces to lat = psi,
			   which is zero, of course. */

			if (fabs (psi) > cs_AnglTest)
			{
				tmp1 = azmed->e_sq * F * azmed->sin_org_lat / sin (psi);
				tmp2 = tan (psi) / azmed->one_esq;
				lat = atan ((cs_One - tmp1) * tmp2);
			}
			else
			{
				lat = cs_Zero;
			}
			break;

		default:

			CS_stncp (csErrnam,"CS_azmed:",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}
	}

	/* Longitude is undefined, mathematically, at either pole. */
	if (rtn_val >= 0)
	{
		if (fabs (lat) > cs_NPTest) rtn_val = cs_CNVRT_INDF;

		/* Longitudes are always normalized for this projection. */

		ll [LNG] = (del_lng + azmed->org_lng) * cs_Radian;
		ll [LAT] = lat * cs_Radian;
	}
	return (rtn_val);
}
Beispiel #15
0
/******************************************************************************
	Constructor
*/
struct csRgf93ToNtf_* CSnewRgf93ToNtf (Const char *catalog)
{
	int index;
	Const char *cp;
	struct csRgf93ToNtf_ *__This;
	struct csDatumCatalog_ *catPtr;
	struct csDatumCatalogEntry_ *catEntryPtr;
	struct csRgf93ToNtfEntry_* dtEntryPtr;
	struct csRgf93ToNtfEntry_* findPtr;

	/* Prepare for an error. */
	__This = NULL;
	catPtr = NULL;
	catEntryPtr = NULL;
	dtEntryPtr = NULL;

	__This = (struct csRgf93ToNtf_*) CS_malc (sizeof (struct csRgf93ToNtf_));
	if (__This == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}
	__This->fallback = NULL;
	__This->cachePtr = NULL;
	__This->listHead = NULL;

	/* Open the catalog file. */
	catPtr = CSnewDatumCatalog (catalog);
	if (catPtr == NULL) goto error;

	/* Get a pointer to the fallback definition.  This will be NULL if there
	   is none. */
	cp = CSgetFallbackName (catPtr);
	if (cp != NULL && *cp != '\0')
	{
		__This->fallback = CSnewFallback (cp,catalog);
		if (__This->fallback == NULL)
		{
			goto error;
		}
	}

	/* For each entry in the catalong, we build an appropriate datum
	   shift entry.  Catalog entries must carry path names to each individual
	   file.  We do not play any games with extensions here. */

	index = 0;
	for (;;)
	{
		catEntryPtr = CSgetDatumCatalogEntry (catPtr,index++);
		if (catEntryPtr == NULL) break;
		dtEntryPtr = CSnewRgf93ToNtfEntry (catEntryPtr);
		if (dtEntryPtr == NULL)
		{
			goto error;
		}
		/* Keep the list in the same order as they appear in the file. */
		if (__This->listHead == NULL)
		{
			__This->listHead = dtEntryPtr;
		}
		else
		{
			for (findPtr = __This->listHead;findPtr->next != NULL;findPtr = findPtr->next);
			findPtr->next = dtEntryPtr;
		}
	}
	CSdeleteDatumCatalog (catPtr);
	catPtr = NULL;

	/* Having done that successfully, allocate a grid cell cache.  If
	   this fails, we can either report it as an error, or just leave it
	   alone.  Lets report it as an error. */
	__This->cachePtr = CSnewLLGridCellCache (32);
	if (__This->cachePtr == NULL)
	{
		goto error;
	}

	/* OK, it's ready to go. */
	return __This;

error:
	if (catPtr != NULL) CSdeleteDatumCatalog (catPtr);
	CSdeleteRgf93ToNtf (__This);
	return NULL;
}
Beispiel #16
0
int EXP_LVL7 CS_bins (csFILE *strm,long32_t start,long32_t eofPos,int rs,Const void *rec,int (*comp)(Const void *pp,Const void *qq))
{
	int st;
	int flag = -1;						/* initialization to keep gcc happy */
	size_t rd_cnt;

	long32_t nrecs;
	long32_t hi_rec;
	long32_t lo_rec;
	long32_t test_rec;
	long32_t test_pos;

	char *buff;

	/* Prepare for a possible error. */
	buff = NULL;

	/* Get a buffer which we can use for record I/O. */
	buff = (char *)CS_malc ((unsigned)rs);
	if (buff == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}

	/* Compute the portion of the file which is to be
	   searched.  Quite often, we don't want to
	   search the whole thing. */
	if (start < 0L)
	{
		start = CS_ftell (strm);
		if (start < 0L)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
	}
	if (eofPos <= 0L)
	{
		st = CS_fseek (strm,0L,SEEK_END);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
		eofPos = CS_ftell (strm);
		if (eofPos < 0L)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
	}

	/* Compute the number of records in the file
	   which are to be searched. */
	nrecs = (eofPos - start) / rs;

	/* If there are no records, we don't have a match,
	   any any record would appear at the start. */
	if (nrecs <= 0)
	{
		st = CS_fseek (strm,start,SEEK_SET);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}

		CS_free (buff);
		buff = NULL;

		return (0);
	}

	/* Set the starting and ending record numbers, where
	   the first record is numbered zero. */
	hi_rec = nrecs - 1;
	lo_rec = 0;

	/* Continue to search the records until we have
	   exhausted all possibilities.  The equal part
	   of this test is nescessary so that the last
	   record in the search gets compared for a match
	   or not. */
	test_pos = start;					/* initialization to keep gcc happy */
	while (lo_rec <= hi_rec)
	{
		/* Select the next record to be tested in terms
		   of record number. */
		test_rec = (hi_rec + lo_rec) / 2;

		/* Convert this to a file position. */
		test_pos = (long32_t)(test_rec * rs) + start;

		/* Read in the new test record. */
		st = CS_fseek (strm,test_pos,SEEK_SET);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
		rd_cnt = CS_fread (buff,1,(unsigned)rs,strm);
		if (rd_cnt != (size_t)rs)
		{
			if (ferror (strm)) CS_erpt (cs_IOERR);
			else			   CS_erpt (cs_INV_FILE);
			goto error;
		}

		/* Compare with our search record. */
		flag = (*comp)(buff,rec);
		if (flag > 0)
		{
			/* Here if our test record is past where
			   our search record will be if it does
			   indeed exist.  We can exclude this
			   record (that we just read) and all
			   records past it from the search. */
			hi_rec = test_rec - 1;
		}
		else if (flag < 0)
		{
			/* Here if the test record is before where
			   our search record will be if it does
			   indeed exist.  We can exclude this
			   record and all which precede it from
			   the search. */
			lo_rec = test_rec + 1;
		}
		else
		{
			/* We have found a matching record.  Before
			   we return, we need to make sure that if
			   there are duplicate records in the file,
			   we are returning with the file positioned
			   to read the first of such duplicates. */
			do
			{
				test_pos -= (long32_t)rs;
				if (test_pos < start)
				{
					/* The last record tested is the
					   first in the search area.
					   Seek to search and break,
					   we're all done. */
					st = CS_fseek (strm,start,SEEK_SET);
					if (st != 0)
					{
						CS_erpt (cs_IOERR);
						goto error;
					}
					break;
				}

				/* Seek to the record just prior
				   to the last one tested and
				   read it in. */
				st = CS_fseek (strm,test_pos,SEEK_SET);
				if (st != 0)
				{
					CS_erpt (cs_IOERR);
					goto error;
				}
				rd_cnt = CS_fread (buff,1,(unsigned)rs,strm);
				if (rd_cnt != (size_t)rs)
				{
					if (ferror (strm)) CS_erpt (cs_IOERR);
					else               CS_erpt (cs_INV_FILE);
					goto error;
				}

				/* See if this record also matches
				   our key.  NOTE, that the read
				   positions the file back to the
				   last record tested, which is the
				   desired file position if the
				   match test fails. */
				flag = (*comp)(buff,rec);
			} while (flag == 0);

			/* Reset flag to zero, i.e. we got here because
			   we found a matching record. */
			flag = 0;

			/* Now we can return. */
			break;
		}
	}

	/* If flag is negative here, the file is correctly
	   positioned since we have read the record in and
	   the file is positioned for the next.  If flag
	   is greater than zero, we need to move the file
	   pointer back one record so that the user will
	   be able to re-read the current record. */
	if (flag > 0)
	{
		st = CS_fseek (strm,test_pos,SEEK_SET);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
	}

	/* OK, return and tell the user if we found the
	   desired record or not. */

	CS_free (buff);
	buff = NULL;
	return (flag == 0);

error:
	if (buff != NULL) CS_free (buff);
	return (-1);
}
Beispiel #17
0
int EXP_LVL9 CSazmedF (Const struct cs_Azmed_ *azmed,double xy [2],Const double ll [2])
{
	extern char csErrnam [MAXPATH];

	extern double cs_Degree;			/* 1.0 / RADIAN  */
	extern double cs_Pi;				/* 3.14159... */
	extern double cs_Two_pi;			/* 2 PI */
	extern double cs_Mpi;				/* -3.14159.... */
	extern double cs_Pi_o_2;			/* PI over 2 */
	extern double cs_Mpi_o_2;			/* Minus PI over 2 */
	extern double cs_Zero;				/* 0.0 */
	extern double cs_One;				/* 1.0 */
	extern double cs_Mone;				/*-1.0 */
	extern double cs_Two;				/* 2.0 */
	extern double cs_Four;				/* 4.0 */
	extern double cs_Six;				/* 6.0 */
	extern double cs_Seven;				/* 7.0 */
	extern double cs_Eight;				/* 8.0 */
	extern double cs_NPTest;			/* 0.001 seconds of arc
										   short of the north pole
										   in radians. */
	extern double cs_AnglTest;			/* 0.001 seconds of arc
										   in radians. */
	extern double cs_AnglTest1;			/* 1.0 - 0.001 seconds of
										   arc in radians.  Could
										   also be considered to
										   be the cosine of
										   cs_AnglTest. */

	int rtn_val;

	double lng;		/* The given longitude, after conversion
					   to radians. */
	double lat;		/* The given latitude after conversion
					   to radians. */
	double x = 0.0;			/* initialized to keep the gcc compiler happy */
	double y = 0.0;			/* initialized to keep the gcc compiler happy */

	double M;
	double N;
	double H;
	double H_sq;
	double H_sq_7;
	double GH;
	double rho;
	double psi;
	double del_lng;
	double sin_del_lng;
	double cos_del_lng;
	double sin_lat;
	double cos_lat;
	double cos_c;
	double c;
	double Az;
	double sin_Az;
	double cos_Az;
	double s;
	double s_sq;
	double s_third;
	double s_fourth;
	double s_fifth;
	double tmp1;
	double tmp2;
	double tmp3;
	double tmp4;

	rtn_val = cs_CNVRT_NRML;

	/* There are two formulae, one for the sphere and
	   one for the ellipsoid.  If the ecentricity
	   of the dataum in use is 0.0 exactly, we
	   shall use the spherical formulae.  There
	   is a miminal amount of stuff which is
	   common to both which we perform first. */

	lng = cs_Degree * ll [LNG];
	lat = cs_Degree * ll [LAT];

	if (fabs (lat) > cs_NPTest)
	{
		rtn_val = cs_CNVRT_INDF;
		if (fabs (lat) > cs_Pi_o_2)
		{
			rtn_val = cs_CNVRT_RNG;
			lat = CS_adj1pi (lat);
		}
	}

	del_lng = lng - azmed->org_lng;
	if      (del_lng > cs_Pi  && azmed->org_lng < 0.0) del_lng -= cs_Two_pi;
	else if (del_lng < cs_Mpi && azmed->org_lng > 0.0) del_lng += cs_Two_pi;
	if (del_lng > cs_Pi || del_lng <= cs_Mpi)
	{
		/* Note, the inverse can't distinguish between -180
		   and +180; therefore we return a range status for
		   -180. */

		rtn_val = cs_CNVRT_RNG;
		del_lng = CS_adj2pi (del_lng);
	}
	sin_del_lng = sin (del_lng);
	cos_del_lng = cos (del_lng);
	sin_lat = sin (lat);
	cos_lat = cos (lat);

	/* See if the datum is a sphere or an ellipsoid. */

	if (azmed->ecent == 0.0)
	{
		/* Here for the sphere. */

		switch (azmed->aspect) {

		case cs_AZMED_NORTH:

			tmp1 = (cs_Pi_o_2 - lat) * azmed->ka;
			x = tmp1 * sin_del_lng;
			y = -tmp1 * cos_del_lng;
			break;

		case cs_AZMED_SOUTH:

			tmp1 = (cs_Pi_o_2 + lat) * azmed->ka;
			x = tmp1 * sin_del_lng;
			y = tmp1 * cos_del_lng;
			break;

		case cs_AZMED_EQUATOR:

			cos_c = cos_lat * cos_del_lng;
			c = acos (cos_c);
			if (fabs (c) < cs_AnglTest)
			{
				/* At the origin. */
				tmp1 = cs_Zero;
			}
			else if (cos_c < -cs_AnglTest1)
			{
				/* AntiPodal */
				rtn_val = cs_CNVRT_RNG;
				tmp1 = azmed->ka * cs_Pi;
			}
			else
			{
				/* Normal */
				tmp1 = azmed->ka * c / sin (c);
			}

			x = tmp1 * cos_lat * sin_del_lng;
			y = tmp1 * sin_lat;
			break;

		case cs_AZMED_GUAM:

			x = azmed->ka * del_lng * cos_lat;
			tmp1 = x * x * tan (lat) / azmed->two_ka;
			y = azmed->ka * (lat - azmed->org_lat) + tmp1;
			break;

		case cs_AZMED_OBLIQUE:

			cos_c = azmed->sin_org_lat * sin_lat +
				azmed->cos_org_lat * cos_lat * cos_del_lng;
			c = acos (cos_c);

			/* C is the angular distance from the origin.  A
			   zero value indicates the orgin which would cause
			   a division by sin (0); but otherwise is a
			   perfectly normal value for this projection.

			   As c approaches PI, however, we approach the
			   point opposite the origin, and this point is
			   not well defined. */

			if (fabs (c) <= cs_AnglTest)
			{
				/* The origin. */
				tmp1 = cs_Zero;
			}
			else if (cos_c < -cs_AnglTest1)
			{
				/* Antipodal to the origin. */
				rtn_val = cs_CNVRT_RNG;
				tmp1 = azmed->ka * cs_Pi;
			}
			else
			{
				/* Normal, We can divide by sin (c). */
				tmp1 = azmed->ka * (c / sin (c));
			}

			x = tmp1 * cos_lat * sin_del_lng;
			y = tmp1 * (azmed->cos_org_lat * sin_lat -
				    azmed->sin_org_lat * cos_lat * cos_del_lng);
			break;
	
		default:

			CS_stncp (csErrnam,"CS_azmed:1",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}
	}
	else
	{
		switch (azmed->aspect) {

		case cs_AZMED_NORTH:

			M = CSmmFcal (&azmed->mmcofF,lat,sin_lat,cos_lat);
			rho = azmed->Mp - M;
			x =  rho * sin_del_lng;
			y = -rho * cos_del_lng;
			break;

		case cs_AZMED_SOUTH:

			M = CSmmFcal (&azmed->mmcofF,lat,sin_lat,cos_lat);
			rho = azmed->Mp + M;
			x = rho * sin_del_lng;
			y = rho * cos_del_lng;
			break;

		case cs_AZMED_GUAM:

			M = CSmmFcal (&azmed->mmcofF,lat,sin_lat,cos_lat);
			tmp1 = sqrt (azmed->e_sq * sin_lat * sin_lat);
			x = azmed->ka * del_lng * cos_lat / tmp1;
			tmp2 = tan (lat) * x * x * tmp1 / azmed->two_ka;
			y = M - azmed->M1 + tmp2;							  /*lint !e834 */
			break;

		case cs_AZMED_EQUATOR:
		case cs_AZMED_OBLIQUE:

			/* Compute Az, the azimuth of the point with respect
			   to the origin on the ellipsoid.

			   Psi is the latitude of the point, adjusted for
			   the ellipsoid.  This is zero or cs_Pi_o_2 if the
			   latitude is a pole (don't want to divide by
			   cos (lat) in this case. */

			if (fabs (lat) > cs_NPTest)
			{
				/* Point is a pole. */
				psi = (lat > 0.0) ? cs_Pi_o_2 : cs_Mpi_o_2;
			}
			else
			{
				/* Cosine (lat) will not be zero, we can
				   compute psi safely. */

				tmp1 = azmed->e_sq * sin_lat * sin_lat;
				N = azmed->ka / sqrt (cs_One - tmp1);
				tmp2 = (azmed->one_esq * tan (lat)) + azmed->psi_t1 /
							      (N * cos_lat);
				psi = atan (tmp2);
			}
			tmp3 = (azmed->cos_org_lat * tan (psi)) -
			       (azmed->sin_org_lat * cos_del_lng);

			/* Tmp3 and sin_del_lng will both be zero if the
			   point is the origin.  Most atan2's (not all) will
			   bomb if both args are zero. */

			if (fabs (sin_del_lng) > cs_AnglTest)
			{
				Az = atan2 (sin_del_lng,tmp3);
				sin_Az = sin (Az);
				cos_Az = cos (Az);
			}
			else
			{
				/* del_lng is zero, we do a quick and
				   dirty atan2. */

				sin_Az = cs_Zero;
				if (tmp3 >= 0.0)
				{
					Az = cs_Zero;
					cos_Az = cs_One;
				}
				else
				{
					Az = cs_Mpi;
					cos_Az = cs_Mone;
				}
			}

			/* Ok, we have the azimuth.  Need to compute the
			   angular distance to the point on the ellipsoid.
			   In the case of small angles, the sine and the
			   angle are equivalent. */

			if (fabs (sin_Az) < cs_AnglTest)
			{
				/* Here to avoid a divide by sin (Az). */

				tmp4 = azmed->cos_org_lat * sin (psi) -
				       azmed->sin_org_lat * cos (psi);
				s = asin (tmp4);
				if (cos_Az < 0.0)
				{
					s = -s;
				}
			}
			else
			{
				s = asin (sin_del_lng * cos (psi) / sin_Az);
			}

			/* S is essentially the angular distance over a
			   sphere. Convert to c, the linear distance over
			   the ellipsoid, via a power series calculation. */

			s_sq = s * s;
			s_third = s_sq * s;
			s_fourth = s_sq * s_sq;
			s_fifth = s_fourth * s;

			H = azmed->e_cos_p1 * cos_Az / azmed->rt_one_esq;
			H_sq = H * H;
			H_sq_7 = cs_Seven * H_sq;
			GH = azmed->G * H;

			tmp2 = H_sq * (cs_Four - H_sq_7);
			tmp2 -= azmed->G_sq_3 * (cs_One - H_sq_7);

			tmp1 = cs_One;
			tmp1 -= s_sq * H_sq * (cs_One - H_sq) / cs_Six;
			tmp1 += (s_third / cs_Eight) * GH * (cs_One - cs_Two * H_sq);
			tmp1 += (s_fourth / 120.0) * tmp2;
			tmp1 -= (s_fifth / 48.0) * GH;
			c = azmed->N1 * s * tmp1;

			x = c * sin_Az;
			y = c * cos_Az;
			break;

		default:
			CS_stncp (csErrnam,"CS_azmed:2",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}
	}

	/* Add the rotation, quad effect, and offset. */
	if (rtn_val >= 0)
	{
		xy [XX] = azmed->cos_Az * x - azmed->sin_Az * y;
		xy [YY] = azmed->cos_Az * y + azmed->sin_Az * x;
		if (azmed->quad == 0)
		{
			xy [XX] += azmed->x_off;
			xy [YY] += azmed->y_off;
		}
		else
		{
			CS_quadF (xy,xy [XX],xy [YY],azmed->x_off,azmed->y_off,
								azmed->quad);
		}
	}
	return (rtn_val);
}
Beispiel #18
0
int EXP_LVL7 CS_tmpfn (char *tmp_fnm)

{
	extern char cs_Dir [];
	extern char *cs_DirP;

	char cc_save;

	int count;

	char *cp;

	/* Establish the drive and the directory. */

	cc_save = *cs_DirP;
	*cs_DirP = '\0';
	cp = CS_stcpy (tmp_fnm,cs_Dir);
	*cs_DirP = cc_save;

	/* Add a file name. */

	cp = CS_stcpy (cp,"DEL_ME.$");

	/* Add an extension which will make this file unique in the
	   directory.  Hopefully, we will never need to iterate
	   more than once since tempoary files should always be
	   deleted after their use. */

	count = 0;
	strcpy (unique,"ZZ");
	do
	{
		count++;
		if (count >= 676)
		{
			CS_erpt (cs_TMPFN_MAXED);
			return (-1);
		}

		/* Bump the unique portion of the name by one, wrapping
		   arround if necessary. */

		if (unique [1] >= 'Z')
		{
			unique [1] = 'A';
			if (unique [0] >= 'Z')
			{
				unique [0] = 'A';
			}
			else unique [0]++;
		} else unique [1]++;

		/* Add the unique two character name generated above
		   to the result. */
		
		(void) CS_stcpy (cp,unique);

		/* We continue generating names until we find one
		   that doesn't exist.  In this case, access
		   does just what we need it to. */

	} while (CS_access (tmp_fnm,0) == 0);

	/* If we get here, we have made a unique name. */

	return (0);
}
Beispiel #19
0
int EXP_LVL7 CS_ips (csFILE *strm,short rs,long32_t eofPos,int (*comp)(Const void *pp,Const void *qq))
{
	int st;
	size_t rec_cnt;	/* Record count */
	size_t buf_siz;	/* Buffer size */
	size_t rd_cnt;	/* Read check. */
	size_t wr_cnt;	/* Write check. */

	long32_t beg;		/* File position of the beginning of
					   the portion of the file which we
					   are to sort but remains unsorted. */
	long32_t end;		/* File position of the end of the
					   portion of the file which we are
					   to sort but remains unsorted. */
	void *buff;		/* Pointer to malloc'ed sort buffer. */

	/* Prepare for a possible error. */
	buff = NULL;

	/* Establish the extrema of the sort.  We support
	   sorting only a portion of a file. */
	beg = CS_ftell (strm);
	if (beg < 0L)
	{
		CS_erpt (cs_IOERR);
		goto error;
	}
	if (eofPos <= 0L)
	{
		st = CS_fseek (strm,0L,SEEK_END);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
		end = CS_ftell (strm);
		if (end < 0L)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
		st = CS_fseek (strm,beg,SEEK_SET);
		if (st != 0)
		{
			CS_erpt (cs_IOERR);
			goto error;
		}
	}
	else
	{
		end = eofPos;
	}

	/* If there is nothing to sort, we done. */
	if (end <= beg)
	{
		return 0;
	}

	/* Set up our buffer area. */
	buf_siz = (size_t)(end - beg);
	buff = malloc (buf_siz);
	if (buff == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}

	/* Compute some basic parameters for the sort. */
	rec_cnt = buf_siz / (unsigned short)rs;

	/* Read in the entire file. */
	rd_cnt = CS_fread (buff,1,buf_siz,strm);
	if (rd_cnt != buf_siz)
	{
		if (ferror (strm)) CS_erpt (cs_IOERR);
		else               CS_erpt (cs_INV_FILE);
		goto error;
	}

	/* Sort it. */
	qsort (buff,rec_cnt,rs,(int (_cdecl *)(Const void *pp,Const void *qq))comp);								/*lint !e732 */

	/* Write it back out. */
	st = CS_fseek (strm,beg,SEEK_SET);
	if (st != 0)
	{
		CS_erpt (cs_IOERR);
		goto error;
	}
	wr_cnt = CS_fwrite (buff,1,buf_siz,strm);
	if (wr_cnt != buf_siz)
	{
		if (ferror (strm)) CS_erpt (cs_IOERR);
		else               CS_erpt (cs_DISK_FULL);
		goto error;
	}

	/* Clean up */
	CS_fseek (strm,beg,SEEK_SET);
	free (buff);
	return (1);

error:
	if (buff != NULL) free (buff);
	return (-1);
}
Beispiel #20
0
int EXP_LVL1 CS_cs2Wkt (char *bufr,size_t bufrSize,const char *csKeyName,int flavor)
{
	int rtnValue = -1;
	
	const char* flavoredCsNamePtr = 0;
	const char* flavoredDtNamePtr = 0;
	const char* flavoredElNamePtr = 0;
	const char* msiCsNamePtr      = 0;
	const char* msiDtNamePtr      = 0;
	const char* msiElNamePtr      = 0; 

	struct cs_Dtdef_ *dtDefPtr = 0;
	struct cs_Eldef_ *elDefPtr = 0;
	struct cs_Csdef_ *csDefPtr = 0;
	
	if (bufrSize > 0)
	{
		*bufr = '\0';
		csDefPtr = CS_csdef (csKeyName);
		if (csDefPtr != 0)
		{
			if (csDefPtr->dat_knm [0] == '\0')
			{
				CS_erpt (cs_WKT_NODTREF);
			}
			else
			{
				dtDefPtr = CS_dtdef (csDefPtr->dat_knm);
				if (dtDefPtr != 0)
				{
					elDefPtr = CS_eldef (dtDefPtr->ell_knm);
					if (elDefPtr != 0)
					{
						msiCsNamePtr = csDefPtr->key_nm;
						msiDtNamePtr = dtDefPtr->key_nm;
						msiElNamePtr = elDefPtr->key_nm;

						/* now flavor that name */
						if (flavor == wktFlvrEsri)
						{
							if (msiCsNamePtr != 0)						/*lint !e774 */
							{
								flavoredCsNamePtr = CS_msiName2Esri(msiCsNamePtr);
							}
							if (msiDtNamePtr != 0)						/*lint !e774 */
							{
								flavoredDtNamePtr = CS_msiDtmName2Esri(msiDtNamePtr, 0);
							}
							if (msiElNamePtr != 0)						/*lint !e774 */
							{
								flavoredElNamePtr = CS_msiElpName2Esri(msiElNamePtr);
							}
						}
						else if (flavor == wktFlvrOracle)
						{
							if (msiCsNamePtr != 0)						/*lint !e774 */
							{
								flavoredCsNamePtr=CS_msiName2Oracle(msiCsNamePtr);
							}
							if (msiDtNamePtr != 0)						/*lint !e774 */
							{
								flavoredDtNamePtr=CS_msiDtmName2Oracle(msiDtNamePtr, 0);
							}
							if (msiElNamePtr != 0)						/*lint !e774 */
							{
								flavoredElNamePtr=CS_msiElpName2Oracle(msiElNamePtr);
							}
						}
						if (flavoredCsNamePtr != 0)
						{
							CS_stncp (csDefPtr->key_nm,flavoredCsNamePtr,cs_KEYNM_MAX);
						}
						if (flavoredDtNamePtr != 0)
						{
							CS_stncp (csDefPtr->dat_knm,flavoredDtNamePtr,cs_KEYNM_MAX);
							CS_stncp (dtDefPtr->key_nm,flavoredDtNamePtr,cs_KEYNM_MAX);
						}
						if (flavoredElNamePtr != 0)
						{
							CS_stncp (dtDefPtr->ell_knm,flavoredElNamePtr,cs_KEYNM_MAX);
							CS_stncp (elDefPtr->key_nm,flavoredElNamePtr,cs_KEYNM_MAX);
						}

						rtnValue = CScs2Wkt (bufr,bufrSize,flavor,csDefPtr,dtDefPtr,elDefPtr);	/*lint !e64 */
						CS_free (elDefPtr);
						elDefPtr = 0;
					}
					CS_free (dtDefPtr);
					dtDefPtr = 0;
				}
			}
			CS_free (csDefPtr);
			csDefPtr = 0;
		}
	}
	return rtnValue;
}
Beispiel #21
0
/******************************************************************************
	Constructor  (for an 'Entry' sub object)
*/
struct csVertconUSEntry_* CSnewVertconUSEntry (struct csDatumCatalogEntry_* catPtr)
{
	extern char cs_DirsepC;
	extern char cs_ExtsepC;
	extern char csErrnam [];

	char *cp;
	struct csVertconUSEntry_* __This;

	/* Prepare for an error. */
	__This = NULL;

	/* Allocate some storage. */
	__This = (struct csVertconUSEntry_*) CS_malc (sizeof (struct csVertconUSEntry_));
	if (__This == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}
	__This->next = NULL;
	__This->usGridPtr = NULL;

	/* Isolate the file name from the path, and the extension from the file name. */
	cp = strrchr (catPtr->pathName,cs_DirsepC);
	if (cp == NULL)
	{
		/* Is not supposed to happen, but we can't allow a bomb. */
		CS_stncp (csErrnam,catPtr->pathName,MAXPATH);
		CS_erpt (cs_DTC_PATH);
		goto error;
	}

	/* Isolate the extension on the file. */
	cp = strrchr (catPtr->pathName,cs_ExtsepC);
	if (cp == NULL)
	{
		/* Is not supposed to happen. */
		CS_stncp (csErrnam,catPtr->pathName,MAXPATH);
		CS_erpt (cs_NAD_EXT);
		goto error;
	}
	cp += 1;

	/* Report special errors concerning the extensions.  Again, specific
	   error messages will reduce frustration. */
	if (CS_stricmp (cp,"94"))
	{
		CS_erpt (cs_VCON_94);
		goto error;
	}
	/* Do what's appropriate for this extension. */
	if (!CS_stricmp (cp,"94"))
	{
		__This->usGridPtr = CSnewGridFileUS (catPtr->pathName,catPtr->bufferSize,catPtr->flags,catPtr->density);
		if (__This->usGridPtr == NULL)
		{
			goto error;
		}
	}
	/* When we know how to do the others, we add that stuff here. */
	else
	{
		CS_erpt (cs_VCON_EXT);
		goto error;
	}
	return __This;
error:
	CSdeleteVertconUSEntry (__This);
	return NULL;
}
Beispiel #22
0
struct cs_Dtcprm_ * EXP_LVL9 CSbdclu (	Const struct cs_Csprm_ *src_cs,
										Const struct cs_Csprm_ *dst_cs,
										int dat_err,
										int blk_err)
{
	extern csThread struct csDtcach_ *csDtcachP;
	extern csThread int csDtcachI;

	unsigned short srcPrjCode;
	unsigned short dstPrjCode;
	int ii;
	

	struct cs_Dtcprm_ *dtc_ptr;
	struct csDtcach_ *ch_ptr;
	struct csDtcach_ *tmp_ptr;
	struct csDtcach_ *last_chp;

	/* Make sure we're not converting between non-georeferenced and georeferenced. */
	srcPrjCode = src_cs->prj_code;
	dstPrjCode = dst_cs->prj_code;

	if (srcPrjCode == cs_PRJCOD_NRTHSRT) srcPrjCode = cs_PRJCOD_NERTH;
	if (dstPrjCode == cs_PRJCOD_NRTHSRT) dstPrjCode = cs_PRJCOD_NERTH;
	
	if ((srcPrjCode == cs_PRJCOD_NERTH) ^ (dstPrjCode == cs_PRJCOD_NERTH))	/*lint !e514 */
	{
		CS_erpt (cs_NOT_NERTH);
		goto error;
	}

	/* If we have not done so already, allocate the cache now. */
	if (csDtcachP == NULL)
	{
		if (csDtcachI <= 1) csDtcachI = 2;
		last_chp = NULL;
		for (ii = 0;ii < csDtcachI;ii++)
		{
			ch_ptr = (struct csDtcach_ *)CS_malc (sizeof (struct csDtcach_));
			if (ch_ptr == NULL)
			{
				CS_erpt (cs_NO_MEM);
				ch_ptr = csDtcachP;
				while (ch_ptr != NULL)
				{
					tmp_ptr = ch_ptr->next;
					CS_free (ch_ptr);
					ch_ptr = tmp_ptr;
				}
				csDtcachP = NULL;
				goto error;
			}
			if (ii == 0)
			{
				csDtcachP = ch_ptr;
			}
			else
			{
				last_chp->next = ch_ptr;				/*lint !e613 */
			}
			ch_ptr->prev = last_chp;
			ch_ptr->next = NULL;
			ch_ptr->dtc_ptr = NULL;
			last_chp = ch_ptr;
		}
	}

	/* Search the existing cache entries for the desired
	   datum combination.  While doing so, we maintain
	   last_chp as a pointer to the last cache entry
	   examined.  We will use this to add a new entry to
	   the cache if we don't find the one we are looking for. */

	dtc_ptr = NULL;
	ch_ptr = csDtcachP;
	last_chp = NULL;
	while (ch_ptr != NULL)
	{
		if (ch_ptr->dtc_ptr == NULL) break;
		if (!CS_stricmp (ch_ptr->dtc_ptr->srcKeyName,src_cs->csdef.dat_knm) &&
		    !CS_stricmp (ch_ptr->dtc_ptr->trgKeyName,dst_cs->csdef.dat_knm))
		{
			dtc_ptr = ch_ptr->dtc_ptr;
			break;
		}
		last_chp = ch_ptr;
		ch_ptr = ch_ptr->next;
	}

	if (dtc_ptr == NULL)
	{
		/* Didn't find one. */
		if (ch_ptr != NULL)
		{
			/* ch_ptr is pointing to an unused entry. */
			dtc_ptr = CS_dtcsu (src_cs,dst_cs,dat_err,blk_err);
			if (dtc_ptr == NULL) goto error;
			ch_ptr->dtc_ptr = dtc_ptr;
		}
		else
		{
			/* All entries in the cache are used. Last_chp
			   points to the last entry in the cache, which is
			   also the least recently used entry. */
			ch_ptr = last_chp;
			CS_dtcls (ch_ptr->dtc_ptr);
			dtc_ptr = ch_ptr->dtc_ptr = CS_dtcsu (src_cs,dst_cs,dat_err,blk_err);
			if (dtc_ptr == NULL) goto error;
		}
	}
	else
	{
		dtc_ptr->block_err = (short)blk_err;
	}

	if (ch_ptr != csDtcachP)
	{
		/* Push this cache entry to the top of the list. */
		ch_ptr->prev->next = ch_ptr->next;			/*lint !e613 */
		if (ch_ptr->next != NULL)					/*lint !e613 */
		{
			ch_ptr->next->prev = ch_ptr->prev;		/*lint !e613 */
		}
		ch_ptr->prev = NULL;						/*lint !e613 */
		ch_ptr->next = csDtcachP;					/*lint !e613 */
		csDtcachP->prev = ch_ptr;
		csDtcachP = ch_ptr;
	}
	return (dtc_ptr);

error:
	return (NULL);
}
Beispiel #23
0
int EXP_LVL3 CScs2WktEx (char *csWktBufr,size_t bufrSize,enum ErcWktFlavor flavor,const struct cs_Csdef_ *cs_def,const struct cs_Dtdef_ *dt_def,const struct cs_Eldef_ *el_def,unsigned short flags)
{
	extern double cs_One;
	extern double cs_K90;
	extern double cs_Degree;
	extern char csErrnam [];
	extern struct cs_Prjtab_ cs_Prjtab [];

	int status;
	short prjCode;

	double tmpDbl;
	double primeMer;
	double unitFactor;

	const char *kCp;
	const char *prjNmPtr;

	const char *prmNmFalseEasting;
	const char *prmNmFalseNorthing;
	const char *prmNmScaleFactor;
	const char *prmNmCentralMeridian;
	const char *prmNmLatitudeOfOrigin;
	const char *prmNmStandardParallel1;
	const char *prmNmStandardParallel2;
	const char *prmNmYAxisAzimuth;
	const char *prmNmAzimuth;
	const char *prmNmLongitudeOfCenter;
	const char *prmNmLatitudeOfCenter;
	const char *prmNmLongitudeOf1stPoint;
	const char *prmNmLatitudeOf1stPoint;
	const char *prmNmLongitudeOf2ndPoint;
	const char *prmNmLatitudeOf2ndPoint;
	const char *prmNmLatitudeOfStdParall;

	struct cs_Dtdef_ *dtDefPtr;
	struct cs_Prjtab_ *prjPtr;

	char refDtmName [24];
	char baseName [24];
	char cTemp [64];

	char datmWkt [512];
	char pmerWkt [512];
	char geogWkt [512];
	char parmWkt [512];
	char unitWkt [128];
	char projWkt [1024];
	char geoAxis [1024];
	char prjAxis [1024];
	char geoTranWkt [1024];
	char projection [64];
	char gcsName [128];
	char dtmName [128];
	char csysWktName [96];
	
	status = 0;
	refDtmName [0] = '\0';
	dtDefPtr = 0;

	if (cs_def == 0)
	{
		CS_stncp (csErrnam,"CS_cs2Wkt:1",MAXPATH);
		CS_erpt (cs_ISER);
		goto error;
	}

	/* Make sure we have a datum pointer. */
	if (dt_def == NULL)
	{
		/* The calling application did not provide a specific datum definition.
		   We use the datum name in the Coordinate System definition to obtain
		   a definition fomr the dictionary. */
		if (cs_def->dat_knm [0] == '\0')
		{
			/* Oops!!! No datum definition in the coordinate system definition.
			   If we were to output something special for a cartographic definition,
			   i.e. a coordinate system referenced directly to an ellipsoid, we
			   would do that here. */
			CS_erpt (cs_NO_REFERNCE);
			goto error;
		}
		
		/* We need to free this definition, we stash it in a new pointer variable. */
		dtDefPtr = CS_dtdef (cs_def->dat_knm);
		if (dtDefPtr == NULL)
		{
			/* If the coordinate system definition came from the dictionary,
			   this shouldn't happen.  If the application got the cs_Csdef_
			   data from somewhere else, it is possible. */
			CS_erpt (cs_NO_REFERNCE);
			goto error;
		}
		dt_def = dtDefPtr;
	}
	
	if (el_def != 0)
	{
		if (CS_stricmp (dt_def->ell_knm,el_def->key_nm))
		{
			CS_erpt (cs_WKT_INCNSIST);
			goto error;
		}
	}

	/* Locate the projection in the projection table.  We need this for access
	   to the flag word for this projection. */
	for (prjPtr = cs_Prjtab;prjPtr->code != cs_PRJCOD_END;prjPtr += 1)
	{
		if (!strcmp (cs_def->prj_knm,prjPtr->key_nm)) break;
	}
	if (prjPtr->code == cs_PRJCOD_END)
	{
		CS_erpt (cs_UNKWN_PROJ);
		goto error;
	}
	prjCode = prjPtr->code;

	prjNmPtr = 0;
	if (prjCode == cs_PRJCOD_SWISS && (flavor == wktFlvrEsri || flavor == wktFlvrOracle))
	{
		prjNmPtr = CSwktPrjCode2Name (cs_PRJCOD_RSKEW,flavor);
	}
	else if (prjCode == cs_PRJCOD_LMTAN)
	{
		prjNmPtr = CSwktPrjCode2Name (cs_PRJCOD_LM1SP,flavor);
	}
	else if (prjPtr->code == cs_PRJCOD_UNITY)
	{
		prjNmPtr = "LL";
	}
	else
	{
		prjNmPtr = CSwktPrjCode2Name (prjCode,flavor);
	}
	if (prjNmPtr == 0 || *prjNmPtr == '\0')
	{
		/* This projection is not supported by this flavor of WKT. */
		CS_stncp (csErrnam,prjPtr->descr,MAXPATH);
		CS_erpt (cs_WKT_PRJSUPRT);
		goto error;
	}

	/* Locate the datum definition, if there is one.  We can't do anything
	   that isn't referenced to a datum. */
	if (dt_def == NULL)										/*lint !e774 */
	{
		/* The calling application did not provide a specific deatum definition.
		   We use the datum name in the Coordinate System definition to obtain
		   a definition fomr the dictionary. */
		if (cs_def->dat_knm [0] == '\0')
		{
			/* Oops!!! No datum definition in the coordinate system definition.
			   If we were to output something special for a cartographic definition,
			   i.e. a coordinate system referenced directly to an ellipsoid, we
			   would do that here. */
			CS_erpt (cs_NO_REFERNCE);	
			goto error;
		}
		dtDefPtr = CS_dtdef (cs_def->dat_knm);
		if (dtDefPtr == NULL)
		{
			/* If the coordinate system definition came from the dictionary,
			   this shouldn't happen.  If the application got the cs_Csdef_
			   data from somewhere else, it is possible. */
			CS_erpt (cs_NO_REFERNCE);
			goto error;
		}
		/* Capture the name of referenced datum which we will be using. */
		CS_stncp (refDtmName,cs_def->dat_knm,sizeof (refDtmName));
		
		/* I don't have to locate the ellipsoid, CSdt2WktEx will do that. */
		status = CSdt2WktEx (datmWkt,sizeof (datmWkt),geoTranWkt,sizeof (geoTranWkt),flavor,dtDefPtr,0,flags);
		CS_free (dtDefPtr);
		dtDefPtr = 0;
	}
	else
	{
		CS_stncp (refDtmName,dt_def->key_nm,sizeof (refDtmName));
		status = CSdt2WktEx (datmWkt,sizeof (datmWkt),geoTranWkt,sizeof (geoTranWkt),flavor,dt_def,el_def,flags);
	}
	if (status != 0)
	{
		/* CSdt2WktEx will have reported the nature of the error. */
		goto error;
	}

	/* Deal with the quad/axis situation. */
	geoAxis [0] = '\0';
	prjAxis [0] = '\0';
	if (cs_def->quad != 0 && cs_def->quad != 1)
	{
		if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0)
		{
			switch (cs_def->quad) {
			default:
			case 0:
			case 1:
				CS_stncp (geoAxis,",AXIS[\"Lon\",EAST],AXIS[\"Lat\",NORTH]",sizeof (prjAxis));
				break;
			case 2:
				CS_stncp (geoAxis,",AXIS[\"Lon\",WEST],AXIS[\"Lat\",NORTH]",sizeof (prjAxis));
				break;
			case 3:
				CS_stncp (geoAxis,",AXIS[\"Lon\",WEST],AXIS[\"Lat\",SOUTH]",sizeof (prjAxis));
				break;
			case 4:
				CS_stncp (geoAxis,",AXIS[\"Lon\",EAST],AXIS[\"Lat\",SOUTH]",sizeof (prjAxis));
				break;
			case -1:
				CS_stncp (geoAxis,",AXIS[\"Lat\",NORTH],AXIS[\"Lon\",EAST]",sizeof (prjAxis));
				break;
			case -2:
				CS_stncp (geoAxis,",AXIS[\"Lat\",NORTH],AXIS[\"Lon\",WEST]",sizeof (prjAxis));
				break;
			case -3:
				CS_stncp (geoAxis,",AXIS[\"Lat\",SOUTH],AXIS[\"Lon\",WEST]",sizeof (prjAxis));
				break;
			case -4:
				CS_stncp (geoAxis,",AXIS[\"Lat\",SOUTH],AXIS[\"Lon\",EAST]",sizeof (prjAxis));
				break;
			}
		}
		else
		{
			switch (cs_def->quad) {
			default:
			case 0:
			case 1:
				CS_stncp (prjAxis,",AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]",sizeof (prjAxis));
				break;
			case 2:
				CS_stncp (prjAxis,",AXIS[\"X\",WEST],AXIS[\"Y\",NORTH]",sizeof (prjAxis));
				break;
			case 3:
				CS_stncp (prjAxis,",AXIS[\"X\",WEST],AXIS[\"Y\",SOUTH]",sizeof (prjAxis));
				break;
			case 4:
				CS_stncp (prjAxis,",AXIS[\"X\",EAST],AXIS[\"Y\",SOUTH]",sizeof (prjAxis));
				break;
			case -1:
				CS_stncp (prjAxis,",AXIS[\"Y\",NORTH],AXIS[\"X\",EAST]",sizeof (prjAxis));
				break;
			case -2:
				CS_stncp (prjAxis,",AXIS[\"Y\",NORTH],AXIS[\"X\",WEST]",sizeof (prjAxis));
				break;
			case -3:
				CS_stncp (prjAxis,",AXIS[\"Y\",SOUTH],AXIS[\"X\",WEST]",sizeof (prjAxis));
				break;
			case -4:
				CS_stncp (prjAxis,",AXIS[\"Y\",SOUTH],AXIS[\"X\",EAST]",sizeof (prjAxis));
				break;
			}
		}
	}

	/* Locate the base.  The base is what this coordinate system is referenced
	   to.  For example, the definition of UTM27-13 defines how to get from
	   LL27 to UTM27-13.  Therefore, LL27 is the base for that coordinate
	   system. */
	if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0)
	{
		/* This is a geographic coordinate system, so the base name is whatever
		   the coordinate system name is. */
		CS_stncp (baseName,cs_def->key_nm,sizeof (baseName));
	}
	else
	{
		/* Otherwise, basename is the name of a geographic coordinate system
		   referenced to the same datum as the projected coordinate system.
		   We have a function which will find this for us.  If we don't
		   have one, we are in trouble. */
		CSllCsFromDt (baseName,sizeof baseName,refDtmName);
		if (!CS_csIsValid (baseName))
		{
			CS_stncp (csErrnam,cs_def->key_nm,MAXPATH);
			CS_erpt (cs_WKT_NOLLBASE);
			return -1;
		}
	}

	/* Manufacture the prime meridian. */
	CS_stncp (pmerWkt,"PRIMEM[\"Greenwich\",0]",sizeof (pmerWkt));
	if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0 && cs_def->org_lng != 0.0)
	{
		int orgLng = (int)cs_def->org_lng;
		switch (orgLng) {
		case 0:
			primeMer = 0.0;
			CS_stncp (pmerWkt,"PRIMEM[\"Greenwich\",0]",sizeof (pmerWkt));
			break;
		case 2:
			primeMer = 2.337229166666667;
			CS_stncp (pmerWkt,"PRIMEM[\"Paris\",2.337229166666667]",sizeof (pmerWkt));
			break;
		case 9:
			primeMer = 9.13190611111111;
			CS_stncp (pmerWkt,"PRIMEM[\"Lisbon\",9.13190611111111]",sizeof (pmerWkt));
			break;
		case -17:
			primeMer = -17.4;
			CS_stncp (pmerWkt,"PRIMEM[\"Ferro\",-17.4]",sizeof (pmerWkt));
			break;
		case -74:
			primeMer = -74.08175;
			CS_stncp (pmerWkt,"PRIMEM[\"Bogota\",-74.08175]",sizeof (pmerWkt));
			break;
		default:
			break;
		}
	}

	/* We will always need the GEOGCS object.  If this is a geographic
	   coordinate system definition, than that's all we'll need.  If this is
	   a Projective coordinate system, the unit is the default for internal
	   coordinates within CS-MAP, namely the degree.  Only if this is a 
	   Geographic Coordinate system, is the actual unit of the definition
	   of importance to us here. */

   	kCp = CSmsiUnitName2WktName ("DEGREE",flavor);
   	if (kCp == 0 || *kCp == '\0')
   	{
		kCp = "Degree";
	}
	sprintf (unitWkt,"UNIT[\"%s\",0.017453292519943295]",kCp);
	if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0)
	{
		/* This is a geographic coordinate system, extract the unit information
		   from the definition. */
	   	kCp = CSmsiUnitName2WktName (cs_def->unit,flavor);
	   	if (kCp == 0)
	   	{
	   		/* Just in case the flavor does not define angular units... */
	   		kCp = "Degree";
			unitFactor = cs_Degree;
	   	}
	   	else
	   	{
			unitFactor = CS_unitlu (cs_UTYP_ANG,cs_def->unit) * cs_Degree;
		}
		sprintf (unitWkt,"UNIT[\"%s\",%.14f]",kCp,unitFactor);
	}
	
	/* If we are mapping names, the GCS name and the Datum name need to be
	   mapped, and then configured for the active flavor.
	   
	   First, we do the default in case anything goes wrong in the mapping
	   process. */
	sprintf (geogWkt,"GEOGCS[\"%s\",%s,%s,%s%s]",baseName,datmWkt,pmerWkt,unitWkt,geoAxis);
	if ((flags & cs_WKTFLG_MAPNAMES) != 0)
	{
		CS_stncp (dtmName,baseName,sizeof (dtmName));
		CS_stncp (gcsName,baseName,sizeof (gcsName));
		if (flavor == wktFlvrEsri)
		{
			kCp = CS_msiDtmName2Esri (dt_def->key_nm,0);
			if (kCp != 0)
			{
				if (*kCp != 'D' || *(kCp + 1) != '_')
				{
					CS_stcpy (dtmName,"D_");
					CS_stncp (&dtmName [2],kCp,sizeof (dtmName) - 2);

					CS_stcpy (gcsName,"GCS_");
					CS_stncp (&gcsName [4],kCp,sizeof (gcsName) - 4);
				}
				else
				{
					CS_stncp (dtmName,kCp,sizeof (dtmName));
					CS_stcpy (gcsName,"GCS_");
					CS_stncp (&gcsName [4],kCp+2,sizeof (gcsName) - 4);
				}
			}
		}
		else if (flavor == wktFlvrOracle)
		{
			kCp = CS_msiDtmName2Oracle (dt_def->key_nm,0);
			if (kCp != 0)
			{
				CS_stncp (dtmName,kCp,sizeof (dtmName));
				if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0)
				{
					sprintf (gcsName,"Longitude / Latitude (%s)",kCp);
				}
				else
				{
					CS_stncp (gcsName,kCp,sizeof (gcsName));
				}
			}
		}
		sprintf (geogWkt,"GEOGCS[\"%s\",%s,%s,%s%s]",gcsName,datmWkt,pmerWkt,unitWkt,geoAxis);
	}

	if ((prjPtr->flags & cs_PRJFLG_GEOGR) != 0)
	{
		/* If this is a geographic coordinate system, we're done. */
		CS_stncp (csWktBufr,geogWkt,(int)bufrSize);
	}
	else
	{
		/* We get here only if the coordinate system is of the projected type. */

		/* Do the linear unit for the projWkt. */
		unitFactor = CS_unitlu (cs_UTYP_LEN,cs_def->unit);
		kCp = CSmsiUnitName2WktName (cs_def->unit,flavor);
		if (kCp == 0 || *kCp == '\0')
		{
			CS_stncp (csErrnam,cs_def->unit,MAXPATH);
			CS_erpt (cs_WKT_UNITMAP);
			return -1;
		}
		sprintf (unitWkt,"UNIT[\"%s\",%.14f]",kCp,unitFactor);

		prmNmFalseEasting        = CSwktPrmEnum2Name (csWktPrmFalseEasting,flavor);
		prmNmFalseNorthing       = CSwktPrmEnum2Name (csWktPrmFalseNorthing,flavor);
		prmNmScaleFactor         = CSwktPrmEnum2Name (csWktPrmScaleAtCenter,flavor);
		prmNmCentralMeridian     = CSwktPrmEnum2Name (csWktPrmLongitudeOfOrg,flavor);
		prmNmLatitudeOfOrigin    = CSwktPrmEnum2Name (csWktPrmLatitudeOfOrg,flavor);
		prmNmStandardParallel1   = CSwktPrmEnum2Name (csWktPrmStdParallel1,flavor);
		prmNmStandardParallel2   = CSwktPrmEnum2Name (csWktPrmStdParallel2,flavor);
		prmNmYAxisAzimuth        = CSwktPrmEnum2Name (csWktPrmYaxisAzimuth,flavor);
		prmNmAzimuth             = CSwktPrmEnum2Name (csWktPrmAzimuth,flavor);
		prmNmLongitudeOfCenter   = CSwktPrmEnum2Name (csWktPrmLongitudeOfCtr,flavor);
		prmNmLatitudeOfCenter    = CSwktPrmEnum2Name (csWktPrmLatitudeOfCtr,flavor);
		prmNmLongitudeOf1stPoint = CSwktPrmEnum2Name (csWktPrmLngFirstPoint,flavor);
		prmNmLatitudeOf1stPoint  = CSwktPrmEnum2Name (csWktPrmLatFirstPoint,flavor);
		prmNmLongitudeOf2ndPoint = CSwktPrmEnum2Name (csWktPrmLngSecondPoint,flavor);
		prmNmLatitudeOf2ndPoint  = CSwktPrmEnum2Name (csWktPrmLatSecondPoint,flavor);
		prmNmLatitudeOfStdParall = CSwktPrmEnum2Name (csWktPrmLatOfStdParall,flavor);

		/* Build the projection and parameter portions of this thing. */ 
		parmWkt [0] = '\0';
		CS_stcpy (projection,prjNmPtr);
		switch (prjCode) {
		case  cs_PRJCOD_TRMER:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_ALBER:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel2,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_MRCAT:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_AZMED:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmYAxisAzimuth,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_PLYCN:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_AZMEA:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmYAxisAzimuth,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_EDCNC:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel2,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_MILLR:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_NZLND:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_SINUS:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_EDCYL:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_VDGRN:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_CSINI:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_ROBIN:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_BONNE:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_EKRT4:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_EKRT6:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_MOLWD:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_PSTRO:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_PSTROSL:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			
			/* Kludge time again.  If the flavor is ESRI, we change the rpojection name based
			   on the origin latitude.  Sorry about that, but this WKT stuff is maddening. */
			if (flavor == wktFlvrEsri)
			{
				if (cs_def->org_lat < -89.0)
				{
					CS_stncp (projection,"Stereographic_South_Pole",sizeof (projection));
				}
				else if (cs_def->org_lat < -89.0)
				{
					CS_stncp (projection,"Stereographic_North_Pole",sizeof (projection));
				}
			}
			break;
		case  cs_PRJCOD_OSTRO:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_LM1SP:
		case  cs_PRJCOD_LMTAN:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_LM2SP:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel1,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmStandardParallel2,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_UTM:
			tmpDbl = 500000.00 / unitFactor;
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,tmpDbl);
			strcat (parmWkt,cTemp);
			tmpDbl = (cs_def->prj_prm2 >= 0.0) ? 0.0 : 10000000.0;
			tmpDbl /= unitFactor;
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,tmpDbl);
			strcat (parmWkt,cTemp);
			tmpDbl = (double)(-183 + (6 * (int)cs_def->prj_prm1)); 				/*lint !e790 */
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,tmpDbl);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",0.9996]",prmNmScaleFactor);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",0.000]",prmNmLatitudeOfOrigin);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_TRMRS:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_HOM1XY:
		case  cs_PRJCOD_RSKEW:
		case  cs_PRJCOD_RSKEWC:
		case  cs_PRJCOD_RSKEWO:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmAzimuth,cs_def->prj_prm3);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLongitudeOfCenter,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfCenter,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_HOM2XY:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLongitudeOf1stPoint,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOf1stPoint,cs_def->prj_prm2);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLongitudeOf2ndPoint,cs_def->prj_prm3);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOf2ndPoint,cs_def->prj_prm4);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfCenter,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_GAUSSK:
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_def->scl_red);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmCentralMeridian,cs_def->prj_prm1);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfOrigin,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		case  cs_PRJCOD_SWISS:
			CS_stncp (projection,prjNmPtr,sizeof (projection));
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseEasting,cs_def->x_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.3f]",prmNmFalseNorthing,cs_def->y_off);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.12f]",prmNmScaleFactor,cs_One);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmAzimuth,cs_K90);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLongitudeOfCenter,cs_def->org_lng);
			strcat (parmWkt,cTemp);
			sprintf (cTemp,",PARAMETER[\"%s\",%.14f]",prmNmLatitudeOfCenter,cs_def->org_lat);
			strcat (parmWkt,cTemp);
			break;
		}												/*lint !e744 */

		/* Need to determine the name we will assign to this definition.  We
		generate a default value which is used if anything else fails. */
		CS_stncp (csysWktName,cs_def->key_nm,sizeof (csysWktName));
		if ((flags & cs_WKTFLG_MAPNAMES) != 0)
		{
			if (flavor == wktFlvrEsri)
			{
				kCp = CS_msiName2Esri (cs_def->key_nm);
				if (kCp != 0)
				{
					CS_stncp (csysWktName,kCp,sizeof (csysWktName));
				}
			}
			else if (flavor == wktFlvrOracle)
			{
				kCp = CS_msiName2Oracle (cs_def->key_nm);
				if (kCp != 0)
				{
					CS_stncp (csysWktName,kCp,sizeof (csysWktName));
				}
			}
		}

		/* Construct the final string. */
		sprintf (projWkt,"PROJCS[\"%s\",%s,PROJECTION[\"%s\"]%s,%s%s]",csysWktName,geogWkt,projection,parmWkt,unitWkt,prjAxis);
		CS_stncp (csWktBufr,projWkt,(int)bufrSize);
	}
	if (dtDefPtr != 0)
	{
		CS_free (dtDefPtr);
	}
	return 0;
error:
	if (dtDefPtr != 0)
	{
		CS_free (dtDefPtr);
	}
	return -1;
}
Beispiel #24
0
struct cs_Csprm_ * EXP_LVL9 CSbcclu (Const char *cs_name)
{
	extern csThread struct csCscach_ *csCscachP;
	extern csThread int csCscachI;

	cs_Register struct csCscach_ *ch_ptr;

	int ii;

	struct csCscach_ *tmp_ptr;
	struct csCscach_ *last_chp;
	struct cs_Csprm_ *cs_ptr;

	char kyTemp [cs_KEYNM_DEF + 2];

	CS_stncp (kyTemp,cs_name,sizeof (kyTemp));
	if (CS_nampp (kyTemp) != 0) return ((struct cs_Csprm_ *)0);

	if (csCscachP == NULL)
	{
		/* Here to allocate the cache. */

		if (csCscachI <= 1) csCscachI = 2;
		last_chp = NULL;
		for (ii = 0;ii < csCscachI;ii++)
		{
			ch_ptr = (struct csCscach_ *)CS_malc (sizeof (struct csCscach_));
			if (ch_ptr == NULL)
			{
				CS_erpt (cs_NO_MEM);
				ch_ptr = csCscachP;
				while (ch_ptr != NULL)
				{
					tmp_ptr = ch_ptr->next;
					CS_free (ch_ptr);
					ch_ptr = tmp_ptr;
				}
				csCscachP = NULL;
				goto error;
			}
			if (ii == 0)
			{
				csCscachP = ch_ptr;
			}
			else
			{
				last_chp->next = ch_ptr;		/*lint !e613 */
			}
			ch_ptr->prev = last_chp;
			ch_ptr->next = NULL;
			ch_ptr->cs_ptr = NULL;
			ch_ptr->cs_nam [0] = '\0';
			last_chp = ch_ptr;
		}
	}

	/* At this point, we have a cache.  It may be empty, but
	   it exists and has more than one entry. */

	cs_ptr = NULL;
	ch_ptr = csCscachP;
	last_chp = NULL;
	while (ch_ptr != NULL)
	{
		if (ch_ptr->cs_ptr == NULL) break;
		if (!CS_stricmp (ch_ptr->cs_nam,kyTemp))
		{
			cs_ptr = ch_ptr->cs_ptr;
			break;
		}

		last_chp = ch_ptr;
		ch_ptr = ch_ptr->next;
	}

	/* If cs_ptr is NULL, we havn't found the one we are looking
	   for.  We must add it to the cache. */

	if (cs_ptr == NULL)
	{
		/* If ch_ptr is not NULL, it must point to the
		   first element in the linked list which is
		   unused.  We simply use this entry. */

		if (ch_ptr != NULL)
		{
			ch_ptr->cs_ptr = CS_csloc (kyTemp);
			if (ch_ptr->cs_ptr == NULL)
			{
				goto error;
			}
			(void)CS_stncp (ch_ptr->cs_nam,kyTemp,sizeof (ch_ptr->cs_nam));
			cs_ptr = ch_ptr->cs_ptr;
		}
		else
		{
			/* We need to reuse an existing entry.  We always
			   reuse that the last entry in the linked list
			   as it should be the least recently accessed
			   entry in the list. */

			ch_ptr = last_chp;
			CS_free (ch_ptr->cs_ptr);
			ch_ptr->cs_nam [0] = '\0';
			ch_ptr->cs_ptr = CS_csloc (kyTemp);
			(void)CS_stncp (ch_ptr->cs_nam,kyTemp,sizeof (ch_ptr->cs_nam));
			cs_ptr = ch_ptr->cs_ptr;
		}
	}

	/* OK, we should now have a coordinate system pointer.  All we
	   need to do is make this one first on the list as an indication
	   that it was the most recently accessed.  Of course, if it
	   is already the first on the list, we do not need to do
	   anything.  The following code assumes that the entry being
	   processed is not the first on the list (i.e. ch_ptr->prev
	   is not NULL). */

	if (ch_ptr != csCscachP)
	{
		/* Remove the current entry from the list. */

		ch_ptr->prev->next = ch_ptr->next;				/*lint !e613 */
		if (ch_ptr->next != NULL)						/*lint !e613 */
		{
			ch_ptr->next->prev = ch_ptr->prev;			/*lint !e613 */
		}

		/* Now we insert it at the top of the list. */

		ch_ptr->prev = NULL;							/*lint !e613 */
		ch_ptr->next = csCscachP;						/*lint !e613 */
		csCscachP->prev = ch_ptr;
		csCscachP = ch_ptr;
	}

	/* Return a pointer to the located coordinate system. */

	return (cs_ptr);

error:
	return ((struct cs_Csprm_ *)0);
}
Beispiel #25
0
int EXP_LVL9 CSparm7S (struct cs_GxXform_* gxXfrm)
{
	extern double cs_One;
	extern double cs_Sec2Rad;			/* 4.848136E-06 */

	struct csParm7_ *parm7;

	double trgScale;
	double sinAlpha, cosAlpha;
	double sinBeta, cosBeta;
	double sinGamma, cosGamma;

	parm7 = &gxXfrm->xforms.parm7;

	parm7->srcERad = gxXfrm->srcDatum.e_rad;
	parm7->srcESqr = gxXfrm->srcDatum.ecent * gxXfrm->srcDatum.ecent;

	parm7->trgERad = gxXfrm->trgDatum.e_rad;
	parm7->trgESqr = gxXfrm->trgDatum.ecent * gxXfrm->trgDatum.ecent;

	parm7->deltaX = gxXfrm->gxDef.parameters.geocentricParameters.deltaX;
	parm7->deltaY = gxXfrm->gxDef.parameters.geocentricParameters.deltaY;
	parm7->deltaZ = gxXfrm->gxDef.parameters.geocentricParameters.deltaZ;

	sinAlpha = sin (gxXfrm->gxDef.parameters.geocentricParameters.rotateX * cs_Sec2Rad);
	cosAlpha = cos (gxXfrm->gxDef.parameters.geocentricParameters.rotateX * cs_Sec2Rad);
	sinBeta  = sin (gxXfrm->gxDef.parameters.geocentricParameters.rotateY * cs_Sec2Rad);
	cosBeta  = cos (gxXfrm->gxDef.parameters.geocentricParameters.rotateY * cs_Sec2Rad);
	sinGamma = sin (gxXfrm->gxDef.parameters.geocentricParameters.rotateZ * cs_Sec2Rad);
	cosGamma = cos (gxXfrm->gxDef.parameters.geocentricParameters.rotateZ * cs_Sec2Rad);

	/* View the following as the development of a 3x3 orthogonal
	   rotation matirx: rt12 = rotate matrix row 1 column 2 */
	parm7->rt11 =  cosBeta * cosGamma;
	parm7->rt21 = -cosBeta * sinGamma;
	parm7->rt31 =  sinBeta;
	parm7->rt12 =  cosAlpha * sinGamma + sinAlpha * sinBeta * cosGamma;
	parm7->rt22 =  cosAlpha * cosGamma - sinAlpha * sinBeta * sinGamma;
	parm7->rt32 = -sinAlpha * cosBeta;
	parm7->rt13 =  sinAlpha * sinGamma - cosAlpha * sinBeta * cosGamma;
	parm7->rt23 =  sinAlpha * cosGamma + cosAlpha * sinBeta * sinGamma;
	parm7->rt33 =  cosAlpha * cosBeta;

	trgScale = cs_One + (gxXfrm->gxDef.parameters.geocentricParameters.scale * 1.0E-06);
	if (fabs (trgScale) < 1.0E-06)
	{
		CS_erpt (cs_ISER);
	}
	else
	{
		parm7->scale = (cs_One + (gxXfrm->gxDef.parameters.geocentricParameters.scale * 1.0E-06));
	}

	parm7->errorValue    = gxXfrm->errorValue;
	parm7->cnvrgValue    = gxXfrm->cnvrgValue;
	parm7->maxIterations = gxXfrm->maxIterations;

	gxXfrm->frwrd2D = (cs_FRWRD2D_CAST)CSparm7F2;
	gxXfrm->frwrd3D = (cs_FRWRD3D_CAST)CSparm7F3;
	gxXfrm->invrs2D = (cs_INVRS2D_CAST)CSparm7I2;
	gxXfrm->invrs3D = (cs_INVRS3D_CAST)CSparm7I3;
	gxXfrm->inRange = (cs_INRANGE_CAST)CSparm7L;
	gxXfrm->release = (cs_RELEASE_CAST)CSparm7R;
	gxXfrm->destroy = (cs_DESTROY_CAST)CSparm7D;

	return 0;
}
Beispiel #26
0
/******************************************************************************
        Constructor
*/
struct csVertconUS_* CSnewVertconUS (Const char *catalog)
{
	int index;
	struct csVertconUS_ *__This;
	struct csDatumCatalog_ *catPtr;
	struct csDatumCatalogEntry_ *catEntryPtr;
	struct csVertconUSEntry_* vcEntryPtr;
	struct csVertconUSEntry_* findPtr;

	/* Prepare for an error. */
	__This = NULL;
	catPtr = NULL;
	catEntryPtr = NULL;
	vcEntryPtr = NULL;

	__This = (struct csVertconUS_*) CS_malc (sizeof (struct csVertconUS_));
	if (__This == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}
	__This->cachePtr = NULL;
	__This->listHead = NULL;

	/* Open the catalog file. */
	catPtr = CSnewDatumCatalog (catalog);
	if (catPtr == NULL) goto error;

	/* For each entry in the catalog, we build an appropriate geoid height
	   grid file entry.  Right now, this is based on file names and file
	   extensions.  Not very good, but that's life. */

	index = 0;
	while (TRUE)												/*lint !e716 */
	{
		catEntryPtr = CSgetDatumCatalogEntry (catPtr,index++);
		if (catEntryPtr == NULL) break;
		vcEntryPtr = CSnewVertconUSEntry (catEntryPtr);
		if (vcEntryPtr == NULL)
		{
			goto error;
		}
		/* Keep the list in the same order as they appear in the file. */
		if (__This->listHead == NULL)
		{
			__This->listHead = vcEntryPtr;
		}
		else
		{
			for (findPtr = __This->listHead;findPtr->next != NULL;findPtr = findPtr->next);
			findPtr->next = vcEntryPtr;
		}
	}
	CSdeleteDatumCatalog (catPtr);
	catPtr = NULL;

	/* Having done that successfully, allocate a grid cell cache.  If
	   this fails, we can either report it as an error, or just leave it
	   alone.  Lets report it as an error. */
	__This->cachePtr = CSnewZGridCellCache (32);
	if (__This->cachePtr == NULL)
	{
		goto error;
	}

	/* OK, we ;re done. */
	return __This;
error:
	if (catPtr != NULL) CSdeleteDatumCatalog (catPtr);
	if (__This != NULL) CS_free (__This);
	return NULL;
}
Beispiel #27
0
/******************************************************************************
	Constructor: This is a constructor for the "Entry" object.  A linked list
	of these "Entry" objects is underlying structure of the main object.

	NOTE: the specific of handling different file types is handled here.
*/
struct csRgf93ToNtfEntry_* CSnewRgf93ToNtfEntry (struct csDatumCatalogEntry_* catPtr)
{
	extern char cs_DirsepC;
	extern char cs_ExtsepC;
	extern char csErrnam [];

	char *cp;
	struct csRgf93ToNtfEntry_* __This;

	/* Prepare for an error. */
	__This = NULL;

	/* Allocate some storage. */
	__This = (struct csRgf93ToNtfEntry_*) CS_malc (sizeof (struct csRgf93ToNtfEntry_));
	if (__This == NULL)
	{
		CS_erpt (cs_NO_MEM);
		goto error;
	}
	__This->next = NULL;
	__This->type = dtRgf93ToNtfNone;
	__This->pointers.txtDatumPtr = NULL;
	__This->pointers.c2DatumPtr = NULL;         /* Yes, redundant! */

	/* Issue an error if information in the catalog file is
	   inconsistent.  That is, if the extension is not one of the
	   two supported. */
	cp = strrchr (catPtr->pathName,cs_DirsepC);
	if (cp == NULL)
	{
		/* Can't find a path specification in the path name. */
		CS_stncp (csErrnam,catPtr->pathName,MAXPATH);
		CS_erpt (cs_DTC_PATH);
		goto error;
	}
	cp = strchr (cp,cs_ExtsepC);
	if (cp == NULL || strlen (cp) != 4)
	{
		/* Can't find an extension in the file name. */
		CS_stncp (csErrnam,catPtr->pathName,MAXPATH);
		CS_erpt (cs_DTC_PATH);
		goto error;
	}
	

	/* Process the entry according to the extension on the file name. */
	cp += 1;                                /* bump past the separator*/
	if (!CS_stricmp (cp,"TXT"))
	{
		/* Construct a text file object.  In the past 10 years, there has only
		   one.  But with htis new implementation (Nov 2008) we supported
		   multiple .txt files as well as multiple .gsb files. */
		__This->pointers.txtDatumPtr = CSnewRgf93ToNtfTxt (catPtr->pathName,catPtr->bufferSize,catPtr->flags,catPtr->density);
		__This->type = dtRgf93ToNtfTxt;
	}
	else if (!CS_stricmp (cp,"GSB"))
	{
		/* Construct a Canadian National Transformation Version 2 object. */
		__This->pointers.c2DatumPtr = CSnewDatumShiftCa2 (dtcTypeCanadian2,catPtr->pathName,catPtr->bufferSize,catPtr->flags,catPtr->density);
		if (__This->pointers.c2DatumPtr == NULL)
		{
			goto error;
		}
		__This->type = dtRgf93ToNtfC2;
	}
	else
	{
		CS_stncp (csErrnam,catPtr->pathName,MAXPATH);
		CS_erpt (cs_NAD_EXT);
		goto error;
	}

	/* Return a pointer to t2he 'constructed' entry object. */
	return __This;
error:
	CSdeleteRgf93ToNtfEntry (__This);
	return NULL;
}
Beispiel #28
0
int EXP_LVL9 CSpstroF (Const struct cs_Pstro_ *pstro,double xy [2],Const double ll [2])

{
	extern char csErrnam [MAXPATH];

	extern double cs_Degree;			/* 1.0 / RADIAN  */
	extern double cs_Half;				/* 0.5 */
	extern double cs_One;				/* 1.0 */
	extern double cs_Pi;				/* 3.14159... */
	extern double cs_Pi_o_2;			/* PI over 2 */
	extern double cs_Pi_o_4;			/* PI over 4 */
	extern double cs_NPTest;			/* 0.001 seconds of arc
										   short of the north pole,
										   in radians. */
	extern double cs_Huge;				/* Huge value, but not too huge. */

	int rtn_val;

	double lng;				/* The given longitude, after conversion
							   to radians. */
	double lat;				/* The given latitude after conversion
							   to radians. */
	double x;
	double y;

	double del_lng;
	double sin_del_lng;
	double cos_del_lng;
	double sin_lat;

	double t;
	double rho;
	double tmp1;
	double tmp2;
	double tmp3;

	rtn_val = cs_CNVRT_NRML;

	/* There are two formulae, one for the sphere and one for the
	   ellipsoid.  If the ecentricity of the dataum in use is 0.0
	   exactly, we shall use the spherical formulae. */

	lat = cs_Degree * ll [LAT];
	if (fabs (lat) > cs_NPTest)
	{
		rtn_val = cs_CNVRT_INDF;
		if (fabs (lat) > cs_Pi_o_2)
		{
			rtn_val = cs_CNVRT_RNG;
			lat = CS_adj1pi (lat);
		}
	}
	lng = cs_Degree * ll [LNG];
	
	/* We first adjust the following so that we can use much
	   of the code below for the southern polar aspect without
	   duplicating it with minor sign changes. */

	if (pstro->aspect == cs_STERO_SOUTH && pstro->ecent != 0.0)
	{
		lat = -lat;
		del_lng = pstro->org_lng - lng;
	}
	else
	{
		del_lng = lng - pstro->org_lng;
	}
	if (fabs (del_lng) > cs_Pi) del_lng = CS_adj2pi (del_lng);

	sin_del_lng = sin (del_lng);
	cos_del_lng = cos (del_lng);
	sin_lat = sin (lat);

	/* See if the datum is a sphere or an ellipsoid. */

	if (pstro->ecent == 0.0)
	{
		/* Here for the sphere. */

		switch (pstro->aspect) {

		case cs_STERO_NORTH:

			tmp1 = cs_Pi_o_4 - (lat * cs_Half);
			tmp1 = pstro->two_ka * tan (tmp1);

			x = tmp1 * sin_del_lng;
			y = -tmp1 * cos_del_lng;
			break;

		case cs_STERO_SOUTH:

			tmp1 = cs_Pi_o_4 + (lat * cs_Half);
			tmp1 = pstro->two_ka * tan (tmp1);

			x = tmp1 * sin_del_lng;
			y = tmp1 * cos_del_lng;
			break;
	
		default:
			x = y = -cs_Huge;
			CS_stncp (csErrnam,"CS_pstro:1",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}									/*lint !e744 */
	}
	else
	{
		/* Here for an ellipsoid model of the earth. */

		tmp1 = pstro->ecent * sin_lat;
		tmp2 = (cs_One - tmp1) / (cs_One + tmp1);
		tmp2 = pow (tmp2,pstro->e_o_2);
		tmp3 = lat * cs_Half;
		t       = tan (cs_Pi_o_4 - tmp3) / tmp2;

		switch (pstro->aspect) {

		case cs_STERO_NORTH:

			rho = pstro->two_ka * t / pstro->e_term;

			x = rho * sin_del_lng;
			y = -rho * cos_del_lng;
			break;

		case cs_STERO_SOUTH:

			rho = pstro->two_ka * t / pstro->e_term;

			x = -rho * sin_del_lng;
			y = rho * cos_del_lng;
			break;

		default:

			x = y = -cs_Huge;
			CS_stncp (csErrnam,"CS_pstro:1",MAXPATH);
			CS_erpt (cs_ISER);
			rtn_val = -1;
			break;
		}									/*lint !e744 */
	}
	
	/* Adjust for the selected quadrant, and, finally, add false
	   easting and false northing. */

	xy [XX] = x;							/*lint !e644 */
	xy [YY] = y;							/*lint !e644 */

	if (pstro->quad == 0)
	{
		xy [XX] = x + pstro->x_off;
		xy [YY] = y + pstro->y_off;
	}
	else
	{
		CS_quadF (xy,x,y,pstro->x_off,pstro->y_off,pstro->quad);
	}
	return (rtn_val);
}
Beispiel #29
0
int EXP_LVL9 CSparm7I2 (struct csParm7_ *parm7,double* trgLl,Const double* srcLl)
{
	int ii;
	int lngOk;
	int latOk;
	int rtnVal;

	double guess [3];
	double newLl [3];
	double epsilon [3];

	/* Assume everything goes OK until we know different. */
	rtnVal = 0;
	epsilon [0] = epsilon [1] = parm7->cnvrgValue;		/* keep gcc compiler happy */

	/* First, we copy the WGS-84 lat/longs to the local array.  This is the
	   default result which the user may want in the event of a fatal error.
	   Note, we assume such has been done below, even if there has not been
	   an error. */
	trgLl [LNG] = guess [LNG] = srcLl [LNG];
	trgLl [LAT] = guess [LAT] = srcLl [LAT];
	trgLl [HGT] = srcLl [HGT];

	/* To improve performancce, we could use CS_bw3dInvrs here to
	   get our guess.  That function will probably reduce the
	   number of iterations require below substantially. */

	/* Start a loop which will iterate as many as maxIteration times. */
	for (ii = 0;ii < parm7->maxIterations;ii++)
	{
		/* Assume we are done until we know different. */
		lngOk = latOk = TRUE;

		/* Compute the WGS-84 lat/long for our current guess. */
		rtnVal = CSparm7F2 (parm7,newLl,guess);
		if (rtnVal != 0)
		{
			/* Oopps!! We must have been given some pretty strange
			   coordinate values. */
			break;
		}

		/* See how far we are off. */
		epsilon [LNG] = srcLl [LNG] - newLl [LNG];
		epsilon [LAT] = srcLl [LAT] - newLl [LAT];

		/* If our guess at the longitude is off by more than
		   small, we adjust our guess by the amount we are off. */
		if (fabs (epsilon [LNG]) > parm7->cnvrgValue)
		{
			lngOk = FALSE;
			guess [LNG] += epsilon [LNG];
		}
		/* If our guess longitude is off by more than
		   small, we adjust our guess by the amount we are off. */
		if (fabs (epsilon [LAT]) > parm7->cnvrgValue)
		{
			latOk = FALSE;
			guess [LAT] += epsilon [LAT];
		}

		/* If our current guess produces a newLl that is within
		   samllValue of srcLl, we are done. */
		if (lngOk && latOk) break;
	}

	/* If we didn't resolve in maxIteration tries, we issue a warning
	   message.  Usually, three or four iterations does the trick. */
	if (ii >= parm7->maxIterations )
	{
		CS_erpt (cs_7P_CNVRG);

		/* Issue a warning if we're close, a fatal if we are still way off.
		   In any case, we return the last computed value.  We could have
		   gotten very fancy with this stuff, but it would have had serious
		   affects on the performance.  So we just check epsilon here as
		   we know we have an error and this doesn't happen very often. */
		rtnVal = 1;
		if (fabs (epsilon [LNG]) > parm7->errorValue ||
		    fabs (epsilon [LAT]) > parm7->errorValue)
		{
			/* This is not supposed to happen.  It will not happen if the
			   input coordinates are anywhere reasonable.  However, since the
			   contract is that once created, a transformation always returns
			   a rational result, with perhaps a warning status, we return a
			   +1 here.  If you prefer a fatal, change this value to -1. */
			rtnVal = 1;
		}
	}

	/* If we are not returning fatal error status, we return the last
	   computed value even if we are returning a warning status.  It may be
	   of value, often is. */
	if (rtnVal >= 0)
	{
		trgLl [LNG] = guess [LNG];
		trgLl [LAT] = guess [LAT];
	}
	return rtnVal;
}
Beispiel #30
0
/******************************************************************************
	Calculate inverse datum shift, the second main man.  Note that this is a
		deviation from using the exact code used by the governmental products.
		The different government supplied programs use the same algorothm, but
		with slightly different implementation details.  Here we use the same
		details for all objects.

	Returns  0 for expected result
	        -1 for hard/fatal failure
			+1 for no data coverage, unshifted result returned
			+2 for no data coverage, fallback used successfully
*/
int CSinverseAts77ToCsrs (struct csAts77ToCsrs_* __This,double* ll_ats77,Const double *ll_csrs)
{
	static int itmax = 10;
	static double small = 1.0E-9;		/* this is degrees */

	short lng_ok;
	short lat_ok;
	int ii;
	int status;

	double guess [3];
	double epsilon [2];
	double newResult [3];

	guess [LNG] = ll_csrs [LNG];
	guess [LAT] = ll_csrs [LAT];
	guess [HGT] = ll_csrs [HGT];

	/* Start a loop which will iterate up to 10 times. The Canadians and
	   the Aussies max out at 4.  We would duplicate theirs, but since
	   this is an inverse, we'll do a little better than they do. */
	for (ii = 1;ii < itmax;ii++)
	{
		/* Assume we are done until we know different. */
		lng_ok = lat_ok = TRUE;

		/* Compute the NAD83 lat/long for our current guess. */
		status = CScalcAts77ToCsrs (__This,newResult,guess);

		/* If there is no data for this lat/long, we use the fallback
		   in one is available. */
		if (status != 0)
		{
			if (status > 0 && __This->fallback != NULL)
			{
				status = CScalcFallbackInverse (__This->fallback,ll_ats77,ll_csrs);
			}
			return (status);
		}

		/* See how far we are off. */
		epsilon [LNG] = ll_csrs [LNG] - newResult [LNG];
		epsilon [LAT] = ll_csrs [LAT] - newResult [LAT];

		/* If our guess at the longitude is off by more than
		   small, we adjust our guess by the amount we are off. */
		if (fabs (epsilon [LNG]) > small)
		{
			lng_ok = FALSE;
			guess [LNG] += epsilon [LNG];
		}
		if (fabs (epsilon [LAT]) > small)
		{
			lat_ok = FALSE;
			guess [LAT] += epsilon [LAT];
		}

		/* If our current guess produces a newResult that is within
		   small of original, we are done. */
		if (lng_ok && lat_ok) break;
	}

	/* If we didn't resolve in four tries, we issue a warning
	   message.  Casual reading of the NADCON code would lead one
	   to believe that they do five iterations, but four is all
	   they really do. */
	if (ii >= itmax)
	{
		CS_erpt (cs_NADCON_ICNT);
		return (1);
	}

	/* Adjust the ll66 value to the computed value, now that we
	   know that it should be correct. */
	ll_ats77 [LNG] = guess [LNG];
	ll_ats77 [LAT] = guess [LAT];
	return 0;
}