main.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /****************************************************************************
  2. *
  3. * MODULE: r.li.patchnum
  4. * AUTHOR(S): Claudio Porta and Lucio Davide Spano (original contributors)
  5. * students of Computer Science University of Pisa (Italy)
  6. * Commission from Faunalia Pontedera (PI) www.faunalia.it
  7. * Fixes: Markus Neteler <neteler itc.it>
  8. *
  9. * PURPOSE: calculates patch number index
  10. * COPYRIGHT: (C) 2007-2007 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdlib.h>
  18. #include <fcntl.h>
  19. #include <grass/gis.h>
  20. #include <grass/raster.h>
  21. #include <grass/glocale.h>
  22. #include "../r.li.daemon/daemon.h"
  23. #include "../r.li.daemon/defs.h"
  24. int main(int argc, char *argv[])
  25. {
  26. struct Option *raster, *conf, *output;
  27. struct GModule *module;
  28. G_gisinit(argv[0]);
  29. module = G_define_module();
  30. module->description =
  31. _("Calculates patch number index on a raster map, using a 4 neighbour algorithm.");
  32. G_add_keyword(_("raster"));
  33. G_add_keyword(_("landscape structure analysis"));
  34. G_add_keyword(_("patch index"));
  35. /* define options */
  36. raster = G_define_standard_option(G_OPT_R_INPUT);
  37. conf = G_define_option();
  38. conf->key = "config";
  39. conf->description = _("Configuration file");
  40. conf->gisprompt = "old_file,file,input";
  41. conf->type = TYPE_STRING;
  42. conf->required = YES;
  43. output = G_define_standard_option(G_OPT_R_OUTPUT);
  44. if (G_parser(argc, argv))
  45. exit(EXIT_FAILURE);
  46. return calculateIndex(conf->answer, patch_number, NULL, raster->answer,
  47. output->answer);
  48. }
  49. int patch_number(int fd, char **par, area_des ad, double *result)
  50. {
  51. CELL *buf, *sup;
  52. int count = 0, i, j, connected = 0, complete_line = 1, other_above = 0;
  53. struct Cell_head hd;
  54. CELL complete_value;
  55. int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0;
  56. Rast_set_c_null_value(&complete_value, 1);
  57. Rast_get_cellhd(ad->raster, "", &hd);
  58. sup = Rast_allocate_c_buf();
  59. /* open mask if needed */
  60. if (ad->mask == 1) {
  61. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
  62. return 0;
  63. mask_buf = malloc(ad->cl * sizeof(int));
  64. mask_sup = malloc(ad->cl * sizeof(int));
  65. }
  66. /*calculate number of patch */
  67. for (i = 0; i < ad->rl; i++) {
  68. buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
  69. if (i > 0) {
  70. sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
  71. }
  72. /* mask values */
  73. if (ad->mask == 1) {
  74. int k;
  75. if (i > 0) {
  76. int *tmp;
  77. tmp = mask_sup;
  78. mask_buf = mask_sup;
  79. }
  80. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
  81. return 0;
  82. for (k = 0; k < ad->cl; k++) {
  83. if (mask_buf[k] == 0) {
  84. Rast_set_c_null_value(mask_buf + k, 1);
  85. null_count++;
  86. }
  87. }
  88. }
  89. if (complete_line) {
  90. if (!Rast_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
  91. buf[ad->x] != complete_value)
  92. count++;
  93. for (j = 0; j < ad->cl - 1; j++) {
  94. if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
  95. complete_line = 0;
  96. if (!Rast_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE) &&
  97. buf[j + 1 + ad->x] != complete_value)
  98. count++;
  99. }
  100. }
  101. if (complete_line) {
  102. complete_value = buf[ad->x];
  103. }
  104. }
  105. else {
  106. complete_line = 1;
  107. connected = 0;
  108. other_above = 0;
  109. for (j = 0; j < ad->cl; j++) {
  110. if (sup[j + ad->x] == buf[j + ad->x]) {
  111. connected = 1;
  112. if (other_above) {
  113. other_above = 0;
  114. count--;
  115. }
  116. }
  117. else {
  118. if (connected &&
  119. !Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE))
  120. other_above = 1;
  121. }
  122. if (j < ad->cl - 1 && buf[j + ad->x] != buf[j + 1 + ad->x]) {
  123. complete_line = 0;
  124. if (!connected &&
  125. !Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {
  126. count++;
  127. connected = 0;
  128. other_above = 0;
  129. }
  130. else {
  131. connected = 0;
  132. other_above = 0;
  133. }
  134. }
  135. }
  136. if (!connected &&
  137. sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
  138. if (!Rast_is_null_value(&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
  139. count++;
  140. complete_line = 0;
  141. }
  142. }
  143. if (complete_line)
  144. complete_value = buf[ad->x];
  145. }
  146. }
  147. *result = count;
  148. G_free(sup);
  149. return RLI_OK;
  150. }