lines.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* plot1() - Level One vector reading */
  2. #include <string.h>
  3. #include <math.h>
  4. #include <grass/gis.h>
  5. #include <grass/raster.h>
  6. #include <grass/vector.h>
  7. #include <grass/display.h>
  8. #include <grass/symbol.h>
  9. #include <grass/glocale.h>
  10. #include <grass/dbmi.h>
  11. #include "plot.h"
  12. #include "local_proto.h"
  13. int palette_ncolors = 16;
  14. struct rgb_color palette[16] = {
  15. {198, 198, 198}, /* 1: light gray */
  16. {127, 127, 127}, /* 2: medium/dark gray */
  17. {255, 0, 0}, /* 3: bright red */
  18. {139, 0, 0}, /* 4: dark red */
  19. {0, 255, 0}, /* 5: bright green */
  20. {0, 139, 0}, /* 6: dark green */
  21. {0, 0, 255}, /* 7: bright blue */
  22. {0, 0, 139}, /* 8: dark blue */
  23. {255, 255, 0}, /* 9: yellow */
  24. {139, 126, 10}, /* 10: olivey brown */
  25. {255, 165, 0}, /* 11: orange */
  26. {255, 192, 203}, /* 12: pink */
  27. {255, 0, 255}, /* 13: magenta */
  28. {139, 0, 139}, /* 14: dark magenta */
  29. {0, 255, 255}, /* 15: cyan */
  30. {0, 139, 139} /* 16: dark cyan */
  31. };
  32. static int draw_line(int, int, int,
  33. const struct line_pnts *, const struct line_cats *,
  34. const struct color_rgb *, const struct color_rgb *, int,
  35. const char *, double, int,
  36. int, int,
  37. int, double,
  38. struct Colors *,
  39. dbCatValArray *, struct Colors *,
  40. dbCatValArray *, int,
  41. dbCatValArray *, int,
  42. dbCatValArray *, int,
  43. const struct cat_list *, SYMBOL *,
  44. RGBA_Color *, RGBA_Color *,
  45. RGBA_Color *,
  46. int *, int *, int *, int *, int *);
  47. int display_lines(struct Map_info *Map, int type, struct cat_list *Clist,
  48. const struct color_rgb *color, const struct color_rgb *fcolor, int chcat,
  49. const char *symbol_name, double size, int sqrt_flag,
  50. int id_flag, int cats_color_flag,
  51. int default_width, double width_scale,
  52. struct Colors* zcolors,
  53. dbCatValArray *cvarr_rgb, struct Colors *colors,
  54. dbCatValArray *cvarr_width, int nrec_width,
  55. dbCatValArray *cvarr_size, int nrec_size,
  56. dbCatValArray *cvarr_rot, int nrec_rot)
  57. {
  58. int ltype, line, nlines;
  59. struct line_pnts *Points;
  60. struct line_cats *Cats;
  61. int n_points, n_lines, n_centroids, n_boundaries, n_faces;
  62. RGBA_Color *line_color, *fill_color, *primary_color;
  63. SYMBOL *Symb;
  64. Symb = NULL;
  65. line_color = G_malloc(sizeof(RGBA_Color));
  66. fill_color = G_malloc(sizeof(RGBA_Color));
  67. primary_color = G_malloc(sizeof(RGBA_Color));
  68. primary_color->a = RGBA_COLOR_OPAQUE;
  69. /* change function prototype to pass RGBA_Color instead of color_rgb? */
  70. if (color) {
  71. line_color->r = color->r;
  72. line_color->g = color->g;
  73. line_color->b = color->b;
  74. line_color->a = RGBA_COLOR_OPAQUE;
  75. }
  76. else
  77. line_color->a = RGBA_COLOR_NONE;
  78. if (fcolor) {
  79. fill_color->r = fcolor->r;
  80. fill_color->g = fcolor->g;
  81. fill_color->b = fcolor->b;
  82. fill_color->a = RGBA_COLOR_OPAQUE;
  83. }
  84. else
  85. fill_color->a = RGBA_COLOR_NONE;
  86. Points = Vect_new_line_struct();
  87. Cats = Vect_new_cats_struct();
  88. /* dynamic symbols for points */
  89. if (!(nrec_size || nrec_rot)) {
  90. Symb = S_read(symbol_name);
  91. if (!Symb)
  92. G_warning(_("Unable to read symbol <%s>, unable to display points"),
  93. symbol_name);
  94. else
  95. S_stroke(Symb, size, 0.0, 0);
  96. }
  97. Vect_rewind(Map);
  98. if (color && !cvarr_rgb && !cats_color_flag)
  99. D_RGB_color(color->r, color->g, color->b);
  100. nlines = -1;
  101. if (id_flag) {
  102. if (Vect_level(Map) < 2)
  103. G_fatal_error(_("Unable to display features by id, topology not available. "
  104. "Please try to rebuild topology using "
  105. "v.build or v.build.all."));
  106. nlines = Vect_get_num_lines(Map);
  107. }
  108. line = 0;
  109. n_points = n_lines = 0;
  110. n_centroids = n_boundaries = 0;
  111. n_faces = 0;
  112. while (TRUE) {
  113. line++;
  114. if (nlines > -1) {
  115. if (line > nlines)
  116. break;
  117. ltype = Vect_read_line(Map, Points, Cats, line);
  118. }
  119. else {
  120. ltype = Vect_read_next_line(Map, Points, Cats);
  121. if (ltype == -1) {
  122. G_fatal_error(_("Unable to read vector map"));
  123. }
  124. else if (ltype == -2) { /* EOF */
  125. break;
  126. }
  127. }
  128. draw_line(type, ltype, line,
  129. Points, Cats,
  130. color, fcolor, chcat,
  131. symbol_name, size, sqrt_flag,
  132. id_flag, cats_color_flag,
  133. default_width, width_scale,
  134. zcolors,
  135. cvarr_rgb, colors,
  136. cvarr_width, nrec_width,
  137. cvarr_size, nrec_size,
  138. cvarr_rot, nrec_rot,
  139. Clist, Symb,
  140. line_color, fill_color,
  141. primary_color,
  142. &n_points, &n_lines, &n_centroids, &n_boundaries,
  143. &n_faces);
  144. }
  145. if ((colors || cvarr_rgb) && get_num_color_rules_skipped() > 0)
  146. G_warning(n_("%d invalid color rule for lines skipped",
  147. "%d invalid color rules for lines skipped",
  148. get_num_color_rules_skipped()),
  149. get_num_color_rules_skipped());
  150. if (n_points > 0)
  151. G_verbose_message(n_("%d point plotted", "%d points plotted", n_points), n_points);
  152. if (n_lines > 0)
  153. G_verbose_message(n_("%d line plotted", "%d lines plotted", n_lines), n_lines);
  154. if (n_centroids > 0)
  155. G_verbose_message(n_("%d centroid plotted", "%d centroids plotted", n_centroids), n_centroids);
  156. if (n_boundaries > 0)
  157. G_verbose_message(n_("%d boundary plotted", "%d boundaries plotted", n_boundaries), n_boundaries);
  158. if (n_faces > 0)
  159. G_verbose_message(n_("%d face plotted", "%d faces plotted", n_faces), n_faces);
  160. Vect_destroy_line_struct(Points);
  161. Vect_destroy_cats_struct(Cats);
  162. G_free(line_color);
  163. G_free(fill_color);
  164. G_free(primary_color);
  165. return 0;
  166. }
  167. int draw_line(int type, int ltype, int line,
  168. const struct line_pnts *Points, const struct line_cats *Cats,
  169. const struct color_rgb *color, const struct color_rgb *fcolor, int chcat,
  170. const char *symbol_name, double size, int sqrt_flag,
  171. int id_flag, int cats_color_flag,
  172. int default_width, double width_scale,
  173. struct Colors *zcolors,
  174. dbCatValArray *cvarr_rgb, struct Colors *colors,
  175. dbCatValArray *cvarr_width, int nrec_width,
  176. dbCatValArray *cvarr_size, int nrec_size,
  177. dbCatValArray *cvarr_rot, int nrec_rot,
  178. const struct cat_list *Clist, SYMBOL *Symb,
  179. RGBA_Color *line_color, RGBA_Color *fill_color,
  180. RGBA_Color *primary_color,
  181. int *n_points, int *n_lines, int *n_centroids, int *n_boundaries,
  182. int *n_faces)
  183. {
  184. double var_size, rotation;
  185. int i, width;
  186. int red, grn, blu;
  187. int custom_rgb;
  188. double x0, y0;
  189. double *x, *y;
  190. int found, cat;
  191. rotation = 0.0;
  192. var_size = size;
  193. custom_rgb = FALSE;
  194. cat = -1;
  195. if (!(type & ltype))
  196. return 0;
  197. if (Points->n_points == 0)
  198. return 0;
  199. found = FALSE;
  200. if (chcat) {
  201. if (id_flag) { /* use line id */
  202. if (!(Vect_cat_in_cat_list(line, Clist)))
  203. return 0;
  204. }
  205. else {
  206. for (i = 0; i < Cats->n_cats; i++) {
  207. if (Cats->field[i] == Clist->field &&
  208. Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
  209. found = TRUE;
  210. break;
  211. }
  212. }
  213. if (!found)
  214. return 0;
  215. }
  216. }
  217. else if (Clist->field > 0) {
  218. for (i = 0; i < Cats->n_cats; i++) {
  219. if (Cats->field[i] == Clist->field) {
  220. found = TRUE;
  221. break;
  222. }
  223. }
  224. /* lines with no category will be displayed */
  225. if (Cats->n_cats > 0 && !found)
  226. return 0;
  227. }
  228. G_debug(3, "\tdisplay feature %d, cat %d", line, cat);
  229. /* z height colors */
  230. if (zcolors && (ltype & GV_POINTS)) {
  231. if (Rast_get_d_color(&Points->z[0], &red, &grn, &blu, zcolors) == 1)
  232. custom_rgb = TRUE;
  233. else
  234. custom_rgb = FALSE;
  235. }
  236. if (colors || cvarr_rgb ||
  237. nrec_width > 0 || nrec_size > 0 || nrec_rot > 0)
  238. /* only first category */
  239. Vect_cat_get(Cats,
  240. (Clist->field > 0 ? Clist->field : (Cats->n_cats > 0 ? Cats->field[0] : 1)),
  241. &cat);
  242. /* custom colors */
  243. if (colors || cvarr_rgb) {
  244. custom_rgb = get_table_color(cat, line, colors, cvarr_rgb,
  245. &red, &grn, &blu);
  246. }
  247. /* random colors */
  248. if (cats_color_flag) {
  249. custom_rgb = get_cat_color(line, Cats, Clist,
  250. &red, &grn, &blu);
  251. }
  252. /* line width */
  253. if (nrec_width) {
  254. width = (int) get_property(cat, line, cvarr_width,
  255. (double) width_scale,
  256. (double) default_width);
  257. D_line_width(width);
  258. }
  259. /* enough of the prep work, lets start plotting stuff */
  260. x = Points->x;
  261. y = Points->y;
  262. if ((ltype & GV_POINTS) && (Symb != NULL || (nrec_size || nrec_rot)) ) {
  263. if (!(color || fcolor || custom_rgb))
  264. return 0;
  265. x0 = x[0];
  266. y0 = y[0];
  267. /* skip if the point is outside of the display window */
  268. /* xy < 0 tests make it go ever-so-slightly faster */
  269. if (x0 > D_get_u_east() || x0 < D_get_u_west() ||
  270. y0 < D_get_u_south() || y0 > D_get_u_north())
  271. return 0;
  272. /* dynamic symbol size */
  273. if (nrec_size)
  274. var_size = get_property(cat, line, cvarr_size, size, size);
  275. if (sqrt_flag)
  276. var_size = sqrt(var_size);
  277. /* dynamic symbol rotation */
  278. if (nrec_rot)
  279. rotation = get_property(cat, line, cvarr_rot, 1.0, 0.0);
  280. if(nrec_size || nrec_rot) {
  281. G_debug(3, "\tdynamic symbol: cat=%d size=%.2f rotation=%.2f",
  282. cat, var_size, rotation);
  283. /* symbol stroking is cumulative, so we need to reread it each time */
  284. if(Symb) /* unclean free() on first iteration if variables are not init'd to NULL? */
  285. G_free(Symb);
  286. Symb = S_read(symbol_name);
  287. if (Symb == NULL)
  288. G_warning(_("Unable to read symbol <%s>, unable to display points"),
  289. symbol_name);
  290. else
  291. S_stroke(Symb, var_size, rotation, 0);
  292. }
  293. /* use random or RGB column color if given, otherwise reset */
  294. /* centroids always use default color to stand out from underlying area */
  295. if (custom_rgb && (ltype != GV_CENTROID)) {
  296. primary_color->r = (unsigned char)red;
  297. primary_color->g = (unsigned char)grn;
  298. primary_color->b = (unsigned char)blu;
  299. D_symbol2(Symb, x0, y0, primary_color, line_color);
  300. }
  301. else
  302. D_symbol(Symb, x0, y0, line_color, fill_color);
  303. /* reset to defaults */
  304. var_size = size;
  305. rotation = 0.0;
  306. }
  307. else if (color || custom_rgb || zcolors) {
  308. if (!cvarr_rgb && !cats_color_flag && !zcolors && !colors)
  309. D_RGB_color(color->r, color->g, color->b);
  310. else {
  311. if (custom_rgb)
  312. D_RGB_color((unsigned char)red, (unsigned char)grn,
  313. (unsigned char)blu);
  314. else
  315. D_RGB_color(color->r, color->g, color->b);
  316. }
  317. /* Plot the lines */
  318. if (Points->n_points == 1) /* line with one coor */
  319. D_polydots_abs(x, y, Points->n_points);
  320. else /* use different user defined render methods */
  321. D_polyline_abs(x, y, Points->n_points);
  322. }
  323. switch (ltype) {
  324. case GV_POINT:
  325. (*n_points)++;
  326. break;
  327. case GV_LINE:
  328. (*n_lines)++;
  329. break;
  330. case GV_CENTROID:
  331. (*n_centroids)++;
  332. break;
  333. case GV_BOUNDARY:
  334. (*n_boundaries)++;
  335. break;
  336. case GV_FACE:
  337. (*n_faces)++;
  338. break;
  339. default:
  340. break;
  341. }
  342. return 1;
  343. }