area.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* Author: Radim Blazek
  2. *
  3. * added color support: Markus Neteler, Martin Landa
  4. */
  5. #include <string.h>
  6. #include <grass/gis.h>
  7. #include <grass/raster.h>
  8. #include <grass/vector.h>
  9. #include <grass/display.h>
  10. #include <grass/colors.h>
  11. #include <grass/glocale.h>
  12. #include "plot.h"
  13. #include "local_proto.h"
  14. int display_area(struct Map_info *Map, struct cat_list *Clist, const struct Cell_head *window,
  15. const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat,
  16. int id_flag, int cats_color_flag,
  17. int default_width, double width_scale,
  18. struct Colors *zcolors,
  19. dbCatValArray *cvarr_rgb, struct Colors *colors,
  20. dbCatValArray *cvarr_width, int nrec_width)
  21. {
  22. int num, area, isle, n_isles, n_points;
  23. double xl, yl;
  24. struct line_pnts *Points, * APoints, **IPoints;
  25. struct line_cats *Cats;
  26. int n_ipoints_alloc;
  27. int cat, centroid;
  28. int red, grn, blu;
  29. int i, custom_rgb, found;
  30. int width;
  31. struct bound_box box;
  32. if (Vect_level(Map) < 2) {
  33. G_warning(_("Unable to display areas, topology not available. "
  34. "Please try to rebuild topology using "
  35. "v.build or v.build.all."));
  36. return 1;
  37. }
  38. G_debug(1, "display areas:");
  39. centroid = 0;
  40. Points = Vect_new_line_struct();
  41. APoints = Vect_new_line_struct();
  42. n_ipoints_alloc = 10;
  43. IPoints = (struct line_pnts **)G_malloc(n_ipoints_alloc * sizeof(struct line_pnts *));
  44. for (i = 0; i < n_ipoints_alloc; i++) {
  45. IPoints[i] = Vect_new_line_struct();
  46. }
  47. Cats = Vect_new_cats_struct();
  48. num = Vect_get_num_areas(Map);
  49. G_debug(2, "\tn_areas = %d", num);
  50. for (area = 1; area <= num; area++) {
  51. G_debug(3, "\tarea = %d", area);
  52. if (!Vect_area_alive(Map, area))
  53. continue;
  54. centroid = Vect_get_area_centroid(Map, area);
  55. if (!centroid) {
  56. continue;
  57. }
  58. /* Check box */
  59. Vect_get_area_box(Map, area, &box);
  60. if (box.N < window->south || box.S > window->north ||
  61. box.E < window->west || box.W > window->east) {
  62. if (window->proj != PROJECTION_LL)
  63. continue;
  64. else {
  65. if (!G_window_overlap(window, box.N, box.S, box.E, box.W))
  66. continue;
  67. }
  68. }
  69. custom_rgb = FALSE;
  70. found = FALSE;
  71. if (chcat) {
  72. if (id_flag) {
  73. if (!(Vect_cat_in_cat_list(area, Clist)))
  74. continue;
  75. }
  76. else {
  77. G_debug(3, "centroid = %d", centroid);
  78. if (centroid < 1)
  79. continue;
  80. Vect_read_line(Map, Points, Cats, centroid);
  81. for (i = 0; i < Cats->n_cats; i++) {
  82. G_debug(3, " centroid = %d, field = %d, cat = %d",
  83. centroid, Cats->field[i], Cats->cat[i]);
  84. if (Cats->field[i] == Clist->field &&
  85. Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
  86. found = TRUE;
  87. break;
  88. }
  89. }
  90. if (!found)
  91. continue;
  92. }
  93. }
  94. else if (Clist->field > 0) {
  95. found = FALSE;
  96. G_debug(3, "\tcentroid = %d", centroid);
  97. if (centroid < 1)
  98. continue;
  99. Vect_read_line(Map, NULL, Cats, centroid);
  100. for (i = 0; i < Cats->n_cats; i++) {
  101. G_debug(3, "\tcentroid = %d, field = %d, cat = %d", centroid,
  102. Cats->field[i], Cats->cat[i]);
  103. if (Cats->field[i] == Clist->field) {
  104. found = TRUE;
  105. break;
  106. }
  107. }
  108. /* lines with no category will be displayed */
  109. if (Cats->n_cats > 0 && !found)
  110. continue;
  111. }
  112. /* fill */
  113. Vect_get_area_points(Map, area, APoints);
  114. G_debug(3, "\tn_points = %d", APoints->n_points);
  115. if (APoints->n_points < 3) {
  116. G_warning(_("Invalid area %d skipped (not enough points)"), area);
  117. continue;
  118. }
  119. Vect_reset_line(Points);
  120. Vect_append_points(Points, APoints, GV_FORWARD);
  121. n_points = Points->n_points;
  122. xl = Points->x[n_points - 1];
  123. yl = Points->y[n_points - 1];
  124. n_isles = Vect_get_area_num_isles(Map, area);
  125. if (n_isles >= n_ipoints_alloc) {
  126. IPoints = (struct line_pnts **)G_realloc(IPoints, (n_isles + 10) * sizeof(struct line_pnts *));
  127. for (i = n_ipoints_alloc; i < n_isles + 10; i++) {
  128. IPoints[i] = Vect_new_line_struct();
  129. }
  130. n_ipoints_alloc = n_isles + 10;
  131. }
  132. for (i = 0; i < n_isles; i++) {
  133. isle = Vect_get_area_isle(Map, area, i);
  134. Vect_get_isle_points(Map, isle, IPoints[i]);
  135. Vect_append_points(Points, IPoints[i], GV_FORWARD);
  136. Vect_append_point(Points, xl, yl, 0.0); /* ??? */
  137. }
  138. cat = Vect_get_area_cat(Map, area,
  139. (Clist->field > 0 ? Clist->field :
  140. (Cats->n_cats > 0 ? Cats->field[0] : 1)));
  141. if (!centroid && cat == -1) {
  142. continue;
  143. }
  144. /* z height colors */
  145. if (zcolors) {
  146. if (Rast_get_d_color(&Points->z[0], &red, &grn, &blu, zcolors) == 1)
  147. custom_rgb = TRUE;
  148. else
  149. custom_rgb = FALSE;
  150. }
  151. /* custom colors */
  152. if (colors || cvarr_rgb) {
  153. custom_rgb = get_table_color(cat, area, colors, cvarr_rgb,
  154. &red, &grn, &blu);
  155. }
  156. /* random colors */
  157. if (cats_color_flag) {
  158. custom_rgb = get_cat_color(area, Cats, Clist,
  159. &red, &grn, &blu);
  160. }
  161. /* line width */
  162. if (nrec_width) {
  163. width = (int) get_property(cat, area, cvarr_width,
  164. (double) width_scale,
  165. (double) default_width);
  166. D_line_width(width);
  167. }
  168. if (fcolor || zcolors) {
  169. if (!cvarr_rgb && !cats_color_flag && !zcolors && !colors) {
  170. D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
  171. D_polygon_abs(Points->x, Points->y, Points->n_points);
  172. }
  173. else {
  174. if (custom_rgb) {
  175. D_RGB_color((unsigned char)red, (unsigned char)grn,
  176. (unsigned char)blu);
  177. }
  178. else {
  179. D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
  180. }
  181. if (cat >= 0) {
  182. D_polygon_abs(Points->x, Points->y, Points->n_points);
  183. }
  184. }
  185. }
  186. /* boundary */
  187. if (bcolor) {
  188. if (custom_rgb) {
  189. D_RGB_color((unsigned char)red, (unsigned char)grn,
  190. (unsigned char)blu);
  191. }
  192. else {
  193. D_RGB_color(bcolor->r, bcolor->g, bcolor->b);
  194. }
  195. /* use different user defined render methods */
  196. D_polyline_abs(APoints->x, APoints->y, APoints->n_points);
  197. for (i = 0; i < n_isles; i++) {
  198. /* use different user defined render methods */
  199. D_polyline_abs(IPoints[i]->x, IPoints[i]->y, IPoints[i]->n_points);
  200. }
  201. }
  202. }
  203. if ((colors || cvarr_rgb) && get_num_color_rules_skipped() > 0)
  204. G_warning(n_("%d invalid color rule for areas skipped",
  205. "%d invalid color rules for areas skipped",
  206. get_num_color_rules_skipped()),
  207. get_num_color_rules_skipped());
  208. Vect_destroy_line_struct(Points);
  209. Vect_destroy_line_struct(APoints);
  210. for (i = 0; i < n_ipoints_alloc; i++) {
  211. Vect_destroy_line_struct(IPoints[i]);
  212. }
  213. G_free(IPoints);
  214. Vect_destroy_cats_struct(Cats);
  215. return 0;
  216. }