areas.c 2.3 KB

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