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 <grass/gis.h>
00029 #include "G.h"
00030 
00031 int G__create_window_mapping (int fd)
00032 {
00033     struct fileinfo *fcb = &G__.fileinfo[fd];
00034     COLUMN_MAPPING *col;
00035     int i;
00036     int x;
00037     double C1, C2;
00038     double west;
00039 
00040     G__init_window () ;
00041 
00042 #define alloc_index(n) (COLUMN_MAPPING *) G_malloc((n)*sizeof(COLUMN_MAPPING))
00043 
00044     if (fcb->open_mode >= 0 && fcb->open_mode != OPEN_OLD)  /* open for write? */
00045         return 0;
00046     if (fcb->open_mode == OPEN_OLD) /* already open ? */
00047         G_free (fcb->col_map);
00048 
00049     col = fcb->col_map = alloc_index (G__.window.cols) ;
00050 
00051 /*
00052  * for each column in the window, go to center of the cell,
00053  * compute nearest column in the data file
00054  * if column is not in data file, set column to 0
00055  *
00056  * for lat/lon move window so that west is bigger than
00057  * cellhd west.
00058  */
00059     west = G__.window.west;
00060     if (G__.window.proj == PROJECTION_LL)
00061     {
00062         while (west > fcb->cellhd.west + 360.0)
00063             west -=360.0;
00064         while (west < fcb->cellhd.west)
00065             west += 360.0;
00066     }
00067 
00068     C1 = G__.window.ew_res / fcb->cellhd.ew_res ;
00069     C2 = (west - fcb->cellhd.west + G__.window.ew_res/2.0) / fcb->cellhd.ew_res; 
00070     for (i = 0; i < G__.window.cols; i++)
00071     {
00072         x = C2;
00073         if (C2 < x)    /* adjust for rounding of negatives */
00074             x--;
00075         if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
00076             x = -1;
00077         *col++ = x+1;
00078         C2 += C1;
00079     }
00080 
00081 /* do wrap around for lat/lon */
00082     if (G__.window.proj == PROJECTION_LL)
00083     {
00084         col = fcb->col_map;
00085         C2 = (west - 360.0 - fcb->cellhd.west + G__.window.ew_res/2.0) / fcb->cellhd.ew_res; 
00086         for (i = 0; i < G__.window.cols; i++)
00087         {
00088             x = C2;
00089             if (C2 < x)    /* adjust for rounding of negatives */
00090                 x--;
00091             if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
00092                 x = -1;
00093             if (*col == 0)  /* only change those not already set */
00094                 *col = x+1;
00095             col++;
00096             C2 += C1;
00097         }
00098     }
00099 
00100 #ifdef DEBUG
00101 fprintf (stderr, "create window mapping (%d cols)", G__.window.cols);
00102     for (i = 0; i < G__.window.cols; i++)
00103         fprintf (stderr, "%s%ld", i%15?" ":"\n", (long)fcb->col_map[i]);
00104     fprintf (stderr, "\n");
00105 #endif
00106 
00107 /*
00108  * compute C1,C2 for row window mapping 
00109  */
00110     fcb->C1 = G__.window.ns_res / fcb->cellhd.ns_res ;
00111     fcb->C2 = (fcb->cellhd.north - G__.window.north + G__.window.ns_res/2.0) / fcb->cellhd.ns_res; 
00112 
00113     return 0;
00114 }
00115 
00116 
00130 double G_northing_to_row (double north,
00131     struct Cell_head *window)
00132 {
00133     return (window->north - north) / window->ns_res;
00134 }
00135 
00136 
00149 double G_adjust_east_longitude (
00150     double east,double west)
00151 {
00152     while (east > west + 360.0)
00153         east -=360.0;
00154     while (east <= west)
00155         east += 360.0;
00156     return east;
00157 }
00158 
00159 
00174 double G_adjust_easting ( double east,
00175     struct Cell_head *window)
00176 {
00177     if (window->proj == PROJECTION_LL)
00178     {
00179         east = G_adjust_east_longitude(east, window->west);
00180         if (east > window->east && east == window->west + 360)
00181             east = window->west;
00182     }
00183     return east;
00184 }
00185 
00186 double G_easting_to_col ( double east,
00187     struct Cell_head *window)
00188 {
00189     east = G_adjust_easting (east, window);
00190     return (east - window->west) / window->ew_res;
00191 }
00192 
00193 /* note: row is a double.
00194  *       row+0.5 will give center
00195  *       row+0.0 will give northern edge of row
00196  *       row+1.0 will give southern edge of row
00197  */
00198 
00218 double G_row_to_northing ( double row,
00219     struct Cell_head *window)
00220 {
00221     return window->north - row * window->ns_res;
00222 }
00223 
00224 
00240 double G_col_to_easting (double col,
00241     struct Cell_head *window)
00242 {
00243     return window->west + col * window->ew_res;
00244 }
00245 
00246 
00255 int G_window_rows ()
00256 {
00257     G__init_window () ;
00258 
00259     return G__.window.rows;
00260 }
00261 
00262 
00289 int G_window_cols ()
00290 {
00291     G__init_window () ;
00292     
00293     return G__.window.cols;
00294 }
00295 
00296 int G__init_window ()
00297 {
00298     if (!G__.window_set)
00299     {
00300         G__.window_set = 1;
00301         G_get_window (&G__.window);
00302     }
00303 
00304     return 0;
00305 }
00306 
00307 /* this routine works fine if the mask is not set
00308  * may give incorrect results with a mask, since the
00309  * mask row may have a different repeat value
00310  * can be fixed by doing it for the mask as well and using
00311  * the smaller value
00312  */
00313 
00314 int G_row_repeat_nomask (int fd, int row)
00315 {
00316     struct fileinfo *fcb = &G__.fileinfo[fd];
00317     double f;
00318     int r1, r2;
00319     int count;
00320 
00321     count = 1;
00322 
00323 /* r1 is the row in the cell file itself.
00324  * r2 is the next row(s) in the cell file
00325  * see get_row.c for details on this calculation
00326  */
00327     f = row * fcb->C1 + fcb->C2;
00328     r1 = f;
00329     if (f < r1)
00330         r1--;
00331 
00332     while (++row < G__.window.rows)
00333     {
00334         f = row * fcb->C1 + fcb->C2;
00335         r2 = f;
00336         if (f < r2)
00337             r2--;
00338         if (r1 != r2)
00339             break;
00340         count++;
00341     }
00342     return count;
00343 }

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4