GRASS Programmer's Manual
6.4.1(2011)
|
00001 00017 #include <stdio.h> 00018 #include <string.h> 00019 #include <stdlib.h> 00020 #include <grass/gis.h> 00021 #include <grass/glocale.h> 00022 00023 00024 #define REQ_KEYS 8 00025 00026 static int compare_wind(const struct Cell_head *, const struct Cell_head *); 00027 static int get_bool(const char *); 00028 static void pr_winerr(int, const char *); 00029 static void edge_sort(float sides[4]); 00030 static int read_old_format(struct G_3dview *, FILE *); 00031 00032 static int vers_major = 4; 00033 static int vers_minor = 1; 00034 static int Suppress_warn = 0; 00035 00036 00047 int G_3dview_warning(int b) 00048 { 00049 Suppress_warn = b ? 0 : 1; 00050 00051 return 0; 00052 } 00053 00054 00063 int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w) 00064 { 00065 if (!v || !w) 00066 return (-1); 00067 00068 v->exag = 1.0; 00069 v->fov = 40.0; 00070 v->from_to[0][0] = (w->east + w->west) / 2.0; 00071 v->from_to[0][1] = w->south - (w->north - w->south); 00072 v->from_to[0][2] = w->north - w->south; 00073 v->from_to[1][0] = (w->east + w->west) / 2.0; 00074 v->from_to[1][1] = (w->north + w->south) / 2.0; 00075 v->from_to[1][2] = 0.0; 00076 00077 v->twist = 0.0; 00078 v->mesh_freq = 15; 00079 v->poly_freq = 1; 00080 v->display_type = 2; 00081 v->colorgrid = v->fringe = v->surfonly = v->lightson = v->doavg = 0; 00082 v->dozero = v->shading = 1; 00083 strcpy(v->bg_col, "black"); 00084 strcpy(v->grid_col, "white"); 00085 strcpy(v->other_col, "red"); 00086 v->ambient = v->shine = 0.3; 00087 v->lightcol[0] = v->lightcol[1] = v->lightcol[2] = 0.8; 00088 v->lightpos[0] = w->west; 00089 v->lightpos[1] = w->north; 00090 v->lightpos[2] = (w->east - w->west) / 2.0; 00091 v->lightpos[3] = 1.0; /* local source */ 00092 00093 v->vwin.north = w->north; 00094 v->vwin.south = w->south; 00095 v->vwin.east = w->east; 00096 v->vwin.west = w->west; 00097 v->vwin.format = w->format; 00098 v->vwin.compressed = w->compressed; 00099 v->vwin.proj = w->proj; 00100 v->vwin.zone = w->zone; 00101 v->vwin.ew_res = w->ew_res; 00102 v->vwin.ns_res = w->ns_res; 00103 v->vwin.cols = w->cols; 00104 v->vwin.rows = w->rows; 00105 00106 return (1); 00107 00108 } 00109 00110 00171 int G_put_3dview(const char *fname, const char *mapset, 00172 const struct G_3dview *View, const struct Cell_head *Win) 00173 { 00174 FILE *fp; 00175 00176 if (NULL == (fp = G_fopen_new("3d.view", fname))) { 00177 G_warning(_("Unable to open %s for writing"), fname); 00178 return (-1); 00179 } 00180 00181 fprintf(fp, "# %01d.%02d\n", vers_major, vers_minor); 00182 fprintf(fp, "PGM_ID: %s\n", View->pgm_id); 00183 00184 if (Win) { 00185 fprintf(fp, "north: %f\n", Win->north); 00186 fprintf(fp, "south: %f\n", Win->south); 00187 fprintf(fp, "east: %f\n", Win->east); 00188 fprintf(fp, "west: %f\n", Win->west); 00189 fprintf(fp, "rows: %d\n", Win->rows); 00190 fprintf(fp, "cols: %d\n", Win->cols); 00191 } 00192 else { 00193 fprintf(fp, "north: %f\n", View->vwin.north); 00194 fprintf(fp, "south: %f\n", View->vwin.south); 00195 fprintf(fp, "east: %f\n", View->vwin.east); 00196 fprintf(fp, "west: %f\n", View->vwin.west); 00197 fprintf(fp, "rows: %d\n", View->vwin.rows); 00198 fprintf(fp, "cols: %d\n", View->vwin.cols); 00199 } 00200 00201 fprintf(fp, "TO_EASTING: %f\n", View->from_to[1][0]); 00202 fprintf(fp, "TO_NORTHING: %f\n", View->from_to[1][1]); 00203 fprintf(fp, "TO_HEIGHT: %f\n", View->from_to[1][2]); 00204 fprintf(fp, "FROM_EASTING: %f\n", View->from_to[0][0]); 00205 fprintf(fp, "FROM_NORTHING: %f\n", View->from_to[0][1]); 00206 fprintf(fp, "FROM_HEIGHT: %f\n", View->from_to[0][2]); 00207 fprintf(fp, "Z_EXAG: %f\n", View->exag); 00208 fprintf(fp, "TWIST: %f\n", View->twist); 00209 fprintf(fp, "FIELD_VIEW: %f\n", View->fov); 00210 fprintf(fp, "MESH_FREQ: %d\n", View->mesh_freq); 00211 fprintf(fp, "POLY_RES: %d\n", View->poly_freq); 00212 fprintf(fp, "DOAVG: %d\n", View->doavg); 00213 fprintf(fp, "DISPLAY_TYPE: %d\n", View->display_type); 00214 fprintf(fp, "DOZERO: %d\n", View->dozero); 00215 00216 fprintf(fp, "COLORGRID: %d\n", View->colorgrid); /* 1 = use color */ 00217 fprintf(fp, "SHADING: %d\n", View->shading); 00218 fprintf(fp, "FRINGE: %d\n", View->fringe); 00219 fprintf(fp, "BG_COL: %s\n", View->bg_col); 00220 fprintf(fp, "GRID_COL: %s\n", View->grid_col); 00221 fprintf(fp, "OTHER_COL: %s\n", View->other_col); 00222 fprintf(fp, "SURFACEONLY: %d\n", View->surfonly); 00223 fprintf(fp, "LIGHTS_ON: %d\n", View->lightson); 00224 fprintf(fp, "LIGHTPOS: %f %f %f %f\n", View->lightpos[0], 00225 View->lightpos[1], View->lightpos[2], View->lightpos[3]); 00226 fprintf(fp, "LIGHTCOL: %f %f %f\n", View->lightcol[0], View->lightcol[1], 00227 View->lightcol[2]); 00228 fprintf(fp, "LIGHTAMBIENT: %f\n", View->ambient); 00229 fprintf(fp, "SHINE: %f\n", View->shine); 00230 00231 fclose(fp); 00232 00233 return (1); 00234 } 00235 00236 00252 int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View) 00253 { 00254 struct Cell_head curwin; 00255 FILE *fp; 00256 char buffer[80], keystring[24], boo[8], nbuf[128], ebuf[128]; 00257 int lap, v_maj, v_min, wind_keys = 0, reqkeys = 0; 00258 int current = 0; /* current version flag */ 00259 00260 mapset = G_find_file2("3d.view", fname, mapset); 00261 if (mapset != NULL) { 00262 if (NULL == (fp = G_fopen_old("3d.view", fname, mapset))) { 00263 G_warning(_("Unable to open %s for reading"), fname); 00264 return (-1); 00265 } 00266 00267 G_get_set_window(&curwin); 00268 G_get_3dview_defaults(View, &curwin); 00269 00270 if (NULL != fgets(buffer, 80, fp)) { 00271 if (buffer[0] != '#') { /* old d.3d format */ 00272 rewind(fp); 00273 if (0 <= read_old_format(View, fp)) 00274 return (0); 00275 else 00276 return (-1); 00277 } 00278 else { 00279 sscanf(buffer, "#%d.%d\n", &v_maj, &v_min); 00280 if (v_maj == vers_major && v_min == vers_minor) 00281 current = 1; /* same version */ 00282 } 00283 } 00284 00285 while (NULL != fgets(buffer, 75, fp)) { 00286 if (buffer[0] != '#') { 00287 00288 sscanf(buffer, "%[^:]:", keystring); 00289 00290 if (!strcmp(keystring, "PGM_ID")) { 00291 sscanf(buffer, "%*s%s", (View->pgm_id)); 00292 continue; 00293 } 00294 if (!strcmp(keystring, "north")) { 00295 sscanf(buffer, "%*s%lf", &(View->vwin.north)); 00296 ++wind_keys; 00297 continue; 00298 } 00299 if (!strcmp(keystring, "south")) { 00300 sscanf(buffer, "%*s%lf", &(View->vwin.south)); 00301 ++wind_keys; 00302 continue; 00303 } 00304 if (!strcmp(keystring, "east")) { 00305 sscanf(buffer, "%*s%lf", &(View->vwin.east)); 00306 ++wind_keys; 00307 continue; 00308 } 00309 if (!strcmp(keystring, "west")) { 00310 sscanf(buffer, "%*s%lf", &(View->vwin.west)); 00311 ++wind_keys; 00312 continue; 00313 } 00314 if (!strcmp(keystring, "rows")) { 00315 sscanf(buffer, "%*s%d", &(View->vwin.rows)); 00316 ++wind_keys; 00317 continue; 00318 } 00319 if (!strcmp(keystring, "cols")) { 00320 sscanf(buffer, "%*s%d", &(View->vwin.cols)); 00321 ++wind_keys; 00322 continue; 00323 } 00324 if (!strcmp(keystring, "TO_EASTING")) { 00325 sscanf(buffer, "%*s%f", &(View->from_to[1][0])); 00326 ++reqkeys; 00327 continue; 00328 } 00329 if (!strcmp(keystring, "TO_NORTHING")) { 00330 sscanf(buffer, "%*s%f", &(View->from_to[1][1])); 00331 ++reqkeys; 00332 continue; 00333 } 00334 if (!strcmp(keystring, "TO_HEIGHT")) { 00335 sscanf(buffer, "%*s%f", &(View->from_to[1][2])); 00336 ++reqkeys; 00337 continue; 00338 } 00339 if (!strcmp(keystring, "FROM_EASTING")) { 00340 sscanf(buffer, "%*s%f", &(View->from_to[0][0])); 00341 ++reqkeys; 00342 continue; 00343 } 00344 if (!strcmp(keystring, "FROM_NORTHING")) { 00345 sscanf(buffer, "%*s%f", &(View->from_to[0][1])); 00346 ++reqkeys; 00347 continue; 00348 } 00349 if (!strcmp(keystring, "FROM_HEIGHT")) { 00350 sscanf(buffer, "%*s%f", &(View->from_to[0][2])); 00351 ++reqkeys; 00352 continue; 00353 } 00354 if (!strcmp(keystring, "Z_EXAG")) { 00355 sscanf(buffer, "%*s%f", &(View->exag)); 00356 ++reqkeys; 00357 continue; 00358 } 00359 if (!strcmp(keystring, "MESH_FREQ")) { 00360 sscanf(buffer, "%*s%d", &(View->mesh_freq)); 00361 continue; 00362 } 00363 if (!strcmp(keystring, "POLY_RES")) { 00364 sscanf(buffer, "%*s%d", &(View->poly_freq)); 00365 continue; 00366 } 00367 if (!strcmp(keystring, "DOAVG")) { 00368 sscanf(buffer, "%*s%d", &(View->doavg)); 00369 continue; 00370 } 00371 if (!strcmp(keystring, "FIELD_VIEW")) { 00372 sscanf(buffer, "%*s%f", &(View->fov)); 00373 ++reqkeys; 00374 continue; 00375 } 00376 if (!strcmp(keystring, "TWIST")) { 00377 sscanf(buffer, "%*s%f", &(View->twist)); 00378 continue; 00379 } 00380 if (!strcmp(keystring, "DISPLAY_TYPE")) { 00381 sscanf(buffer, "%*s%d", &View->display_type); 00382 continue; 00383 } 00384 if (!strcmp(keystring, "DOZERO")) { 00385 sscanf(buffer, "%*s%s", boo); 00386 View->dozero = get_bool(boo); 00387 continue; 00388 } 00389 if (!strcmp(keystring, "COLORGRID")) { 00390 sscanf(buffer, "%*s%s", boo); 00391 View->colorgrid = get_bool(boo); 00392 continue; 00393 } 00394 if (!strcmp(keystring, "FRINGE")) { 00395 sscanf(buffer, "%*s%s", boo); 00396 View->fringe = get_bool(boo); 00397 continue; 00398 } 00399 if (!strcmp(keystring, "SHADING")) { 00400 sscanf(buffer, "%*s%s", boo); 00401 View->shading = get_bool(boo); 00402 continue; 00403 } 00404 if (!strcmp(keystring, "BG_COL")) { 00405 sscanf(buffer, "%*s%s", View->bg_col); 00406 continue; 00407 } 00408 if (!strcmp(keystring, "GRID_COL")) { 00409 sscanf(buffer, "%*s%s", View->grid_col); 00410 continue; 00411 } 00412 if (!strcmp(keystring, "OTHER_COL")) { 00413 sscanf(buffer, "%*s%s", View->other_col); 00414 continue; 00415 } 00416 if (!strcmp(keystring, "SURFACEONLY")) { 00417 sscanf(buffer, "%*s%s", boo); 00418 View->surfonly = get_bool(boo); 00419 continue; 00420 } 00421 if (!strcmp(keystring, "LIGHTS_ON")) { 00422 sscanf(buffer, "%*s%s", boo); 00423 View->lightson = get_bool(boo); 00424 continue; 00425 } 00426 if (!strcmp(keystring, "LIGHTPOS")) { 00427 sscanf(buffer, "%*s%f%f%f%f", &(View->lightpos[0]), 00428 &(View->lightpos[1]), &(View->lightpos[2]), 00429 &(View->lightpos[3])); 00430 continue; 00431 } 00432 if (!strcmp(keystring, "LIGHTCOL")) { 00433 sscanf(buffer, "%*s%f%f%f", &(View->lightcol[0]), 00434 &(View->lightcol[1]), &(View->lightcol[2])); 00435 continue; 00436 } 00437 if (!strcmp(keystring, "LIGHTAMBIENT")) { 00438 sscanf(buffer, "%*s%f", &(View->ambient)); 00439 continue; 00440 } 00441 if (!strcmp(keystring, "SHINE")) { 00442 sscanf(buffer, "%*s%f", &(View->shine)); 00443 continue; 00444 } 00445 } 00446 } 00447 00448 fclose(fp); 00449 00450 if (reqkeys != REQ_KEYS) /* required keys not found */ 00451 return (-1); 00452 00453 /* fill rest of View->vwin */ 00454 if (wind_keys == 6) { 00455 View->vwin.ew_res = (View->vwin.east - View->vwin.west) / 00456 View->vwin.cols; 00457 View->vwin.ns_res = (View->vwin.north - View->vwin.south) / 00458 View->vwin.rows; 00459 } 00460 else 00461 return (0); /* older format */ 00462 00463 if (!Suppress_warn) { 00464 if (95 > (lap = compare_wind(&(View->vwin), &curwin))) { 00465 00466 fprintf(stderr, _("GRASS window when view was saved:\n")); 00467 G_format_northing(View->vwin.north, nbuf, G_projection()); 00468 fprintf(stderr, "north: %s\n", nbuf); 00469 G_format_northing(View->vwin.south, nbuf, G_projection()); 00470 fprintf(stderr, "south: %s\n", nbuf); 00471 G_format_easting(View->vwin.east, ebuf, G_projection()); 00472 fprintf(stderr, "east: %s\n", ebuf); 00473 G_format_easting(View->vwin.west, ebuf, G_projection()); 00474 fprintf(stderr, "west: %s\n", ebuf); 00475 pr_winerr(lap, fname); 00476 } 00477 } 00478 } 00479 else { 00480 G_warning(_("Unable to open %s for reading"), fname); 00481 return (-1); 00482 } 00483 00484 if (current) 00485 return (2); 00486 00487 return (1); 00488 } 00489 00490 00491 /* returns the percentage of savedwin that overlaps curwin */ 00492 00493 static int compare_wind(const struct Cell_head *savedwin, 00494 const struct Cell_head *curwin) 00495 { 00496 float e_ings[4], n_ings[4], area_lap, area_saved; 00497 int outside = 0; 00498 00499 if (savedwin->north < curwin->south) 00500 outside = 1; 00501 if (savedwin->south > curwin->north) 00502 outside = 1; 00503 if (savedwin->east < curwin->west) 00504 outside = 1; 00505 if (savedwin->west > curwin->east) 00506 outside = 1; 00507 if (outside) 00508 return (0); 00509 00510 e_ings[0] = savedwin->west; 00511 e_ings[1] = savedwin->east; 00512 e_ings[2] = curwin->west; 00513 e_ings[3] = curwin->east; 00514 edge_sort(e_ings); 00515 00516 n_ings[0] = savedwin->south; 00517 n_ings[1] = savedwin->north; 00518 n_ings[2] = curwin->south; 00519 n_ings[3] = curwin->north; 00520 edge_sort(n_ings); 00521 00522 area_lap = (e_ings[2] - e_ings[1]) * (n_ings[2] - n_ings[1]); 00523 area_saved = (savedwin->east - savedwin->west) * 00524 (savedwin->north - savedwin->south); 00525 00526 return ((int)(area_lap * 100.0 / area_saved)); 00527 } 00528 00529 00530 static int get_bool(const char *str) 00531 { 00532 if (str[0] == 'y' || str[0] == 'Y') 00533 return (1); 00534 if (str[0] == 'n' || str[0] == 'N') 00535 return (0); 00536 00537 return (atoi(str) ? 1 : 0); 00538 } 00539 00540 00541 static void pr_winerr(int vis, /* % of saved window overlapping current window */ 00542 const char *viewname) 00543 { 00544 switch (vis) { 00545 case 0: 00546 G_warning(_(" Window saved in \"%s\" is completely outside of current GRASS window."), 00547 viewname); 00548 break; 00549 default: 00550 G_warning(_(" Only %d%% of window saved in \"%s\" overlaps with current GRASS window."), 00551 vis, viewname); 00552 break; 00553 } 00554 } 00555 00556 /*********************************************************************/ 00557 /* sorts 4 floats from lowest to highest */ 00558 00559 static void edge_sort(float sides[4]) 00560 { 00561 int i, j; 00562 float temp; 00563 00564 for (i = 0; i < 4; ++i) { 00565 for (j = i + 1; j < 4; ++j) { 00566 if (sides[j] < sides[i]) { /* then swap */ 00567 temp = sides[i]; 00568 sides[i] = sides[j]; 00569 sides[j] = temp; 00570 } 00571 } 00572 } 00573 } 00574 00575 00576 static int read_old_format(struct G_3dview *v, FILE * fp) 00577 { 00578 char buffer[80]; 00579 int req_keys = 0; 00580 double td; 00581 char boo[8]; 00582 00583 strcpy((v->pgm_id), "d.3d"); 00584 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][0]))) 00585 ++req_keys; 00586 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][1]))) 00587 ++req_keys; 00588 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][2]))) 00589 ++req_keys; 00590 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][0]))) 00591 ++req_keys; 00592 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][1]))) 00593 ++req_keys; 00594 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][2]))) 00595 ++req_keys; 00596 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->exag))) 00597 ++req_keys; 00598 sscanf(fgets(buffer, 80, fp), "%d", &(v->mesh_freq)); 00599 if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->fov))) 00600 ++req_keys; 00601 if (1 == sscanf(fgets(buffer, 80, fp), "%lf", &td)) { /* resolution */ 00602 v->vwin.rows = (v->vwin.north - v->vwin.south) / td; 00603 v->vwin.cols = (v->vwin.east - v->vwin.west) / td; 00604 v->vwin.ew_res = v->vwin.ns_res = td; 00605 } 00606 00607 sscanf(fgets(buffer, 80, fp), "%s", boo); /* linesonly */ 00608 v->display_type = get_bool(boo) ? 1 : 3; 00609 sscanf(fgets(buffer, 80, fp), "%s", boo); 00610 v->dozero = get_bool(boo); 00611 sscanf(fgets(buffer, 80, fp), "%s", v->grid_col); 00612 if (!strcmp(v->grid_col, "color")) 00613 v->colorgrid = 1; 00614 00615 sscanf(fgets(buffer, 80, fp), "%s", v->other_col); 00616 sscanf(fgets(buffer, 80, fp), "%s", v->bg_col); 00617 sscanf(fgets(buffer, 80, fp), "%s", boo); 00618 v->doavg = get_bool(boo); 00619 00620 if (v->exag) { /* old 3d.view files saved height with no exag */ 00621 v->from_to[0][2] /= v->exag; 00622 v->from_to[1][2] /= v->exag; 00623 } 00624 00625 00626 fclose(fp); 00627 if (req_keys == REQ_KEYS) 00628 return (1); 00629 else 00630 return (-1); 00631 }