GRASS Programmer's Manual 6.4.1(2011)
view.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines