OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
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 This function was adapted from the Robinson projection code (FORTRAN)
10 in the General Cartographic Transformation Package software which is
11 available from the U.S. Geological Survey National Mapping Division.
12 
13 ALGORITHM REFERENCES
14 
15 1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
16  The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
17 
18 2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
19  Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
20  State Government Printing Office, Washington D.C., 1987.
21 
22 3. "Software Documentation for GCTP General Cartographic Transformation
23  Package", U.S. Geological Survey National Mapping Division, May 1982.
24 *******************************************************************************/
25 #include "oli_cproj.h"
26 #include "oli_local.h"
27 
28 /* Variables common to all subroutines in this code file
29  -----------------------------------------------------*/
30 static double lon_center; /* Center longitude (projection center) */
31 static double R; /* Radius of the earth (sphere) */
32 static double false_easting; /* x offset in meters */
33 static double false_northing; /* y offset in meters */
34 static double pr[21];
35 static double xlr[21];
36 
37 /* Initialize the ROBINSON projection
38  ---------------------------------*/
39 long robinvint
40 (
41  double r, /* (I) Radius of the earth (sphere) */
42  double center_long, /* (I) Center longitude */
43  double false_east, /* x offset in meters */
44  double false_north /* y offset in meters */
45 )
46 {
47 long i;
48 
49 /* Place parameters in static storage for common use
50  -------------------------------------------------*/
51 R = r;
52 lon_center = center_long;
53 false_easting = false_east;
54 false_northing = false_north;
55 
56  pr[1]= -0.062;
57  xlr[1]=0.9986;
58  pr[2]=0.0;
59  xlr[2]=1.0;
60  pr[3]=0.062;
61  xlr[3]=0.9986;
62  pr[4]=0.124;
63  xlr[4]=0.9954;
64  pr[5]=0.186;
65  xlr[5]=0.99;
66  pr[6]=0.248;
67  xlr[6]=0.9822;
68  pr[7]=0.31;
69  xlr[7]=0.973;
70  pr[8]=0.372;
71  xlr[8]=0.96;
72  pr[9]=0.434;
73  xlr[9]=0.9427;
74  pr[10]=0.4958;
75  xlr[10]=0.9216;
76  pr[11]=0.5571;
77  xlr[11]=0.8962;
78  pr[12]=0.6176;
79  xlr[12]=0.8679;
80  pr[13]=0.6769;
81  xlr[13]=0.835;
82  pr[14]=0.7346;
83  xlr[14]=0.7986;
84  pr[15]=0.7903;
85  xlr[15]=0.7597;
86  pr[16]=0.8435;
87  xlr[16]=0.7186;
88  pr[17]=0.8936;
89  xlr[17]=0.6732;
90  pr[18]=0.9394;
91  xlr[18]=0.6213;
92  pr[19]=0.9761;
93  xlr[19]=0.5722;
94  pr[20]=1.0;
95  xlr[20]=0.5322;
96 
97  for (i = 0; i < 21; i++)
98  xlr[i] *= 0.9858;
99 
100 /* Report parameters to the user
101  -----------------------------*/
102 gctp_print_title("ROBINSON");
104 gctp_print_cenlon(center_long);
106 return(OK);
107 }
108 
109 /* Robinson inverse equations--mapping x,y to lat/long
110  ------------------------------------------------------------*/
111 long robinv
112 (
113  double x, /* (O) X projection coordinate */
114  double y, /* (O) Y projection coordinate */
115  double *lon, /* (I) Longitude */
116  double *lat /* (I) Latitude */
117 )
118 
119 {
120 double yy;
121 double p2;
122 double u,v,t,c;
123 double phid;
124 double y1;
125 long ip1;
126 long i;
127 
128 
129 /* Inverse equations
130  -----------------*/
131 x -= false_easting;
132 y -= false_northing;
133 
134 yy = 2.0 * y / PI / R;
135 phid = yy * 90.0;
136 p2 = fabs(phid / 5.0);
137 ip1 = (long) (p2 - EPSLN);
138 if (ip1 == 0)
139  ip1 = 1;
140 
141 /* Stirling's interpolation formula as used in forward transformation is
142  reversed for first estimation of LAT. from rectangular coordinates. LAT.
143  is then adjusted by iteration until use of forward series provides correct
144  value of Y within tolerance.
145 ---------------------------------------------------------------------------*/
146 for (i = 0;;)
147  {
148  u = pr[ip1 + 3] - pr[ip1 + 1];
149  v = pr[ip1 + 3] - 2.0 * pr[ip1 + 2] + pr[ip1 + 1];
150  t = 2.0 * (fabs(yy) - pr[ip1 + 2]) / u;
151  c = v / u;
152  p2 = t * (1.0 - c * t * (1.0 - 2.0 * c * t));
153 
154  if ((p2 >= 0.0) || (ip1 == 1))
155  {
156  if (y >= 0)
157  phid = (p2 + (double) ip1 ) * 5.0;
158  else
159  phid = -(p2 + (double) ip1 ) * 5.0;
160 
161  do
162  {
163  p2 = fabs(phid / 5.0);
164  ip1 = (long) (p2 - EPSLN);
165  p2 -= (double) ip1;
166 
167  if (y >= 0)
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  else
172  y1 = -R * (pr[ip1 +2] + p2 *(pr[ip1 + 3] - pr[ip1 +1]) / 2.0 + p2
173  * p2 * (pr[ip1 + 3] - 2.0 * pr[ip1 + 2] + pr[ip1 + 1])/2.0)
174  * PI / 2.0;
175  phid += -180.0 * (y1 - y) / PI / R;
176  i++;
177  if (i > 75)
178  {
179  GCTP_PRINT_ERROR("Too many iterations in inverse");
180  return(234);
181  }
182  }
183  while (fabs(y1 - y) > .00001);
184  break;
185  }
186  else
187  {
188  ip1 -= 1;
189  if (ip1 < 0)
190  {
191  GCTP_PRINT_ERROR("Too many iterations in inverse");
192  return(234);
193  }
194  }
195  }
196 *lat = phid * .01745329252;
197 
198 /* calculate LONG. using final LAT. with transposed forward Stirling's
199  interpolation formula.
200 ---------------------------------------------------------------------*/
201 *lon = lon_center + x / R / (xlr[ip1 + 2] + p2 * (xlr[ip1 + 3] - xlr[ip1 + 1])
202  / 2.0 + p2 * p2 * (xlr[ip1 + 3] - 2.0 * xlr[ip1 + 2] +
203  xlr[ip1 + 1]) / 2.0);
204 *lon = adjust_lon(*lon);
205 
206 return(OK);
207 }
long robinv(double x, double y, double *lon, double *lat)
Definition: robinv.c:112
int r
Definition: decode_rs.h:73
data_t t[NROOTS+1]
Definition: decode_rs.h:77
void gctp_print_title(const char *proj_name)
Definition: gctp_report.c:14
double false_northing
Definition: polyconic.c:53
void gctp_print_cenlon(double A)
Definition: gctp_report.c:40
#define GCTP_PRINT_ERROR(format,...)
Definition: oli_local.h:81
float * lat
double adjust_lon(double x)
Definition: proj_cproj.c:349
#define PI
Definition: l3_get_org.c:6
long robinvint(double r, double center_long, double false_east, double false_north)
Definition: robinv.c:40
double false_easting
Definition: polyconic.c:54
void gctp_print_offsetp(double A, double B)
Definition: gctp_report.c:91
#define OK
Definition: ancil.h:30
integer, parameter double
data_t u
Definition: decode_rs.h:74
#define fabs(a)
Definition: misc.h:93
float * lon
void gctp_print_radius(double radius)
Definition: gctp_report.c:22
#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