mpa.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /****************************************************************************
  2. *
  3. * MODULE: r.li.mpa
  4. * AUTHOR(S): Serena Pallecchi (original contributor)
  5. * student of Computer Science University of Pisa (Italy)
  6. * Commission from Faunalia Pontedera (PI) www.faunalia.it
  7. * Rewrite: Markus Metz
  8. *
  9. * PURPOSE: calculates mean pixel attribute index
  10. * COPYRIGHT: (C) 2007-2014 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 <grass/gis.h>
  18. #include <grass/raster.h>
  19. #include <grass/glocale.h>
  20. #include <stdlib.h>
  21. #include <fcntl.h>
  22. #include <math.h>
  23. #include "../r.li.daemon/defs.h"
  24. #include "../r.li.daemon/daemon.h"
  25. rli_func meanPixelAttribute;
  26. int calculate(int fd, struct area_entry *ad, double *result);
  27. int calculateD(int fd, struct area_entry *ad, double *result);
  28. int calculateF(int fd, struct area_entry *ad, double *result);
  29. int main(int argc, char *argv[])
  30. {
  31. struct Option *raster, *conf, *output;
  32. struct GModule *module;
  33. G_gisinit(argv[0]);
  34. module = G_define_module();
  35. module->description =
  36. _("Calculates mean pixel attribute index on a raster map");
  37. G_add_keyword(_("raster"));
  38. G_add_keyword(_("landscape structure analysis"));
  39. G_add_keyword(_("patch index"));
  40. /* define options */
  41. raster = G_define_standard_option(G_OPT_R_INPUT);
  42. conf = G_define_standard_option(G_OPT_F_INPUT);
  43. conf->key = "config";
  44. conf->description = _("Configuration file");
  45. conf->required = YES;
  46. output = G_define_standard_option(G_OPT_R_OUTPUT);
  47. if (G_parser(argc, argv))
  48. exit(EXIT_FAILURE);
  49. return calculateIndex(conf->answer, meanPixelAttribute, NULL,
  50. raster->answer, output->answer);
  51. }
  52. int meanPixelAttribute(int fd, char **par, struct area_entry *ad, double *result)
  53. {
  54. int ris = 0;
  55. double indice = 0;
  56. switch (ad->data_type) {
  57. case CELL_TYPE:
  58. {
  59. ris = calculate(fd, ad, &indice);
  60. break;
  61. }
  62. case DCELL_TYPE:
  63. {
  64. ris = calculateD(fd, ad, &indice);
  65. break;
  66. }
  67. case FCELL_TYPE:
  68. {
  69. ris = calculateF(fd, ad, &indice);
  70. break;
  71. }
  72. default:
  73. {
  74. G_fatal_error("data type unknown");
  75. return RLI_ERRORE;
  76. }
  77. }
  78. if (ris != RLI_OK) {
  79. return RLI_ERRORE;
  80. }
  81. *result = indice;
  82. return RLI_OK;
  83. }
  84. int calculate(int fd, struct area_entry *ad, double *result)
  85. {
  86. CELL *buf;
  87. int i, j;
  88. int mask_fd = -1, *mask_buf = NULL;
  89. int masked = FALSE;
  90. double area = 0;
  91. double somma = 0;
  92. /* open mask if needed */
  93. if (ad->mask == 1) {
  94. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
  95. G_fatal_error("can't open mask");
  96. return RLI_ERRORE;
  97. }
  98. mask_buf = G_malloc(ad->cl * sizeof(int));
  99. if (mask_buf == NULL) {
  100. G_fatal_error("malloc mask_buf failed");
  101. return RLI_ERRORE;
  102. }
  103. masked = TRUE;
  104. }
  105. for (j = 0; j < ad->rl; j++) {
  106. buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
  107. if (masked) {
  108. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  109. G_fatal_error("mask read failed");
  110. return RLI_ERRORE;
  111. }
  112. }
  113. for (i = 0; i < ad->cl; i++) {
  114. if (masked && mask_buf[i] == 0) {
  115. Rast_set_c_null_value(&buf[i + ad->x], 1);
  116. }
  117. if (!(Rast_is_c_null_value(&buf[i + ad->x]))) {
  118. area++;
  119. somma = somma + buf[i + ad->x];
  120. }
  121. }
  122. }
  123. if (area > 0)
  124. *result = somma / area;
  125. else
  126. Rast_set_d_null_value(result, 1);
  127. if (masked) {
  128. close(mask_fd);
  129. G_free(mask_buf);
  130. }
  131. return RLI_OK;
  132. }
  133. int calculateD(int fd, struct area_entry *ad, double *result)
  134. {
  135. DCELL *buf;
  136. int i, j;
  137. int mask_fd = -1, *mask_buf = NULL;
  138. int masked = FALSE;
  139. double area = 0;
  140. double somma = 0;
  141. /* open mask if needed */
  142. if (ad->mask == 1) {
  143. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
  144. G_fatal_error("can't open mask");
  145. return RLI_ERRORE;
  146. }
  147. mask_buf = G_malloc(ad->cl * sizeof(int));
  148. if (mask_buf == NULL) {
  149. G_fatal_error("malloc mask_buf failed");
  150. return RLI_ERRORE;
  151. }
  152. masked = TRUE;
  153. }
  154. for (j = 0; j < ad->rl; j++) {
  155. buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
  156. if (masked) {
  157. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  158. G_fatal_error("mask read failed");
  159. return RLI_ERRORE;
  160. }
  161. }
  162. for (i = 0; i < ad->cl; i++) {
  163. if (masked && mask_buf[i] == 0) {
  164. Rast_set_d_null_value(&buf[i + ad->x], 1);
  165. }
  166. if (!(Rast_is_d_null_value(&buf[i + ad->x]))) {
  167. area++;
  168. somma = somma + buf[i + ad->x];
  169. }
  170. }
  171. }
  172. if (area > 0)
  173. *result = somma / area;
  174. else
  175. Rast_set_d_null_value(result, 1);
  176. if (masked) {
  177. close(mask_fd);
  178. G_free(mask_buf);
  179. }
  180. return RLI_OK;
  181. }
  182. int calculateF(int fd, struct area_entry *ad, double *result)
  183. {
  184. FCELL *buf;
  185. int i, j;
  186. int mask_fd = -1, *mask_buf = NULL;
  187. int masked = FALSE;
  188. double area = 0;
  189. double somma = 0;
  190. /* open mask if needed */
  191. if (ad->mask == 1) {
  192. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
  193. G_fatal_error("can't open mask");
  194. return RLI_ERRORE;
  195. }
  196. mask_buf = G_malloc(ad->cl * sizeof(int));
  197. if (mask_buf == NULL) {
  198. G_fatal_error("malloc mask_buf failed");
  199. return RLI_ERRORE;
  200. }
  201. masked = TRUE;
  202. }
  203. for (j = 0; j < ad->rl; j++) {
  204. buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
  205. if (masked) {
  206. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  207. G_fatal_error("mask read failed");
  208. return RLI_ERRORE;
  209. }
  210. }
  211. for (i = 0; i < ad->cl; i++) {
  212. if (masked && mask_buf[i] == 0) {
  213. Rast_set_f_null_value(&buf[i + ad->x], 1);
  214. }
  215. if (!(Rast_is_f_null_value(&buf[i + ad->x]))) {
  216. area++;
  217. somma = somma + buf[i + ad->x];
  218. }
  219. }
  220. }
  221. if (area > 0)
  222. *result = somma / area;
  223. else
  224. Rast_set_d_null_value(result, 1);
  225. if (masked) {
  226. close(mask_fd);
  227. G_free(mask_buf);
  228. }
  229. return RLI_OK;
  230. }