/* !C***************************************************************************** !Description: A short C program to convert a point at latitude and longitude to row and column numbers in sinusoidal (SIN) or integerized sinusoidal (ISIN) tile, in the V4 MOD11 and V3 MOD11 products, respectively. Minor modifications were made in order to deal with the boundaries of tiles appropriately. !Input Parameters: lat and lon (in degrees) as the 1st and 2nd arguments. is_sin (optional) in the 3rd argument, default 1 for SIN or 0 for ISIN. !Output Parameters (as stdout): ih and iv (tile IDs) values of row and column centers (starting from 0) and the distances from the centers in the 1km-resolution tile values of row and column centers (starting from 0) and the distances from the centers in the 5km-resolution tile. !Revision History: $Log: lat_lon_to_row_col.c $ Revision 4.2.0 2004/01/31 10:31 Z. Wan !Team-unique Header: This program is a part of the code developed by Zhengming Wan (wan@icess.ucsb.edu), University of California, Santa Barbara for the National Aeronautics and Space Administration, Goddard Space Flight Center, under NASA contract NAS5-31370. It is adapted from L2B library functions Lbin_SelTile_sin(), Lbin_SelTile_isin(), Lbin_FwdW_sin() and Lbin_FwdW_isin() written by Robert Wolfe, MODIS Land Team Support Group (robert.e.wolfe.1@gsfc.nasa.gov) in the MODIS Land Science Team led by Chris Justice (justice@hermes.geog.umd.edu), based on the software with * Original Copyright from RATFOR version: * * Copyright 1988-1992 by Rosenstiel School of Marine and Atmospheric Science, * University of Miami, Miami, Florida. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for non-commercial purposes and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that both * that copyright notice and this permission notice appear in supporting * documentation, and that the names of University of Miami and/or RSMAS not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. * * UNIVERSITY OF MIAMI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT * SHALL UNIVERSITY OF MIAMI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. !END*************************************************************************** */ #include #include #include #include #include #define RE_IS 6371.007181 /* Earth radius (km), sphere with the best surface area fit of WGS84 ellipsoid, being consistent with grid.h in PGE12/MOD_PRMGPNTR */ #define PI (4.0 * atan(1.0)) #define HALFPI (2.0 * atan(1.0)) double ang_size_lat_1km; double hf_ang_size_lat_1km; double ang_size_lon_1km; int nrow_1km = 1200; int ncol_1km = 1200; int tot_nrow_1km, tot_ncol_1km; int nrow_5km = 240; int ncol_5km = 240; main(int argc, char **argv) { int i, j; int is_sin = 1; int i_1km_glb_loc, i_1km_glb, i_1km_tile, i_5km_glb; int j_1km_glb_loc, j_1km_glb, j_1km_tile, j_5km_glb; int i_5km, j_5km; int ih_grid, iv_grid; double lat, lon; double lat_rad, lon_rad; double f_row, f_col; double f_row_glb, f_col_glb, f_col_glb_loc; double f_row_tile, f_col_tile, delta = 1.0e-8; double f_row_5km_glb, f_col_5km_glb; double f_row_5km_tile, f_col_5km_tile; double full_ncol_cen, half_ncol_cen, n_col_glb_start; double row_cen_lat, row_blat, row_ref_lon; if ( argc < 3 ) { fprintf(stderr, "usage: %s lat lon [is_sin]\n", argv[0]); exit (1); } lat = atof (argv[1]); lon = atof (argv[2]); if ( argc >= 4 ) is_sin = atoi (argv[3]); lat_rad = lat * PI / 180.0; lon_rad = lon * PI / 180.0; tot_nrow_1km = 18 * nrow_1km; tot_ncol_1km = 36 * ncol_1km; ang_size_lat_1km = PI / tot_nrow_1km; hf_ang_size_lat_1km = 0.5 * ang_size_lat_1km; f_row_glb = (HALFPI - lat_rad) / ang_size_lat_1km - delta; iv_grid = f_row_glb / nrow_1km; f_row_tile = f_row_glb - iv_grid * nrow_1km; i_1km_tile = f_row_tile; f_row_tile -= i_1km_tile + 0.5; i_1km_glb = f_row_glb; f_row_glb -= i_1km_glb + 0.5; row_cen_lat = HALFPI - (i_1km_glb * ang_size_lat_1km + hf_ang_size_lat_1km); row_blat = row_cen_lat; full_ncol_cen = tot_ncol_1km * cos(row_blat) + 0.5; half_ncol_cen = 0.5 * full_ncol_cen; ang_size_lon_1km = ang_size_lat_1km / cos(row_blat); row_ref_lon = -PI; if ( is_sin ) { row_blat = (lat_rad < 0) ? row_cen_lat - 0.5 * ang_size_lat_1km : row_cen_lat + 0.5 * ang_size_lat_1km; full_ncol_cen = 2 * (int) ( 0.5 * tot_ncol_1km * cos(row_blat) ); half_ncol_cen = 0.5 * full_ncol_cen; if ( cos(row_blat) > 0.25 * ang_size_lat_1km ) ang_size_lon_1km = ang_size_lat_1km / cos(row_blat); row_ref_lon = - half_ncol_cen * ang_size_lon_1km; } n_col_glb_start = 0.5 * tot_ncol_1km - half_ncol_cen; f_col_glb_loc = (lon_rad - row_ref_lon) / ang_size_lon_1km - delta; j_1km_glb_loc = f_col_glb_loc; if ( j_1km_glb_loc >= tot_ncol_1km ) j_1km_glb_loc = tot_ncol_1km - 1; j_1km_glb = n_col_glb_start + j_1km_glb_loc; f_col_glb = f_col_glb_loc - j_1km_glb_loc - 0.5; ih_grid = j_1km_glb / ncol_1km; j_1km_tile = j_1km_glb - ih_grid * ncol_1km; f_col_tile = f_col_glb; f_row_5km_glb = (i_1km_glb + f_row_glb + 0.5) / 5.0; i_5km_glb = f_row_5km_glb; f_row_5km_glb -= i_5km_glb + 0.5; f_col_5km_glb = (j_1km_glb + f_col_glb + 0.5) / 5.0; j_5km_glb = f_col_5km_glb; f_col_5km_glb -= j_5km_glb + 0.5; f_row = (i_1km_tile + f_row_tile + 0.5) / 5.0; i_5km = f_row; f_row -= i_5km + 0.5; f_col = (j_1km_tile + f_col_tile + 0.5) / 5.0; j_5km = f_col; f_col -= j_5km + 0.5; printf("latitude %.4f longitude %.4f in %s tile h%02dv%02d\n", lat, lon, (is_sin) ? "SIN" : "ISIN", ih_grid, iv_grid); printf("\t\t at row %4d%s%5.3f col %4d%s%5.3f in 1km-resolution tile\n", i_1km_tile, (f_row_tile > 0.0) ? "+" : "", f_row_tile, j_1km_tile, (f_col_tile > 0.0) ? "+" : "", f_col_tile); printf("\t\t row %4d%s%5.3f col %4d%s%5.3f in 5km-resolution tile.\n", i_5km, (f_row > 0.0)? "+" : "", f_row, j_5km, (f_col > 0.0)? "+" : "", f_col ); return; }