|
ocssw
1.0
|
00001 /* 00002 This file contains all subroutines for the seawifs level 3 binning 00003 */ 00004 00005 00006 #include <sys/types.h> 00007 #include <math.h> 00008 #include <stdlib.h> 00009 00010 #include <seaproto.h> 00011 00012 #define PI 3.141592653589793 00013 00014 /* 00015 global variables only used inside this file, the call to 'bin_init' 00016 may pass these variables to the calling routine 00017 00018 NUMROWS : total number of rows for binning 00019 *NUMBIN : no. of bin in each row 00020 *BASEBIN: 1st bin of each row 00021 TOTBINS: total bin numbers 00022 *LATBIN: center latitude of each row 00023 */ 00024 00025 int32 *NUMBIN, *BASEBIN; 00026 float *LATBIN; 00027 int32 TOTBINS; 00028 int32 NUMROWS; 00029 float SEAM_LON; 00030 00031 /* 00032 bin_init: given the total row number, this subroutine returns 00033 above variables. 00034 00035 */ 00036 00037 void bin_init(int32 nrow, int32 **nbin, int32 **bbin, float **lbin, int32 *tbin) 00038 { 00039 int i; 00040 double radfac; 00041 static int first=1; 00042 00043 if (nrow == -1) /* free the memory if not the first call */ 00044 { 00045 free(NUMBIN); 00046 free(BASEBIN); 00047 free(LATBIN); 00048 first = 1; 00049 return; 00050 } 00051 00052 // if (!first) return; // remove JMG 03/19/09 00053 first = 0; 00054 00055 00056 SEAM_LON = -180.0; /* this value should be passed in */ 00057 NUMROWS = nrow; 00058 00059 NUMBIN = (int32 *) calloc(NUMROWS, sizeof(int32)); 00060 BASEBIN = (int32 *) calloc(NUMROWS, sizeof(int32)); 00061 LATBIN = (float *) calloc(NUMROWS, sizeof(float)); 00062 00063 radfac = PI / 180.0; 00064 00065 for (i=0; i<NUMROWS; i++) 00066 { 00067 *(LATBIN+i) = (i + 0.5) * (180.0 / NUMROWS) - 90.0; 00068 *(NUMBIN+i) = (int32) (cos(*(LATBIN+i)*radfac) * (2.0 * NUMROWS) + 0.5); 00069 } 00070 00071 *BASEBIN = 1; 00072 00073 for (i=1; i<NUMROWS; i++) 00074 *(BASEBIN+i) = *(BASEBIN+i-1) + *(NUMBIN+i-1); 00075 00076 TOTBINS = *(BASEBIN+NUMROWS-1) + *(NUMBIN+NUMROWS-1) - 1; 00077 00078 *nbin = NUMBIN; /* pass pointer back to the calling routine */ 00079 *bbin = BASEBIN; 00080 *lbin = LATBIN; 00081 *tbin = TOTBINS; 00082 } 00083 00084 00085 00086 00087 /* 00088 given a bin number, return the center lat/lon of that bin number 00089 heuristic and binary search algorithm is used 00090 */ 00091 void bin2ll(int32 bin, float *lat, float *lon) 00092 { 00093 int32 row, rlow, rhi, rmid; 00094 static int32 old_row=0; /* 1-relative */ 00095 00096 if (old_row > 0 && *(BASEBIN+old_row-1) <= bin && *(BASEBIN+old_row) > bin) 00097 { 00098 row = old_row; 00099 } 00100 else 00101 { 00102 if (bin < 1) 00103 bin = 1; /* south pole */ 00104 if (bin > TOTBINS) 00105 bin = TOTBINS; /* north pole */ 00106 00107 /* binary search for row in range [1..NUMROWS] */ 00108 rlow = 1; /* 1-relative */ 00109 rhi = NUMROWS; /* 1-relative */ 00110 while (1) 00111 { 00112 rmid = (rlow + rhi - 1) / 2; /* 0-relative */ 00113 if (*(BASEBIN+rmid) > bin) 00114 rhi = rmid; 00115 else 00116 rlow = rmid + 1; 00117 00118 if (rlow == rhi) 00119 { 00120 row = rlow; 00121 break; 00122 } 00123 } 00124 old_row = row; 00125 } 00126 00127 *lat = *(LATBIN+row-1); 00128 *lon = 360.0 * (bin - *(BASEBIN+row-1) + 0.5) / *(NUMBIN+row-1); 00129 *lon = *lon + SEAM_LON; /* note, *lon returned here may be in 0 to 360 */ 00130 } 00131 00132 00133 00134 /* 00135 given the lat/lon, return the bin number 00136 lon has to be in the range of -180.0 to 180.0 00137 */ 00138 void ll2bin(float lat, float lon, int32 *bin) 00139 { 00140 int32 row, col; /* 0-relative */ 00141 00142 row = (int32) ((90.0 + lat) * (float) NUMROWS / 180.0); 00143 col = (int32) ((float) (*(NUMBIN+row)) * (lon - SEAM_LON) / 360.0); 00144 *bin = *(BASEBIN+row) + col; 00145 } 00146 00147 00148 00149 00150 /* 00151 given the lat/lon, return the row, column 00152 lon has to be in the range of -180.0 to 180.0 00153 00154 6/96. Cast double in order to get same bin #'s for SeaWiFS smap9 00155 and SeaDAS smigen. 00156 */ 00157 void ll2rc(float lat, float lon, int32 *row, int32 *col) 00158 { 00159 *row = (int32) ((90.0 + (double) lat) * (double) NUMROWS / 180.0); 00160 *col = (int32) ((double) (*(NUMBIN + (*row))) * ((double) lon - SEAM_LON) / 360.0); 00161 *row = *row + 1; 00162 *col = *col + 1; 00163 } 00164 00165 00166 00167 00168 /* 00169 given row/column, return lat/lon 00170 */ 00171 void rc2ll(int32 row, int32 col, float *lat, float *lon) 00172 { 00173 *lat = *(LATBIN+row-1); 00174 *lon = SEAM_LON + (360.0 * (col - 0.5) / *(NUMBIN+row-1)); 00175 } 00176 00177 00178 00179 00180 /* 00181 given a row/column number, return the bin number (1-relative) 00182 */ 00183 void rc2bin(int32 row, int32 col, int32 *bin) 00184 { 00185 *bin = *(BASEBIN+row-1) + col - 1; 00186 } 00187 00188 00189 00190 /* 00191 given a bin number, return the row and column (both are 1-relative) 00192 heuristic and binary search algorithm is used 00193 */ 00194 void bin2rc(int32 bin, int32 *row, int32 *col) 00195 { 00196 int32 rlow, rhi, rmid; 00197 static int32 old_row=0; /* 1-relative */ 00198 00199 if (old_row > 0 && *(BASEBIN+old_row-1) <= bin && *(BASEBIN+old_row) > bin) 00200 { 00201 *row = old_row; 00202 } 00203 else 00204 { 00205 if (bin < 1) 00206 bin = 1; /* south pole */ 00207 if (bin > TOTBINS) 00208 bin = TOTBINS; /* north pole */ 00209 00210 /* binary search for row in range [1..NUMROWS] */ 00211 rlow = 1; /* 1-relative */ 00212 rhi = NUMROWS; /* 1-relative */ 00213 while (1) 00214 { 00215 rmid = (rlow + rhi - 1) / 2; /* 0-relative */ 00216 if (*(BASEBIN+rmid) > bin) 00217 rhi = rmid; 00218 else 00219 rlow = rmid + 1; 00220 00221 if (rlow == rhi) 00222 { 00223 *row = rlow; 00224 break; 00225 } 00226 } 00227 old_row = *row; 00228 } 00229 00230 *col = bin - *(BASEBIN + (*row) - 1) + 1; 00231 } 00232 00233 00234 00235 /* 00236 given a bin number, return the center lat/lon of that bin number 00237 no heuristic or binary search algorithm is used 00238 this routine is very slow due to the array reference (I think) 00239 */ 00240 00241 /* 00242 void old_bin2ll(bin, lat, lon) 00243 int32 bin; 00244 float *lat, *lon; 00245 { 00246 int32 row; 00247 00248 row = NUMROWS-1; 00249 00250 while (bin < BASEBIN[row]) 00251 row--; 00252 00253 *lat = LATBIN[row]; 00254 *lon = 360.0 * (bin - BASEBIN[row] + 0.5) / NUMBIN[row]; 00255 } 00256 00257 */ 00258 00259 00260 /* update version, much faster than using array reference */ 00261 00262 void old_bin2ll(int32 bin, float *lat, float *lon) 00263 { 00264 int32 row; 00265 int32 *tmpptr; 00266 00267 row = NUMROWS - 1; 00268 tmpptr = BASEBIN + NUMROWS - 1; 00269 00270 while (bin < *tmpptr--) 00271 row--; 00272 00273 *lat = LATBIN[row]; 00274 *lon = 360.0 * (bin - BASEBIN[row] + 0.5) / NUMBIN[row]; 00275 } 00276
1.7.6.1