wind_overlap.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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 (V <= 0.0)
  85. return 0.0;
  86. /* global wrap-around, part 1 */
  87. if (window->proj == PROJECTION_LL) {
  88. shift = 0.0;
  89. while (E + shift > window->east)
  90. shift -= 360.0;
  91. while (E + shift < window->west)
  92. shift += 360.0;
  93. E += shift;
  94. W += shift;
  95. }
  96. /* horizontal width of the box that overlaps the window */
  97. if ((e = window->east) > E)
  98. e = E;
  99. if ((w = window->west) < W)
  100. w = W;
  101. H = e - w;
  102. if (H <= 0.0)
  103. return 0.0;
  104. /* global wrap-around, part 2 */
  105. if (window->proj == PROJECTION_LL) {
  106. shift = 0.0;
  107. while (W + shift < window->west)
  108. shift += 360.0;
  109. while (W + shift > window->east)
  110. shift -= 360.0;
  111. if (shift) {
  112. E += shift;
  113. W += shift;
  114. if ((e = window->east) > E)
  115. e = E;
  116. if ((w = window->west) < W)
  117. w = W;
  118. H += e - w;
  119. }
  120. }
  121. return (H * V) / ((N - S) * (E - W));
  122. }