areas.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. /* This function now does one of 3 things:
  7. * 1) It reads the areas of the areas.
  8. * 2) It reads the perimeter lengths of the areas. If projection is LL, the geodesic distance is used.
  9. * 3) It calculates the compactness using this formula:
  10. * compactness = perimeter / (2 * sqrt(M_PI * area))
  11. * 4) It calculates the fractal dimension of the bounding curve:
  12. * D_L = 2 * log(perimeter) / log(area)
  13. * (See B.B. Mandelbrot, The Fractal Geometry of Nature. 1982.)
  14. */
  15. int read_areas(struct Map_info *Map)
  16. {
  17. int i, idx, found;
  18. int area_num, nareas;
  19. struct line_cats *Cats;
  20. struct line_pnts *Ppoints;
  21. double area, perimeter;
  22. Cats = Vect_new_cats_struct();
  23. nareas = Vect_get_num_areas(Map);
  24. G_message(_("Reading areas..."));
  25. /* Cycle through all areas */
  26. for (area_num = 1; area_num <= nareas; area_num++) {
  27. Ppoints = Vect_new_line_struct();
  28. area = 0;
  29. perimeter = 0;
  30. if ((options.option == O_COMPACT) || (options.option == O_FD) ||
  31. (options.option == O_AREA)) {
  32. area = Vect_get_area_area(Map, area_num);
  33. }
  34. if ((options.option == O_COMPACT) || (options.option == O_FD) ||
  35. (options.option == O_PERIMETER)) {
  36. perimeter = Vect_get_area_perimeter(Map, area_num);
  37. }
  38. found = 0;
  39. if (Vect_get_area_cats(Map, area_num, Cats) == 0) {
  40. for (i = 0; i < Cats->n_cats; i++) {
  41. if (Cats->field[i] == options.field) {
  42. idx = find_cat(Cats->cat[i], 1);
  43. switch (options.option) {
  44. case O_AREA:
  45. Values[idx].d1 += area;
  46. break;
  47. case O_PERIMETER:
  48. Values[idx].d1 += perimeter;
  49. break;
  50. case O_COMPACT:
  51. Values[idx].d1 =
  52. perimeter / (2.0 * sqrt(M_PI * area));
  53. break;
  54. case O_FD:
  55. Values[idx].d1 = 2.0 * log(perimeter) / log(area);
  56. break;
  57. }
  58. found = 1;
  59. }
  60. }
  61. /* why do we do this? */
  62. if (!found) { /* no category found */
  63. idx = find_cat(0, 1);
  64. if (options.option == O_AREA) {
  65. Values[idx].d1 += area;
  66. }
  67. else if (options.option == O_PERIMETER) {
  68. Values[idx].d1 += area;
  69. }
  70. }
  71. }
  72. G_percent(area_num, nareas, 2);
  73. }
  74. return 0;
  75. }