dopolys.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <grass/gis.h>
  4. #include <grass/raster.h>
  5. #include <grass/glocale.h>
  6. void recurse_list(int flag, int *cells, int sz, int start)
  7. {
  8. int cnt, i, j, ii, jj;
  9. i = cells[start];
  10. j = cells[start + 1];
  11. cells[start + 2] = flag;
  12. for (cnt = 0; cnt < sz; cnt += 3) {
  13. ii = cells[cnt];
  14. jj = cells[cnt + 1];
  15. if (ii == i - 1 && (jj == j - 1 || jj == j || jj == j + 1)) {
  16. if (cells[cnt + 2] == 0)
  17. recurse_list(flag, cells, sz, cnt);
  18. }
  19. else if (ii == i && (jj == j - 1 || jj == j + 1)) {
  20. if (cells[cnt + 2] == 0)
  21. recurse_list(flag, cells, sz, cnt);
  22. }
  23. else if (ii == i + 1 && (jj == j - 1 || jj == j || jj == j + 1)) {
  24. if (cells[cnt + 2] == 0)
  25. recurse_list(flag, cells, sz, cnt);
  26. }
  27. }
  28. }
  29. /* scan the direction file and construct a list of all cells with negative
  30. * values. The list will contain the row and column of the cell and a space
  31. * to include the polygon number */
  32. int dopolys(int fd, int fm, int nl, int ns)
  33. {
  34. int cnt, i, j, found, flag;
  35. int bufsz, cellsz;
  36. int *cells;
  37. int *dir;
  38. bufsz = ns * sizeof(int);
  39. dir = (int *)G_calloc(ns, sizeof(int));
  40. cellsz = 3 * ns;
  41. cells = (int *)G_malloc(cellsz * sizeof(int));
  42. found = 0;
  43. lseek(fd, bufsz, SEEK_SET);
  44. for (i = 1; i < nl - 1; i += 1) {
  45. read(fd, dir, bufsz);
  46. for (j = 1; j < ns - 1; j += 1) {
  47. if (Rast_is_c_null_value(&dir[j]) || dir[j] >= 0)
  48. continue;
  49. cells[found++] = i;
  50. cells[found++] = j;
  51. cells[found++] = 0;
  52. if (found >= cellsz) {
  53. cellsz += 3 * ns;
  54. cells = (int *)G_realloc(cells, cellsz * sizeof(int));
  55. }
  56. }
  57. }
  58. if (found == 0)
  59. return 0;
  60. /* Loop through the list, assigning polygon numbers to unassigned entries
  61. and carrying the same assignment over to adjacent cells. Repeat
  62. recursively */
  63. flag = 0;
  64. for (i = 0; i < found; i += 3) {
  65. if (cells[i + 2] == 0) {
  66. flag += 1;
  67. recurse_list(flag, cells, found, i);
  68. }
  69. }
  70. G_message(n_("Found %d unresolved area",
  71. "Found %d unresolved areas", flag), flag);
  72. /* Compose a new raster map to contain the resulting assignments */
  73. lseek(fm, 0, SEEK_SET);
  74. cnt = 0;
  75. for (i = 0; i < nl; i += 1) {
  76. for (j = 0; j < ns; j += 1)
  77. dir[j] = -1;
  78. while (cells[cnt] == i) {
  79. dir[cells[cnt + 1]] = cells[cnt + 2];
  80. cnt += 3;
  81. }
  82. write(fm, dir, bufsz);
  83. }
  84. G_free(cells);
  85. G_free(dir);
  86. return flag;
  87. }