|
ocssw
1.0
|
00001 /* 00002 This program extracts data from level-3 HDF bin files and 00003 writes them out as an ASCII table. 00004 00005 Regions of interest can be specified by latitude and longitude 00006 boundaries or by a central coordinate and a radius in kilometers. 00007 00008 Norman Kuring 14-Feb-2003 Original development 00009 Norman Kuring 11-Dec-2007 Fix memory-overrun bug and add a 00010 couple of calls to free(). 00011 Norman Kuring 21-Dec-2011 Give a precision when printing out 00012 bit strings to avoid unwanted printing 00013 of uninitialized memory. 00014 Norman Kuring 21-Mar-2013 Change the latbin array from 32-bit 00015 floats to 64-bit to reduce rounding- 00016 error effects on bin numbers at smaller 00017 bin sizes. Thanks to George White for 00018 pointing this one out. 00019 */ 00020 00021 #include <stdio.h> 00022 #include <stdlib.h> 00023 #include <string.h> 00024 #include <math.h> 00025 #include "hdf.h" 00026 00027 #define PI 3.1415926535897932384626433832795029L 00028 00029 double sqrt(double x); 00030 double asin(double x); 00031 double sin(double x); 00032 double cos(double x); 00033 double fabs(double x); 00034 00035 #define INFILE argv[1] 00036 #define PARAM argv[2] 00037 00038 #define USAGE(prog) fprintf(stderr,"\ 00039 Usage:\n\ 00040 %s main_file_path parameter bin_number\n\ 00041 or\n\ 00042 %s main_file_path parameter lat lon radius\n\ 00043 or\n\ 00044 %s main_file_path parameter north south west east\n\ 00045 ",prog,prog,prog) 00046 00047 #define NUMROWS 2160 00048 #define EARTH_RADIUS 6371.229 00049 00050 static int32 basebin[NUMROWS]; 00051 static int16 numbin[NUMROWS]; 00052 static float64 latbin[NUMROWS]; 00053 static int32 totbins; 00054 00055 #define BLIST_FIELDS "bin_num,nobs,nscenes,time_rec,weights,sel_cat,flags_set" 00056 #define BLIST_SIZE 19 00057 static uint8 blistrec[BLIST_SIZE]; 00058 static int32 bin_num,flags_set; 00059 static int16 nobs,nscenes,time_rec; 00060 static float32 weights; 00061 static uint8 sel_cat; 00062 static VOIDP bufptrs[] = { 00063 &bin_num,&nobs,&nscenes,&time_rec,&weights,&sel_cat,&flags_set 00064 }; 00065 00066 #define PREC_SIZE 8 00067 static uint8 paramrec[PREC_SIZE]; 00068 static char *param_fields; 00069 static float32 sum,sum_sq; 00070 static VOIDP paramptrs[] = {&sum,&sum_sq}; 00071 00072 void initbin(void); 00073 int32 latlon2bin(double lat, double lon); 00074 void bin2latlon(int32 bin, double *clat, double *clon); 00075 void bin2bounds(int32 bin, double *n, double *s, double *w, double *e); 00076 int16 lat2row(double lat); 00077 int32 rowlon2bin(int16 row, double lon); 00078 int32 binsearch(int32 bin, int32 vdata_id, int32 numrecs); 00079 double constrain_lat(double lat); 00080 double constrain_lon(double lon); 00081 char *bitstr16(int16 n); 00082 char *bitstr32(int32 n); 00083 00084 int main(int argc, char *argv[]){ 00085 00086 int32 numbins = 0, *binnums = NULL; 00087 int32 i; 00088 int32 file_id,vdata_ref,vdata_id,numrecs,pvd_id; 00089 00090 initbin(); 00091 00092 if(argc == 4){ 00093 /* Input arguments are: main_file_path parameter bin_number. */ 00094 int32 bin_number; 00095 bin_number = atol(argv[3]); 00096 numbins = 1; 00097 binnums = (int32 *)malloc(sizeof(int32)); 00098 if(binnums == NULL){ 00099 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00100 __FILE__,__LINE__); 00101 return(EXIT_FAILURE); 00102 } 00103 binnums[0] = bin_number; 00104 } 00105 00106 else if(argc == 6){ 00107 /* Input arguments are: main_file_path parameter lat lon radius. */ 00108 double clat, clon, radius, radius_degrees; 00109 00110 clat = constrain_lat(atof(argv[3])); 00111 clon = constrain_lon(atof(argv[4])); 00112 radius = atof(argv[5]); 00113 00114 radius_degrees = (radius/EARTH_RADIUS) * (180.0/PI); 00115 if(radius_degrees > 180){ 00116 int32 b; 00117 00118 /* The entire globe has been selected. */ 00119 binnums = (int32 *)realloc(binnums,totbins*sizeof(int32)); 00120 if(binnums == NULL){ 00121 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00122 __FILE__,__LINE__); 00123 return(EXIT_FAILURE); 00124 } 00125 for(b = 1; b <= totbins; b++){ 00126 binnums[numbins++] = b; 00127 } 00128 } 00129 else{ 00130 double north, south; 00131 double sin_c_over_2; 00132 int16 n_row, s_row, row; 00133 00134 sin_c_over_2 = sin((radius/EARTH_RADIUS)/2); 00135 00136 north = clat + radius_degrees; 00137 south = clat - radius_degrees; 00138 00139 if(north > 90){ 00140 /* 00141 Chosen radius extends north to pole and over the other side to some 00142 latitude south of the north pole. Set the new north to this new 00143 latitude. All bins north of this latitude get selected. 00144 */ 00145 int32 n, b; 00146 00147 north = 180 - north; 00148 n_row = lat2row(north); 00149 n = totbins - basebin[n_row] + 1; 00150 binnums = (int32 *)realloc(binnums,(numbins + n)*sizeof(int32)); 00151 if(binnums == NULL){ 00152 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00153 __FILE__,__LINE__); 00154 return(EXIT_FAILURE); 00155 } 00156 for(b = basebin[n_row]; b <= totbins; b++){ 00157 binnums[numbins++] = b; 00158 } 00159 } 00160 else{ 00161 n_row = lat2row(north) + 1; 00162 } 00163 00164 if(south < -90){ 00165 /* 00166 Chosen radius extends south to pole and over the other side to some 00167 latitude north of the south pole. Set the new south to this new 00168 latitude. All bins south of this latitude get selected. 00169 */ 00170 int32 n, b; 00171 00172 south = -180 - south; 00173 s_row = lat2row(south); 00174 n = basebin[s_row] + numbin[s_row]; 00175 binnums = (int32 *)realloc(binnums,(numbins + n)*sizeof(int32)); 00176 if(binnums == NULL){ 00177 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00178 __FILE__,__LINE__); 00179 return(EXIT_FAILURE); 00180 } 00181 for(b = 1; b <= n; b++){ 00182 binnums[numbins++] = b; 00183 } 00184 } 00185 else{ 00186 s_row = lat2row(south) - 1; 00187 } 00188 00189 for(row = s_row + 1; row < n_row; row++){ 00190 double deltalon; 00191 double sin_deltalat_over_2; 00192 double west, east; 00193 00194 sin_deltalat_over_2 = sin((latbin[row] - clat)*(PI/180.0) / 2); 00195 00196 /* 00197 The following equation is a rearranged version of 00198 Equation 5-3a on page 30 of 00199 Map Projections -- A Working Manual 00200 by John P. Snyder 00201 U.S. Geological Survey Professional Paper 1395 00202 1987 00203 (Fourth printing 1997) 00204 */ 00205 deltalon = 2 * asin( sqrt( fabs( 00206 (sin_c_over_2*sin_c_over_2 - sin_deltalat_over_2*sin_deltalat_over_2) 00207 /( cos(latbin[row]*(PI/180.0)) * cos(clat*(PI/180.0)) ) 00208 ))); 00209 00210 deltalon *= 180.0/PI; 00211 00212 west = constrain_lon(clon - deltalon); 00213 east = constrain_lon(clon + deltalon); 00214 00215 if(east < west){ 00216 /* User's region of interest spans the 180-degree meridian. */ 00217 int32 b,b1,b2,b3,b4,n1,n2; 00218 b1 = rowlon2bin(row,west); 00219 b2 = rowlon2bin(row, 180); 00220 b3 = rowlon2bin(row,-180); 00221 b4 = rowlon2bin(row,east); 00222 n1 = b2 - b1 + 1; 00223 n2 = b4 - b3 + 1; 00224 binnums = (int32 *)realloc(binnums,(numbins + n1 + n2)*sizeof(int32)); 00225 if(binnums == NULL){ 00226 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00227 __FILE__,__LINE__); 00228 return(EXIT_FAILURE); 00229 } 00230 for(b = b1; b <= b2; b++){ 00231 binnums[numbins++] = b; 00232 } 00233 for(b = b3; b <= b4; b++){ 00234 binnums[numbins++] = b; 00235 } 00236 } 00237 else{ 00238 /* User's region of interest does not span the 180-degree meridian. */ 00239 int32 b,b1,bn,n; 00240 00241 b1 = rowlon2bin(row,west); 00242 bn = rowlon2bin(row,east); 00243 n = bn - b1 + 1; 00244 binnums = (int32 *)realloc(binnums,(numbins + n)*sizeof(int32)); 00245 if(binnums == NULL){ 00246 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00247 __FILE__,__LINE__); 00248 return(EXIT_FAILURE); 00249 } 00250 for(b = b1; b <= bn; b++){ 00251 binnums[numbins++] = b; 00252 } 00253 } 00254 } 00255 } 00256 } 00257 00258 else if(argc == 7){ 00259 /* Input arguments are: main_file_path parameter north south west east. */ 00260 double north, south, west, east; 00261 int16 n_row, s_row, row; 00262 00263 north = constrain_lat(atof(argv[3])); 00264 south = constrain_lat(atof(argv[4])); 00265 west = constrain_lon(atof(argv[5])); 00266 east = constrain_lon(atof(argv[6])); 00267 00268 if(south > north){ 00269 double tmp; 00270 00271 fprintf(stderr,"-W- %s line %d: ",__FILE__,__LINE__); 00272 fprintf(stderr, 00273 "Specified south latitude is greater than specified north latitude.\n"); 00274 fprintf(stderr,"I will swap the two.\n"); 00275 tmp = north; 00276 north = south; 00277 south = tmp; 00278 } 00279 00280 n_row = lat2row(north); 00281 s_row = lat2row(south); 00282 00283 for(row = s_row; row <= n_row; row++){ 00284 00285 if(east < west){ 00286 /* User's region of interest spans the 180-degree meridian. */ 00287 int32 b,b1,b2,b3,b4,n1,n2; 00288 b1 = rowlon2bin(row,west); 00289 b2 = rowlon2bin(row, 180); 00290 b3 = rowlon2bin(row,-180); 00291 b4 = rowlon2bin(row,east); 00292 n1 = b2 - b1 + 1; 00293 n2 = b4 - b3 + 1; 00294 binnums = (int32 *)realloc(binnums,(numbins + n1 + n2)*sizeof(int32)); 00295 if(binnums == NULL){ 00296 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00297 __FILE__,__LINE__); 00298 return(EXIT_FAILURE); 00299 } 00300 for(b = b1; b <= b2; b++){ 00301 binnums[numbins++] = b; 00302 } 00303 for(b = b3; b <= b4; b++){ 00304 binnums[numbins++] = b; 00305 } 00306 } 00307 else{ 00308 /* User's region of interest does not span the 180-degree meridian. */ 00309 int32 b,b1,bn,n; 00310 00311 b1 = rowlon2bin(row,west); 00312 bn = rowlon2bin(row,east); 00313 n = bn - b1 + 1; 00314 binnums = (int32 *)realloc(binnums,(numbins + n)*sizeof(int32)); 00315 if(binnums == NULL){ 00316 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00317 __FILE__,__LINE__); 00318 return(EXIT_FAILURE); 00319 } 00320 for(b = b1; b <= bn; b++){ 00321 binnums[numbins++] = b; 00322 } 00323 } 00324 } 00325 } 00326 00327 else{ 00328 USAGE(argv[0]); 00329 return(EXIT_FAILURE); 00330 } 00331 00332 /* 00333 Now that I have a list of desired bins, I can extract the 00334 corresponding data from the level-3 bin files. 00335 */ 00336 00337 /* Open the HDF file. */ 00338 file_id = Hopen(INFILE, DFACC_READ, 0); 00339 if(file_id == FAIL){ 00340 fprintf(stderr,"-E- %s line %d: Hopen(%s,DFACC_READ,0) failed.\n", 00341 __FILE__,__LINE__,INFILE); 00342 return(EXIT_FAILURE); 00343 } 00344 /* Initialize the Vdata interface. */ 00345 if(Vstart(file_id) == FAIL){ 00346 fprintf(stderr,"-E- %s line %d: Vstart(%d) failed.\n", 00347 __FILE__,__LINE__,file_id); 00348 return(EXIT_FAILURE); 00349 } 00350 00351 /* Open the "BinList" Vdata. */ 00352 vdata_ref = VSfind(file_id,"BinList"); 00353 if(vdata_ref == FAIL){ 00354 fprintf(stderr,"-E- %s line %d: VSfind(%d,\"BinList\") failed.\n", 00355 __FILE__,__LINE__,file_id); 00356 return(EXIT_FAILURE); 00357 } 00358 vdata_id = VSattach(file_id, vdata_ref, "r"); 00359 if(vdata_id == FAIL){ 00360 fprintf(stderr,"-E- %s line %d: VSattach(%d,%d,\"r\") failed.\n", 00361 __FILE__,__LINE__,file_id,vdata_ref); 00362 return(EXIT_FAILURE); 00363 } 00364 /* Find out how many bins are stored in this file. */ 00365 numrecs = VSelts(vdata_id); 00366 if(numrecs == FAIL){ 00367 fprintf(stderr,"-E- %s line %d: VSelts(%d) failed.\n", 00368 __FILE__,__LINE__,vdata_id); 00369 return(EXIT_FAILURE); 00370 } 00371 /* Set up to read the fields in the BinList Vdata records. */ 00372 if(VSsetfields(vdata_id,BLIST_FIELDS) == FAIL){ 00373 fprintf(stderr,"-E- %s line %d: VSsetfields(%d,%s) failed.\n", 00374 __FILE__,__LINE__,vdata_id,BLIST_FIELDS); 00375 return(EXIT_FAILURE); 00376 } 00377 00378 /* Open the parameter-specific Vdata. */ 00379 vdata_ref = VSfind(file_id,PARAM); 00380 if(vdata_ref == 0){ 00381 fprintf(stderr,"-E- %s line %d: VSfind(%d,\"%s\") failed.\n", 00382 __FILE__,__LINE__,file_id,PARAM); 00383 return(EXIT_FAILURE); 00384 } 00385 pvd_id = VSattach(file_id, vdata_ref, "r"); 00386 if(pvd_id == FAIL){ 00387 fprintf(stderr,"-E- %s line %d: VSattach(%d,%d,\"r\") failed.\n", 00388 __FILE__,__LINE__,file_id,vdata_ref); 00389 return(EXIT_FAILURE); 00390 } 00391 /* Set up to read the fields in the parameter-specific Vdata records. */ 00392 { 00393 int len; 00394 len = 2*strlen(PARAM) + strlen("_sum,") + strlen("_sum_sq") + 1; 00395 param_fields = (char *)malloc(len); 00396 if(param_fields == NULL){ 00397 fprintf(stderr,"-E- %s line %d: Memory allocation failed.\n", 00398 __FILE__,__LINE__); 00399 return(EXIT_FAILURE); 00400 } 00401 strcpy(param_fields,PARAM); 00402 strcat(param_fields,"_sum,"); 00403 strcat(param_fields,PARAM); 00404 strcat(param_fields,"_sum_sq"); 00405 } 00406 if(VSsetfields(pvd_id,param_fields) == FAIL){ 00407 fprintf(stderr,"-E- %s line %d: VSsetfields(%d,%s) failed.\n", 00408 __FILE__,__LINE__,pvd_id,param_fields); 00409 return(EXIT_FAILURE); 00410 } 00411 00412 /* Output a header record to identify the fields written out below. */ 00413 printf("%80s%15.15s %15.15s\n"," ",PARAM,PARAM); 00414 printf(" bin centerlat centerlon"); 00415 printf(" north south west east"); 00416 printf(" n N sum_obs sum_squared_obs weight"); 00417 printf(" time_trend_bits l2_flag_bits sel\n"); 00418 printf("------- --------- ----------"); 00419 printf(" --------- --------- ---------- ----------"); 00420 printf(" ---- --- --------------- --------------- ---------------"); 00421 printf(" ---------------- -------------------------------- ---\n"); 00422 00423 for(i = 0; i < numbins; i++){ 00424 int32 recno; 00425 00426 recno = binsearch(binnums[i],vdata_id,numrecs); 00427 if(recno >= 0){ 00428 double n,s,w,e,clat,clon; 00429 00430 /* 00431 Read the sum and sum-of-squares for the 00432 the specified parameter for this bin. 00433 */ 00434 if(VSseek(pvd_id,recno) == FAIL){ 00435 fprintf(stderr,"-E- %s line %d: VSseek(%d,%d) failed.\n", 00436 __FILE__,__LINE__,pvd_id,recno); 00437 return(EXIT_FAILURE); 00438 } 00439 if(VSread(pvd_id,paramrec,1,FULL_INTERLACE) != 1){ 00440 fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__); 00441 fprintf(stderr,"VSread(%d,paramrec,1,FULL_INTERLACE) failed.\n", 00442 pvd_id); 00443 return(EXIT_FAILURE); 00444 } 00445 /* 00446 VSfpack() sets the global sum and sum_sq variables 00447 via the paramptrs pointer array. 00448 */ 00449 if( 00450 VSfpack( 00451 pvd_id,_HDF_VSUNPACK,param_fields,paramrec,PREC_SIZE,1,NULL,paramptrs 00452 ) 00453 == FAIL){ 00454 fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__); 00455 fprintf(stderr,"VSfpack(%d, ...) failed.\n", pvd_id); 00456 return(EXIT_FAILURE); 00457 } 00458 00459 /* Get the geographical coordinates associated with this bin. */ 00460 bin2latlon(binnums[i],&clat,&clon); 00461 bin2bounds(binnums[i],&n,&s,&w,&e); 00462 00463 /* Output the results. */ 00464 printf("%7d %9.5f %10.5f %9.5f %9.5f %10.5f %10.5f ", 00465 binnums[i],clat,clon,n,s,w,e); 00466 printf("%4d %3d ",nobs,nscenes); 00467 printf("% .8e % .8e % .8e ",sum,sum_sq,weights); 00468 printf("%.16s %.32s ",bitstr16(time_rec),bitstr32(flags_set)); 00469 printf("%3d",sel_cat); 00470 printf("\n"); 00471 } 00472 00473 } 00474 00475 if(VSdetach(pvd_id) == FAIL){ 00476 fprintf(stderr,"-E- %s line %d: VSdetach(%d) failed.\n", 00477 __FILE__,__LINE__,pvd_id); 00478 return(EXIT_FAILURE); 00479 } 00480 if(VSdetach(vdata_id) == FAIL){ 00481 fprintf(stderr,"-E- %s line %d: VSdetach(%d) failed.\n", 00482 __FILE__,__LINE__,vdata_id); 00483 return(EXIT_FAILURE); 00484 } 00485 if(Vend(file_id) == FAIL){ 00486 fprintf(stderr,"-E- %s line %d: Vend(%d) failed.\n", 00487 __FILE__,__LINE__,file_id); 00488 return(EXIT_FAILURE); 00489 } 00490 if(Hclose(file_id) == FAIL){ 00491 fprintf(stderr,"-E- %s line %d: Hclose(%d) failed.\n", 00492 __FILE__,__LINE__,file_id); 00493 return(EXIT_FAILURE); 00494 } 00495 00496 free(param_fields); 00497 free(binnums); 00498 00499 return(EXIT_SUCCESS); 00500 } /* End of main() function */ 00501 00502 int32 binsearch(int32 bin, int32 vdata_id, int32 numrecs){ 00503 int32 lo, hi, mid; 00504 00505 lo = 0; 00506 hi = numrecs - 1; 00507 while(lo <= hi){ 00508 mid = (lo + hi)/2; 00509 if(VSseek(vdata_id,mid) == FAIL){ 00510 fprintf(stderr,"-E- %s line %d: VSseek(%d,%d) failed.\n", 00511 __FILE__,__LINE__,vdata_id,mid); 00512 exit(EXIT_FAILURE); 00513 } 00514 if(VSread(vdata_id,blistrec,1,FULL_INTERLACE) != 1){ 00515 fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__); 00516 fprintf(stderr,"VSread(%d,blistrec,1,FULL_INTERLACE) failed.\n", 00517 vdata_id); 00518 exit(EXIT_FAILURE); 00519 } 00520 /* 00521 VSfpack() sets the global bin_num variable (and others) 00522 via the bufptrs pointer array. 00523 */ 00524 if( 00525 VSfpack( 00526 vdata_id,_HDF_VSUNPACK,BLIST_FIELDS,blistrec,BLIST_SIZE,1,NULL,bufptrs 00527 ) 00528 == FAIL){ 00529 fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__); 00530 fprintf(stderr,"VSfpack(%d, ...) failed.\n", vdata_id); 00531 exit(EXIT_FAILURE); 00532 } 00533 if (bin < bin_num) hi = mid - 1; 00534 else if(bin > bin_num) lo = mid + 1; 00535 else return(mid); 00536 } 00537 return(-1); 00538 } 00539 00540 char *bitstr16(int16 n){ 00541 static char str[17]; 00542 int i; 00543 00544 str[16]=0; 00545 for(i = 0; i < 16; i++){ 00546 if(n & (1 << i)) str[i] = '1'; 00547 else str[i] = '0'; 00548 } 00549 return(str); 00550 } 00551 00552 char *bitstr32(int32 n){ 00553 static char str[33]; 00554 int i; 00555 00556 str[32] = 0; 00557 for(i = 0; i < 32; i++){ 00558 if(n & (1 << i)) str[i] = '1'; 00559 else str[i] = '0'; 00560 } 00561 return(str); 00562 } 00563 00564 /* 00565 The following functions are based on the pseudocode found in Appendix A of: 00566 00567 Campbell, J.W., J.M. Blaisdell, and M. Darzi, 1995: 00568 Level-3 SeaWiFS Data Products: Spatial and Temporal Binning Algorithms. 00569 NASA Tech. Memo. 104566, Vol. 32, 00570 S.B. Hooker, E.R. Firestone, and J.G. Acker, Eds., 00571 NASA Goddard Space Flight Center, Greenbelt, Maryland 00572 */ 00573 00574 void initbin(void){ 00575 int row; 00576 00577 basebin[0] = 1; 00578 for(row=0; row<NUMROWS; row++){ 00579 latbin[row] = ((row + 0.5)*180.0/NUMROWS) - 90.0; 00580 numbin[row] = (int16)(2*NUMROWS*cos(latbin[row]*PI/180.0) + 0.5); 00581 if(row > 0){ 00582 basebin[row] = basebin[row - 1] + numbin[row - 1]; 00583 } 00584 } 00585 totbins = basebin[NUMROWS - 1] + numbin[NUMROWS - 1] - 1; 00586 } 00587 00588 int16 lat2row(double lat){ 00589 int16 row; 00590 00591 row = (int16)((90 + lat)*NUMROWS/180.0); 00592 if(row >= NUMROWS) row = NUMROWS - 1; 00593 return(row); 00594 } 00595 00596 int32 rowlon2bin(int16 row, double lon){ 00597 int16 col; 00598 int32 bin; 00599 00600 lon = constrain_lon(lon); 00601 col = (int16)((lon + 180.0)*numbin[row]/360.0); 00602 if(col >= numbin[row]) col = numbin[row] - 1; 00603 bin = basebin[row] + col; 00604 return(bin); 00605 } 00606 00607 int32 latlon2bin(double lat, double lon){ 00608 int16 row, col; 00609 int32 bin; 00610 00611 /* Constrain latitudes to [-90,90] and longitudes to [-180,180]. */ 00612 lat = constrain_lat(lat); 00613 lon = constrain_lon(lon); 00614 00615 row = lat2row(lat); 00616 col = (int16)((lon + 180.0)*numbin[row]/360.0); 00617 if(col >= numbin[row]) col = numbin[row] - 1; 00618 bin = basebin[row] + col; 00619 return(bin); 00620 } 00621 00622 void bin2latlon(int32 bin, double *clat, double *clon){ 00623 int16 row; 00624 00625 row = NUMROWS - 1; 00626 if(bin < 1) bin = 1; 00627 while(bin < basebin[row]) row--; 00628 *clat = latbin[row]; 00629 *clon = 360.0*(bin - basebin[row] + 0.5)/numbin[row] - 180.0; 00630 } 00631 00632 void bin2bounds( 00633 int32 bin, 00634 double *north, 00635 double *south, 00636 double *west, 00637 double *east 00638 ){ 00639 int16 row; 00640 double lon; 00641 00642 row = NUMROWS - 1; 00643 if(bin < 1) bin = 1; 00644 while(bin < basebin[row]) row--; 00645 *north = latbin[row] + 90.0/NUMROWS; 00646 *south = latbin[row] - 90.0/NUMROWS; 00647 lon = 360.0*(bin - basebin[row] + 0.5)/numbin[row] - 180.0; 00648 *west = lon - 180.0/numbin[row]; 00649 *east = lon + 180.0/numbin[row]; 00650 } 00651 00652 double constrain_lat(double lat){ 00653 if(lat > 90) lat = 90; 00654 if(lat < -90) lat = -90; 00655 return(lat); 00656 } 00657 00658 double constrain_lon(double lon){ 00659 while(lon < -180) lon += 360; 00660 while(lon > 180) lon -= 360; 00661 return(lon); 00662 }
1.7.6.1