support.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * Update a history file. Some of the digit file information is placed in
  3. * the hist file.
  4. * returns 0 - successful creation of history file
  5. * -1 - error
  6. */
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <grass/gis.h>
  11. #include <grass/colors.h>
  12. #include <grass/raster.h>
  13. #include <grass/dbmi.h>
  14. #include <grass/vector.h>
  15. #include <grass/glocale.h>
  16. #include "local.h"
  17. struct My_labels_rule
  18. {
  19. dbString label;
  20. double d;
  21. int i;
  22. };
  23. int update_hist(const char *raster_name, const char *vector_name, long scale)
  24. {
  25. struct History hist;
  26. if (raster_name == NULL)
  27. return (-1);
  28. Rast_short_history(raster_name, "raster", &hist);
  29. /* store information from digit file into history */
  30. Rast_format_history(&hist, HIST_DATSRC_1,
  31. "Vector Map: %s", vector_name);
  32. Rast_format_history(&hist, HIST_DATSRC_2,
  33. "Original scale from vector map: 1:%ld", scale); /* 4.0 */
  34. /* store command line options */
  35. Rast_command_history(&hist);
  36. Rast_write_history(raster_name, &hist);
  37. return 0;
  38. }
  39. int update_cats(const char *raster_name)
  40. {
  41. /* TODO: maybe attribute transfer from vector map?
  42. Use Rast_set_cat() somewhere */
  43. struct Categories cats;
  44. Rast_init_cats(raster_name, &cats);
  45. Rast_write_cats(raster_name, &cats);
  46. return 0;
  47. }
  48. int update_dbcolors(const char *rast_name, const char *vector_map, int field,
  49. const char *rgb_column, int is_fp, const char *attr_column)
  50. {
  51. int i;
  52. /* Map */
  53. struct Map_info Map;
  54. /* Attributes */
  55. int nrec;
  56. struct field_info *Fi;
  57. dbDriver *Driver;
  58. dbCatValArray cvarr;
  59. /* colors */
  60. int cat;
  61. struct Colors colors;
  62. struct My_color_rule
  63. {
  64. int red;
  65. int green;
  66. int blue;
  67. double d;
  68. int i;
  69. } *my_color_rules;
  70. int colors_n_values = 0;
  71. int red;
  72. int grn;
  73. int blu;
  74. /* init colors structure */
  75. Rast_init_colors(&colors);
  76. /* open vector map and database driver */
  77. if (Vect_open_old(&Map, vector_map, "") < 0)
  78. G_fatal_error(_("Unable to open vector map <%s>"), vector_map);
  79. db_CatValArray_init(&cvarr);
  80. if ((Fi = Vect_get_field(&Map, field)) == NULL)
  81. G_fatal_error(_("Database connection not defined for layer %d"),
  82. field);
  83. if ((Driver =
  84. db_start_driver_open_database(Fi->driver, Fi->database)) == NULL)
  85. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  86. Fi->database, Fi->driver);
  87. if (!attr_column)
  88. attr_column = Fi->key;
  89. /* get number of records in attr_column */
  90. if ((nrec =
  91. db_select_CatValArray(Driver, Fi->table, Fi->key, attr_column, NULL,
  92. &cvarr)) == -1)
  93. G_fatal_error(_("Unknown column <%s> in table <%s>"), attr_column,
  94. Fi->table);
  95. if (nrec < 0)
  96. G_fatal_error(_("No records selected from table <%s>"), Fi->table);
  97. G_debug(3, "nrec = %d", nrec);
  98. /* allocate space for color rules */
  99. my_color_rules =
  100. (struct My_color_rule *)G_malloc(sizeof(struct My_color_rule) * nrec);
  101. /* for each attribute */
  102. for (i = 0; i < cvarr.n_values; i++) {
  103. char colorstring[12];
  104. dbValue value;
  105. /* selecect color attribute and category */
  106. cat = cvarr.value[i].cat;
  107. if (db_select_value
  108. (Driver, Fi->table, Fi->key, cat, rgb_column, &value) < 0) {
  109. G_warning(_("No records selected"));
  110. continue;
  111. }
  112. sprintf(colorstring, "%s", value.s.string);
  113. /* convert color string to three color integers */
  114. if (*colorstring != '\0') {
  115. G_debug(3, "element colorstring: %s", colorstring);
  116. if (G_str_to_color(colorstring, &red, &grn, &blu) == 1) {
  117. G_debug(3, "cat %d r:%d g:%d b:%d", cat, red, grn, blu);
  118. }
  119. else {
  120. G_warning(_("Error in color definition column (%s) "
  121. "with cat %d: colorstring [%s]"), rgb_column, cat,
  122. colorstring);
  123. G_warning(_("Color set to [200:200:200]"));
  124. red = grn = blu = 200;
  125. }
  126. }
  127. else {
  128. G_warning(_("Error in color definition column (%s), with cat %d"),
  129. rgb_column, cat);
  130. }
  131. /* append color rules to my_color_rules array, they will be set
  132. * later all togheter */
  133. colors_n_values++;
  134. my_color_rules[i].red = red;
  135. my_color_rules[i].green = grn;
  136. my_color_rules[i].blue = blu;
  137. if (is_fp) {
  138. my_color_rules[i].d = cvarr.value[i].val.d;
  139. G_debug(2, "val: %f rgb: %s", cvarr.value[i].val.d, colorstring);
  140. }
  141. else {
  142. my_color_rules[i].i = cvarr.value[i].val.i;
  143. G_debug(2, "val: %d rgb: %s", cvarr.value[i].val.i, colorstring);
  144. }
  145. } /* /for each value in database */
  146. /* close the database driver */
  147. db_close_database_shutdown_driver(Driver);
  148. /* set the color rules: for each rule */
  149. for (i = 0; i < colors_n_values - 1; i++) {
  150. if (is_fp) { /* add floating point color rule */
  151. Rast_add_d_color_rule(&my_color_rules[i].d,
  152. my_color_rules[i].red,
  153. my_color_rules[i].green,
  154. my_color_rules[i].blue,
  155. &my_color_rules[i + 1].d,
  156. my_color_rules[i + 1].red,
  157. my_color_rules[i + 1].green,
  158. my_color_rules[i + 1].blue, &colors);
  159. }
  160. else { /* add CELL color rule */
  161. Rast_add_c_color_rule(&my_color_rules[i].i,
  162. my_color_rules[i].red, my_color_rules[i].green,
  163. my_color_rules[i].blue,
  164. &my_color_rules[i + 1].i,
  165. my_color_rules[i + 1].red,
  166. my_color_rules[i + 1].green,
  167. my_color_rules[i + 1].blue, &colors);
  168. }
  169. }
  170. /* write the rules */
  171. Rast_write_colors(rast_name, G_mapset(), &colors);
  172. return 1;
  173. }
  174. static int cmp_labels_d(const void *a, const void *b)
  175. {
  176. struct My_labels_rule *al = (struct My_labels_rule *) a;
  177. struct My_labels_rule *bl = (struct My_labels_rule *) b;
  178. if (al->d < bl->d)
  179. return -1;
  180. return (al->d > bl->d);
  181. }
  182. static int cmp_labels_i(const void *a, const void *b)
  183. {
  184. struct My_labels_rule *al = (struct My_labels_rule *) a;
  185. struct My_labels_rule *bl = (struct My_labels_rule *) b;
  186. if (al->i < bl->i)
  187. return -1;
  188. return (al->i > bl->i);
  189. }
  190. /* add labels to raster cells */
  191. int update_labels(const char *rast_name, const char *vector_map, int field,
  192. const char *label_column, int use, int val,
  193. const char *attr_column)
  194. {
  195. int i, j;
  196. /* Map */
  197. struct Map_info Map;
  198. /* Attributes */
  199. int nrec;
  200. struct field_info *Fi;
  201. dbDriver *Driver;
  202. dbCatValArray cvarr;
  203. int col_type;
  204. /* labels */
  205. struct Categories rast_cats;
  206. int labels_n_values = 0;
  207. struct My_labels_rule *my_labels_rules;
  208. /* init raster categories */
  209. Rast_init_cats("Categories", &rast_cats);
  210. switch (use) {
  211. case USE_ATTR:
  212. {
  213. int is_fp = Rast_map_is_fp(rast_name, G_mapset());
  214. if (!label_column) {
  215. G_verbose_message(_("Label column was not specified, no labels will be written"));
  216. break;
  217. }
  218. Rast_set_cats_title("Rasterized vector map from labels", &rast_cats);
  219. /* open vector map and database driver */
  220. Vect_set_open_level(1);
  221. if (Vect_open_old(&Map, vector_map, G_find_vector2(vector_map, "")) < 0)
  222. G_fatal_error(_("Unable to open vector map <%s>"), vector_map);
  223. db_CatValArray_init(&cvarr);
  224. if (!(Fi = Vect_get_field(&Map, field)))
  225. G_fatal_error(_("Database connection not defined for layer %d"),
  226. field);
  227. Vect_close(&Map);
  228. if (!
  229. (Driver =
  230. db_start_driver_open_database(Fi->driver, Fi->database)))
  231. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  232. Fi->database, Fi->driver);
  233. /* get number of records in label_column */
  234. if ((nrec =
  235. db_select_CatValArray(Driver, Fi->table, Fi->key,
  236. attr_column, NULL, &cvarr)) == -1)
  237. G_fatal_error(_("Unknown column <%s> in table <%s>"),
  238. attr_column, Fi->table);
  239. if (nrec < 0)
  240. G_fatal_error(_("No records selected from table <%s>"),
  241. Fi->table);
  242. G_debug(3, "nrec = %d", nrec);
  243. my_labels_rules =
  244. (struct My_labels_rule *)
  245. G_malloc(sizeof(struct My_labels_rule) * nrec);
  246. /* get column type */
  247. if ((col_type =
  248. db_column_Ctype(Driver, Fi->table,
  249. label_column)) == -1) {
  250. G_fatal_error(_("Column <%s> not found"), label_column);
  251. }
  252. /* for each attribute */
  253. for (i = 0; i < cvarr.n_values; i++) {
  254. char tmp[64];
  255. dbValue value;
  256. int cat = cvarr.value[i].cat;
  257. if (db_select_value
  258. (Driver, Fi->table, Fi->key, cat, label_column,
  259. &value) < 0) {
  260. G_warning(_("No records selected"));
  261. continue;
  262. }
  263. labels_n_values++;
  264. db_init_string(&my_labels_rules[i].label);
  265. /* switch the column type */
  266. switch (col_type) {
  267. case DB_C_TYPE_DOUBLE:
  268. sprintf(tmp, "%lf", db_get_value_double(&value));
  269. db_set_string(&my_labels_rules[i].label, tmp);
  270. break;
  271. case DB_C_TYPE_INT:
  272. sprintf(tmp, "%d", db_get_value_int(&value));
  273. db_set_string(&my_labels_rules[i].label, tmp);
  274. break;
  275. case DB_C_TYPE_STRING:
  276. db_set_string(&my_labels_rules[i].label,
  277. db_get_value_string(&value));
  278. break;
  279. default:
  280. G_warning(_("Column type (%s) not supported"),
  281. db_sqltype_name(col_type));
  282. }
  283. /* add the raster category to label */
  284. if (is_fp)
  285. my_labels_rules[i].d = cvarr.value[i].val.d;
  286. else
  287. my_labels_rules[i].i = cvarr.value[i].val.i;
  288. } /* for each value in database */
  289. /* close the database driver */
  290. db_close_database_shutdown_driver(Driver);
  291. /* set the labels */
  292. if (labels_n_values > 0) {
  293. char *lblstr;
  294. /* remove values without labels */
  295. j = 0;
  296. for (i = 0; i < labels_n_values; i++) {
  297. lblstr = db_get_string(&my_labels_rules[i].label);
  298. if (lblstr && *lblstr) {
  299. my_labels_rules[j] = my_labels_rules[i];
  300. j++;
  301. }
  302. }
  303. labels_n_values = j;
  304. }
  305. if (labels_n_values > 0) {
  306. char *lblstr;
  307. if (is_fp) {
  308. DCELL val1, val2;
  309. qsort(my_labels_rules, labels_n_values,
  310. sizeof(struct My_labels_rule), cmp_labels_d);
  311. /* remove duplicate values */
  312. j = 1;
  313. for (i = 1; i < labels_n_values; i++) {
  314. if (my_labels_rules[i - 1].d != my_labels_rules[i].d) {
  315. my_labels_rules[j] = my_labels_rules[i];
  316. j++;
  317. }
  318. else {
  319. if (strcmp(db_get_string(&my_labels_rules[i].label),
  320. db_get_string(&my_labels_rules[i - 1].label)) != 0) {
  321. G_warning(_("Different labels for the same value are not supported"));
  322. }
  323. }
  324. }
  325. labels_n_values = j;
  326. /* add labels */
  327. i = 0;
  328. val1 = val2 = my_labels_rules[i].d;
  329. lblstr = db_get_string(&my_labels_rules[i].label);
  330. for (i = 1; i < labels_n_values; i++) {
  331. if (strcmp(lblstr, db_get_string(&my_labels_rules[i].label)) == 0) {
  332. val2 = my_labels_rules[i].d;
  333. }
  334. else {
  335. Rast_set_d_cat(&val1, &val2, lblstr,
  336. &rast_cats);
  337. val1 = val2 = my_labels_rules[i].d;
  338. lblstr = db_get_string(&my_labels_rules[i].label);
  339. }
  340. }
  341. Rast_set_d_cat(&val1, &val2, lblstr, &rast_cats);
  342. }
  343. else {
  344. CELL val1, val2;
  345. qsort(my_labels_rules, labels_n_values,
  346. sizeof(struct My_labels_rule), cmp_labels_i);
  347. /* remove duplicate values */
  348. j = 1;
  349. for (i = 1; i < labels_n_values; i++) {
  350. if (my_labels_rules[i - 1].i != my_labels_rules[i].i) {
  351. my_labels_rules[j] = my_labels_rules[i];
  352. j++;
  353. }
  354. else {
  355. if (strcmp(db_get_string(&my_labels_rules[i].label),
  356. db_get_string(&my_labels_rules[i - 1].label)) != 0) {
  357. G_warning(_("Different labels for the same value are not supported"));
  358. }
  359. }
  360. }
  361. labels_n_values = j;
  362. /* add labels */
  363. i = 0;
  364. val1 = val2 = my_labels_rules[i].i;
  365. lblstr = db_get_string(&my_labels_rules[i].label);
  366. for (i = 1; i < labels_n_values; i++) {
  367. if (strcmp(lblstr, db_get_string(&my_labels_rules[i].label)) == 0) {
  368. val2 = my_labels_rules[i].i;
  369. }
  370. else {
  371. Rast_set_c_cat(&val1, &val2, lblstr,
  372. &rast_cats);
  373. val1 = val2 = my_labels_rules[i].i;
  374. lblstr = db_get_string(&my_labels_rules[i].label);
  375. }
  376. }
  377. Rast_set_c_cat(&val1, &val2, lblstr, &rast_cats);
  378. }
  379. }
  380. }
  381. break;
  382. case USE_VAL:
  383. {
  384. char msg[64];
  385. RASTER_MAP_TYPE map_type;
  386. struct FPRange fprange;
  387. struct Range range;
  388. map_type = Rast_map_type(rast_name, G_mapset());
  389. Rast_set_cats_title("Rasterized vector map from values", &rast_cats);
  390. if (map_type == CELL_TYPE) {
  391. CELL min, max;
  392. Rast_read_range(rast_name, G_mapset(), &range);
  393. Rast_get_range_min_max(&range, &min, &max);
  394. sprintf(msg, "Value %d", val);
  395. Rast_set_cat(&min, &max, msg, &rast_cats, map_type);
  396. }
  397. else {
  398. DCELL fmin, fmax;
  399. Rast_read_fp_range(rast_name, G_mapset(), &fprange);
  400. Rast_get_fp_range_min_max(&fprange, &fmin, &fmax);
  401. sprintf(msg, "Value %.4f", (double)val);
  402. Rast_set_cat(&fmin, &fmax, msg, &rast_cats, map_type);
  403. }
  404. }
  405. break;
  406. case USE_CAT:
  407. {
  408. int row, rows, fd;
  409. void *rowbuf;
  410. struct Cell_stats stats;
  411. CELL n;
  412. RASTER_MAP_TYPE map_type;
  413. long count;
  414. map_type = Rast_map_type(rast_name, G_mapset());
  415. if (label_column) {
  416. Rast_set_cats_title("Rasterized vector map from labels", &rast_cats);
  417. /* open vector map and database driver */
  418. Vect_set_open_level(1);
  419. if (Vect_open_old(&Map, vector_map, G_find_vector2(vector_map, "")) < 0)
  420. G_fatal_error(_("Unable to open vector map <%s>"),
  421. vector_map);
  422. db_CatValArray_init(&cvarr);
  423. if (!(Fi = Vect_get_field(&Map, field)))
  424. G_fatal_error(_("Database connection not defined for layer %d"),
  425. field);
  426. Vect_close(&Map);
  427. if (!
  428. (Driver =
  429. db_start_driver_open_database(Fi->driver, Fi->database)))
  430. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  431. Fi->database, Fi->driver);
  432. /* get number of records in label_column */
  433. if ((nrec =
  434. db_select_CatValArray(Driver, Fi->table, Fi->key,
  435. label_column, NULL, &cvarr)) == -1)
  436. G_fatal_error(_("Unknown column <%s> in table <%s>"),
  437. label_column, Fi->table);
  438. if (nrec < 0)
  439. G_fatal_error(_("No records selected from table <%s>"),
  440. Fi->table);
  441. G_debug(3, "nrec = %d", nrec);
  442. my_labels_rules =
  443. (struct My_labels_rule *)
  444. G_malloc(sizeof(struct My_labels_rule) * nrec);
  445. /* get column type */
  446. if ((col_type =
  447. db_column_Ctype(Driver, Fi->table,
  448. label_column)) == -1) {
  449. G_fatal_error(_("Column <%s> not found"), label_column);
  450. }
  451. /* close the database driver */
  452. db_close_database_shutdown_driver(Driver);
  453. /* for each attribute */
  454. for (i = 0; i < cvarr.n_values; i++) {
  455. char tmp[2000];
  456. int cat = cvarr.value[i].cat;
  457. labels_n_values++;
  458. db_init_string(&my_labels_rules[i].label);
  459. /* switch the column type */
  460. switch (col_type) {
  461. case DB_C_TYPE_DOUBLE:
  462. sprintf(tmp, "%lf", cvarr.value[i].val.d);
  463. db_set_string(&my_labels_rules[i].label, tmp);
  464. break;
  465. case DB_C_TYPE_INT:
  466. sprintf(tmp, "%d", cvarr.value[i].val.i);
  467. db_set_string(&my_labels_rules[i].label, tmp);
  468. break;
  469. case DB_C_TYPE_STRING:
  470. db_set_string(&my_labels_rules[i].label,
  471. db_get_string(cvarr.value[i].val.s));
  472. break;
  473. default:
  474. G_warning(_("Column type (%s) not supported"),
  475. db_sqltype_name(col_type));
  476. }
  477. /* add the raster category to label */
  478. my_labels_rules[i].i = cat;
  479. Rast_set_cat(&(my_labels_rules[i].i),
  480. &(my_labels_rules[i].i),
  481. db_get_string(&my_labels_rules[i].label),
  482. &rast_cats, map_type);
  483. } /* for each value in database */
  484. }
  485. else {
  486. Rast_set_cats_title("Rasterized vector map from categories", &rast_cats);
  487. /* Rast_set_cat() is terribly slow for many categories,
  488. * and the added labels are not really informative:
  489. * 1:Category 1
  490. * 2:Category 2
  491. * ...
  492. * 100000:Category 100000
  493. * -> skip */
  494. #if 0
  495. fd = Rast_open_old(rast_name, G_mapset());
  496. rowbuf = Rast_allocate_buf(map_type);
  497. Rast_init_cell_stats(&stats);
  498. rows = Rast_window_rows();
  499. for (row = 0; row < rows; row++) {
  500. Rast_get_row(fd, rowbuf, row, map_type);
  501. Rast_update_cell_stats(rowbuf, Rast_window_cols(), &stats);
  502. }
  503. Rast_rewind_cell_stats(&stats);
  504. while (Rast_next_cell_stat(&n, &count, &stats)) {
  505. char msg[80];
  506. sprintf(msg, "Category %d", n);
  507. Rast_set_cat(&n, &n, msg, &rast_cats, map_type);
  508. }
  509. Rast_close(fd);
  510. G_free(rowbuf);
  511. #endif
  512. }
  513. }
  514. break;
  515. case USE_D:
  516. {
  517. DCELL fmin, fmax;
  518. RASTER_MAP_TYPE map_type;
  519. char msg[64];
  520. map_type = Rast_map_type(rast_name, G_mapset());
  521. Rast_set_cats_title("Rasterized vector map from line direction", &rast_cats);
  522. Rast_write_units(rast_name, "degrees CCW from +x");
  523. for (i = 1; i <= 360; i++) {
  524. sprintf(msg, "%d degrees", i);
  525. if (i == 360) {
  526. fmin = 359.5;
  527. fmax = 360.0;
  528. Rast_set_cat(&fmin, &fmax, msg, &rast_cats, map_type);
  529. fmin = 0.0;
  530. fmax = 0.5;
  531. }
  532. else {
  533. fmin = i - 0.5;
  534. fmax = i + 0.5;
  535. }
  536. Rast_set_cat(&fmin, &fmax, msg, &rast_cats, map_type);
  537. }
  538. }
  539. break;
  540. case USE_Z:
  541. /* TODO or not TODO */
  542. break;
  543. default:
  544. G_fatal_error(_("Unknown use type: %d"), use);
  545. break;
  546. }
  547. Rast_write_cats(rast_name, &rast_cats);
  548. Rast_free_cats(&rast_cats);
  549. return 1;
  550. }