GRASS Programmer's Manual
6.4.2(2012)
|
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 <ESC> 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 }