window_map.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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, east;
  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. east = R__.rd_window.east;
  50. if (R__.rd_window.proj == PROJECTION_LL) {
  51. while (west > fcb->cellhd.west + 360.0) {
  52. west -= 360.0;
  53. east -= 360.0;
  54. }
  55. while (west < fcb->cellhd.west) {
  56. west += 360.0;
  57. east += 360.0;
  58. }
  59. }
  60. C1 = R__.rd_window.ew_res / fcb->cellhd.ew_res;
  61. C2 = (west - fcb->cellhd.west +
  62. R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
  63. for (i = 0; i < R__.rd_window.cols; i++) {
  64. x = C2;
  65. if (C2 < x) /* adjust for rounding of negatives */
  66. x--;
  67. if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
  68. x = -1;
  69. *col++ = x + 1;
  70. C2 += C1;
  71. }
  72. /* do wrap around for lat/lon */
  73. if (R__.rd_window.proj == PROJECTION_LL) {
  74. while (east - 360.0 > fcb->cellhd.west) {
  75. east -= 360.0;
  76. west -= 360.0;
  77. col = fcb->col_map;
  78. C2 = (west - fcb->cellhd.west +
  79. R__.rd_window.ew_res / 2.0) / fcb->cellhd.ew_res;
  80. for (i = 0; i < R__.rd_window.cols; i++) {
  81. x = C2;
  82. if (C2 < x) /* adjust for rounding of negatives */
  83. x--;
  84. if (x < 0 || x >= fcb->cellhd.cols) /* not in data file */
  85. x = -1;
  86. if (*col == 0) /* only change those not already set */
  87. *col = x + 1;
  88. col++;
  89. C2 += C1;
  90. }
  91. }
  92. }
  93. G_debug(3, "create window mapping (%d columns)", R__.rd_window.cols);
  94. /* for (i = 0; i < R__.rd_window.cols; i++)
  95. fprintf(stderr, "%s%ld", i % 15 ? " " : "\n", (long)fcb->col_map[i]);
  96. fprintf(stderr, "\n");
  97. */
  98. /* compute C1,C2 for row window mapping */
  99. fcb->C1 = R__.rd_window.ns_res / fcb->cellhd.ns_res;
  100. fcb->C2 =
  101. (fcb->cellhd.north - R__.rd_window.north +
  102. R__.rd_window.ns_res / 2.0) / fcb->cellhd.ns_res;
  103. }
  104. /*!
  105. * \brief Loops rows until mismatch?.
  106. *
  107. * This routine works fine if the mask is not set. It may give
  108. * incorrect results with a mask, since the mask row may have a
  109. * different repeat value. The issue can be fixed by doing it for the
  110. * mask as well and using the smaller value.
  111. *
  112. * \param fd file descriptor
  113. * \param row starting row
  114. *
  115. * \return number of rows completed
  116. */
  117. int Rast_row_repeat_nomask(int fd, int row)
  118. {
  119. struct fileinfo *fcb = &R__.fileinfo[fd];
  120. double f;
  121. int r1, r2;
  122. int count;
  123. count = 1;
  124. /* r1 is the row in the raster map itself.
  125. * r2 is the next row(s) in the raster map
  126. * see get_row.c for details on this calculation
  127. */
  128. f = row * fcb->C1 + fcb->C2;
  129. r1 = f;
  130. if (f < r1)
  131. r1--;
  132. while (++row < R__.rd_window.rows) {
  133. f = row * fcb->C1 + fcb->C2;
  134. r2 = f;
  135. if (f < r2)
  136. r2--;
  137. if (r1 != r2)
  138. break;
  139. count++;
  140. }
  141. return count;
  142. }