PlotProfile.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* PlotProfile.c
  2. *
  3. * function defined:
  4. *
  5. * PlotProfile(profile,letter,min,max)
  6. *
  7. * struct Profile profile; - profile structure
  8. * int min, - min cell-file value
  9. * max; - max cell-file calue
  10. *
  11. * PURPOSE: To plot a profile in the currently chosen on-screen window.
  12. * The profile's length is scaled to fit along the x-axis. The profile
  13. * is scaled to fit the maximum and minimum cell-file values (instead of
  14. * the maximum and minimum profile values) on the y-axis.
  15. *
  16. * NOTES:
  17. *
  18. * 1) assumes that R_open_driver has already been called.
  19. *
  20. * 2) assumes that the profile structure has been both initialized by
  21. * a call to InitProfile, and filled with data by a call to ExtractProfile.
  22. *
  23. * Dave Johnson
  24. * DBA Systems, Inc.
  25. * 10560 Arrowhead Drive
  26. * Fairfax, Virginia 22030
  27. *
  28. */
  29. #include <limits.h>
  30. #include <grass/raster.h>
  31. #include <grass/display.h>
  32. #include "profile.h"
  33. #define ORIGIN_X 0.13
  34. #define ORIGIN_Y 0.07
  35. #define YAXIS_END 0.77
  36. #define XAXIS_END 0.95
  37. #define TEXT_HEIGHT 0.11
  38. #define TEXT_COLUMN 0.07
  39. double _get_cat(UCAT *, int);
  40. int PlotProfile(struct Profile profile, char *letter, int min, int max)
  41. {
  42. struct ProfileNode *ptr;
  43. char txt_buf[512];
  44. int done;
  45. int text_width,
  46. text_height,
  47. i, t, b, l, r, tt, tb, tl, tr, height, width, x_line[3], y_line[3];
  48. double yoffset, xoffset, xscale, yscale;
  49. /* get current graphics window coordinates */
  50. D_get_screen_window(&t, &b, &l, &r);
  51. R_set_window(t, b, l, r);
  52. /* erase current graphics window to black */
  53. R_standard_color(D_translate_color(DEFAULT_BG_COLOR));
  54. D_erase_window();
  55. /* create axis lines */
  56. height = b - t;
  57. width = r - l;
  58. x_line[0] = x_line[1] = l + (int)(ORIGIN_X * width);
  59. x_line[2] = l + (int)(XAXIS_END * width);
  60. y_line[0] = b - (int)(YAXIS_END * height);
  61. y_line[1] = y_line[2] = b - (int)(ORIGIN_Y * height);
  62. R_standard_color(D_translate_color(DEFAULT_FG_COLOR));
  63. /* figure scaling factors and offsets for profile line */
  64. xscale = ((double)(x_line[2] - x_line[1]) / ((double)profile.count));
  65. yscale = ((double)(y_line[1] - y_line[0])) / ((double)(max - min));
  66. yoffset = (double)(y_line[1]);
  67. xoffset = (double)x_line[1];
  68. /* plot profile */
  69. ptr = profile.ptr;
  70. R_move_abs((int)xoffset, (int)yoffset);
  71. for (i = 0; i <= profile.count; i++) {
  72. if (ptr == NULL)
  73. break;
  74. if (xscale > 1) {
  75. R_cont_abs((int)(xoffset + xscale * i),
  76. (int)(yoffset - yscale * _get_cat(&ptr->cat, min)));
  77. R_cont_abs((int)(xoffset + xscale * (i + 1.0)),
  78. (int)(yoffset - yscale * _get_cat(&ptr->cat, min)));
  79. }
  80. else
  81. R_cont_abs((int)(xoffset + xscale * i),
  82. (int)(yoffset - yscale * _get_cat(&ptr->cat, min)));
  83. ptr = ptr->next;
  84. }
  85. R_standard_color(D_translate_color("red"));
  86. R_polyline_abs(x_line, y_line, 3);
  87. /* loop until coordinate text is sized correctly to fit in window */
  88. text_height = TEXT_HEIGHT * (b - t);
  89. text_width = text_height * 0.8;
  90. R_standard_color(D_translate_color(DEFAULT_FG_COLOR));
  91. sprintf(txt_buf, "%s: From (%10.2f,%10.2f) to (%10.2f,%10.2f)",
  92. letter, profile.e1, profile.n1, profile.e2, profile.n2);
  93. done = 0;
  94. do {
  95. R_get_text_box(txt_buf, &tt, &tb, &tl, &tr);
  96. if ((tr - tl) >= (r - l)) {
  97. text_height *= 0.95;
  98. text_width *= 0.95;
  99. R_text_size(text_width, text_height);
  100. }
  101. else
  102. done = 1;
  103. }
  104. while (!done);
  105. R_move_abs((int)(l + 0.5 * (r - l) - .5 * (tr - tl)),
  106. (int)(t + .12 * (b - t)));
  107. R_text(txt_buf);
  108. /* set text size for y-axis labels */
  109. text_height = TEXT_HEIGHT * (b - t);
  110. text_width = text_height * 0.8;
  111. R_text_size(text_width, text_height);
  112. /* plot y-axis label (bottom) */
  113. sprintf(txt_buf, "%d", min);
  114. R_get_text_box(txt_buf, &tt, &tb, &tl, &tr);
  115. R_move_abs((int)(l + TEXT_COLUMN * (r - l) - .5 * (tr - tl)),
  116. (int)(yoffset + .5 * (tb - tt)));
  117. R_text(txt_buf);
  118. /* plot y-axis label (top) */
  119. sprintf(txt_buf, "%d", max);
  120. R_get_text_box(txt_buf, &tt, &tb, &tl, &tr);
  121. R_move_abs((int)(l + TEXT_COLUMN * (r - l) - .5 * (tr - tl)),
  122. (int)(y_line[0] + .5 * (tb - tt)));
  123. R_text(txt_buf);
  124. R_flush();
  125. return 0;
  126. }
  127. double _get_cat(UCAT * theCat, int min)
  128. {
  129. switch (theCat->type) {
  130. case CELL_TYPE:
  131. if (theCat->val.c >= min)
  132. return (double)(theCat->val.c - (double)min);
  133. else
  134. return (double)0.0;
  135. case FCELL_TYPE:
  136. if (theCat->val.f >= min)
  137. return (double)(theCat->val.f - (double)min);
  138. else
  139. return (double)0.0;
  140. case DCELL_TYPE:
  141. if (theCat->val.d >= min)
  142. return (theCat->val.d - (double)min);
  143. else
  144. return (double)0.0;
  145. default: /* Shouldn't happen */
  146. return (double)0.0;
  147. }
  148. }
  149. /* vim: set softtabstop=4 shiftwidth=4 expandtab: */