scale.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* Function: scale
  2. **
  3. ** This function returns the horizontal extent of the map in inches and
  4. ** modifies the text string. Much of this code is from p.map's scale.c.
  5. **
  6. ** Author: Paul W. Carlson April 1992
  7. */
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <grass/gis.h>
  11. #include <grass/glocale.h>
  12. #include "local_proto.h"
  13. #include "distance.h"
  14. #define PWIDTH (PS.page_width-PS.left_marg-PS.right_marg)
  15. static double do_scale(char *);
  16. #ifdef __GNUC_MINOR__
  17. static int OOPS(void) __attribute__ ((__noreturn__));
  18. #else
  19. static int OOPS();
  20. #endif
  21. double scale(char *text)
  22. {
  23. double inches;
  24. inches = do_scale(text);
  25. return inches;
  26. }
  27. static double do_scale(char *text)
  28. {
  29. char unit1[30];
  30. char unit2[30];
  31. char equals[30];
  32. char dummy[2];
  33. long n1, n2;
  34. double u1, u2;
  35. /*
  36. * absolute horizontal width specification
  37. * x inches
  38. * x panels
  39. * convert text to 1 : n
  40. */
  41. u1 = 0;
  42. *unit1 = 0;
  43. *dummy = 0;
  44. if (sscanf(text, "%lf %s %1s", &u1, unit1, dummy) == 2 && *dummy == 0) {
  45. u2 = -1;
  46. if (strncmp(unit1, "panel", 5) == 0 && u1 > 0)
  47. u2 = u1 * (PWIDTH);
  48. else if (strncmp(unit1, "inch", 4) == 0 && u1 > 0)
  49. u2 = u1;
  50. if (u2 > 0) {
  51. sprintf(text, "1 : %.0f",
  52. METERS_TO_INCHES * distance(PS.w.east, PS.w.west) / u2);
  53. return u2;
  54. }
  55. }
  56. /*
  57. * unitless ratio specification
  58. * n : m
  59. */
  60. *dummy = 0;
  61. n1 = n2 = 0;
  62. if (sscanf(text, "%ld : %ld%1s", &n1, &n2, dummy) == 2) {
  63. if (n1 <= 0 || n2 <= 0 || *dummy)
  64. OOPS();
  65. sprintf(text, "%ld : %ld", n1, n2);
  66. return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * n1 / n2;
  67. }
  68. /*
  69. *
  70. * ratio specification with unit conversions
  71. * x inches equals y miles
  72. * x inches equals y meters
  73. * x inches equals y kilometers
  74. */
  75. *unit1 = 0;
  76. *unit2 = 0;
  77. *equals = 0;
  78. n1 = n2 = 0;
  79. if (sscanf(text, "%ld %s %s %ld %s", &n1, unit1, equals, &n2, unit2) == 5) {
  80. if (n1 <= 0 || n2 <= 0)
  81. OOPS();
  82. if (strcmp(equals, "=") != 0 && strncmp(equals, "equal", 5) != 0)
  83. OOPS();
  84. /* unit1: inches */
  85. if (strncmp(unit1, "inch", 4) == 0)
  86. u1 = n1;
  87. else
  88. OOPS();
  89. /* unit2: meters, miles, kilometers */
  90. if (strncmp(unit2, "mile", 4) == 0) {
  91. u2 = MILES_TO_INCHES;
  92. strcpy(unit2, "mile");
  93. }
  94. else if (strncmp(unit2, "meter", 5) == 0) {
  95. u2 = METERS_TO_INCHES;
  96. strcpy(unit2, "meter");
  97. }
  98. else if (strncmp(unit2, "kilometer", 9) == 0) {
  99. u2 = METERS_TO_INCHES * 1000;
  100. strcpy(unit2, "kilometer");
  101. }
  102. else
  103. OOPS();
  104. u2 *= n2;
  105. strcpy(unit1, "inch");
  106. strcpy(equals, "equal");
  107. if (n1 == 1)
  108. strcat(equals, "s");
  109. else
  110. strcat(unit1, "es");
  111. if (n2 != 1)
  112. strcat(unit2, "s");
  113. sprintf(text, "%ld %s %s %ld %s", n1, unit1, equals, n2, unit2);
  114. return METERS_TO_INCHES * distance(PS.w.east, PS.w.west) * u1 / u2;
  115. }
  116. OOPS();
  117. }
  118. static int OOPS(void)
  119. {
  120. G_fatal_error(_("PSmap: do_scale(): shouldn't happen"));
  121. }