area.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 { /* out of bounds for -180 to 180, try 0 to 360 as well */
  65. if (box.N < window->south || box.S > window->north)
  66. continue;
  67. if (box.E + 360 < window->west || box.W + 360 > window->east)
  68. continue;
  69. }
  70. }
  71. custom_rgb = FALSE;
  72. found = FALSE;
  73. if (chcat) {
  74. if (id_flag) {
  75. if (!(Vect_cat_in_cat_list(area, Clist)))
  76. continue;
  77. }
  78. else {
  79. G_debug(3, "centroid = %d", centroid);
  80. if (centroid < 1)
  81. continue;
  82. Vect_read_line(Map, Points, Cats, centroid);
  83. for (i = 0; i < Cats->n_cats; i++) {
  84. G_debug(3, " centroid = %d, field = %d, cat = %d",
  85. centroid, Cats->field[i], Cats->cat[i]);
  86. if (Cats->field[i] == Clist->field &&
  87. Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
  88. found = TRUE;
  89. break;
  90. }
  91. }
  92. if (!found)
  93. continue;
  94. }
  95. }
  96. else if (Clist->field > 0) {
  97. found = FALSE;
  98. G_debug(3, "\tcentroid = %d", centroid);
  99. if (centroid < 1)
  100. continue;
  101. Vect_read_line(Map, NULL, Cats, centroid);
  102. for (i = 0; i < Cats->n_cats; i++) {
  103. G_debug(3, "\tcentroid = %d, field = %d, cat = %d", centroid,
  104. Cats->field[i], Cats->cat[i]);
  105. if (Cats->field[i] == Clist->field) {
  106. found = TRUE;
  107. break;
  108. }
  109. }
  110. /* lines with no category will be displayed */
  111. if (Cats->n_cats > 0 && !found)
  112. continue;
  113. }
  114. /* fill */
  115. Vect_get_area_points(Map, area, APoints);
  116. G_debug(3, "\tn_points = %d", APoints->n_points);
  117. if (APoints->n_points < 3) {
  118. G_warning(_("Invalid area %d skipped (not enough points)"), area);
  119. continue;
  120. }
  121. Vect_reset_line(Points);
  122. Vect_append_points(Points, APoints, GV_FORWARD);
  123. n_points = Points->n_points;
  124. xl = Points->x[n_points - 1];
  125. yl = Points->y[n_points - 1];
  126. n_isles = Vect_get_area_num_isles(Map, area);
  127. if (n_isles >= n_ipoints_alloc) {
  128. IPoints = (struct line_pnts **)G_realloc(IPoints, (n_isles + 10) * sizeof(struct line_pnts *));
  129. for (i = n_ipoints_alloc; i < n_isles + 10; i++) {
  130. IPoints[i] = Vect_new_line_struct();
  131. }
  132. n_ipoints_alloc = n_isles + 10;
  133. }
  134. for (i = 0; i < n_isles; i++) {
  135. isle = Vect_get_area_isle(Map, area, i);
  136. Vect_get_isle_points(Map, isle, IPoints[i]);
  137. Vect_append_points(Points, IPoints[i], GV_FORWARD);
  138. Vect_append_point(Points, xl, yl, 0.0); /* ??? */
  139. }
  140. cat = Vect_get_area_cat(Map, area,
  141. (Clist->field > 0 ? Clist->field :
  142. (Cats->n_cats > 0 ? Cats->field[0] : 1)));
  143. if (!centroid && cat == -1) {
  144. continue;
  145. }
  146. /* z height colors */
  147. if (zcolors) {
  148. if (Rast_get_d_color(&Points->z[0], &red, &grn, &blu, zcolors) == 1)
  149. custom_rgb = TRUE;
  150. else
  151. custom_rgb = FALSE;
  152. }
  153. /* custom colors */
  154. if (colors || cvarr_rgb) {
  155. custom_rgb = get_table_color(cat, area, colors, cvarr_rgb,
  156. &red, &grn, &blu);
  157. }
  158. /* random colors */
  159. if (cats_color_flag) {
  160. custom_rgb = get_cat_color(area, Cats, Clist,
  161. &red, &grn, &blu);
  162. }
  163. /* line width */
  164. if (nrec_width) {
  165. width = (int) get_property(cat, area, cvarr_width,
  166. (double) width_scale,
  167. (double) default_width);
  168. D_line_width(width);
  169. }
  170. if (fcolor || zcolors) {
  171. if (!cvarr_rgb && !cats_color_flag && !zcolors && !colors) {
  172. D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
  173. D_polygon_abs(Points->x, Points->y, Points->n_points);
  174. }
  175. else {
  176. if (custom_rgb) {
  177. D_RGB_color((unsigned char)red, (unsigned char)grn,
  178. (unsigned char)blu);
  179. }
  180. else {
  181. D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
  182. }
  183. if (cat >= 0) {
  184. D_polygon_abs(Points->x, Points->y, Points->n_points);
  185. }
  186. }
  187. }
  188. /* boundary */
  189. if (bcolor) {
  190. if (custom_rgb) {
  191. D_RGB_color((unsigned char)red, (unsigned char)grn,
  192. (unsigned char)blu);
  193. }
  194. else {
  195. D_RGB_color(bcolor->r, bcolor->g, bcolor->b);
  196. }
  197. /* use different user defined render methods */
  198. D_polyline_abs(APoints->x, APoints->y, APoints->n_points);
  199. for (i = 0; i < n_isles; i++) {
  200. /* use different user defined render methods */
  201. D_polyline_abs(IPoints[i]->x, IPoints[i]->y, IPoints[i]->n_points);
  202. }
  203. }
  204. }
  205. Vect_destroy_line_struct(Points);
  206. Vect_destroy_line_struct(APoints);
  207. for (i = 0; i < n_ipoints_alloc; i++) {
  208. Vect_destroy_line_struct(IPoints[i]);
  209. }
  210. G_free(IPoints);
  211. Vect_destroy_cats_struct(Cats);
  212. return 0;
  213. }