areas.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 bound_box Bbox;
  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. area = 0;
  28. perimeter = 0;
  29. if ((options.option == O_COMPACT) || (options.option == O_FD) ||
  30. (options.option == O_AREA)) {
  31. area = Vect_get_area_area(Map, area_num);
  32. }
  33. if ((options.option == O_COMPACT) || (options.option == O_FD) ||
  34. (options.option == O_PERIMETER)) {
  35. perimeter = Vect_get_area_perimeter(Map, area_num);
  36. if (G_projection() != PROJECTION_LL && G_projection() != PROJECTION_XY)
  37. perimeter = perimeter * G_database_units_to_meters_factor();
  38. }
  39. if (options.option == O_BBOX) {
  40. Vect_get_area_box(Map, area_num, &Bbox);
  41. }
  42. found = 0;
  43. if (Vect_get_area_cats(Map, area_num, Cats) == 0) {
  44. for (i = 0; i < Cats->n_cats; i++) {
  45. if (Cats->field[i] == options.field) {
  46. idx = find_cat(Cats->cat[i], 1);
  47. switch (options.option) {
  48. case O_AREA:
  49. Values[idx].d1 += area;
  50. break;
  51. case O_PERIMETER:
  52. Values[idx].d1 += perimeter;
  53. break;
  54. case O_COMPACT:
  55. case O_FD:
  56. Values[idx].d1 += area;
  57. Values[idx].d2 += perimeter;
  58. break;
  59. case O_BBOX:
  60. if (Values[idx].d1 < Bbox.N)
  61. Values[idx].d1 = Bbox.N;
  62. if (Values[idx].d2 > Bbox.S)
  63. Values[idx].d2 = Bbox.S;
  64. if (Values[idx].d3 < Bbox.E)
  65. Values[idx].d3 = Bbox.E;
  66. if (Values[idx].d4 > Bbox.W)
  67. Values[idx].d4 = Bbox.W;
  68. break;
  69. }
  70. found = 1;
  71. }
  72. }
  73. if (!found) { /* Values for no category (cat = -1) are reported at the end */
  74. idx = find_cat(-1, 1);
  75. switch (options.option) {
  76. case O_AREA:
  77. Values[idx].d1 += area;
  78. break;
  79. case O_PERIMETER:
  80. Values[idx].d1 += perimeter;
  81. break;
  82. case O_COMPACT:
  83. case O_FD:
  84. Values[idx].d1 += area;
  85. Values[idx].d2 += perimeter;
  86. break;
  87. case O_BBOX:
  88. if (Values[idx].d1 < Bbox.N)
  89. Values[idx].d1 = Bbox.N;
  90. if (Values[idx].d2 > Bbox.S)
  91. Values[idx].d2 = Bbox.S;
  92. if (Values[idx].d3 < Bbox.E)
  93. Values[idx].d3 = Bbox.E;
  94. if (Values[idx].d4 > Bbox.W)
  95. Values[idx].d4 = Bbox.W;
  96. break;
  97. }
  98. }
  99. }
  100. G_percent(area_num, nareas, 2);
  101. }
  102. return 0;
  103. }