OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
alberinv.c
Go to the documentation of this file.
1 /*******************************************************************************
2 NAME ALBERS CONICAL EQUAL-AREA
3 
4 PURPOSE: Transforms input Easting and Northing to longitude and
5  latitude for the Albers Conical Equal Area projection. The
6  Easting and Northing must be in meters. The longitude
7  and latitude values will be returned in radians.
8 
9 ALGORITHM REFERENCES
10 
11 1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
12  Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
13  State Government Printing Office, Washington D.C., 1987.
14 
15 2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
16  U.S. Geological Survey Professional Paper 1453 , United State Government
17  Printing Office, Washington D.C., 1989.
18 *******************************************************************************/
19 #include "oli_cproj.h"
20 #include "oli_local.h"
21 
22 /* Variables common to all subroutines in this code file
23  -----------------------------------------------------*/
24  static double r_major; /* major axis */
25  static double r_minor; /* minor axis */
26  static double c; /* constant c */
27  static double e3; /* eccentricity */
28  static double es; /* eccentricity squared */
29  static double rh; /* heigth above elipsoid */
30  static double ns0; /* ratio between meridians */
31  static double lon_center; /* center longitude */
32  static double false_easting; /* x offset in meters */
33  static double false_northing; /* y offset in meters */
34 
35 /* Initialize the Albers projection
36  -------------------------------*/
37 long alberinvint
38 (
39  double r_maj, /* major axis */
40  double r_min, /* minor axis */
41  double lat1, /* first standard parallel */
42  double lat2, /* second standard parallel */
43  double lon0, /* center longitude */
44  double lat0, /* center lattitude */
45  double false_east, /* x offset in meters */
46  double false_north /* y offset in meters */
47 )
48 {
49 double sin_po,cos_po; /* sine and cos values */
50 double con; /* temporary variable */
51 double temp; /* temporary variable */
52 double ms1; /* small m 1 */
53 double ms2; /* small m 2 */
54 double qs0; /* small q 0 */
55 double qs1; /* small q 1 */
56 double qs2; /* small q 2 */
57 
58 false_easting = false_east;
59 false_northing = false_north;
60 lon_center = lon0;
61 if (fabs(lat1 + lat2) < EPSLN)
62  {
64  "Equal latitudes for Standard Parallels on opposite sides of equator");
65  return(31);
66  }
67 r_major = r_maj;
68 r_minor = r_min;
69 temp = r_minor / r_major;
70 es = 1.0 - SQUARE(temp);
71 e3 = sqrt(es);
72 
73 sincos(lat1, &sin_po, &cos_po);
74 con = sin_po;
75 
76 ms1 = gctp_calc_small_radius(e3,sin_po,cos_po);
77 qs1 = qsfnz(e3,sin_po);
78 
79 sincos(lat2,&sin_po,&cos_po);
80 
81 ms2 = gctp_calc_small_radius(e3,sin_po,cos_po);
82 qs2 = qsfnz(e3,sin_po);
83 
84 sincos(lat0,&sin_po,&cos_po);
85 
86 qs0 = qsfnz(e3,sin_po);
87 
88 if (fabs(lat1 - lat2) > EPSLN)
89  ns0 = (ms1 * ms1 - ms2 *ms2)/ (qs2 - qs1);
90 else
91  ns0 = con;
92 c = ms1 * ms1 + ns0 * qs1;
93 rh = r_major * sqrt(c - ns0 * qs0)/ns0;
94 
95 /* Report parameters to the user
96  -----------------------------*/
97 gctp_print_title("ALBERS CONICAL EQUAL-AREA");
98 gctp_print_radius2(r_major, r_minor);
99 gctp_print_stanparl(lat1,lat2);
100 gctp_print_cenlonmer(lon_center);
101 gctp_print_origin(lat0);
102 gctp_print_offsetp(false_easting,false_northing);
103 
104 return(OK);
105 }
106 
107 /* Albers Conical Equal Area inverse equations--mapping x,y to lat/long
108  -------------------------------------------------------------------*/
109 long alberinv
110 (
111  double x, /* (O) X projection coordinate */
112  double y, /* (O) Y projection coordinate */
113  double *lon, /* (I) Longitude */
114  double *lat /* (I) Latitude */
115 )
116 {
117 double rh1; /* height above ellipsoid */
118 double qs; /* function q */
119 double con; /* temporary sign value */
120 double theta; /* angle */
121 long flag; /* error flag; */
122 
123 
124 flag = 0;
125 x -= false_easting;
126 y = rh - y + false_northing;;
127 if (ns0 >= 0)
128  {
129  rh1 = sqrt(x * x + y * y);
130  con = 1.0;
131  }
132 else
133  {
134  rh1 = -sqrt(x * x + y * y);
135  con = -1.0;
136  }
137 theta = 0.0;
138 if (rh1 != 0.0)
139  theta = atan2(con * x, con * y);
140 con = rh1 * ns0 / r_major;
141 qs = (c - con * con) / ns0;
142 if (e3 >= 1e-10)
143  {
144  con = 1 - .5 * (1.0 - es) * log((1.0 - e3) / (1.0 + e3))/e3;
145  if (fabs(fabs(con) - fabs(qs)) > .0000000001 )
146  {
147  *lat = phi1z(e3,qs,&flag);
148  if (flag != 0)
149  return(flag);
150  }
151  else
152  {
153  if (qs >= 0)
154  *lat = .5 * PI;
155  else
156  *lat = -.5 * PI;
157  }
158  }
159 else
160  {
161  *lat = phi1z(e3,qs,&flag);
162  if (flag != 0)
163  return(flag);
164  }
165 
166 *lon = adjust_lon(theta/ns0 + lon_center);
167 
168 return(OK);
169 }
#define SQUARE(x)
Definition: proj_define.h:99
void gctp_print_origin(double A)
Definition: gctp_report.c:65
void gctp_print_title(const char *proj_name)
Definition: gctp_report.c:14
long alberinv(double x, double y, double *lon, double *lat)
Definition: alberinv.c:110
#define GCTP_PRINT_ERROR(format,...)
Definition: oli_local.h:81
float * lat
double phi1z(double eccent, double qs, int32_t *flag)
Definition: proj_cproj.c:115
double adjust_lon(double x)
Definition: proj_cproj.c:349
#define PI
Definition: l3_get_org.c:6
double qsfnz(double eccent, double sinphi, double cosphi)
Definition: proj_cproj.c:97
void gctp_print_stanparl(double A, double B)
Definition: gctp_report.c:73
void gctp_print_offsetp(double A, double B)
Definition: gctp_report.c:91
#define OK
Definition: ancil.h:30
#define sincos
Definition: proj_define.h:108
void gctp_print_radius2(double radius1, double radius2)
Definition: gctp_report.c:30
void gctp_print_cenlonmer(double A)
Definition: gctp_report.c:48
double gctp_calc_small_radius(double eccent, double sinphi, double cosphi)
Definition: gctp_utility.c:253
#define fabs(a)
Definition: misc.h:93
float * lon
long alberinvint(double r_maj, double r_min, double lat1, double lat2, double lon0, double lat0, double false_east, double false_north)
Definition: alberinv.c:38
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
#define EPSLN
Definition: proj_define.h:86