raster.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include <grass/gis.h>
  2. #include <grass/raster.h>
  3. #include <grass/vector.h>
  4. #include "local.h"
  5. struct Cell_head region, page;
  6. static union
  7. {
  8. CELL **cell;
  9. DCELL **dcell;
  10. } raster;
  11. static int max_rows;
  12. static int at_row;
  13. static CELL cat;
  14. static DCELL dcat;
  15. static int cur_x, cur_y;
  16. static int format;
  17. static int dense;
  18. static CELL *cell;
  19. static DCELL *dcell;
  20. static char **null_flags;
  21. static char isnull;
  22. /* function prototypes */
  23. static int configure_plot(void);
  24. static int cell_dot(int, int);
  25. static int dcell_dot(int, int);
  26. static int cont(int, int);
  27. static int move(int, int);
  28. static int (*dot) (int, int);
  29. int begin_rasterization(int cache_mb, int f, int do_dense)
  30. {
  31. int i;
  32. double row_mb;
  33. int pages;
  34. size_t size;
  35. dense = (do_dense != 0);
  36. /* otherwise get complaints about window changes */
  37. G_suppress_warnings(1);
  38. format = f;
  39. G_get_set_window(&region);
  40. G_get_set_window(&page);
  41. row_mb = (double) region.cols * (sizeof(char) + Rast_cell_size(f)) /
  42. (1 << 20);
  43. max_rows = cache_mb / row_mb;
  44. if (max_rows < 1)
  45. max_rows = 4;
  46. pages = (region.rows + max_rows - 1) / max_rows;
  47. if (max_rows > region.rows)
  48. max_rows = region.rows;
  49. G_debug(1, "%d of %d rows are cached", max_rows, region.rows);
  50. size = (size_t) max_rows * region.cols;
  51. switch (format) {
  52. case CELL_TYPE:
  53. raster.cell =
  54. (CELL **) G_calloc(max_rows * sizeof(char), sizeof(CELL *));
  55. raster.cell[0] = (CELL *) G_calloc(size * sizeof(char), sizeof(CELL));
  56. for (i = 1; i < max_rows; i++)
  57. raster.cell[i] = raster.cell[i - 1] + region.cols;
  58. dot = cell_dot;
  59. break;
  60. case DCELL_TYPE:
  61. raster.dcell =
  62. (DCELL **) G_calloc(max_rows * sizeof(char), sizeof(DCELL *));
  63. raster.dcell[0] =
  64. (DCELL *) G_calloc(size * sizeof(char), sizeof(DCELL));
  65. for (i = 1; i < max_rows; i++)
  66. raster.dcell[i] = raster.dcell[i - 1] + region.cols;
  67. dot = dcell_dot;
  68. break;
  69. }
  70. null_flags = (char **)G_calloc(max_rows * sizeof(char), sizeof(char *));
  71. null_flags[0] = (char *)G_calloc(size * sizeof(char), sizeof(char));
  72. for (i = 1; i < max_rows; i++)
  73. null_flags[i] = null_flags[i - 1] + region.cols;
  74. at_row = 0;
  75. configure_plot();
  76. return pages;
  77. }
  78. static int configure_plot(void)
  79. {
  80. int i, j;
  81. int nrows;
  82. int ncols;
  83. nrows = region.rows - at_row;
  84. if (nrows <= 0)
  85. return 1;
  86. if (nrows > max_rows)
  87. nrows = max_rows;
  88. ncols = region.cols;
  89. /* zero the raster */
  90. switch (format) {
  91. case CELL_TYPE:
  92. for (i = 0; i < nrows; i++)
  93. for (j = 0; j < ncols; j++)
  94. raster.cell[i][j] = 0;
  95. break;
  96. case DCELL_TYPE:
  97. for (i = 0; i < nrows; i++)
  98. for (j = 0; j < ncols; j++)
  99. raster.dcell[i][j] = 0;
  100. break;
  101. }
  102. for (i = 0; i < nrows; i++)
  103. for (j = 0; j < ncols; j++)
  104. null_flags[i][j] = 1;
  105. /* change the region */
  106. page.north = region.north - at_row * region.ns_res;
  107. page.south = page.north - nrows * region.ns_res;
  108. G_set_window(&page);
  109. /* configure the plot routines */
  110. if (dense)
  111. setup_plot(0, page.rows, 0, page.cols, dot);
  112. else
  113. G_setup_plot(-0.5, page.rows - 0.5, -0.5, page.cols - 0.5, move, cont);
  114. return 0;
  115. }
  116. int output_raster(int fd)
  117. {
  118. int i;
  119. for (i = 0; i < page.rows; i++, at_row++) {
  120. G_percent(i, page.rows, 2);
  121. switch (format) {
  122. case CELL_TYPE:
  123. cell = raster.cell[i];
  124. /* insert the NULL values */
  125. Rast_insert_c_null_values(cell, null_flags[i], page.cols);
  126. Rast_put_c_row(fd, cell);
  127. break;
  128. case DCELL_TYPE:
  129. dcell = raster.dcell[i];
  130. /* insert the NULL values */
  131. Rast_insert_d_null_values(dcell, null_flags[i], page.cols);
  132. Rast_put_d_row(fd, dcell);
  133. break;
  134. }
  135. }
  136. G_percent(1, 1, 1);
  137. return configure_plot();
  138. }
  139. int set_cat(CELL x)
  140. {
  141. cat = x;
  142. if ((isnull = ISNULL(&cat)))
  143. cat = 0;
  144. return 0;
  145. }
  146. int set_dcat(DCELL x)
  147. {
  148. dcat = x;
  149. if ((isnull = ISDNULL(&dcat)))
  150. dcat = 0;
  151. return 0;
  152. }
  153. static int move(int x, int y)
  154. {
  155. cur_x = x;
  156. cur_y = y;
  157. return 0;
  158. }
  159. static int cont(int x, int y)
  160. {
  161. if (cur_x < 0 && x < 0) {
  162. move(x, y);
  163. return 0;
  164. }
  165. if (cur_y < 0 && y < 0) {
  166. move(x, y);
  167. return 0;
  168. }
  169. if (cur_x >= page.cols && x >= page.cols) {
  170. move(x, y);
  171. return 0;
  172. }
  173. if (cur_y >= page.rows && y >= page.rows) {
  174. move(x, y);
  175. return 0;
  176. }
  177. G_bresenham_line(cur_x, cur_y, x, y, dot);
  178. move(x, y);
  179. return 0;
  180. }
  181. static int cell_dot(int x, int y)
  182. {
  183. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows) {
  184. raster.cell[y][x] = cat;
  185. null_flags[y][x] = isnull;
  186. }
  187. return 0;
  188. }
  189. static int dcell_dot(int x, int y)
  190. {
  191. if (x >= 0 && x < page.cols && y >= 0 && y < page.rows) {
  192. raster.dcell[y][x] = dcat;
  193. null_flags[y][x] = isnull;
  194. }
  195. return 0;
  196. }