do_areas.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/vector.h>
  5. #include <grass/dbmi.h>
  6. #include <grass/glocale.h>
  7. #include "local.h"
  8. static struct list
  9. {
  10. double size;
  11. int index;
  12. CELL cat;
  13. } *list;
  14. static int nareas;
  15. /* function prototypes */
  16. static int compare(const void *, const void *);
  17. int do_areas(struct Map_info *Map, struct line_pnts *Points,
  18. dbCatValArray * Cvarr, int ctype, int use,
  19. double value, int value_type)
  20. {
  21. int i;
  22. CELL cval, cat;
  23. DCELL dval;
  24. if (nareas <= 0)
  25. return 0;
  26. G_important_message(_("Reading areas..."));
  27. for (i = 0; i < nareas; i++) {
  28. /* Note: in old version (grass5.0) there was a check here if the current area
  29. * is identical to previous one. I don't see any reason for this in topological vectors */
  30. G_percent(i, nareas, 2);
  31. cat = list[i].cat;
  32. G_debug(3, "Area cat = %d", cat);
  33. if (ISNULL(&cat)) { /* No centroid or no category */
  34. set_cat(cat);
  35. }
  36. else {
  37. if (use == USE_ATTR) {
  38. if (ctype == DB_C_TYPE_INT) {
  39. if ((db_CatValArray_get_value_int(Cvarr, cat, &cval)) !=
  40. DB_OK) {
  41. G_warning(_("No record for area (cat = %d)"), cat);
  42. SETNULL(&cval);
  43. }
  44. set_cat(cval);
  45. }
  46. else if (ctype == DB_C_TYPE_DOUBLE) {
  47. if ((db_CatValArray_get_value_double(Cvarr, cat, &dval))
  48. != DB_OK) {
  49. G_warning(_("No record for area (cat = %d)"), cat);
  50. SETDNULL(&dval);
  51. }
  52. set_dcat(dval);
  53. }
  54. else {
  55. G_fatal_error(_("Unable to use column specified"));
  56. }
  57. }
  58. else if (use == USE_CAT) {
  59. set_cat(cat);
  60. }
  61. else {
  62. if (value_type == CELL_TYPE)
  63. set_cat((int)value);
  64. else
  65. set_dcat(value);
  66. }
  67. }
  68. if (Vect_get_area_points(Map, list[i].index, Points) <= 0) {
  69. G_warning(_("Get area %d failed"), list[i].index);
  70. return -1;
  71. }
  72. G_plot_polygon(Points->x, Points->y, Points->n_points);
  73. }
  74. G_percent(1, 1, 1);
  75. return nareas;
  76. }
  77. int sort_areas(struct Map_info *Map, struct line_pnts *Points,
  78. int field, struct cat_list *cat_list)
  79. {
  80. int i, centroid, nareas_selected;
  81. struct line_cats *Cats;
  82. CELL cat;
  83. G_begin_polygon_area_calculations();
  84. Cats = Vect_new_cats_struct();
  85. /* first count valid areas */
  86. nareas = Vect_get_num_areas(Map);
  87. if (nareas == 0)
  88. return 0;
  89. /* allocate list to hold valid area info */
  90. list =
  91. (struct list *)G_calloc(nareas * sizeof(char), sizeof(struct list));
  92. /* store area size,cat,index in list */
  93. nareas_selected = 0;
  94. for (i = 0; i < nareas; i++) {
  95. centroid = Vect_get_area_centroid(Map, i + 1);
  96. SETNULL(&cat);
  97. if (centroid <= 0) {
  98. G_debug(2,_("Area without centroid (OK for island)"));
  99. }
  100. else {
  101. Vect_read_line(Map, NULL, Cats, centroid);
  102. if (field > 0) {
  103. if (Vect_cats_in_constraint(Cats, field, cat_list)) {
  104. Vect_cat_get(Cats, field, &cat);
  105. nareas_selected++;
  106. }
  107. else {
  108. G_debug(2, _("Area centroid without category"));
  109. }
  110. }
  111. else {
  112. /* field < 1, process all areas with centroid */
  113. cat = 0;
  114. nareas_selected++;
  115. }
  116. }
  117. list[i].index = i + 1;
  118. Vect_get_area_points(Map, i + 1, Points);
  119. list[i].size =
  120. G_area_of_polygon(Points->x, Points->y, Points->n_points);
  121. list[i].cat = cat;
  122. }
  123. if (nareas_selected > 0) {
  124. /* sort the list by size */
  125. qsort(list, nareas * sizeof(char), sizeof(struct list), compare);
  126. }
  127. return nareas_selected;
  128. }
  129. static int compare(const void *aa, const void *bb)
  130. {
  131. const struct list *a = aa, *b = bb;
  132. if (a->size < b->size)
  133. return 1;
  134. if (a->size > b->size)
  135. return -1;
  136. return 0;
  137. }