Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
gctp.c
Go to the documentation of this file.
1 /*******************************************************************************
2 NAME GCTP
3 
4 ALGORITHM REFERENCES
5 
6 1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
7  Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
8  State Government Printing Office, Washington D.C., 1987.
9 
10 2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
11  U.S. Geological Survey Professional Paper 1453 , United State Government
12  Printing Office, Washington D.C., 1989.
13 *******************************************************************************/
14 #include "oli_cproj.h"
15 #include "gctp.h"
16 #include "oli_local.h"
17 
18 #define TRUE 1
19 #define FALSE 0
20 
21 static long iter = 0; /* First time flag */
22 static long inpj[MAXPROJ + 1]; /* input projection array */
23 static long indat[MAXPROJ + 1]; /* input dataum array */
24 static long inzn[MAXPROJ + 1]; /* input zone array */
25 static double pdin[MAXPROJ + 1][COEFCT];/* input projection parm array */
26 static long outpj[MAXPROJ + 1]; /* output projection array */
27 static long outdat[MAXPROJ + 1]; /* output dataum array */
28 static long outzn[MAXPROJ + 1]; /* output zone array */
29 static double pdout[MAXPROJ+1][COEFCT]; /* output projection parm array */
30 static long (*for_trans[MAXPROJ + 1])(double,double,double*,double*);
31  /* forward function pointer array*/
32 static long (*inv_trans[MAXPROJ + 1])(double,double,double*,double*);
33  /* inverse function pointer array*/
34 
35 void gctp
36 (
37  const double *incoor, /* input coordinates */
38  const long *insys, /* input projection code */
39  const long *inzone, /* input zone number */
40  const double *inparm, /* input projection parameter array */
41  long *inunit, /* input units */
42  const long *inspheroid, /* input spheroid */
43  double *outcoor, /* output coordinates */
44  const long *outsys, /* output projection code */
45  const long *outzone, /* output zone */
46  const double *outparm, /* output projection array */
47  long *outunit, /* output units */
48  const long *outspheroid,/* output spheroid */
49  long *iflg /* error flag */
50 )
51 {
52 double x; /* x coordinate */
53 double y; /* y coordinate */
54 double factor; /* conversion factor */
55 double lon; /* longitude */
56 double lat; /* latitude */
57 long i,j; /* loop counters */
58 long ininit_flag; /* input initilization flag */
59 long outinit_flag; /* output initilization flag */
60 long unit; /* temporary unit variable */
61 
62 /* setup initilization flags and output message flags
63 ---------------------------------------------------*/
64 ininit_flag = FALSE;
65 outinit_flag = FALSE;
66 *iflg = 0;
67 
68 
69 /* check to see if initilization is required
70 only the first 13 projection parameters are currently used.
71 If more are added the loop should be increased.
72 ---------------------------------------------------------*/
73 if (iter == 0)
74  {
75  for (i = 0; i < MAXPROJ + 1; i++)
76  {
77  inpj[i] = 0;
78  indat[i] = 0;
79  inzn[i] = 0;
80  outpj[i] = 0;
81  outdat[i] = 0;
82  outzn[i] = 0;
83  for (j = 0; j < COEFCT; j++)
84  {
85  pdin[i][j] = 0.0;
86  pdout[i][j] = 0.0;
87  }
88  }
89  ininit_flag = TRUE;
90  outinit_flag = TRUE;
91  iter = 1;
92  }
93 else
94  {
95  if (*insys != GEO)
96  {
97  if ((inzn[*insys] != *inzone) || (indat[*insys] != *inspheroid) ||
98  (inpj[*insys] != *insys))
99  {
100  ininit_flag = TRUE;
101  }
102  else
103  for (i = 0; i < 13; i++)
104  if (pdin[*insys][i] != inparm[i])
105  {
106  ininit_flag = TRUE;
107  break;
108  }
109  }
110  if (*outsys != GEO)
111  {
112  if ((outzn[*outsys] != *outzone) || (outdat[*outsys] != *outspheroid) ||
113  (outpj[*outsys] != *outsys))
114  {
115  outinit_flag = TRUE;
116  }
117  else
118  for (i = 0; i < 13; i++)
119  if (pdout[*outsys][i] != outparm[i])
120  {
121  outinit_flag = TRUE;
122  break;
123  }
124  }
125  }
126 
127 /* Check input and output projection numbers
128 ------------------------------------------*/
129 if ((*insys < GEO) || (*insys > MAXPROJ))
130  {
131  GCTP_PRINT_ERROR("Insys is illegal");
132  *iflg = 1;
133  return;
134  }
135 if ((*outsys < GEO) || (*outsys > MAXPROJ))
136  {
137  GCTP_PRINT_ERROR("Outsys is illegal");
138  *iflg = 2;
139  return;
140  }
141 
142 /* find the correct conversion factor for units
143 ---------------------------------------------*/
144 unit = *inunit;
145 
146 /* find the factor unit conversions--all transformations are in radians
147  or meters
148  --------------------------------*/
149 if (*insys == GEO)
150  *iflg = untfz(unit,RADIAN,&factor);
151 else
152  *iflg = untfz(unit,METER,&factor);
153 if (*iflg != 0)
154  {
155  return;
156  }
157 
158 x = incoor[0] * factor;
159 y = incoor[1] * factor;
160 
161 /* Initialize inverse transformation
162 ----------------------------------*/
163 if (ininit_flag)
164  {
165  inpj[*insys] = *insys;
166  indat[*insys] = *inspheroid;
167  inzn[*insys] = *inzone;
168  for (i = 0;i < COEFCT; i++)
169  pdin[*insys][i] = inparm[i];
170 
171  /* Call the initialization function
172  ----------------------------------*/
173  inv_init(*insys,*inzone,inparm,*inspheroid,iflg,inv_trans);
174  if (*iflg != 0)
175  {
176  return;
177  }
178  }
179 
180 /* Do actual transformations
181 --------------------------*/
182 
183 /* Inverse transformations
184 ------------------------*/
185 if (*insys == GEO)
186  {
187  lon = x;
188  lat = y;
189  }
190 else
191 if ((*iflg = inv_trans[*insys](x, y, &lon, &lat)) != 0)
192  {
193  return;
194  }
195 
196 /* DATUM conversion should go here
197 --------------------------------*/
198 
199 /*
200  The datum conversion facilities should go here
201 */
202 
203 /* Initialize forward transformation
204 ----------------------------------*/
205 if (outinit_flag)
206  {
207  outpj[*outsys] = *outsys;
208  outdat[*outsys] = *outspheroid;
209  outzn[*outsys] = *outzone;
210  for (i = 0;i < COEFCT; i++)
211  pdout[*outsys][i] = outparm[i];
212 
213  /* Call the forward initialization function */
214  for_init(*outsys,*outzone,outparm,*outspheroid,iflg,for_trans);
215  if (*iflg != 0)
216  {
217  return;
218  }
219  }
220 
221 /* Forward transformations
222 ------------------------*/
223 if (*outsys == GEO)
224  {
225  outcoor[0] = lon;
226  outcoor[1] = lat;
227  }
228 else
229 if ((*iflg = for_trans[*outsys](lon, lat, &outcoor[0], &outcoor[1])) != 0)
230  {
231  return;
232  }
233 
234 /* find the correct conversion factor for units
235 ---------------------------------------------*/
236 unit = *outunit;
237 
238 if (*outsys == GEO)
239  *iflg = untfz(RADIAN,unit,&factor);
240 else
241  *iflg = untfz(METER,unit,&factor);
242 
243 outcoor[0] *= factor;
244 outcoor[1] *= factor;
245 return;
246 }
int j
Definition: decode_rs.h:73
#define GCTP_PRINT_ERROR(format,...)
Definition: oli_local.h:81
#define GEO
Definition: proj_define.h:36
#define FALSE
Definition: gctp.c:19
void inv_init(long insys, long inzone, const double *inparm, long inspheroid, long *iflg, long(*inv_trans[])(double, double, double *, double *))
Definition: inv_init.c:20
long untfz(long inunit, long outunit, double *factor)
Definition: untfz.c:35
integer, parameter double
#define TRUE
Definition: gctp.c:18
#define MAXPROJ
Definition: proj_define.h:74
#define RADIAN
Definition: gctp.h:89
#define COEFCT
Definition: proj_define.h:70
void gctp(const double *incoor, const long *insys, const long *inzone, const double *inparm, long *inunit, const long *inspheroid, double *outcoor, const long *outsys, const long *outzone, const double *outparm, long *outunit, const long *outspheroid, long *iflg)
Definition: gctp.c:36
int i
Definition: decode_rs.h:71
#define METER
Definition: gctp.h:91
void for_init(long outsys, long outzone, const double *outparm, long outspheroid, long *iflg, long(*for_trans[])(double, double, double *, double *))
Definition: for_init.c:20