do_scalebar.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /* Function to draw scalebar on page */
  2. #include <string.h>
  3. #include <math.h>
  4. #include <grass/glocale.h>
  5. #include "local_proto.h"
  6. #include "distance.h"
  7. #define LEFT 0
  8. #define RIGHT 1
  9. #define LOWER 0
  10. #define UPPER 1
  11. #define CENTER 2
  12. static char *nice_number(double);
  13. int do_scalebar(void)
  14. {
  15. double scale_size;
  16. double length, width;
  17. double x, x1, x2, y1, y2, y3;
  18. int seg, i, j, lab;
  19. int margin;
  20. char num[50];
  21. /* get scale size */
  22. scale_size =
  23. METERS_TO_INCHES * distance(PS.w.east, PS.w.west) / scale(PS.scaletext);
  24. /* convert scale size to map inches */
  25. length = (sb.length / scale_size) *
  26. G_database_units_to_meters_factor() * METERS_TO_INCHES;
  27. /* if(sb.units == SB_UNITS_AUTO) { do nothing } */
  28. if(sb.units == SB_UNITS_METERS)
  29. length /= G_database_units_to_meters_factor();
  30. else if(sb.units == SB_UNITS_KM)
  31. length *= KILOMETERS_TO_METERS / G_database_units_to_meters_factor();
  32. else if(sb.units == SB_UNITS_FEET)
  33. length *= FEET_TO_METERS / G_database_units_to_meters_factor();
  34. else if(sb.units == SB_UNITS_MILES)
  35. length *= MILES_TO_METERS / G_database_units_to_meters_factor();
  36. else if(sb.units == SB_UNITS_NMILES)
  37. length *= NAUT_MILES_TO_METERS / G_database_units_to_meters_factor();
  38. width = sb.height;
  39. seg = sb.segment;
  40. j = 0;
  41. lab = 0;
  42. margin = (int)(0.2 * (double)sb.fontsize + 0.5);
  43. if (margin < 2)
  44. margin = 2;
  45. fprintf(PS.fp, "/mg %d def\n", margin);
  46. x = sb.x - (length / 2.);
  47. set_font_name(sb.font);
  48. set_font_size(sb.fontsize);
  49. set_line_width(sb.width);
  50. if (strcmp(sb.type, "f") == 0) {
  51. /* draw fancy scale bar */
  52. for (i = 0; i < seg; i++) {
  53. /* draw a filled rectangle */
  54. x1 = 72.0 * (x + (length / seg) * i) + 0.5;
  55. y1 = 72.0 * (PS.page_height - sb.y);
  56. x2 = 72.0 * (x + (length / seg) * (i + 1)) + 0.5;
  57. y2 = (72.0 * (PS.page_height - sb.y)) + (width * 72.0);
  58. /* Alternate black and white */
  59. if (j == 0) {
  60. fprintf(PS.fp, "0.0 0.0 0.0 C\n");
  61. j = 1;
  62. }
  63. else {
  64. fprintf(PS.fp, "1.0 1.0 1.0 C\n");
  65. j = 0;
  66. }
  67. fprintf(PS.fp, "%.1f %.1f %.1f %.1f B\n", x1, y1, x2, y2);
  68. /* set outline to black */
  69. fprintf(PS.fp, "F 0.0 0.0 0.0 C\n");
  70. fprintf(PS.fp, "D\n");
  71. lab++;
  72. /* do text */
  73. if (i == 0 || lab == sb.numbers) {
  74. sprintf(num, "%s", nice_number((sb.length / sb.segment) * i));
  75. text_box_path(x1, y2 + margin, CENTER, LOWER, num, 0);
  76. if (sb.bgcolor) { /* TODO: take bg color, not just [white|none] */
  77. set_rgb_color(WHITE);
  78. fprintf(PS.fp, "F ");
  79. }
  80. set_rgb_color(sb.color);
  81. fprintf(PS.fp, "TIB\n");
  82. lab = 0;
  83. }
  84. if ((lab > 0 && i == seg - 1) ||
  85. (sb.numbers == 1 && i == seg - 1)) {
  86. /* special case for last label */
  87. sprintf(num, "%s", nice_number(sb.length));
  88. text_box_path(x2, y2 + margin, CENTER, LOWER, num, 0);
  89. if (sb.bgcolor) {
  90. set_rgb_color(WHITE);
  91. fprintf(PS.fp, "F ");
  92. }
  93. set_rgb_color(sb.color);
  94. fprintf(PS.fp, "TIB\n");
  95. }
  96. }
  97. }
  98. else {
  99. /* draw simple scalebar */
  100. x1 = 72.0 * x + 0.5;
  101. y1 = (72.0 * (PS.page_height - sb.y)) + (width * 72.0);
  102. x2 = 72.0 * x + 0.5;
  103. y2 = 72.0 * (PS.page_height - sb.y);
  104. fprintf(PS.fp, "%.1f %.1f %.1f %.1f L D\n", x1, y1, x2, y2);
  105. /* draw label */
  106. text_box_path(x1, y1 + margin, CENTER, LOWER, "0", 0);
  107. if (sb.bgcolor) {
  108. set_rgb_color(WHITE);
  109. fprintf(PS.fp, "F ");
  110. }
  111. set_rgb_color(sb.color);
  112. fprintf(PS.fp, "TIB\n");
  113. x1 = 72.0 * x + 0.5;
  114. y1 = 72.0 * (PS.page_height - sb.y);
  115. x2 = 72.0 * (x + length) + 0.5;
  116. y2 = 72.0 * (PS.page_height - sb.y);
  117. fprintf(PS.fp, "%.1f %.1f %.1f %.1f L D\n", x1, y1, x2, y2);
  118. x1 = 72.0 * (x + length) + 0.5;
  119. y2 = (72.0 * (PS.page_height - sb.y)) + (width * 72.0);
  120. x2 = 72.0 * (x + length) + 0.5;
  121. y1 = 72.0 * (PS.page_height - sb.y);
  122. fprintf(PS.fp, "%.1f %.1f %.1f %.1f L D\n", x1, y1, x2, y2);
  123. /* draw label */
  124. sprintf(num, "%s", nice_number(sb.length));
  125. text_box_path(x1, y2 + margin, CENTER, LOWER, num, 0);
  126. if (sb.bgcolor) {
  127. set_rgb_color(WHITE);
  128. fprintf(PS.fp, "F ");
  129. }
  130. set_rgb_color(sb.color);
  131. fprintf(PS.fp, "TIB\n");
  132. for (i = 1; i < seg; i++) {
  133. x1 = 72.0 * (x + (length / seg) * i) + 0.5;
  134. y1 = 72.0 * (PS.page_height - sb.y);
  135. x2 = 72.0 * (x + (length / seg) * i) + 0.5;
  136. y2 = (72.0 * (PS.page_height - sb.y)) + (width / 2. * 72.0);
  137. y3 = (72.0 * (PS.page_height - sb.y)) + (width * 72.0);
  138. fprintf(PS.fp, "%.1f %.1f %.1f %.1f L D\n", x1, y1, x2, y2);
  139. lab++;
  140. /* do text */
  141. if (lab == sb.numbers) {
  142. sprintf(num, "%s", nice_number((sb.length / sb.segment) * i));
  143. text_box_path(x1, y3 + margin, CENTER, LOWER, num, 0);
  144. if (sb.bgcolor) {
  145. set_rgb_color(WHITE);
  146. fprintf(PS.fp, "F ");
  147. }
  148. set_rgb_color(sb.color);
  149. fprintf(PS.fp, "TIB\n");
  150. lab = 0;
  151. }
  152. }
  153. }
  154. /* draw units label */
  155. if (sb.units == SB_UNITS_AUTO)
  156. strcpy(num, G_database_unit_name(TRUE));
  157. else if(sb.units == SB_UNITS_METERS)
  158. strcpy(num, _("meters"));
  159. else if(sb.units == SB_UNITS_KM)
  160. strcpy(num, _("kilometers"));
  161. else if(sb.units == SB_UNITS_FEET)
  162. strcpy(num, _("feet"));
  163. else if(sb.units == SB_UNITS_MILES)
  164. strcpy(num, _("miles"));
  165. else if(sb.units == SB_UNITS_NMILES)
  166. strcpy(num, _("nautical miles"));
  167. text_box_path(72.0 * (x + length/2), 72.0 * (PS.page_height - (sb.y + 0.075)),
  168. CENTER, UPPER, num, 0);
  169. if (sb.bgcolor) {
  170. set_rgb_color(WHITE);
  171. fprintf(PS.fp, "F ");
  172. }
  173. set_rgb_color(sb.color);
  174. fprintf(PS.fp, "TIB\n");
  175. return 0;
  176. }
  177. /* Make a nice number -- reduce to less than 3 decimal places */
  178. static char *nice_number(double val)
  179. {
  180. static char text[50];
  181. if (val == (int)val)
  182. sprintf(text, "%.0f", val);
  183. else if ((val * 10.) == (int)(val * 10))
  184. sprintf(text, "%.1f", val);
  185. else if ((val * 100.) == (int)(val * 100))
  186. sprintf(text, "%.2f", val);
  187. else
  188. sprintf(text, "%.3f", val);
  189. return text;
  190. }