edges.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /****************************************************************************
  2. *
  3. * MODULE: r.distance
  4. *
  5. * AUTHOR(S): Michael Shapiro - CERL
  6. * Sort/reverse sort by distance by Huidae Cho
  7. *
  8. * PURPOSE: Locates the closest points between objects in two
  9. * raster maps.
  10. *
  11. * COPYRIGHT: (C) 2003-2014 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General
  14. * Public License (>=v2). Read the file COPYING that
  15. * comes with GRASS for details.
  16. *
  17. ***************************************************************************/
  18. #include <stdlib.h>
  19. #include <grass/raster.h>
  20. #include <grass/glocale.h>
  21. #include "defs.h"
  22. void print_edge_info(struct Map *map)
  23. {
  24. int i;
  25. fprintf(stdout, "%s: %d edge cells\n", map->fullname, map->edges.count);
  26. for (i = 0; i < map->edges.ncats; i++)
  27. fprintf(stdout, " %d", map->edges.catlist[i].cat);
  28. fprintf(stdout, "\n");
  29. }
  30. void find_edge_cells(struct Map *map, int null)
  31. {
  32. void init_edge_list();
  33. void add_edge_cell();
  34. void sort_edge_list();
  35. int nrows, ncols, row, col;
  36. int fd;
  37. CELL *buf0, *buf1, *buf2, *tmp;
  38. G_message(_("Reading map %s ..."), map->fullname);
  39. ncols = Rast_window_cols();
  40. nrows = Rast_window_rows();
  41. buf0 = (CELL *) G_calloc(ncols + 2, sizeof(CELL));
  42. buf1 = (CELL *) G_calloc(ncols + 2, sizeof(CELL));
  43. buf2 = (CELL *) G_calloc(ncols + 2, sizeof(CELL));
  44. for (col = 0; col < (ncols + 2); col++) {
  45. buf0[col] = 0;
  46. buf1[col] = 0;
  47. buf2[col] = 0;
  48. }
  49. fd = Rast_open_old(map->name, map->mapset);
  50. init_edge_list(map);
  51. for (row = 0; row < nrows; row++) {
  52. G_percent(row, nrows, 2);
  53. /* rotate the input buffers */
  54. tmp = buf0;
  55. buf0 = buf1;
  56. buf1 = buf2;
  57. buf2 = tmp;
  58. /* read a row */
  59. Rast_get_c_row(fd, &buf1[1], row);
  60. for (col = 1; col <= ncols; col++) {
  61. if ((buf1[col] /* is a valid category */
  62. &&(buf1[col - 1] != buf1[col] /* 4 neighbors not the same? */
  63. ||buf1[col + 1] != buf1[col]
  64. || buf0[col] != buf1[col]
  65. || buf2[col] != buf1[col])) &&
  66. (null || !Rast_is_c_null_value(&buf1[col])))
  67. add_edge_cell(map, buf1[col], row, col - 1);
  68. }
  69. }
  70. G_percent(row, nrows, 2);
  71. Rast_close(fd);
  72. G_free(buf0);
  73. G_free(buf1);
  74. G_free(buf2);
  75. sort_edge_list(map);
  76. }
  77. void add_edge_cell(struct Map *map, CELL cat, int row, int col)
  78. {
  79. int i, k;
  80. /* search for this cat (note: sequential search for now) */
  81. for (i = 0; i < map->edges.ncats; i++)
  82. if (cat == map->edges.catlist[i].cat)
  83. break;
  84. if (i == map->edges.ncats) { /* new category */
  85. map->edges.ncats += 1;
  86. if (map->edges.nalloc < map->edges.ncats) {
  87. map->edges.nalloc += 32;
  88. map->edges.catlist =
  89. (struct CatEdgeList *)G_realloc(map->edges.catlist,
  90. map->edges.nalloc *
  91. sizeof(struct CatEdgeList));
  92. }
  93. map->edges.catlist[i].ncells = 0;
  94. map->edges.catlist[i].nalloc = 0;
  95. map->edges.catlist[i].row = NULL;
  96. map->edges.catlist[i].col = NULL;
  97. map->edges.catlist[i].cat = cat;
  98. }
  99. /* new edge cell insert */
  100. k = map->edges.catlist[i].ncells;
  101. map->edges.catlist[i].ncells += 1;
  102. if (map->edges.catlist[i].nalloc < map->edges.catlist[i].ncells) {
  103. map->edges.catlist[i].nalloc += 256;
  104. map->edges.catlist[i].row =
  105. (int *)G_realloc(map->edges.catlist[i].row,
  106. map->edges.catlist[i].nalloc * sizeof(int));
  107. map->edges.catlist[i].col =
  108. (int *)G_realloc(map->edges.catlist[i].col,
  109. map->edges.catlist[i].nalloc * sizeof(int));
  110. }
  111. map->edges.catlist[i].row[k] = row;
  112. map->edges.catlist[i].col[k] = col;
  113. /* for good measure, count the total edge cells */
  114. map->edges.count++;
  115. }
  116. void init_edge_list(struct Map *map)
  117. {
  118. map->edges.count = 0;
  119. map->edges.ncats = 0;
  120. map->edges.nalloc = 0;
  121. map->edges.catlist = NULL;
  122. }
  123. static int cmp(const void *aa, const void *bb)
  124. {
  125. const struct CatEdgeList *a = aa, *b = bb;
  126. return (int)(a->cat - b->cat);
  127. }
  128. void sort_edge_list(struct Map *map)
  129. {
  130. if (map->edges.ncats > 0)
  131. qsort(map->edges.catlist, map->edges.ncats,
  132. sizeof(struct CatEdgeList), cmp);
  133. }