OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
proj_robinv.c
Go to the documentation of this file.
1 /*******************************************************************************
2 NAME ROBINSON
3 
4 PURPOSE: Transforms input Easting and Northing to longitude and
5  latitude for the Robinson projection. The
6  Easting and Northing must be in meters. The longitude
7  and latitude values will be returned in radians.
8 
9 PROGRAMMER DATE REASON
10 ---------- ---- ------
11 T. Mittan March, 1993 Converted from FORTRAN to C.
12 S. Nelson Nov, 1993 Changed number of iterations from 20
13  to 75. This seemed to give a valid
14  Latitude with less fatal errors.
15 
16 This function was adapted from the Robinson projection code (FORTRAN)
17 in the General Cartographic Transformation Package software which is
18 available from the U.S. Geological Survey National Mapping Division.
19 
20 ALGORITHM REFERENCES
21 
22 1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
23  The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
24 
25 2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
26  Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
27  State Government Printing Office, Washington D.C., 1987.
28 
29 3. "Software Documentation for GCTP General Cartographic Transformation
30  Package", U.S. Geological Survey National Mapping Division, May 1982.
31  *******************************************************************************/
32 #include "proj_cproj.h"
33 #include <stdint.h>
34 
35 /* Variables common to all subroutines in this code file
36  -----------------------------------------------------*/
37 static double lon_center; /* Center longitude (projection center) */
38 static double R; /* Radius of the earth (sphere) */
39 static double false_easting; /* x offset in meters */
40 static double false_northing; /* y offset in meters */
41 static double pr[21];
42 static double xlr[21];
43 
44 /* Initialize the ROBINSON projection
45  ---------------------------------*/
46 int robinvint(r, center_long, false_east, false_north)
47 
48 double r; /* (I) Radius of the earth (sphere) */
49 double center_long; /* (I) Center longitude */
50 double false_east; /* x offset in meters */
51 double false_north; /* y offset in meters */
52 {
53  int32_t i;
54 
55  /* Place parameters in static storage for common use
56  -------------------------------------------------*/
57  R = r;
58  lon_center = center_long;
59  false_easting = false_east;
60  false_northing = false_north;
61 
62  pr[1] = -0.062;
63  xlr[1] = 0.9986;
64  pr[2] = 0.0;
65  xlr[2] = 1.0;
66  pr[3] = 0.062;
67  xlr[3] = 0.9986;
68  pr[4] = 0.124;
69  xlr[4] = 0.9954;
70  pr[5] = 0.186;
71  xlr[5] = 0.99;
72  pr[6] = 0.248;
73  xlr[6] = 0.9822;
74  pr[7] = 0.31;
75  xlr[7] = 0.973;
76  pr[8] = 0.372;
77  xlr[8] = 0.96;
78  pr[9] = 0.434;
79  xlr[9] = 0.9427;
80  pr[10] = 0.4958;
81  xlr[10] = 0.9216;
82  pr[11] = 0.5571;
83  xlr[11] = 0.8962;
84  pr[12] = 0.6176;
85  xlr[12] = 0.8679;
86  pr[13] = 0.6769;
87  xlr[13] = 0.835;
88  pr[14] = 0.7346;
89  xlr[14] = 0.7986;
90  pr[15] = 0.7903;
91  xlr[15] = 0.7597;
92  pr[16] = 0.8435;
93  xlr[16] = 0.7186;
94  pr[17] = 0.8936;
95  xlr[17] = 0.6732;
96  pr[18] = 0.9394;
97  xlr[18] = 0.6213;
98  pr[19] = 0.9761;
99  xlr[19] = 0.5722;
100  pr[20] = 1.0;
101  xlr[20] = 0.5322;
102 
103  for (i = 0; i < 21; i++)
104  xlr[i] *= 0.9858;
105 
106  return (OK);
107 }
108 
109 /* Robinson inverse equations--mapping x,y to lat/long
110  ------------------------------------------------------------*/
111 int robinv(x, y, lon, lat)
112 double x; /* (O) X projection coordinate */
113 double y; /* (O) Y projection coordinate */
114 double *lon; /* (I) Longitude */
115 double *lat; /* (I) Latitude */
116 
117 {
118  double adjust_lon();
119  double yy;
120  double p2;
121  double u, v, t, c;
122  double phid;
123  double y1;
124  int32_t ip1;
125  int32_t i;
126 
127 
128  /* Inverse equations
129  -----------------*/
130  x -= false_easting;
131  y -= false_northing;
132 
133  yy = 2.0 * y / PI / R;
134  phid = yy * 90.0;
135  p2 = fabs(phid / 5.0);
136  ip1 = (int32_t) (p2 - EPSLN);
137  if (ip1 == 0)
138  ip1 = 1;
139 
140  /* Stirling's interpolation formula as used in forward transformation is
141  reversed for first estimation of LAT. from rectangular coordinates. LAT.
142  is then adjusted by iteration until use of forward series provides correct
143  value of Y within tolerance.
144  ---------------------------------------------------------------------------*/
145  for (i = 0;;) {
146  u = pr[ip1 + 3] - pr[ip1 + 1];
147  v = pr[ip1 + 3] - 2.0 * pr[ip1 + 2] + pr[ip1 + 1];
148  t = 2.0 * (fabs(yy) - pr[ip1 + 2]) / u;
149  c = v / u;
150  p2 = t * (1.0 - c * t * (1.0 - 2.0 * c * t));
151 
152  if ((p2 >= 0.0) || (ip1 == 1)) {
153  if (y >= 0)
154  phid = (p2 + (double) ip1) * 5.0;
155  else
156  phid = -(p2 + (double) ip1) * 5.0;
157 
158  do {
159  p2 = fabs(phid / 5.0);
160  ip1 = (int32_t) (p2 - EPSLN);
161  p2 -= (double) ip1;
162 
163  if (y >= 0)
164  y1 = R * (pr[ip1 + 2] + p2 * (pr[ip1 + 3] - pr[ip1 + 1]) / 2.0 + p2
165  * p2 * (pr[ip1 + 3] - 2.0 * pr[ip1 + 2] + pr[ip1 + 1]) / 2.0)
166  * PI / 2.0;
167  else
168  y1 = -R * (pr[ip1 + 2] + p2 * (pr[ip1 + 3] - pr[ip1 + 1]) / 2.0 + p2
169  * p2 * (pr[ip1 + 3] - 2.0 * pr[ip1 + 2] + pr[ip1 + 1]) / 2.0)
170  * PI / 2.0;
171  phid += -180.0 * (y1 - y) / PI / R;
172  i++;
173  if (i > 75) {
174  /*
175  p_error("Too many iterations in inverse","robinv-conv");
176  */
177  return (234);
178  }
179  } while (fabs(y1 - y) > .00001);
180  break;
181  } else {
182  ip1 -= 1;
183  if (ip1 < 0) {
184  /*
185  p_error("Too many iterations in inverse","robinv-conv");
186  */
187  return (234);
188  }
189  }
190  }
191  *lat = phid * .01745329252;
192 
193  /* calculate LONG. using final LAT. with transposed forward Stirling's
194  interpolation formula.
195  ---------------------------------------------------------------------*/
196  *lon = lon_center + x / R / (xlr[ip1 + 2] + p2 * (xlr[ip1 + 3] - xlr[ip1 + 1])
197  / 2.0 + p2 * p2 * (xlr[ip1 + 3] - 2.0 * xlr[ip1 + 2] +
198  xlr[ip1 + 1]) / 2.0);
199  if ((*lon < (-PI)) || (*lon > PI))
200  return -1;
201  /*
202  *lon = adjust_lon(*lon);
203  */
204  return (OK);
205 }
int r
Definition: decode_rs.h:73
data_t t[NROOTS+1]
Definition: decode_rs.h:77
float * lat
double adjust_lon(double x)
Definition: proj_cproj.c:349
#define PI
Definition: l3_get_org.c:6
#define OK
Definition: ancil.h:30
integer, parameter double
int robinvint(double r, double center_long, double false_east, double false_north)
Definition: proj_robinv.c:46
data_t u
Definition: decode_rs.h:74
#define fabs(a)
Definition: misc.h:93
float * lon
int robinv(double x, double y, double *lon, double *lat)
Definition: proj_robinv.c:111
#define R
Definition: make_L3_v1.1.c:96
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
int i
Definition: decode_rs.h:71
#define EPSLN
Definition: proj_define.h:86