GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
view.c
Go to the documentation of this file.
1 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <grass/gis.h>
21 #include <grass/glocale.h>
22 
23 
24 #define REQ_KEYS 8
25 
26 static int compare_wind(const struct Cell_head *, const struct Cell_head *);
27 static int get_bool(const char *);
28 static void pr_winerr(int, const char *);
29 static void edge_sort(float sides[4]);
30 static int read_old_format(struct G_3dview *, FILE *);
31 
32 static int vers_major = 4;
33 static int vers_minor = 1;
34 static int Suppress_warn = 0;
35 
36 
48 {
49  Suppress_warn = b ? 0 : 1;
50 
51  return 0;
52 }
53 
54 
63 int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
64 {
65  if (!v || !w)
66  return (-1);
67 
68  v->exag = 1.0;
69  v->fov = 40.0;
70  v->from_to[0][0] = (w->east + w->west) / 2.0;
71  v->from_to[0][1] = w->south - (w->north - w->south);
72  v->from_to[0][2] = w->north - w->south;
73  v->from_to[1][0] = (w->east + w->west) / 2.0;
74  v->from_to[1][1] = (w->north + w->south) / 2.0;
75  v->from_to[1][2] = 0.0;
76 
77  v->twist = 0.0;
78  v->mesh_freq = 15;
79  v->poly_freq = 1;
80  v->display_type = 2;
81  v->colorgrid = v->fringe = v->surfonly = v->lightson = v->doavg = 0;
82  v->dozero = v->shading = 1;
83  strcpy(v->bg_col, "black");
84  strcpy(v->grid_col, "white");
85  strcpy(v->other_col, "red");
86  v->ambient = v->shine = 0.3;
87  v->lightcol[0] = v->lightcol[1] = v->lightcol[2] = 0.8;
88  v->lightpos[0] = w->west;
89  v->lightpos[1] = w->north;
90  v->lightpos[2] = (w->east - w->west) / 2.0;
91  v->lightpos[3] = 1.0; /* local source */
92 
93  v->vwin.north = w->north;
94  v->vwin.south = w->south;
95  v->vwin.east = w->east;
96  v->vwin.west = w->west;
97  v->vwin.format = w->format;
98  v->vwin.compressed = w->compressed;
99  v->vwin.proj = w->proj;
100  v->vwin.zone = w->zone;
101  v->vwin.ew_res = w->ew_res;
102  v->vwin.ns_res = w->ns_res;
103  v->vwin.cols = w->cols;
104  v->vwin.rows = w->rows;
105 
106  return (1);
107 
108 }
109 
110 
171 int G_put_3dview(const char *fname, const char *mapset,
172  const struct G_3dview *View, const struct Cell_head *Win)
173 {
174  FILE *fp;
175 
176  if (NULL == (fp = G_fopen_new("3d.view", fname))) {
177  G_warning(_("Unable to open %s for writing"), fname);
178  return (-1);
179  }
180 
181  fprintf(fp, "# %01d.%02d\n", vers_major, vers_minor);
182  fprintf(fp, "PGM_ID: %s\n", View->pgm_id);
183 
184  if (Win) {
185  fprintf(fp, "north: %f\n", Win->north);
186  fprintf(fp, "south: %f\n", Win->south);
187  fprintf(fp, "east: %f\n", Win->east);
188  fprintf(fp, "west: %f\n", Win->west);
189  fprintf(fp, "rows: %d\n", Win->rows);
190  fprintf(fp, "cols: %d\n", Win->cols);
191  }
192  else {
193  fprintf(fp, "north: %f\n", View->vwin.north);
194  fprintf(fp, "south: %f\n", View->vwin.south);
195  fprintf(fp, "east: %f\n", View->vwin.east);
196  fprintf(fp, "west: %f\n", View->vwin.west);
197  fprintf(fp, "rows: %d\n", View->vwin.rows);
198  fprintf(fp, "cols: %d\n", View->vwin.cols);
199  }
200 
201  fprintf(fp, "TO_EASTING: %f\n", View->from_to[1][0]);
202  fprintf(fp, "TO_NORTHING: %f\n", View->from_to[1][1]);
203  fprintf(fp, "TO_HEIGHT: %f\n", View->from_to[1][2]);
204  fprintf(fp, "FROM_EASTING: %f\n", View->from_to[0][0]);
205  fprintf(fp, "FROM_NORTHING: %f\n", View->from_to[0][1]);
206  fprintf(fp, "FROM_HEIGHT: %f\n", View->from_to[0][2]);
207  fprintf(fp, "Z_EXAG: %f\n", View->exag);
208  fprintf(fp, "TWIST: %f\n", View->twist);
209  fprintf(fp, "FIELD_VIEW: %f\n", View->fov);
210  fprintf(fp, "MESH_FREQ: %d\n", View->mesh_freq);
211  fprintf(fp, "POLY_RES: %d\n", View->poly_freq);
212  fprintf(fp, "DOAVG: %d\n", View->doavg);
213  fprintf(fp, "DISPLAY_TYPE: %d\n", View->display_type);
214  fprintf(fp, "DOZERO: %d\n", View->dozero);
215 
216  fprintf(fp, "COLORGRID: %d\n", View->colorgrid); /* 1 = use color */
217  fprintf(fp, "SHADING: %d\n", View->shading);
218  fprintf(fp, "FRINGE: %d\n", View->fringe);
219  fprintf(fp, "BG_COL: %s\n", View->bg_col);
220  fprintf(fp, "GRID_COL: %s\n", View->grid_col);
221  fprintf(fp, "OTHER_COL: %s\n", View->other_col);
222  fprintf(fp, "SURFACEONLY: %d\n", View->surfonly);
223  fprintf(fp, "LIGHTS_ON: %d\n", View->lightson);
224  fprintf(fp, "LIGHTPOS: %f %f %f %f\n", View->lightpos[0],
225  View->lightpos[1], View->lightpos[2], View->lightpos[3]);
226  fprintf(fp, "LIGHTCOL: %f %f %f\n", View->lightcol[0], View->lightcol[1],
227  View->lightcol[2]);
228  fprintf(fp, "LIGHTAMBIENT: %f\n", View->ambient);
229  fprintf(fp, "SHINE: %f\n", View->shine);
230 
231  fclose(fp);
232 
233  return (1);
234 }
235 
236 
252 int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
253 {
254  struct Cell_head curwin;
255  FILE *fp;
256  char buffer[80], keystring[24], boo[8], nbuf[128], ebuf[128];
257  int lap, v_maj, v_min, wind_keys = 0, reqkeys = 0;
258  int current = 0; /* current version flag */
259 
260  mapset = G_find_file2("3d.view", fname, mapset);
261  if (mapset != NULL) {
262  if (NULL == (fp = G_fopen_old("3d.view", fname, mapset))) {
263  G_warning(_("Unable to open %s for reading"), fname);
264  return (-1);
265  }
266 
267  G_get_set_window(&curwin);
268  G_get_3dview_defaults(View, &curwin);
269 
270  if (NULL != fgets(buffer, 80, fp)) {
271  if (buffer[0] != '#') { /* old d.3d format */
272  rewind(fp);
273  if (0 <= read_old_format(View, fp))
274  return (0);
275  else
276  return (-1);
277  }
278  else {
279  sscanf(buffer, "#%d.%d\n", &v_maj, &v_min);
280  if (v_maj == vers_major && v_min == vers_minor)
281  current = 1; /* same version */
282  }
283  }
284 
285  while (NULL != fgets(buffer, 75, fp)) {
286  if (buffer[0] != '#') {
287 
288  sscanf(buffer, "%[^:]:", keystring);
289 
290  if (!strcmp(keystring, "PGM_ID")) {
291  sscanf(buffer, "%*s%s", (View->pgm_id));
292  continue;
293  }
294  if (!strcmp(keystring, "north")) {
295  sscanf(buffer, "%*s%lf", &(View->vwin.north));
296  ++wind_keys;
297  continue;
298  }
299  if (!strcmp(keystring, "south")) {
300  sscanf(buffer, "%*s%lf", &(View->vwin.south));
301  ++wind_keys;
302  continue;
303  }
304  if (!strcmp(keystring, "east")) {
305  sscanf(buffer, "%*s%lf", &(View->vwin.east));
306  ++wind_keys;
307  continue;
308  }
309  if (!strcmp(keystring, "west")) {
310  sscanf(buffer, "%*s%lf", &(View->vwin.west));
311  ++wind_keys;
312  continue;
313  }
314  if (!strcmp(keystring, "rows")) {
315  sscanf(buffer, "%*s%d", &(View->vwin.rows));
316  ++wind_keys;
317  continue;
318  }
319  if (!strcmp(keystring, "cols")) {
320  sscanf(buffer, "%*s%d", &(View->vwin.cols));
321  ++wind_keys;
322  continue;
323  }
324  if (!strcmp(keystring, "TO_EASTING")) {
325  sscanf(buffer, "%*s%f", &(View->from_to[1][0]));
326  ++reqkeys;
327  continue;
328  }
329  if (!strcmp(keystring, "TO_NORTHING")) {
330  sscanf(buffer, "%*s%f", &(View->from_to[1][1]));
331  ++reqkeys;
332  continue;
333  }
334  if (!strcmp(keystring, "TO_HEIGHT")) {
335  sscanf(buffer, "%*s%f", &(View->from_to[1][2]));
336  ++reqkeys;
337  continue;
338  }
339  if (!strcmp(keystring, "FROM_EASTING")) {
340  sscanf(buffer, "%*s%f", &(View->from_to[0][0]));
341  ++reqkeys;
342  continue;
343  }
344  if (!strcmp(keystring, "FROM_NORTHING")) {
345  sscanf(buffer, "%*s%f", &(View->from_to[0][1]));
346  ++reqkeys;
347  continue;
348  }
349  if (!strcmp(keystring, "FROM_HEIGHT")) {
350  sscanf(buffer, "%*s%f", &(View->from_to[0][2]));
351  ++reqkeys;
352  continue;
353  }
354  if (!strcmp(keystring, "Z_EXAG")) {
355  sscanf(buffer, "%*s%f", &(View->exag));
356  ++reqkeys;
357  continue;
358  }
359  if (!strcmp(keystring, "MESH_FREQ")) {
360  sscanf(buffer, "%*s%d", &(View->mesh_freq));
361  continue;
362  }
363  if (!strcmp(keystring, "POLY_RES")) {
364  sscanf(buffer, "%*s%d", &(View->poly_freq));
365  continue;
366  }
367  if (!strcmp(keystring, "DOAVG")) {
368  sscanf(buffer, "%*s%d", &(View->doavg));
369  continue;
370  }
371  if (!strcmp(keystring, "FIELD_VIEW")) {
372  sscanf(buffer, "%*s%f", &(View->fov));
373  ++reqkeys;
374  continue;
375  }
376  if (!strcmp(keystring, "TWIST")) {
377  sscanf(buffer, "%*s%f", &(View->twist));
378  continue;
379  }
380  if (!strcmp(keystring, "DISPLAY_TYPE")) {
381  sscanf(buffer, "%*s%d", &View->display_type);
382  continue;
383  }
384  if (!strcmp(keystring, "DOZERO")) {
385  sscanf(buffer, "%*s%s", boo);
386  View->dozero = get_bool(boo);
387  continue;
388  }
389  if (!strcmp(keystring, "COLORGRID")) {
390  sscanf(buffer, "%*s%s", boo);
391  View->colorgrid = get_bool(boo);
392  continue;
393  }
394  if (!strcmp(keystring, "FRINGE")) {
395  sscanf(buffer, "%*s%s", boo);
396  View->fringe = get_bool(boo);
397  continue;
398  }
399  if (!strcmp(keystring, "SHADING")) {
400  sscanf(buffer, "%*s%s", boo);
401  View->shading = get_bool(boo);
402  continue;
403  }
404  if (!strcmp(keystring, "BG_COL")) {
405  sscanf(buffer, "%*s%s", View->bg_col);
406  continue;
407  }
408  if (!strcmp(keystring, "GRID_COL")) {
409  sscanf(buffer, "%*s%s", View->grid_col);
410  continue;
411  }
412  if (!strcmp(keystring, "OTHER_COL")) {
413  sscanf(buffer, "%*s%s", View->other_col);
414  continue;
415  }
416  if (!strcmp(keystring, "SURFACEONLY")) {
417  sscanf(buffer, "%*s%s", boo);
418  View->surfonly = get_bool(boo);
419  continue;
420  }
421  if (!strcmp(keystring, "LIGHTS_ON")) {
422  sscanf(buffer, "%*s%s", boo);
423  View->lightson = get_bool(boo);
424  continue;
425  }
426  if (!strcmp(keystring, "LIGHTPOS")) {
427  sscanf(buffer, "%*s%f%f%f%f", &(View->lightpos[0]),
428  &(View->lightpos[1]), &(View->lightpos[2]),
429  &(View->lightpos[3]));
430  continue;
431  }
432  if (!strcmp(keystring, "LIGHTCOL")) {
433  sscanf(buffer, "%*s%f%f%f", &(View->lightcol[0]),
434  &(View->lightcol[1]), &(View->lightcol[2]));
435  continue;
436  }
437  if (!strcmp(keystring, "LIGHTAMBIENT")) {
438  sscanf(buffer, "%*s%f", &(View->ambient));
439  continue;
440  }
441  if (!strcmp(keystring, "SHINE")) {
442  sscanf(buffer, "%*s%f", &(View->shine));
443  continue;
444  }
445  }
446  }
447 
448  fclose(fp);
449 
450  if (reqkeys != REQ_KEYS) /* required keys not found */
451  return (-1);
452 
453  /* fill rest of View->vwin */
454  if (wind_keys == 6) {
455  View->vwin.ew_res = (View->vwin.east - View->vwin.west) /
456  View->vwin.cols;
457  View->vwin.ns_res = (View->vwin.north - View->vwin.south) /
458  View->vwin.rows;
459  }
460  else
461  return (0); /* older format */
462 
463  if (!Suppress_warn) {
464  if (95 > (lap = compare_wind(&(View->vwin), &curwin))) {
465 
466  fprintf(stderr, _("GRASS window when view was saved:\n"));
467  G_format_northing(View->vwin.north, nbuf, G_projection());
468  fprintf(stderr, "north: %s\n", nbuf);
469  G_format_northing(View->vwin.south, nbuf, G_projection());
470  fprintf(stderr, "south: %s\n", nbuf);
471  G_format_easting(View->vwin.east, ebuf, G_projection());
472  fprintf(stderr, "east: %s\n", ebuf);
473  G_format_easting(View->vwin.west, ebuf, G_projection());
474  fprintf(stderr, "west: %s\n", ebuf);
475  pr_winerr(lap, fname);
476  }
477  }
478  }
479  else {
480  G_warning(_("Unable to open %s for reading"), fname);
481  return (-1);
482  }
483 
484  if (current)
485  return (2);
486 
487  return (1);
488 }
489 
490 
491 /* returns the percentage of savedwin that overlaps curwin */
492 
493 static int compare_wind(const struct Cell_head *savedwin,
494  const struct Cell_head *curwin)
495 {
496  float e_ings[4], n_ings[4], area_lap, area_saved;
497  int outside = 0;
498 
499  if (savedwin->north < curwin->south)
500  outside = 1;
501  if (savedwin->south > curwin->north)
502  outside = 1;
503  if (savedwin->east < curwin->west)
504  outside = 1;
505  if (savedwin->west > curwin->east)
506  outside = 1;
507  if (outside)
508  return (0);
509 
510  e_ings[0] = savedwin->west;
511  e_ings[1] = savedwin->east;
512  e_ings[2] = curwin->west;
513  e_ings[3] = curwin->east;
514  edge_sort(e_ings);
515 
516  n_ings[0] = savedwin->south;
517  n_ings[1] = savedwin->north;
518  n_ings[2] = curwin->south;
519  n_ings[3] = curwin->north;
520  edge_sort(n_ings);
521 
522  area_lap = (e_ings[2] - e_ings[1]) * (n_ings[2] - n_ings[1]);
523  area_saved = (savedwin->east - savedwin->west) *
524  (savedwin->north - savedwin->south);
525 
526  return ((int)(area_lap * 100.0 / area_saved));
527 }
528 
529 
530 static int get_bool(const char *str)
531 {
532  if (str[0] == 'y' || str[0] == 'Y')
533  return (1);
534  if (str[0] == 'n' || str[0] == 'N')
535  return (0);
536 
537  return (atoi(str) ? 1 : 0);
538 }
539 
540 
541 static void pr_winerr(int vis, /* % of saved window overlapping current window */
542  const char *viewname)
543 {
544  switch (vis) {
545  case 0:
546  G_warning(_(" Window saved in \"%s\" is completely outside of current GRASS window."),
547  viewname);
548  break;
549  default:
550  G_warning(_(" Only %d%% of window saved in \"%s\" overlaps with current GRASS window."),
551  vis, viewname);
552  break;
553  }
554 }
555 
556 /*********************************************************************/
557 /* sorts 4 floats from lowest to highest */
558 
559 static void edge_sort(float sides[4])
560 {
561  int i, j;
562  float temp;
563 
564  for (i = 0; i < 4; ++i) {
565  for (j = i + 1; j < 4; ++j) {
566  if (sides[j] < sides[i]) { /* then swap */
567  temp = sides[i];
568  sides[i] = sides[j];
569  sides[j] = temp;
570  }
571  }
572  }
573 }
574 
575 
576 static int read_old_format(struct G_3dview *v, FILE * fp)
577 {
578  char buffer[80];
579  int req_keys = 0;
580  double td;
581  char boo[8];
582 
583  strcpy((v->pgm_id), "d.3d");
584  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][0])))
585  ++req_keys;
586  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][1])))
587  ++req_keys;
588  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[1][2])))
589  ++req_keys;
590  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][0])))
591  ++req_keys;
592  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][1])))
593  ++req_keys;
594  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->from_to[0][2])))
595  ++req_keys;
596  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->exag)))
597  ++req_keys;
598  sscanf(fgets(buffer, 80, fp), "%d", &(v->mesh_freq));
599  if (1 == sscanf(fgets(buffer, 80, fp), "%f", &(v->fov)))
600  ++req_keys;
601  if (1 == sscanf(fgets(buffer, 80, fp), "%lf", &td)) { /* resolution */
602  v->vwin.rows = (v->vwin.north - v->vwin.south) / td;
603  v->vwin.cols = (v->vwin.east - v->vwin.west) / td;
604  v->vwin.ew_res = v->vwin.ns_res = td;
605  }
606 
607  sscanf(fgets(buffer, 80, fp), "%s", boo); /* linesonly */
608  v->display_type = get_bool(boo) ? 1 : 3;
609  sscanf(fgets(buffer, 80, fp), "%s", boo);
610  v->dozero = get_bool(boo);
611  sscanf(fgets(buffer, 80, fp), "%s", v->grid_col);
612  if (!strcmp(v->grid_col, "color"))
613  v->colorgrid = 1;
614 
615  sscanf(fgets(buffer, 80, fp), "%s", v->other_col);
616  sscanf(fgets(buffer, 80, fp), "%s", v->bg_col);
617  sscanf(fgets(buffer, 80, fp), "%s", boo);
618  v->doavg = get_bool(boo);
619 
620  if (v->exag) { /* old 3d.view files saved height with no exag */
621  v->from_to[0][2] /= v->exag;
622  v->from_to[1][2] /= v->exag;
623  }
624 
625 
626  fclose(fp);
627  if (req_keys == REQ_KEYS)
628  return (1);
629  else
630  return (-1);
631 }
float b
Definition: named_colr.c:8
int G_3dview_warning(int b)
Turns 3D View warnings on and off.
Definition: view.c:47
int G_get_set_window(struct Cell_head *window)
Get the current working window.
Definition: set_window.c:30
int G_get_3dview_defaults(struct G_3dview *v, struct Cell_head *w)
Sets default for v based on w.
Definition: view.c:63
int G_put_3dview(const char *fname, const char *mapset, const struct G_3dview *View, const struct Cell_head *Win)
Saves info to a 3d.view file.
Definition: view.c:171
#define REQ_KEYS
Definition: view.c:24
int G_get_3dview(const char *fname, const char *mapset, struct G_3dview *View)
Gets a 3D View.
Definition: view.c:252
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:197
return NULL
Definition: dbfopen.c:1394
char * G_find_file2(const char *element, const char *name, const char *mapset)
searches for a file from the mapset search list or in a specified mapset. (look but don&#39;t touch) retu...
Definition: find_file.c:191
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_format_easting(double east, char *buf, int projection)
Easting to ASCII.
Definition: wind_format.c:61
fclose(fd)
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:226
int G_format_northing(double north, char *buf, int projection)
Northing to ASCII.
Definition: wind_format.c:36
int G_projection(void)
query cartographic projection
Definition: proj1.c:33