shape.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #include <grass/vector.h>
  2. #include <grass/dbmi.h>
  3. #include <grass/raster.h>
  4. #include <grass/glocale.h>
  5. #include "local_proto.h"
  6. static int ncolor_rules_skipped = 0;
  7. int get_num_color_rules_skipped()
  8. {
  9. return ncolor_rules_skipped;
  10. }
  11. int display_shape(struct Map_info *Map, int type, struct cat_list *Clist, const struct Cell_head *window,
  12. const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat,
  13. const char *icon, double size, const char *size_column, int sqrt_flag, const char *rot_column, /* lines only */
  14. int id_flag, int cats_colors_flag, char *rgb_column,
  15. int default_width, char *width_column, double width_scale,
  16. char *z_style)
  17. {
  18. int open_db, field, i, stat;
  19. dbCatValArray cvarr_rgb, cvarr_width, cvarr_size, cvarr_rot;
  20. struct field_info *fi;
  21. dbDriver *driver;
  22. int nrec_rgb, nrec_width, nrec_size, nrec_rot, have_colors;
  23. struct Colors colors, zcolors;
  24. struct bound_box box;
  25. stat = 0;
  26. nrec_rgb = nrec_width = nrec_size = nrec_rot = 0;
  27. open_db = rgb_column || width_column || size_column || rot_column;
  28. if (open_db) {
  29. field = Clist->field > 0 ? Clist->field : 1;
  30. fi = Vect_get_field(Map, field);
  31. if (!fi) {
  32. G_fatal_error(_("Database connection not defined for layer %d"),
  33. field);
  34. }
  35. driver = db_start_driver_open_database(fi->driver, fi->database);
  36. if (!driver)
  37. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  38. fi->database, fi->driver);
  39. db_set_error_handler_driver(driver);
  40. }
  41. /* fisrt search for color table */
  42. have_colors = Vect_read_colors(Vect_get_name(Map), Vect_get_mapset(Map),
  43. &colors);
  44. if (have_colors && rgb_column) {
  45. G_warning(_("Both color table and <%s> option detected. "
  46. "Color table will ignored."), "rgb_column");
  47. have_colors = FALSE;
  48. }
  49. if (rgb_column) {
  50. /* read RRR:GGG:BBB color strings from table */
  51. db_CatValArray_init(&cvarr_rgb);
  52. nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key,
  53. rgb_column, NULL, &cvarr_rgb);
  54. G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb);
  55. if (cvarr_rgb.ctype != DB_C_TYPE_STRING) {
  56. G_warning(_("Color definition column ('%s') not a string. "
  57. "Column must be of form 'RRR:GGG:BBB' where RGB values range 0-255. "
  58. "You can use '%s' module to define color rules. "
  59. "Unable to colorize features."),
  60. rgb_column, "v.colors");
  61. rgb_column = NULL;
  62. }
  63. else {
  64. if (nrec_rgb < 0)
  65. G_fatal_error(_("Unable to select data ('%s') from table"),
  66. rgb_column);
  67. G_debug(2, "\n%d records selected from table", nrec_rgb);
  68. }
  69. }
  70. if (width_column) {
  71. if (*width_column == '\0')
  72. G_fatal_error(_("Line width column not specified"));
  73. db_CatValArray_init(&cvarr_width);
  74. nrec_width = db_select_CatValArray(driver, fi->table, fi->key,
  75. width_column, NULL, &cvarr_width);
  76. G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width);
  77. if (cvarr_width.ctype != DB_C_TYPE_INT &&
  78. cvarr_width.ctype != DB_C_TYPE_DOUBLE)
  79. G_fatal_error(_("Line width column ('%s') not a number"),
  80. width_column);
  81. if (nrec_width < 0)
  82. G_fatal_error(_("Unable to select data ('%s') from table"),
  83. width_column);
  84. G_debug(2, "\n%d records selected from table", nrec_width);
  85. for (i = 0; i < cvarr_width.n_values; i++) {
  86. G_debug(4, "cat = %d %s = %d", cvarr_width.value[i].cat,
  87. width_column,
  88. (cvarr_width.ctype ==
  89. DB_C_TYPE_INT ? cvarr_width.value[i].val.
  90. i : (int)cvarr_width.value[i].val.d));
  91. }
  92. }
  93. if (size_column) {
  94. if (*size_column == '\0')
  95. G_fatal_error(_("Symbol size column not specified"));
  96. db_CatValArray_init(&cvarr_size);
  97. nrec_size = db_select_CatValArray(driver, fi->table, fi->key,
  98. size_column, NULL, &cvarr_size);
  99. G_debug(3, "nrec_size (%s) = %d", size_column, nrec_size);
  100. if (cvarr_size.ctype != DB_C_TYPE_INT &&
  101. cvarr_size.ctype != DB_C_TYPE_DOUBLE)
  102. G_fatal_error(_("Symbol size column ('%s') is not numeric"),
  103. size_column);
  104. if (nrec_size < 0)
  105. G_fatal_error(_("Unable to select data ('%s') from table"),
  106. size_column);
  107. G_debug(2, " %d records selected from table", nrec_size);
  108. for (i = 0; i < cvarr_size.n_values; i++) {
  109. G_debug(4, "(size) cat = %d %s = %.2f", cvarr_size.value[i].cat,
  110. size_column,
  111. (cvarr_size.ctype ==
  112. DB_C_TYPE_INT ? (double)cvarr_size.value[i].val.i
  113. : cvarr_size.value[i].val.d));
  114. }
  115. }
  116. if (rot_column) {
  117. if (*rot_column == '\0')
  118. G_fatal_error(_("Symbol rotation column not specified"));
  119. db_CatValArray_init(&cvarr_rot);
  120. nrec_rot = db_select_CatValArray(driver, fi->table, fi->key,
  121. rot_column, NULL, &cvarr_rot);
  122. G_debug(3, "nrec_rot (%s) = %d", rot_column, nrec_rot);
  123. if (cvarr_rot.ctype != DB_C_TYPE_INT &&
  124. cvarr_rot.ctype != DB_C_TYPE_DOUBLE)
  125. G_fatal_error(_("Symbol rotation column ('%s') is not numeric"),
  126. rot_column);
  127. if (nrec_rot < 0)
  128. G_fatal_error(_("Unable to select data ('%s') from table"),
  129. rot_column);
  130. G_debug(2, " %d records selected from table", nrec_rot);
  131. for (i = 0; i < cvarr_rot.n_values; i++) {
  132. G_debug(4, "(rot) cat = %d %s = %.2f", cvarr_rot.value[i].cat,
  133. rot_column,
  134. (cvarr_rot.ctype ==
  135. DB_C_TYPE_INT ? (double)cvarr_rot.value[i].val.i
  136. : cvarr_rot.value[i].val.d));
  137. }
  138. }
  139. if (open_db) {
  140. db_close_database_shutdown_driver(driver);
  141. }
  142. if (z_style) {
  143. if (!Vect_is_3d(Map)) {
  144. G_warning(_("Vector map is not 3D. Unable to colorize features based on z-coordinates."));
  145. z_style = NULL;
  146. }
  147. else if (rgb_column) {
  148. G_warning(_("%s= and %s= are mutually exclusive. "
  149. "%s= will be ignored."), "zcolor", "rgb_column", "zcolor");
  150. z_style = NULL;
  151. }
  152. else {
  153. Vect_get_map_box(Map, &box);
  154. Rast_make_fp_colors(&zcolors, z_style, box.B, box.T);
  155. }
  156. }
  157. stat = 0;
  158. if (type & GV_AREA && Vect_get_num_primitives(Map, GV_CENTROID | GV_BOUNDARY) > 0)
  159. stat += display_area(Map, Clist, window,
  160. bcolor, fcolor, chcat,
  161. id_flag, cats_colors_flag,
  162. default_width, width_scale,
  163. z_style ? &zcolors : NULL,
  164. rgb_column ? &cvarr_rgb : NULL,
  165. have_colors ? &colors : NULL,
  166. &cvarr_width, nrec_width);
  167. stat += display_lines(Map, type, Clist,
  168. bcolor, fcolor, chcat,
  169. icon, size, sqrt_flag,
  170. id_flag, cats_colors_flag,
  171. default_width, width_scale,
  172. z_style ? &zcolors : NULL,
  173. rgb_column ? &cvarr_rgb : NULL,
  174. have_colors ? &colors : NULL,
  175. &cvarr_width, nrec_width,
  176. &cvarr_size, nrec_size,
  177. &cvarr_rot, nrec_rot);
  178. return stat;
  179. }
  180. int get_table_color(int cat, int line,
  181. struct Colors *colors, dbCatValArray *cvarr,
  182. int *red, int *grn, int *blu)
  183. {
  184. int custom_rgb;
  185. char colorstring[12]; /* RRR:GGG:BBB */
  186. dbCatVal *cv;
  187. custom_rgb = FALSE;
  188. cv = NULL;
  189. if (cat < 0)
  190. return custom_rgb;
  191. if (colors) {
  192. /* read color table */
  193. if (Rast_get_c_color(&cat, red, grn, blu, colors) == 1) {
  194. custom_rgb = TRUE;
  195. G_debug(3, "\tb: %d, g: %d, r: %d", *blu, *grn, *red);
  196. }
  197. }
  198. /* read RGB colors from db for current area # */
  199. if (cvarr && db_CatValArray_get_value(cvarr, cat, &cv) == DB_OK) {
  200. sprintf(colorstring, "%s", db_get_string(cv->val.s));
  201. if (*colorstring != '\0') {
  202. G_debug(3, "element %d: colorstring: %s", line,
  203. colorstring);
  204. if (G_str_to_color(colorstring, red, grn, blu) == 1) {
  205. custom_rgb = TRUE;
  206. G_debug(3, "element:%d cat %d r:%d g:%d b:%d",
  207. line, cat, *red, *grn, *blu);
  208. }
  209. else {
  210. G_debug(3, "Invalid color definition '%s' ignored", colorstring);
  211. ncolor_rules_skipped++;
  212. }
  213. }
  214. else {
  215. G_debug(3, "Invalid color definition '%s' ignored", colorstring);
  216. ncolor_rules_skipped++;
  217. }
  218. }
  219. return custom_rgb;
  220. }
  221. int get_cat_color(int line, const struct line_cats *Cats, const struct cat_list *Clist,
  222. int *red, int *grn, int *blu)
  223. {
  224. int custom_rgb;
  225. unsigned char which;
  226. int cat;
  227. custom_rgb = FALSE;
  228. if (Clist->field > 0) {
  229. Vect_cat_get(Cats, Clist->field, &cat);
  230. if (cat >= 0) {
  231. G_debug(3, "display element %d, cat %d", line, cat);
  232. /* fetch color number from category */
  233. which = (cat % palette_ncolors);
  234. G_debug(3, "cat:%d which color:%d r:%d g:%d b:%d", cat,
  235. which, palette[which].R, palette[which].G,
  236. palette[which].B);
  237. custom_rgb = TRUE;
  238. *red = palette[which].R;
  239. *grn = palette[which].G;
  240. *blu = palette[which].B;
  241. }
  242. }
  243. else if (Cats->n_cats > 0) {
  244. /* fetch color number from layer */
  245. which = (Cats->field[0] % palette_ncolors);
  246. G_debug(3, "layer:%d which color:%d r:%d g:%d b:%d",
  247. Cats->field[0], which, palette[which].R,
  248. palette[which].G, palette[which].B);
  249. custom_rgb = TRUE;
  250. *red = palette[which].R;
  251. *grn = palette[which].G;
  252. *blu = palette[which].B;
  253. }
  254. return custom_rgb;
  255. }
  256. double get_property(int cat, int line, dbCatValArray *cvarr, double scale, double default_value)
  257. {
  258. double value;
  259. dbCatVal *cv;
  260. cv = NULL;
  261. if (cat < 0)
  262. return default_value;
  263. /* Read line width from db for current area # */
  264. if (db_CatValArray_get_value(cvarr, cat, &cv) != DB_OK) {
  265. value = default_value;
  266. }
  267. else {
  268. value = scale * (cvarr->ctype ==
  269. DB_C_TYPE_INT ? (double) cv->val.i : cv->val.d);
  270. if (value < 0) {
  271. G_important_message(_("Invalid negative value - feature %d with category %d"),
  272. line, cat);
  273. value = default_value;
  274. }
  275. }
  276. return value;
  277. }