window_map.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*!
  2. * \file window_map.c
  3. *
  4. * \brief GIS Library - Window mapping functions.
  5. *
  6. * (C) 2001-2009 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 Original author CERL
  12. */
  13. #include <stdlib.h>
  14. #include <grass/gis.h>
  15. #include "G.h"
  16. /*!
  17. * \brief Northing to row.
  18. *
  19. * Converts a <i>north</i>ing relative to a <i>window</i> to a row.
  20. * <b>Note:</b> The result is a double. Casting it to an integer will
  21. * give the row number.
  22. *
  23. * \param north northing value
  24. * \param window pointer to Cell_head
  25. *
  26. * \return row number
  27. */
  28. double G_northing_to_row(double north, const struct Cell_head *window)
  29. {
  30. return (window->north - north) / window->ns_res;
  31. }
  32. /*!
  33. * \brief Adjust east longitude.
  34. *
  35. * This routine returns an equivalent <i>east</i> that is
  36. * larger, but no more than 360 larger than the <i>west</i>
  37. * coordinate.
  38. * <b>Note:</b> This routine should be used only with
  39. * latitude-longitude coordinates.
  40. *
  41. * \param east east coordinate
  42. * \param west west coordinate
  43. *
  44. * \return east coordinate
  45. */
  46. double G_adjust_east_longitude(double east, double west)
  47. {
  48. while (east > west + 360.0)
  49. east -= 360.0;
  50. while (east <= west)
  51. east += 360.0;
  52. return east;
  53. }
  54. /*!
  55. * \brief Returns east larger than west.
  56. *
  57. * If the region projection is <tt>PROJECTION_LL</tt>, then this routine
  58. * returns an equivalent <i>east</i> that is larger, but no more than
  59. * 360 degrees larger, than the coordinate for the western edge of the
  60. * region. Otherwise no adjustment is made and the original
  61. * <i>east</i> is returned.
  62. *
  63. * \param east east coordinate
  64. * \param window pointer to Cell_head
  65. *
  66. * \return east coordinate
  67. */
  68. double G_adjust_easting(double east, const struct Cell_head *window)
  69. {
  70. if (window->proj == PROJECTION_LL) {
  71. east = G_adjust_east_longitude(east, window->west);
  72. if (east > window->east && east == window->west + 360)
  73. east = window->west;
  74. }
  75. return east;
  76. }
  77. /*!
  78. * \brief Easting to column.
  79. *
  80. * Converts <i>east</i> relative to a <i>window</i> to a column.
  81. * <b>Note:</b> The result is a <i>double</i>. Casting it to an
  82. * <i>int</i> will give the column number.
  83. *
  84. * \param east east coordinate
  85. * \param window pointer to Cell_head
  86. *
  87. * \return column number
  88. */
  89. double G_easting_to_col(double east, const struct Cell_head *window)
  90. {
  91. east = G_adjust_easting(east, window);
  92. return (east - window->west) / window->ew_res;
  93. }
  94. /*!
  95. * \brief Row to northing.
  96. *
  97. * Converts a <i>row</i> relative to a <i>window</i> to a
  98. * northing.
  99. * <b>Note:</b> row is a double:
  100. * - row+0.0 will return the northing for the northern edge of the row.
  101. * - row+0.5 will return the northing for the center of the row.
  102. * - row+1.0 will return the northing for the southern edge of the row.
  103. *
  104. * <b>Note:</b> The result is a <i>double</i>. Casting it to an
  105. * <i>int</i> will give the column number.
  106. *
  107. * \param row row number
  108. * \param[in] window pointer to Cell_head
  109. *
  110. * \return north coordinate
  111. */
  112. double G_row_to_northing(double row, const struct Cell_head *window)
  113. {
  114. return window->north - row * window->ns_res;
  115. }
  116. /*!
  117. * \brief Column to easting.
  118. *
  119. * Converts a <i>col</i> relative to a <i>window</i> to an easting.
  120. *
  121. * <b>Note:</b> <i>col</i> is a <i>double</i>:
  122. * - col+0.0 will return the easting for the western edge of the column.
  123. * - col+0.5 will return the easting for the center of the column.
  124. * - col+1.0 will return the easting for the eastern edge of the column.
  125. *
  126. * \param col column number
  127. * \param[in] window pointer to Cell_head
  128. *
  129. * \return east coordinate
  130. */
  131. double G_col_to_easting(double col, const struct Cell_head *window)
  132. {
  133. return window->west + col * window->ew_res;
  134. }
  135. /*!
  136. * \brief Number of rows in active window.
  137. *
  138. * This routine returns the number of rows in the active module window.
  139. * Before raster files can be read or written, it is necessary to
  140. * known how many rows are in the active window. For example:
  141. \code
  142. int nrows, cols;
  143. int row, col;
  144. nrows = G_window_rows();
  145. ncols = G_window_cols();
  146. for (row = 0; row < nrows; row++) {
  147. // read row ...
  148. for (col = 0; col < ncols; col++) {
  149. // process col ...
  150. }
  151. }
  152. \endcode
  153. *
  154. * \return number of rows
  155. */
  156. int G_window_rows(void)
  157. {
  158. G__init_window();
  159. return G__.window.rows;
  160. }
  161. /*!
  162. * \brief Number of columns in active window.
  163. *
  164. * These routines return the number of rows and columns (respectively)
  165. * in the active module region. Before raster maps can be read or
  166. * written, it is necessary to known how many rows and columns are in
  167. * the active region. For example:
  168. *
  169. \code
  170. int nrows, cols;
  171. int row, col;
  172. nrows = G_window_rows();
  173. ncols = G_window_cols();
  174. for (row = 0; row < nrows; row++) {
  175. // read row ...
  176. for (col = 0; col < ncols; col++) {
  177. // process col ...
  178. }
  179. }
  180. \endcode
  181. *
  182. * \return number of columns
  183. */
  184. int G_window_cols(void)
  185. {
  186. G__init_window();
  187. return G__.window.cols;
  188. }
  189. /*!
  190. * \brief Initialize window.
  191. *
  192. */
  193. void G__init_window(void)
  194. {
  195. if (G_is_initialized(&G__.window_set))
  196. return;
  197. G_get_window(&G__.window);
  198. G_initialize_done(&G__.window_set);
  199. }