GRASS Programmer's Manual  6.4.2(2012)
edit_cellhd.c
Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003  *
00004  * MODULE:       edit library functions
00005  * AUTHOR(S):    Originally part of gis lib dir in CERL GRASS code
00006  *               Subsequent (post-CVS) contributors:
00007  *               Glynn Clements <glynn gclements.plus.com>,
00008  *               Radim Blazek <radim.blazek gmail.com>,
00009  *               Eric G. Miller <egm2 jps.net>,
00010  *               Markus Neteler <neteler itc.it>,
00011  *               Brad Douglas <rez touchofmadness.com>,
00012  *               Bernhard Reiter <bernhard intevation.de>
00013  * PURPOSE:      libraries for interactively editing raster support data
00014  * COPYRIGHT:    (C) 1996-2006 by the GRASS Development Team
00015  *
00016  *               This program is free software under the GNU General Public
00017  *               License (>=v2). Read the file COPYING that comes with GRASS
00018  *               for details.
00019  *
00020  *****************************************************************************/
00021 #define AS_CELLHD 1
00022 #define AS_WINDOW 0
00023 #define AS_DEF_WINDOW -1
00024 
00025 /* modified 26nov to use word region instead of window
00026  * as far as the USER is concerned.
00027  */
00028 /*
00029  **********************************************************************
00030  *
00031  *   E_edit_cellhd (cellhd, type)
00032  *      struct Cell_head *cellhd   (cellhd to be defined)
00033  *      int type 
00034  *        0 = region - user input resolutions
00035  *       -1 = default region - user input resolutions
00036  *        1 = cellhd - rows and cols must be set
00037  *
00038  *   Screen oriented user interactive session for modifying a cell header
00039  *   or region.
00040  *   Uses the visual_ask V_ask routines.  As such, programs including
00041  *   this must load the GRASS library $(VASKLIB) and include $(CURSES) in
00042  *   in the compile line
00043  *
00044  *   returns:
00045  *      -1 error of some sort, or user cancels the edit
00046  *       0 ok
00047  *
00048  **********************************************************************/
00049 
00050 /* Documentation moved here from the g.region man page:
00051  *  (g.region no longer does interactive; lib/init/set_data.c is the
00052  *   only thing left using E_edit_cellhd() AFAICT.  --HB 28 Jan 2008)
00053  *
00054  * <h2>REGION EDIT PROMPT</h2>
00055  *
00056  * Most of the options will require the user to edit a
00057  * geographic region, be it the current geographic region or
00058  * one stored in the user's named region definitions
00059  * (the <kbd>windows</kbd> directory).  A standard prompt is
00060  * used to perform this edit.  An example is shown below:
00061  *
00062  *
00063  *
00064  * <pre>
00065  * ---------------------------------------------------------------
00066  *  |                         IDENTIFY REGION                     |
00067  *  |                                                             |
00068  *  |           ===========  DEFAULT REGION  ==========           |
00069  *  |           |    Default North: 3402025.00        |           |
00070  *  |           |                                     |           |
00071  *  |           |          ===YOUR REGION===          |           |
00072  *  |           |          |  NORTH EDGE   |          |           |
00073  *  |           |          |  3402025.00_  |          |           |
00074  *  |           |          |               |          |           |
00075  *  | Def West: |WEST EDGE |               |EAST EDGE | Def.East: |
00076  *  | 233975.00 |233975.00_|               |236025.00_| 236025.00 |
00077  *  |           |          |  SOUTH EDGE   |          |           |
00078  *  |           |          |  3399975.00_  |          |           |
00079  *  |           |          =================          |           |
00080  *  |           |                                     |           |
00081  *  |           |    Default South: 3399975.00        |           |
00082  *  |           =======================================           |
00083  *  |                                                             |
00084  *  |              Default   GRID RESOLUTION   Region             |
00085  *  |               50.00   --- East-West ---  50.00__            |
00086  *  |               50.00   -- North-South --  50.00__            |
00087  *  |                                                             |
00088  *  |                                                             |
00089  *  |     AFTER COMPLETING ALL ANSWERS, HIT &lt;ESC&gt; TO CONTINUE     |
00090  *  ---------------------------------------------------------------
00091  *  </pre>
00092  *
00093  *  The fields NORTH EDGE, SOUTH EDGE, WEST EDGE and EAST EDGE,
00094  *  are the boundaries of the geographic region that the user
00095  *  can change.  The fields Default North, Default South, Def
00096  *  West and Def East are the boundaries of the default
00097  *  geographic region that are displayed for reference and
00098  *  <em>cannot</em> be changed.  The two GRID RESOLUTION Region
00099  *  fields (east-west, and north-south) are the geographic
00100  *  region's cell resolutions that the user can change.  The
00101  *  two GRID RESOLUTION Default fields list the resolutions of
00102  *  the default geographic region;  these are displayed for
00103  *  reference and cannot be changed here by the user.
00104  *
00105  */
00106 
00107 #include <string.h>
00108 #include <stdlib.h>
00109 #include <grass/vask.h>
00110 #include <grass/gis.h>
00111 #include <grass/edit.h>
00112 
00113 
00114 static void format_value(int (*func) (double, char *, int),
00115                          double x, char *buf, int projection);
00116 static void format_northing(double north, char *buf, int projection);
00117 static void format_easting(double east, char *buf, int projection);
00118 static void format_resolution(double res, char *buf, int projection);
00119 static int hitreturn(void);
00120 
00121 
00122 static char *cellhd_screen[] = {
00123     "                           IDENTIFY CELL HEADER",
00124     "",
00125     "           ============================= DEFAULT REGION ========",
00126     "           |          Default North:                           |",
00127     "           |                                                   |",
00128     "           |           =======  CELL HEADER  =======           |",
00129     "           |           | NORTH EDGE:               |           |",
00130     "           |           |                           |           |",
00131     " Def. West |WEST EDGE  |                           |EAST EDGE  | Def. East",
00132     "           |           |                           |           |",
00133     "           |           | SOUTH EDGE:               |           |",
00134     "           |           =============================           |",
00135     "           |                                                   |",
00136     "           |          Default South:                           |",
00137     "           =====================================================",
00138     "           PROJECTION:                                ZONE:",
00139     NULL
00140 };
00141 
00142 static char *window_screen[] = {
00143     "                              IDENTIFY REGION",
00144     "",
00145     "           ============================= DEFAULT REGION ========",
00146     "           |          Default North:                           |",
00147     "           |                                                   |",
00148     "           |           =======  YOUR REGION  =======           |",
00149     "           |           | NORTH EDGE:               |           |",
00150     "           |           |                           |           |",
00151     " Def. West |WEST EDGE  |                           |EAST EDGE  | Def. East",
00152     "           |           |                           |           |",
00153     "           |           | SOUTH EDGE:               |           |",
00154     "           |           =============================           |",
00155     "           |                                                   |",
00156     "           |          Default South:                           |",
00157     "           =====================================================",
00158     "           PROJECTION:                                ZONE:",
00159     "",
00160     "                   Default   GRID RESOLUTION   Region",
00161     "                            --- East-West ---",
00162     "                            -- North-South --",
00163     NULL
00164 };
00165 
00166 static char *def_window_screen[] = {
00167     "                         DEFINE THE DEFAULT REGION",
00168     "",
00169     "",
00170     "",
00171     "",
00172     "                       ====== DEFAULT REGION =======",
00173     "                       | NORTH EDGE:               |",
00174     "                       |                           |",
00175     "            WEST EDGE  |                           |EAST EDGE",
00176     "                       |                           |",
00177     "                       | SOUTH EDGE:               |",
00178     "                       =============================",
00179     "",
00180     "",
00181     "",
00182     "           PROJECTION:                                ZONE:",
00183     "",
00184     "                             GRID RESOLUTION",
00185     "                                 East-West:",
00186     "                               North-South:",
00187     NULL
00188 };
00189 
00190 
00191 static void format_value(int (*func) (double, char *, int),
00192                          double x, char *buf, int projection)
00193 {
00194     if (projection != PROJECTION_XY) {
00195         int k = (projection == PROJECTION_LL) ? 3600 : 1;
00196         int i = (int)(x * k + (x < 0 ? -0.5 : 0.5));
00197 
00198         x = (double)i / k;
00199     }
00200 
00201     func(x, buf, projection);
00202     buf[10] = '\0';
00203 }
00204 
00205 
00206 static void format_northing(double north, char *buf, int projection)
00207 {
00208     format_value(G_format_northing, north, buf, projection);
00209 }
00210 
00211 
00212 static void format_easting(double east, char *buf, int projection)
00213 {
00214     format_value(G_format_easting, east, buf, projection);
00215 }
00216 
00217 
00218 static void format_resolution(double res, char *buf, int projection)
00219 {
00220     format_value(G_format_resolution, res, buf, projection);
00221 }
00222 
00223 
00224 int E_edit_cellhd(struct Cell_head *cellhd, int type)
00225 {
00226     char ll_north[20];
00227     char ll_south[20];
00228     char ll_east[20];
00229     char ll_west[20];
00230     char ll_nsres[20];
00231     char ll_ewres[20];
00232     char ll_def_north[20];
00233     char ll_def_south[20];
00234     char ll_def_east[20];
00235     char ll_def_west[20];
00236     char ll_def_ewres[20];
00237     char ll_def_nsres[20];
00238     char projection[80];
00239     char **screen;
00240 
00241     struct Cell_head def_wind;
00242     double north, south, east, west;
00243     double nsres, ewres;
00244     char buf[64], buf2[30], *p;
00245     short ok;
00246     int line;
00247     char *prj;
00248     char *err;
00249 
00250     if (type == AS_CELLHD && (cellhd->rows <= 0 || cellhd->cols <= 0)) {
00251         G_message("E_edit_cellhd() - programmer error");
00252         G_message("  ** rows and cols must be positive **");
00253         return -1;
00254     }
00255     if (type != AS_DEF_WINDOW) {
00256         if (G_get_default_window(&def_wind) != 1)
00257             return -1;
00258 
00259         if (cellhd->proj < 0) {
00260             cellhd->proj = def_wind.proj;
00261             cellhd->zone = def_wind.zone;
00262         }
00263         else if (cellhd->zone < 0)
00264             cellhd->zone = def_wind.zone;
00265     }
00266 
00267     prj = G__projection_name(cellhd->proj);
00268     if (!prj)
00269         prj = "** unknown **";
00270     sprintf(projection, "%d (%s)", cellhd->proj, prj);
00271 
00272     if (type != AS_DEF_WINDOW) {
00273         if (cellhd->west >= cellhd->east || cellhd->south >= cellhd->north) {
00274             cellhd->north = def_wind.north;
00275             cellhd->south = def_wind.south;
00276             cellhd->west = def_wind.west;
00277             cellhd->east = def_wind.east;
00278 
00279             if (type != AS_CELLHD) {
00280                 cellhd->ew_res = def_wind.ew_res;
00281                 cellhd->ns_res = def_wind.ns_res;
00282                 cellhd->rows = def_wind.rows;
00283                 cellhd->cols = def_wind.cols;
00284             }
00285         }
00286 
00287         if (cellhd->proj != def_wind.proj) {
00288             if (type == AS_CELLHD)
00289                 G_message
00290                     ("header projection %d differs from default projection %d",
00291                      cellhd->proj, def_wind.proj);
00292             else
00293                 G_message
00294                     ("region projection %d differs from default projection %d",
00295                      cellhd->proj, def_wind.proj);
00296 
00297             if (!G_yes("do you want to make them match? ", 1))
00298                 return -1;
00299 
00300             cellhd->proj = def_wind.proj;
00301             cellhd->zone = def_wind.zone;
00302         }
00303 
00304         if (cellhd->zone != def_wind.zone) {
00305             if (type == AS_CELLHD)
00306                 G_message("header zone %d differs from default zone %d",
00307                           cellhd->zone, def_wind.zone);
00308             else
00309                 G_message("region zone %d differs from default zone %d",
00310                           cellhd->zone, def_wind.zone);
00311 
00312             if (!G_yes("do you want to make them match? ", 1))
00313                 return -1;
00314 
00315             cellhd->zone = def_wind.zone;
00316         }
00317 
00318         *ll_def_north = 0;
00319         *ll_def_south = 0;
00320         *ll_def_east = 0;
00321         *ll_def_west = 0;
00322         *ll_def_ewres = 0;
00323         *ll_def_nsres = 0;
00324         format_northing(def_wind.north, ll_def_north, def_wind.proj);
00325         format_northing(def_wind.south, ll_def_south, def_wind.proj);
00326         format_easting(def_wind.east, ll_def_east, def_wind.proj);
00327         format_easting(def_wind.west, ll_def_west, def_wind.proj);
00328         format_resolution(def_wind.ew_res, ll_def_ewres, def_wind.proj);
00329         format_resolution(def_wind.ns_res, ll_def_nsres, def_wind.proj);
00330     }
00331 
00332     *ll_north = 0;
00333     *ll_south = 0;
00334     *ll_east = 0;
00335     *ll_west = 0;
00336     *ll_ewres = 0;
00337     *ll_nsres = 0;
00338     format_northing(cellhd->north, ll_north, cellhd->proj);
00339     format_northing(cellhd->south, ll_south, cellhd->proj);
00340     format_easting(cellhd->east, ll_east, cellhd->proj);
00341     format_easting(cellhd->west, ll_west, cellhd->proj);
00342     format_resolution(cellhd->ew_res, ll_ewres, cellhd->proj);
00343     format_resolution(cellhd->ns_res, ll_nsres, cellhd->proj);
00344 
00345     while (1) {
00346         ok = 1;
00347 
00348         /* List window options on the screen for the user to answer */
00349         switch (type) {
00350         case AS_CELLHD:
00351             screen = cellhd_screen;
00352             break;
00353         case AS_DEF_WINDOW:
00354             screen = def_window_screen;
00355             break;
00356         default:
00357             screen = window_screen;
00358             break;
00359         }
00360 
00361         V_clear();
00362         line = 0;
00363         while (*screen)
00364             V_line(line++, *screen++);
00365 
00366         /* V_ques ( variable, type, row, col, length) ; */
00367         V_ques(ll_north, 's', 6, 36, 10);
00368         V_ques(ll_south, 's', 10, 36, 10);
00369         V_ques(ll_west, 's', 9, 12, 10);
00370         V_ques(ll_east, 's', 9, 52, 10);
00371 
00372         if (type != AS_CELLHD) {
00373             V_ques(ll_ewres, 's', 18, 48, 10);
00374             V_ques(ll_nsres, 's', 19, 48, 10);
00375         }
00376 
00377         if (type != AS_DEF_WINDOW) {
00378             V_const(ll_def_north, 's', 3, 36, 10);
00379             V_const(ll_def_south, 's', 13, 36, 10);
00380             V_const(ll_def_west, 's', 9, 1, 10);
00381             V_const(ll_def_east, 's', 9, 65, 10);
00382 
00383             if (type != AS_CELLHD) {
00384                 V_const(ll_def_ewres, 's', 18, 21, 10);
00385                 V_const(ll_def_nsres, 's', 19, 21, 10);
00386             }
00387         }
00388 
00389         V_const(projection, 's', 15, 23, (int)strlen(projection));
00390         V_const(&cellhd->zone, 'i', 15, 60, 3);
00391 
00392         V_intrpt_ok();
00393         if (!V_call())
00394             return -1;
00395 
00396         G_squeeze(ll_north);
00397         G_squeeze(ll_south);
00398         G_squeeze(ll_east);
00399         G_squeeze(ll_west);
00400 
00401         if (type != AS_CELLHD) {
00402             G_squeeze(ll_ewres);
00403             G_squeeze(ll_nsres);
00404         }
00405 
00406         if (!G_scan_northing(ll_north, &cellhd->north, cellhd->proj)) {
00407             G_warning("Illegal value for north: %s", ll_north);
00408             ok = 0;
00409         }
00410 
00411         if (!G_scan_northing(ll_south, &cellhd->south, cellhd->proj)) {
00412             G_warning("Illegal value for south: %s", ll_south);
00413             ok = 0;
00414         }
00415 
00416         if (!G_scan_easting(ll_east, &cellhd->east, cellhd->proj)) {
00417             G_warning("Illegal value for east: %s", ll_east);
00418             ok = 0;
00419         }
00420 
00421         if (!G_scan_easting(ll_west, &cellhd->west, cellhd->proj)) {
00422             G_warning("Illegal value for west: %s", ll_west);
00423             ok = 0;
00424         }
00425 
00426         if (type != AS_CELLHD) {
00427             if (!G_scan_resolution(ll_ewres, &cellhd->ew_res, cellhd->proj)) {
00428                 G_warning("Illegal east-west resolution: %s", ll_ewres);
00429                 ok = 0;
00430             }
00431 
00432             if (!G_scan_resolution(ll_nsres, &cellhd->ns_res, cellhd->proj)) {
00433                 G_warning("Illegal north-south resolution: %s", ll_nsres);
00434                 ok = 0;
00435             }
00436         }
00437 
00438         if (!ok) {
00439             hitreturn();
00440             continue;
00441         }
00442 
00443         /* Adjust and complete the cell header */
00444         north = cellhd->north;
00445         south = cellhd->south;
00446         east = cellhd->east;
00447         west = cellhd->west;
00448         nsres = cellhd->ns_res;
00449         ewres = cellhd->ew_res;
00450 
00451         if ((err =
00452              G_adjust_Cell_head(cellhd, type == AS_CELLHD,
00453                                 type == AS_CELLHD))) {
00454             G_message("%s", err);
00455             hitreturn();
00456             continue;
00457         }
00458 
00459         if (type == AS_CELLHD) {
00460             nsres = cellhd->ns_res;
00461             ewres = cellhd->ew_res;
00462         }
00463 
00464       SHOW:
00465         fprintf(stderr, "\n\n");
00466         G_message("  projection:   %s", projection);
00467         G_message("  zone:         %d", cellhd->zone);
00468 
00469         G_format_northing(cellhd->north, buf, cellhd->proj);
00470         G_format_northing(north, buf2, cellhd->proj);
00471         fprintf(stderr, "  north:       %s", buf);
00472 
00473         if (strcmp(buf, buf2) != 0) {
00474             ok = 0;
00475             fprintf(stderr, "  (Changed to match resolution)");
00476         }
00477         fprintf(stderr, "\n");
00478 
00479         G_format_northing(cellhd->south, buf, cellhd->proj);
00480         G_format_northing(south, buf2, cellhd->proj);
00481         fprintf(stderr, "  south:       %s", buf);
00482         if (strcmp(buf, buf2) != 0) {
00483             ok = 0;
00484             fprintf(stderr, "  (Changed to match resolution)");
00485         }
00486         fprintf(stderr, "\n");
00487 
00488         G_format_easting(cellhd->east, buf, cellhd->proj);
00489         G_format_easting(east, buf2, cellhd->proj);
00490         fprintf(stderr, "  east:        %s", buf);
00491         if (strcmp(buf, buf2) != 0) {
00492             ok = 0;
00493             fprintf(stderr, "  (Changed to match resolution)");
00494         }
00495         fprintf(stderr, "\n");
00496 
00497         G_format_easting(cellhd->west, buf, cellhd->proj);
00498         G_format_easting(west, buf2, cellhd->proj);
00499         fprintf(stderr, "  west:        %s", buf);
00500         if (strcmp(buf, buf2) != 0) {
00501             ok = 0;
00502             fprintf(stderr, "  (Changed to match resolution)");
00503         }
00504         fprintf(stderr, "\n\n");
00505 
00506         G_format_resolution(cellhd->ew_res, buf, cellhd->proj);
00507         G_format_resolution(ewres, buf2, cellhd->proj);
00508         fprintf(stderr, "  e-w res:     %s", buf);
00509         if (strcmp(buf, buf2) != 0) {
00510             ok = 0;
00511             fprintf(stderr, "  (Changed to conform to grid)");
00512         }
00513         fprintf(stderr, "\n");
00514 
00515         G_format_resolution(cellhd->ns_res, buf, cellhd->proj);
00516         G_format_resolution(nsres, buf2, cellhd->proj);
00517         fprintf(stderr, "  n-s res:     %s", buf);
00518         if (strcmp(buf, buf2) != 0) {
00519             ok = 0;
00520             fprintf(stderr, "  (Changed to conform to grid)");
00521         }
00522         fprintf(stderr, "\n\n");
00523 
00524         G_message("  total rows:  %15d", cellhd->rows);
00525         G_message("  total cols:  %15d", cellhd->cols);
00526 
00527         sprintf(buf, "%lf", (double)cellhd->rows * cellhd->cols);
00528         *(p = strchr(buf, '.')) = 0;
00529         G_insert_commas(buf);
00530         G_message("  total cells: %15s", buf);
00531         fprintf(stderr, "\n");
00532 
00533         if (type != AS_DEF_WINDOW) {
00534             if (cellhd->north > def_wind.north) {
00535                 G_warning("north falls outside the default region");
00536                 ok = 0;
00537             }
00538 
00539             if (cellhd->south < def_wind.south) {
00540                 G_warning("south falls outside the default region");
00541                 ok = 0;
00542             }
00543 
00544             if (cellhd->proj != PROJECTION_LL) {
00545                 if (cellhd->east > def_wind.east) {
00546                     G_warning("east falls outside the default region");
00547                     ok = 0;
00548                 }
00549 
00550                 if (cellhd->west < def_wind.west) {
00551                     G_warning("west falls outside the default region");
00552                     ok = 0;
00553                 }
00554             }
00555         }
00556 
00557       ASK:
00558         fflush(stdin);
00559         if (type == AS_CELLHD)
00560             fprintf(stderr, "\nDo you accept this header? (y/n) [%s] > ",
00561                     ok ? "y" : "n");
00562         else
00563             fprintf(stderr, "\nDo you accept this region? (y/n) [%s] > ",
00564                     ok ? "y" : "n");
00565 
00566         if (!G_gets(buf))
00567             goto SHOW;
00568 
00569         G_strip(buf);
00570         switch (*buf) {
00571         case 0:
00572             break;
00573         case 'y':
00574         case 'Y':
00575             ok = 1;
00576             break;
00577         case 'n':
00578         case 'N':
00579             ok = 0;
00580             break;
00581         default:
00582             goto ASK;
00583         }
00584 
00585         if (ok)
00586             return 0;
00587     }
00588 }
00589 
00590 
00591 static int hitreturn(void)
00592 {
00593     char buf[100];
00594 
00595     fprintf(stderr, "hit RETURN -->");
00596     if (!fgets(buf, 100, stdin))
00597         exit(EXIT_SUCCESS);
00598 
00599     G_strip(buf);
00600     if (!strncmp(buf, "exit", sizeof(buf)))
00601         exit(EXIT_SUCCESS);
00602 
00603     return 0;
00604 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines