window_map.c

Go to the documentation of this file.
00001 /*************************************************************
00002  * G__create_window_mapping(fd)
00003  *    int fd                   file descriptor for map to be mapped
00004  *
00005  * function:
00006  *     create mapping from cell header into window
00007  *     the boundaries and resolution of the two spaces do not
00008  *     have to be the same or aligned in any way.
00009  * parms:
00010  *     fd:      open file descriptor for cell file
00011  *
00012  * called by:
00013  *     G_open_cell_old()
00014  *     G_set_window()
00015  ***************************************************************
00016  * G_window_rows(), G_window_cols()
00017  *
00018  * function
00019  *      return the number of rows, cols in the current window
00020  *
00021  * parms: (none)
00022  *
00023  * called by
00024  *      any user program
00025  *************************************************************/
00026 
00027 #include <stdlib.h>
00028 #include "gis.h"
00029 #include "G.h"
00030 
00031 #define FCB     G__.fileinfo[fd]
00032 #define CMAP    FCB.col_map
00033 #define CELLHD  FCB.cellhd
00034 #define WINDOW  G__.window
00035 #define WINDOW_NCOLS  WINDOW.cols
00036 #define WINDOW_NROWS  WINDOW.rows
00037 
00038 int G__create_window_mapping (int fd)
00039 {
00040     COLUMN_MAPPING *col;
00041     int i;
00042     int x;
00043     double C1, C2;
00044     double west;
00045 
00046     G__init_window () ;
00047 
00048 #define alloc_index(n) (COLUMN_MAPPING *) G_malloc((n)*sizeof(COLUMN_MAPPING))
00049 
00050     if (FCB.open_mode >= 0 && FCB.open_mode != OPEN_OLD)  /* open for write? */
00051         return 0;
00052     if (FCB.open_mode == OPEN_OLD) /* already open ? */
00053         free (CMAP);
00054 
00055     col = CMAP = alloc_index (WINDOW_NCOLS) ;
00056 
00057 /*
00058  * for each column in the window, go to center of the cell,
00059  * compute nearest column in the data file
00060  * if column is not in data file, set column to 0
00061  *
00062  * for lat/lon move window so that west is bigger than
00063  * cellhd west.
00064  */
00065     west = WINDOW.west;
00066     if (WINDOW.proj == PROJECTION_LL)
00067     {
00068         while (west > CELLHD.west + 360.0)
00069             west -=360.0;
00070         while (west < CELLHD.west)
00071             west += 360.0;
00072     }
00073 
00074     C1 = WINDOW.ew_res / CELLHD.ew_res ;
00075     C2 = (west - CELLHD.west + WINDOW.ew_res/2.0) / CELLHD.ew_res; 
00076     for (i = 0; i < WINDOW_NCOLS; i++)
00077     {
00078         x = C2;
00079         if (C2 < x)    /* adjust for rounding of negatives */
00080             x--;
00081         if (x < 0 || x >= CELLHD.cols) /* not in data file */
00082             x = -1;
00083         *col++ = x+1;
00084         C2 += C1;
00085     }
00086 
00087 /* do wrap around for lat/lon */
00088     if (WINDOW.proj == PROJECTION_LL)
00089     {
00090         col = CMAP;
00091         C2 = (west - 360.0 - CELLHD.west + WINDOW.ew_res/2.0) / CELLHD.ew_res; 
00092         for (i = 0; i < WINDOW_NCOLS; i++)
00093         {
00094             x = C2;
00095             if (C2 < x)    /* adjust for rounding of negatives */
00096                 x--;
00097             if (x < 0 || x >= CELLHD.cols) /* not in data file */
00098                 x = -1;
00099             if (*col == 0)  /* only change those not already set */
00100                 *col = x+1;
00101             col++;
00102             C2 += C1;
00103         }
00104     }
00105 
00106 #ifdef DEBUG
00107 fprintf (stderr, "create window mapping (%d cols)", WINDOW_NCOLS);
00108     for (i = 0; i < WINDOW_NCOLS; i++)
00109         fprintf (stderr, "%s%ld", i%15?" ":"\n", (long)CMAP[i]);
00110     fprintf (stderr, "\n");
00111 #endif
00112 
00113 /*
00114  * compute C1,C2 for row window mapping 
00115  */
00116     FCB.C1 = WINDOW.ns_res / CELLHD.ns_res ;
00117     FCB.C2 = (CELLHD.north - WINDOW.north + WINDOW.ns_res/2.0) / CELLHD.ns_res; 
00118 
00119     return 0;
00120 }
00121 
00122 
00136 double G_northing_to_row (double north,
00137     struct Cell_head *window)
00138 {
00139     return (window->north - north) / window->ns_res;
00140 }
00141 
00142 
00155 double G_adjust_east_longitude (
00156     double east,double west)
00157 {
00158     while (east > west + 360.0)
00159         east -=360.0;
00160     while (east <= west)
00161         east += 360.0;
00162     return east;
00163 }
00164 
00165 
00180 double G_adjust_easting ( double east,
00181     struct Cell_head *window)
00182 {
00183     if (window->proj == PROJECTION_LL)
00184     {
00185         east = G_adjust_east_longitude(east, window->west);
00186         if (east > window->east && east == window->west + 360)
00187             east = window->west;
00188     }
00189     return east;
00190 }
00191 
00192 double G_easting_to_col ( double east,
00193     struct Cell_head *window)
00194 {
00195     east = G_adjust_easting (east, window);
00196     return (east - window->west) / window->ew_res;
00197 }
00198 
00199 /* note: row is a double.
00200  *       row+0.5 will give center
00201  *       row+0.0 will give northern edge of row
00202  *       row+1.0 will give southern edge of row
00203  */
00204 
00224 double G_row_to_northing ( double row,
00225     struct Cell_head *window)
00226 {
00227     return window->north - row * window->ns_res;
00228 }
00229 
00230 
00246 double G_col_to_easting (double col,
00247     struct Cell_head *window)
00248 {
00249     return window->west + col * window->ew_res;
00250 }
00251 
00252 
00261 int G_window_rows ()
00262 {
00263     G__init_window () ;
00264 
00265     return WINDOW_NROWS;
00266 }
00267 
00268 
00295 int G_window_cols ()
00296 {
00297     G__init_window () ;
00298     
00299     return WINDOW_NCOLS;
00300 }
00301 
00302 int G__init_window ()
00303 {
00304     if (!G__.window_set)
00305     {
00306         G__.window_set = 1;
00307         G_get_window (&G__.window);
00308     }
00309 
00310     return 0;
00311 }
00312 
00313 /* this routine works fine if the mask is not set
00314  * may give incorrect results with a mask, since the
00315  * mask row may have a different repeat value
00316  * can be fixed by doing it for the mask as well and using
00317  * the smaller value
00318  */
00319 
00320 int G_row_repeat_nomask (int fd, int row)
00321 {
00322     double f;
00323     int r1, r2;
00324     int count;
00325 
00326     count = 1;
00327 
00328 /* r1 is the row in the cell file itself.
00329  * r2 is the next row(s) in the cell file
00330  * see get_row.c for details on this calculation
00331  */
00332     f = row * FCB.C1 + FCB.C2;
00333     r1 = f;
00334     if (f < r1)
00335         r1--;
00336 
00337     while (++row < WINDOW_NROWS)
00338     {
00339         f = row * FCB.C1 + FCB.C2;
00340         r2 = f;
00341         if (f < r2)
00342             r2--;
00343         if (r1 != r2)
00344             break;
00345         count++;
00346     }
00347     return count;
00348 }

Generated on Sat Jul 22 22:06:15 2006 for GRASS by  doxygen 1.4.7