do_grid.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* Functions: do_grid, do_grid_numbers, format_northing, format_easting
  2. **
  3. ** These functions are much modified versions of the p.map functions.
  4. **
  5. ** Author: Paul W. Carlson April 1992
  6. */
  7. #include <string.h>
  8. #include <math.h>
  9. #include "local_proto.h"
  10. #define LEFT 0
  11. #define RIGHT 1
  12. #define LOWER 0
  13. #define UPPER 1
  14. #define CENTER 2
  15. static char *format_northing(double, int);
  16. static char *format_easting(double, int);
  17. int do_grid(void)
  18. {
  19. double g, e1, e2;
  20. int j;
  21. if (PS.grid <= 0)
  22. return 1;
  23. /* set color and set line width to 1 */
  24. set_ps_color(&PS.grid_color);
  25. set_line_width(PS.grid_width);
  26. /* draw horizontal lines in 3 pieces -- lat-lon lines must not
  27. * extend more than half the globe
  28. * start with first grid line just south of the window north
  29. */
  30. e1 = (PS.w.east * 2 + PS.w.west) / 3;
  31. e2 = (PS.w.west * 2 + PS.w.east) / 3;
  32. g = floor(PS.w.north / PS.grid) * PS.grid;
  33. for (j = 0; g >= PS.w.south; j++, g -= PS.grid) {
  34. if (g == PS.w.north || g == PS.w.south)
  35. continue;
  36. start_line(PS.w.east, g);
  37. sec_draw = 0;
  38. G_plot_line(PS.w.east, g, e1, g);
  39. fprintf(PS.fp, " D ");
  40. start_line(e1, g);
  41. sec_draw = 0;
  42. G_plot_line(e1, g, e2, g);
  43. fprintf(PS.fp, " D ");
  44. start_line(e2, g);
  45. sec_draw = 0;
  46. G_plot_line(e2, g, PS.w.west, g);
  47. fprintf(PS.fp, " D\n");
  48. }
  49. /* vertical lines */
  50. /* start with first grid line just west of the window east */
  51. g = floor(PS.w.east / PS.grid) * PS.grid;
  52. for (j = 0; g > PS.w.west; j++, g -= PS.grid) {
  53. if (g == PS.w.east || g == PS.w.west)
  54. continue;
  55. start_line(g, PS.w.north);
  56. sec_draw = 0;
  57. G_plot_line(g, PS.w.north, g, PS.w.south);
  58. if (j & 1)
  59. fprintf(PS.fp, " D\n");
  60. else
  61. fprintf(PS.fp, " D ");
  62. }
  63. return 0;
  64. }
  65. int do_grid_cross(void)
  66. {
  67. double g_north, g_east;
  68. int j, k;
  69. if (PS.grid <= 0)
  70. return 1;
  71. /* set color and set line width to 1 */
  72. set_ps_color(&PS.grid_color);
  73. set_line_width(PS.grid_width);
  74. g_north = floor(PS.w.north / PS.grid) * PS.grid;
  75. g_east = floor(PS.w.east / PS.grid) * PS.grid;
  76. for (j = 0; g_north >= PS.w.south; j++, g_north -= PS.grid) {
  77. for (k = 0; g_east > PS.w.west; k++, g_east -= PS.grid) {
  78. if (g_north == PS.w.north || g_north == PS.w.south)
  79. continue;
  80. if (g_east == PS.w.east || g_east == PS.w.west)
  81. continue;
  82. start_line(g_east - PS.grid_cross, g_north);
  83. G_plot_line(g_east - PS.grid_cross, g_north,
  84. g_east + PS.grid_cross, g_north);
  85. fprintf(PS.fp, " D ");
  86. start_line(g_east, g_north - PS.grid_cross);
  87. G_plot_line(g_east, g_north - PS.grid_cross, g_east,
  88. g_north + PS.grid_cross);
  89. fprintf(PS.fp, " D ");
  90. }
  91. g_east = floor(PS.w.east / PS.grid) * PS.grid;
  92. }
  93. return 0;
  94. }
  95. int do_grid_numbers(void)
  96. {
  97. double g;
  98. char num_text[50];
  99. int grid, vy, vx, hy = 0, hx = 0;
  100. int first, len, x, y, last_bottom, last_right;
  101. int rounded_grid, margin;
  102. if (PS.grid <= 0 || PS.grid_numbers <= 0)
  103. return 1;
  104. grid = PS.grid * PS.grid_numbers;
  105. /* round grid to multiple of 10 */
  106. rounded_grid = 1;
  107. if (PS.w.proj != PROJECTION_LL) {
  108. sprintf(num_text, "%d", PS.grid);
  109. len = strlen(num_text);
  110. while (len-- && num_text[len] == '0')
  111. rounded_grid *= 10;
  112. if (rounded_grid == 10)
  113. rounded_grid = 1;
  114. }
  115. /* initialize */
  116. set_font_name(PS.grid_font);
  117. set_font_size(PS.grid_fontsize);
  118. set_ps_color(&PS.grid_numbers_color);
  119. first = 1;
  120. /* horizontal grid numbers
  121. * these numbers only appear on the left edge of the first panel.
  122. * center the numbers on each grid line.
  123. * suppress number if it falls off the map or would overlay the previous
  124. * label
  125. */
  126. margin = (int)(0.2 * (double)PS.grid_fontsize + 0.5);
  127. if (margin < 2)
  128. margin = 2;
  129. fprintf(PS.fp, "/mg %d def\n", margin);
  130. g = floor(PS.w.north / grid) * grid;
  131. last_bottom = (int)PS.map_top;
  132. first = 1;
  133. /* x = XCONV(PS.w.west); */
  134. for (; g > PS.w.south; g -= grid) {
  135. /*y = YCONV(g); */
  136. G_plot_where_xy(PS.w.west, g, &vx, &vy);
  137. x = (double)vx / 10.;
  138. y = (double)vy / 10.;
  139. if (y + PS.grid_fontsize > last_bottom)
  140. continue;
  141. if (y - PS.grid_fontsize < (int)PS.map_bot)
  142. continue;
  143. sprintf(num_text, "%s", format_northing(g, rounded_grid));
  144. text_box_path(x, y, LEFT, CENTER, num_text, 0);
  145. set_rgb_color(WHITE);
  146. fprintf(PS.fp, "F ");
  147. set_ps_color(&PS.grid_numbers_color);
  148. fprintf(PS.fp, "TIB\n");
  149. last_bottom = y - PS.grid_fontsize;
  150. if (first) {
  151. first = 0;
  152. hy = y + (int)(0.5 * (double)PS.grid_fontsize + 0.5) + margin;
  153. hx = x + 0.7 * strlen(num_text) * PS.grid_fontsize + 2 * margin;
  154. }
  155. }
  156. /* vertical grid numbers
  157. * center the numbers on each grid line.
  158. * suppress number if it falls of the map or would overlay the previous
  159. * label
  160. */
  161. g = floor(PS.w.west / grid) * grid;
  162. last_right = (int)PS.map_left;
  163. /* y = YCONV(PS.w.north); */
  164. for (; g < PS.w.east; g += grid) {
  165. /* x = XCONV(g); */
  166. G_plot_where_xy(g, PS.w.north, &vx, &vy);
  167. x = (double)vx / 10.;
  168. y = (double)vy / 10.;
  169. if (x - PS.grid_fontsize < last_right)
  170. continue;
  171. if (x + PS.grid_fontsize > (int)PS.map_right)
  172. continue;
  173. sprintf(num_text, "%s", format_easting(g, rounded_grid));
  174. vy = y - 0.7 * strlen(num_text) * PS.grid_fontsize - 2 * margin;
  175. vx = x - (int)(0.5 * (double)PS.grid_fontsize + 0.5) - margin;
  176. if (vx < hx && vy < hy)
  177. continue;
  178. fprintf(PS.fp, "ZB (%s) PB 90 rotate\n", num_text);
  179. fprintf(PS.fp, "%d br sub bl add mg add\n", y);
  180. fprintf(PS.fp, "%d bt bb sub D2 add mg sub neg TR TB\n", x);
  181. set_rgb_color(WHITE);
  182. fprintf(PS.fp, "F ");
  183. set_ps_color(&PS.grid_numbers_color);
  184. fprintf(PS.fp, "TIB\n");
  185. last_right = x + PS.grid_fontsize;
  186. }
  187. return 0;
  188. }
  189. static char *format_northing(double n, int round)
  190. {
  191. static char text[50];
  192. if (PS.w.proj == PROJECTION_LL)
  193. G_format_northing(n, text, PS.w.proj);
  194. else {
  195. n = floor(n / round);
  196. sprintf(text, "%.0f", n);
  197. }
  198. return text;
  199. }
  200. static char *format_easting(double e, int round)
  201. {
  202. static char text[50];
  203. if (PS.w.proj == PROJECTION_LL)
  204. G_format_easting(e, text, PS.w.proj);
  205. else {
  206. e = floor(e / round);
  207. sprintf(text, "%.0f", e);
  208. }
  209. return text;
  210. }