OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
gctp_transform.c
Go to the documentation of this file.
1 /****************************************************************************
2 Name: gctp_transform
3 
4 Purpose: Performs a coordinate transformation with the given previously
5  created transformation.
6 
7 ****************************************************************************/
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <limits.h>
11 #include "gctp.h"
12 #include "oli_local.h"
13 #include "oli_cproj.h"
14 
15 /****************************************************************************
16 Name: call_gctp
17 
18 Purpose: Helper routine to perform a transformation by calling the old gctp
19  interface. Note that this routine should be eliminated when all of the
20  projections have been converted to the new interface.
21 
22 Returns: GCTP_SUCCESS, GCTP_ERROR or GCTP_IN_BREAK
23 
24 ****************************************************************************/
25 static int call_gctp
26 (
27  const GCTP_TRANSFORMATION *trans, /* I: transformation to use */
28  const double *in_coor, /* I: array of (lon, lat) or (x, y) */
29  double *out_coor /* O: array of (x, y) or (lon, lat) */
30 )
31 {
32  /* Set up local variables for calling the old gctp routine */
33  const GCTP_PROJECTION *in_proj = &trans->inverse.proj;
34  const GCTP_PROJECTION *out_proj = &trans->forward.proj;
35  long insys = in_proj->proj_code;
36  long inzone = in_proj->zone;
37  long inunit = in_proj->units;
38  long inspheroid = in_proj->spheroid;
39  long outsys = out_proj->proj_code;
40  long outzone = out_proj->zone;
41  long outunit = out_proj->units;
42  long outspheroid = out_proj->spheroid;
43  long iflg = 0;
44 
45  /* Call the original gctp routine */
46  gctp(in_coor, &insys, &inzone, in_proj->parameters, &inunit, &inspheroid,
47  out_coor, &outsys, &outzone, out_proj->parameters, &outunit,
48  &outspheroid, &iflg);
49 
50  /* Convert the error flag */
51  if (iflg == OK)
52  return GCTP_SUCCESS;
53  else if (iflg == IN_BREAK)
54  return GCTP_IN_BREAK;
55  else
56  return GCTP_ERROR;
57 }
58 
59 /****************************************************************************
60 Name: gctp_transform
61 
62 Purpose: Performs a coordinate transformation with the given previously
63  created transformation.
64 
65 Returns: GCTP_SUCCESS, GCTP_ERROR or GCTP_IN_BREAK
66 
67 ****************************************************************************/
69 (
70  const GCTP_TRANSFORMATION *trans, /* I: transformation to use */
71  const double *in_coor, /* I: array of (lon, lat) or (x, y) */
72  double *out_coor /* O: array of (x, y) or (lon, lat) */
73 )
74 {
75  double lon;
76  double lat;
77  double x;
78  double y;
79 
80  /* Verify the transformation provided is valid */
81  if (!trans)
82  {
83  GCTP_PRINT_ERROR("Invalid transformation provided");
84  return GCTP_ERROR;
85  }
86 
87  /* If the use_gctp flag is set, fall back to using gctp */
88  /* TODO - remove this after all the projections have been converted */
89  if (trans->use_gctp)
90  {
91  return call_gctp(trans, in_coor, out_coor);
92  }
93 
94  /* Convert the input coordinate into the correct units for this
95  transformation since the transforms always operate in radians or meters
96  and the caller may have provided the coordinate in different units */
97  x = in_coor[0] * trans->inverse.unit_conversion_factor;
98  y = in_coor[1] * trans->inverse.unit_conversion_factor;
99 
100  if (trans->inverse.transform)
101  {
102  int status;
103 
104  status = trans->inverse.transform(&trans->inverse, x, y, &lon, &lat);
105  if (status != GCTP_SUCCESS)
106  {
107  if (status == IN_BREAK)
108  {
109  /* In a break area, so return that indication */
110  return GCTP_IN_BREAK;
111  }
112  GCTP_PRINT_ERROR("Error in inverse transformation");
113  return GCTP_ERROR;
114  }
115  }
116  else
117  {
118  /* no inverse transform, so copy input to lat/lon */
119  lon = x;
120  lat = y;
121  }
122 
123  if (trans->forward.transform)
124  {
125  if (trans->forward.transform(&trans->forward, lon, lat,
126  &out_coor[0], &out_coor[1]) != GCTP_SUCCESS)
127  {
128  GCTP_PRINT_ERROR("Error in forward transformation");
129  return GCTP_ERROR;
130  }
131  }
132  else
133  {
134  /* no forward transform, so copy input to temp */
135  out_coor[0] = lon;
136  out_coor[1] = lat;
137  }
138 
139  /* Convert the output coordinate into the correct units for this
140  transformation since the transforms always operate in radians or meters
141  and the caller may have requested different units */
142  out_coor[0] *= trans->forward.unit_conversion_factor;
143  out_coor[1] *= trans->forward.unit_conversion_factor;
144 
145  return GCTP_SUCCESS;
146 }
int status
Definition: l1_czcs_hdf.c:32
#define GCTP_ERROR
Definition: gctp.h:81
#define GCTP_PRINT_ERROR(format,...)
Definition: oli_local.h:81
float * lat
#define GCTP_IN_BREAK
Definition: gctp.h:86
#define IN_BREAK
Definition: proj_define.h:69
#define OK
Definition: ancil.h:30
#define GCTP_SUCCESS
Definition: gctp.h:82
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 gctp_transform(const GCTP_TRANSFORMATION *trans, const double *in_coor, double *out_coor)