OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
oli_cproj.c
Go to the documentation of this file.
1 /*******************************************************************************
2 NAME Projection support routines listed below.
3 
4 PURPOSE: The following functions are included in CPROJ.C.
5 
6  SINCOS: Calculates the sine and cosine.
7  ASINZ: Eliminates roundoff errors.
8  MSFNZ: Computes the constant small m for Oblique Equal Area.
9  QSFNZ: Computes the constant small q for Oblique Equal Area.
10  PHI1Z: Computes phi1 for Albers Conical Equal-Area.
11  PHI2Z: Computes the latitude angle, phi2, for Lambert
12  Conformal Conic and Polar Stereographic.
13  PHI3Z: Computes the latitude, phi3, for Equidistant Conic.
14  PHI4Z: Computes the latitude, phi4, for Polyconic.
15  PAKCZ: Converts a 2 digit alternate packed DMS format to
16  standard packed DMS format.
17  PAKR2DM: Converts radians to 3 digit packed DMS format.
18  TSFNZ: Computes the small t for Lambert Conformal Conic and
19  Polar Stereographic.
20  SIGN: Returns the sign of an argument.
21  ADJUST_LON: Adjusts a longitude angle to range -180 to 180.
22  E0FN, E1FN, E2FN, E3FN:
23  Computes the constants e0,e1,e2,and e3 for
24  calculating the distance along a meridian.
25  E4FN: Computes e4 used for Polar Stereographic.
26  MLFN: Computes M, the distance along a meridian.
27  CALC_UTM_ZONE: Calculates the UTM zone number.
28 
29 *******************************************************************************/
30 #include "oli_cproj.h"
31 #include "oli_local.h"
32 
33 #define MAX_VAL 4
34 #define MAXLONG 2147483647.
35 #define DBLLONG 4.61168601e18
36 
37 /* FIXME Temporarily disable the sincos function since newer versions of gcc
38  seem to include it no matter what and it causes problems */
39 #if MACINTOSH
40 /* Function to calculate the sine and cosine in one call. Some computer
41  systems have implemented this function, resulting in a faster implementation
42  than calling each function separately. It is provided here for those
43  computer systems which don`t implement this function
44  ----------------------------------------------------*/
45 void sincos
46 (
47  double val,
48  double *sin_val,
49  double *cos_val
50 )
51 {
52  *sin_val = sin(val);
53  *cos_val = cos(val);
54 }
55 #endif
56 
57 /* Function to eliminate roundoff errors in asin
58 ----------------------------------------------*/
59 double asinz
60 (
61  double con
62 )
63 {
64  if (fabs(con) > 1.0)
65  {
66  if (con > 1.0)
67  con = 1.0;
68  else
69  con = -1.0;
70  }
71  return(asin(con));
72 }
73 
74 /* Function to compute constant small q which is the radius of a
75  parallel of latitude, phi, divided by the semimajor axis.
76 ------------------------------------------------------------*/
77 double qsfnz
78 (
79  double eccent,
80  double sinphi
81 )
82 {
83  double con;
84 
85  if (eccent > 1.0e-7)
86  {
87  con = eccent * sinphi;
88  return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) -
89  (.5/eccent) * log((1.0 - con)/(1.0 + con))));
90  }
91  else
92  return(2.0 * sinphi);
93 }
94 
95 /* Function to compute phi1, the latitude for the inverse of the
96  Albers Conical Equal-Area projection.
97 -------------------------------------------*/
98 double phi1z
99 (
100  double eccent, /* Eccentricity angle in radians */
101  double qs, /* Angle in radians */
102  long *flag /* Error flag number */
103 )
104 {
105  double eccnts;
106  double dphi;
107  double con;
108  double com;
109  double sinpi;
110  double cospi;
111  double phi;
112  long i;
113 
114  phi = asinz(.5 * qs);
115  if (eccent < EPSLN)
116  return(phi);
117  eccnts = eccent * eccent;
118  for (i = 1; i <= 25; i++)
119  {
120  sincos(phi,&sinpi,&cospi);
121  con = eccent * sinpi;
122  com = 1.0 - con * con;
123  dphi = .5 * com * com / cospi * (qs / (1.0 - eccnts) - sinpi / com +
124  .5 / eccent * log ((1.0 - con) / (1.0 + con)));
125  phi = phi + dphi;
126  if (fabs(dphi) <= 1e-7)
127  return(phi);
128  }
129  GCTP_PRINT_ERROR("Convergence error");
130  *flag = 001;
131  return(ERROR);
132 }
133 
134 /* Function to compute latitude, phi3, for the inverse of the Equidistant
135  Conic projection.
136 -----------------------------------------------------------------*/
137 double phi3z
138 (
139  double ml, /* Constant */
140  double e0, /* Constant */
141  double e1, /* Constant */
142  double e2, /* Constant */
143  double e3, /* Constant */
144  long *flag /* Error flag number */
145 )
146 {
147  double phi;
148  double dphi;
149  long i;
150 
151  phi = ml;
152  for (i = 0; i < 15; i++)
153  {
154  dphi = (ml + e1 * sin(2.0 * phi) - e2 * sin(4.0 * phi) + e3 *
155  sin(6.0 * phi)) / e0 - phi;
156  phi += dphi;
157  if (fabs(dphi) <= .0000000001)
158  {
159  *flag = 0;
160  return(phi);
161  }
162  }
163  GCTP_PRINT_ERROR("Latitude failed to converge after 15 iterations");
164  *flag = 3;
165  return(3);
166 }
167 
168 /* Function to adjust a longitude angle to range from -180 to 180 radians
169  added if statments
170  -----------------------------------------------------------------------*/
171 double adjust_lon
172 (
173  double x /* Angle in radians */
174 )
175 {
176  long count = 0;
177  for(;;)
178  {
179  if (fabs(x)<=PI)
180  break;
181  else if (((long) fabs(x / PI)) < 2)
182  x = x-(gctp_get_sign(x) *TWO_PI);
183  else if (((long) fabs(x / TWO_PI)) < MAXLONG)
184  x = x-(((long)(x / TWO_PI))*TWO_PI);
185  else if (((long) fabs(x / (MAXLONG * TWO_PI))) < MAXLONG)
186  x = x-(((long)(x / (MAXLONG * TWO_PI))) * (TWO_PI * MAXLONG));
187  else if (((long) fabs(x / (DBLLONG * TWO_PI))) < MAXLONG)
188  x = x-(((long)(x / (DBLLONG * TWO_PI))) * (TWO_PI * DBLLONG));
189  else
190  x = x-(gctp_get_sign(x) *TWO_PI);
191  count++;
192  if (count > MAX_VAL)
193  break;
194  }
195 
196  return(x);
197 }
#define MAX_VAL
Definition: oli_cproj.c:33
double phi3z(double ml, double e0, double e1, double e2, double e3, long *flag)
Definition: oli_cproj.c:138
#define GCTP_PRINT_ERROR(format,...)
Definition: oli_local.h:81
int gctp_get_sign(double x)
Definition: gctp_utility.c:103
double phi1z(double eccent, double qs, long *flag)
Definition: oli_cproj.c:99
#define PI
Definition: l3_get_org.c:6
double adjust_lon(double x)
Definition: oli_cproj.c:172
#define TWO_PI
Definition: make_L3_v1.1.c:92
double asinz(double con)
Definition: oli_cproj.c:60
#define sincos
Definition: proj_define.h:108
double qsfnz(double eccent, double sinphi)
Definition: oli_cproj.c:78
#define fabs(a)
Definition: misc.h:93
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
#define DBLLONG
Definition: oli_cproj.c:35
#define MAXLONG
Definition: oli_cproj.c:34
#define ERROR
Definition: ancil.h:24
#define EPSLN
Definition: proj_define.h:86
int count
Definition: decode_rs.h:79