wind_overlap.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*!
  2. * \file lib/gis/wind_overlap.c
  3. *
  4. * \brief GIS Library - Window overlap functions.
  5. *
  6. * (C) 2001-2014 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author GRASS GIS Development Team
  12. *
  13. * \date 1999-2014
  14. */
  15. #include <grass/gis.h>
  16. /**
  17. * \brief Determines if a box overlays a map window.
  18. *
  19. * Given a map <b>window</b>, and a box of <b>N</b>,<b>S</b>,<b>E</b>,<b>W</b>
  20. * does the box overlap the map <b>window</b>?<br>
  21. *
  22. * Note: knows about global wrap-around for lat-long.
  23. *
  24. * \param[in] window pointer to window structure
  25. * \param[in] N north
  26. * \param[in] S south
  27. * \param[in] E east
  28. * \param[in] W west
  29. * \return 1 if box overlaps window
  30. * \return 0 if box does not overlap window
  31. */
  32. int G_window_overlap(const struct Cell_head *window,
  33. double N, double S, double E, double W)
  34. {
  35. if (window->north <= S)
  36. return 0;
  37. if (window->south >= N)
  38. return 0;
  39. if (window->proj == PROJECTION_LL) {
  40. while (E < window->west) {
  41. E += 360.0;
  42. W += 360.0;
  43. }
  44. while (W > window->east) {
  45. E -= 360.0;
  46. W -= 360.0;
  47. }
  48. }
  49. if (window->east <= W)
  50. return 0;
  51. if (window->west >= E)
  52. return 0;
  53. return 1;
  54. }
  55. /**
  56. * \brief Determines percentage of box is contained in the <b>window</b>.
  57. *
  58. * This version returns the percentage (from 0 to 1) of the box
  59. * contained in the window. This feature can be used during vector
  60. * plotting to decide if it is more efficient to do a level-one
  61. * read of the whole vector map, or to pay the price of a
  62. * level-two startup so only those arcs that enter the window are
  63. * actually read.
  64. *
  65. * \param[in] window pointer to widnow structure
  66. * \param[in] N north
  67. * \param[in] S south
  68. * \param[in] E east
  69. * \param[in] W west
  70. * \return percentage of overlap
  71. */
  72. double G_window_percentage_overlap(const struct Cell_head *window,
  73. double N, double S, double E, double W)
  74. {
  75. double V, H;
  76. double n, s, e, w;
  77. double shift;
  78. /* vertical height of the box that overlaps the window */
  79. if ((n = window->north) > N)
  80. n = N;
  81. if ((s = window->south) < S)
  82. s = S;
  83. V = n - s;
  84. if (N == S) {
  85. V = (N < window->north && N > window->south);
  86. N = 1;
  87. S = 0;
  88. }
  89. if (V <= 0.0)
  90. return 0.0;
  91. /* global wrap-around, part 1 */
  92. if (window->proj == PROJECTION_LL) {
  93. shift = 0.0;
  94. while (E + shift > window->east)
  95. shift -= 360.0;
  96. while (E + shift < window->west)
  97. shift += 360.0;
  98. E += shift;
  99. W += shift;
  100. }
  101. /* horizontal width of the box that overlaps the window */
  102. if ((e = window->east) > E)
  103. e = E;
  104. if ((w = window->west) < W)
  105. w = W;
  106. H = e - w;
  107. if (W == E)
  108. H = (E > window->west && E < window->east);
  109. if (H <= 0.0)
  110. return 0.0;
  111. /* global wrap-around, part 2 */
  112. if (window->proj == PROJECTION_LL) {
  113. shift = 0.0;
  114. while (W + shift < window->west)
  115. shift += 360.0;
  116. while (W + shift > window->east)
  117. shift -= 360.0;
  118. if (shift) {
  119. E += shift;
  120. W += shift;
  121. if ((e = window->east) > E)
  122. e = E;
  123. if ((w = window->west) < W)
  124. w = W;
  125. H += e - w;
  126. }
  127. }
  128. if (W == E) {
  129. W = 0;
  130. E = 1;
  131. }
  132. return (H * V) / ((N - S) * (E - W));
  133. }