window_map.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*!
  2. * \file lib/raster/window_map.c
  3. *
  4. * \brief Raster 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 <grass/raster.h>
  16. #include "R.h"
  17. #define alloc_index(n) (COLUMN_MAPPING *) G_malloc((n)*sizeof(COLUMN_MAPPING))
  18. /*!
  19. * \brief Create window mapping.
  20. *
  21. * Creates mapping from cell header into window. The boundaries and
  22. * resolution of the two spaces do not have to be the same or aligned in
  23. * any way.
  24. *
  25. * \param fd file descriptor
  26. */
  27. void Rast__create_window_mapping(int fd)
  28. {
  29. struct fileinfo *fcb = &R__.fileinfo[fd];
  30. COLUMN_MAPPING *col;
  31. int i;
  32. int x;
  33. double C1, C2;
  34. double west;
  35. if (fcb->open_mode >= 0 && fcb->open_mode != OPEN_OLD) /* open for write? */
  36. return;
  37. if (fcb->open_mode == OPEN_OLD) /* already open ? */
  38. G_free(fcb->col_map);
  39. col = fcb->col_map = alloc_index(R__.rd_window.cols);
  40. /*
  41. * for each column in the window, go to center of the cell,
  42. * compute nearest column in the data file
  43. * if column is not in data file, set column to 0
  44. *
  45. * for lat/lon move window so that west is bigger than
  46. * cellhd west.
  47. */
  48. west = R__.rd_window.west;
  49. if (R__.rd_window.proj == PROJECTION_LL) {
  50. while (west > fcb->cellhd.west + 360.0)
  51. west -= 360.0;
  52. while (west < fcb->cellhd.west)
  53. west += 360.0;
  54. }
  55. C1 = R__.rd_window.ew_res / fcb->cellhd.ew_res;
  56. C2 = (west - fcb->cellhd.west +
  57. R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
  58. for (i = 0; i < R__.rd_window.cols; i++) {
  59. x = C2;
  60. if (C2 < x) /* adjust for rounding of negatives */
  61. x--;
  62. if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
  63. x = -1;
  64. *col++ = x + 1;
  65. C2 += C1;
  66. }
  67. /* do wrap around for lat/lon */
  68. if (R__.rd_window.proj == PROJECTION_LL) {
  69. col = fcb->col_map;
  70. C2 = (west - 360.0 - fcb->cellhd.west +
  71. R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
  72. for (i = 0; i < R__.rd_window.cols; i++) {
  73. x = C2;
  74. if (C2 < x) /* adjust for rounding of negatives */
  75. x--;
  76. if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
  77. x = -1;
  78. if (*col == 0) /* only change those not already set */
  79. *col = x + 1;
  80. col++;
  81. C2 += C1;
  82. }
  83. }
  84. G_debug(3, "create window mapping (%d columns)", R__.rd_window.cols);
  85. /* for (i = 0; i < R__.rd_window.cols; i++)
  86. fprintf(stderr, "%s%ld", i % 15 ? " " : "\n", (long)fcb->col_map[i]);
  87. fprintf(stderr, "\n");
  88. */
  89. /* compute C1,C2 for row window mapping */
  90. fcb->C1 = R__.rd_window.ns_res / fcb->cellhd.ns_res;
  91. fcb->C2 =
  92. (fcb->cellhd.north - R__.rd_window.north +
  93. R__.rd_window.ns_res / 2.0) / fcb->cellhd.ns_res;
  94. }
  95. /*!
  96. * \brief Loops rows until mismatch?.
  97. *
  98. * This routine works fine if the mask is not set. It may give
  99. * incorrect results with a mask, since the mask row may have a
  100. * different repeat value. The issue can be fixed by doing it for the
  101. * mask as well and using the smaller value.
  102. *
  103. * \param fd file descriptor
  104. * \param row starting row
  105. *
  106. * \return number of rows completed
  107. */
  108. int Rast_row_repeat_nomask(int fd, int row)
  109. {
  110. struct fileinfo *fcb = &R__.fileinfo[fd];
  111. double f;
  112. int r1, r2;
  113. int count;
  114. count = 1;
  115. /* r1 is the row in the raster map itself.
  116. * r2 is the next row(s) in the raster map
  117. * see get_row.c for details on this calculation
  118. */
  119. f = row * fcb->C1 + fcb->C2;
  120. r1 = f;
  121. if (f < r1)
  122. r1--;
  123. while (++row < R__.rd_window.rows) {
  124. f = row * fcb->C1 + fcb->C2;
  125. r2 = f;
  126. if (f < r2)
  127. r2--;
  128. if (r1 != r2)
  129. break;
  130. count++;
  131. }
  132. return count;
  133. }