OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
imolwfor.c
Go to the documentation of this file.
1 /*******************************************************************************
2 NAME INTERRUPTED MOLLWEIDE
3 
4 PURPOSE: Transforms input longitude and latitude to Easting and
5  Northing for the Interrupted Mollweide projection. The
6  longitude and latitude must be in radians. The Easting
7  and Northing values will be returned in meters.
8 
9 ALGORITHM REFERENCES
10 
11 1. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
12  U.S. Geological Survey Professional Paper 1453 , United State Government
13  Printing Office, Washington D.C., 1989.
14 
15 2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
16  Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
17  State Government Printing Office, Washington D.C., 1987.
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; /* Radius of the earth (sphere) */
25 static double lon_center[6]; /* Central meridians, one for each region */
26 static double feast[6]; /* False easting, one for each region */
27 
28 /* Initialize the Interrupted Mollweide projection
29  --------------------------------------------*/
30 long imolwforint
31 (
32  double r /* (I) Radius of the earth (sphere) */
33 )
34 {
35 /* Place parameters in static storage for common use
36  -------------------------------------------------*/
37 R = r;
38 
39 /* Initialize central meridians for each of the 6 regions
40  ------------------------------------------------------*/
41 lon_center[0] = 1.0471975512; /* 60.0 degrees */
42 lon_center[1] = -2.96705972839; /* -170.0 degrees */
43 lon_center[2] = -0.523598776; /* -30.0 degrees */
44 lon_center[3] = 1.57079632679; /* 90.0 degrees */
45 lon_center[4] = -2.44346095279; /* -140.0 degrees */
46 lon_center[5] = -0.34906585; /* -20.0 degrees */
47 
48 /* Initialize false eastings for each of the 6 regions
49  ---------------------------------------------------*/
50 feast[0] = R * -2.19988776387;
51 feast[1] = R * -0.15713484;
52 feast[2] = R * 2.04275292359;
53 feast[3] = R * -1.72848324304;
54 feast[4] = R * 0.31426968;
55 feast[5] = R * 2.19988776387;
56 
57 /* Report parameters to the user
58  -----------------------------*/
59 gctp_print_title("INTERRUPTED MOLLWEIDE EQUAL-AREA");
61 return(OK);
62 }
63 
64 /* Interrupted Mollweide forward equations--mapping lat,long to x,y
65  -------------------------------------------------------------*/
66 long imolwfor
67 (
68  double lon, /* (I) Longitude */
69  double lat, /* (I) Latitude */
70  double *x, /* (O) X projection coordinate */
71  double *y /* (O) Y projection coordinate */
72 )
73 {
74 double delta_lon; /* Delta longitude (Given longitude - center */
75 double theta;
76 double delta_theta;
77 double con;
78 long i;
79 long region;
80 
81 /* Forward equations
82  -----------------*/
83 /* Note: PI has been adjusted so that the correct region will be assigned
84  when lon = 180 deg.
85  ----------------------------------------------------------------------*/
86 if (lat >= 0.0)
87  {
88  if (lon >= 0.34906585 && lon < 1.91986217719) region = 0;
89  else if
90  ((lon >= 1.919862177 && lon <= (PI + 1.0E-14)) ||
91  (lon >= (-PI - 1.0E-14) && lon < -1.745329252))
92  region=1;
93  else region = 2;
94  }
95 else
96  {
97  if (lon >= 0.34906585 && lon < 2.44346095279) region = 3;
98  else if
99  ((lon >= 2.44346095279 && lon <= (PI +1.0E-14)) ||
100  (lon >= (-PI - 1.0E-14) && lon<-1.2217304764))
101  region=4;
102  else region = 5;
103  }
104 
105 delta_lon = adjust_lon(lon - lon_center[region]);
106 theta = lat;
107 con = PI * sin(lat);
108 
109 /* Iterate using the Newton-Raphson method to find theta
110  -----------------------------------------------------*/
111 for (i=0;;i++)
112  {
113  delta_theta = -(theta + sin(theta) - con) / (1.0 + cos(theta));
114  theta += delta_theta;
115  if (fabs(delta_theta) < EPSLN) break;
116  if (i >= 50)
117  GCTP_PRINT_ERROR("Iteration failed to converge");
118  }
119 theta /= 2.0;
120 
121 /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"
122  this is done here because of percision problems with "cos(theta)"
123  --------------------------------------------------------------------------*/
124 if (PI / 2 - fabs(lat) < EPSLN)
125  delta_lon = 0;
126 *x = feast[region] + 0.900316316158 * R * delta_lon * cos(theta);
127 *y = R * 1.4142135623731 * sin(theta);
128 return(OK);
129 }
int r
Definition: decode_rs.h:73
void gctp_print_title(const char *proj_name)
Definition: gctp_report.c:14
#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
#define OK
Definition: ancil.h:30
#define fabs(a)
Definition: misc.h:93
float * lon
long imolwfor(double lon, double lat, double *x, double *y)
Definition: imolwfor.c:67
void gctp_print_radius(double radius)
Definition: gctp_report.c:22
#define R
Definition: make_L3_v1.1.c:96
long imolwforint(double r)
Definition: imolwfor.c:31
int i
Definition: decode_rs.h:71
#define EPSLN
Definition: proj_define.h:86