areas.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. Vect_get_area_points(Map, area_num, Ppoints);
  37. perimeter = Vect_line_geodesic_length(Ppoints);
  38. }
  39. found = 0;
  40. if (Vect_get_area_cats(Map, area_num, Cats) == 0) {
  41. for (i = 0; i < Cats->n_cats; i++) {
  42. if (Cats->field[i] == options.field) {
  43. idx = find_cat(Cats->cat[i], 1);
  44. switch (options.option) {
  45. case O_AREA:
  46. Values[idx].d1 += area;
  47. break;
  48. case O_PERIMETER:
  49. Values[idx].d1 += perimeter;
  50. break;
  51. case O_COMPACT:
  52. Values[idx].d1 =
  53. perimeter / (2.0 * sqrt(M_PI * area));
  54. break;
  55. case O_FD:
  56. Values[idx].d1 = 2.0 * log(perimeter) / log(area);
  57. break;
  58. }
  59. found = 1;
  60. }
  61. }
  62. /* why do we do this? */
  63. if (!found) { /* no category found */
  64. idx = find_cat(0, 1);
  65. if (options.option == O_AREA) {
  66. Values[idx].d1 += area;
  67. }
  68. else if (options.option == O_PERIMETER) {
  69. Values[idx].d1 += area;
  70. }
  71. }
  72. }
  73. G_percent(area_num, nareas, 2);
  74. }
  75. return 0;
  76. }