OB.DAAC Logo
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
float * lat
#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
float * lon
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