trans3.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/vector.h>
  4. #include <grass/dbmi.h>
  5. #include <grass/glocale.h>
  6. #include "local_proto.h"
  7. static int srch(const void *, const void *);
  8. /*!
  9. \brief transform 3d vector features to 2d (z-coordinate is omitted)
  10. \param In input vector
  11. \param Out output vector
  12. \param type feature type to be transformed
  13. \param field layer number
  14. \param zcolumn attribute column where to store height
  15. */
  16. void trans3d(struct Map_info *In, struct Map_info *Out, int type,
  17. const char *field_name, const char *zcolumn)
  18. {
  19. int ltype, line;
  20. int ctype;
  21. int field;
  22. struct line_pnts *Points;
  23. struct line_cats *Cats;
  24. struct field_info *Fi;
  25. dbDriver *driver;
  26. dbString stmt;
  27. char buf[2000];
  28. int ncats, *cats, cat, *cex;
  29. Points = Vect_new_line_struct();
  30. Cats = Vect_new_cats_struct();
  31. db_init_string(&stmt);
  32. field = Vect_get_field_number(In, field_name);
  33. if (zcolumn) {
  34. if (field == -1) {
  35. G_warning(_("Invalid layer number %d, assuming 1"), field);
  36. field = 1;
  37. }
  38. Fi = Vect_get_field(Out, field);
  39. if (!Fi) {
  40. G_fatal_error(_("Database connection not defined for layer <%s>"),
  41. field_name);
  42. }
  43. driver = db_start_driver_open_database(Fi->driver, Fi->database);
  44. if (!driver) {
  45. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  46. Fi->database, Fi->driver);
  47. }
  48. db_set_error_handler_driver(driver);
  49. /* column type must numeric */
  50. ctype = db_column_Ctype(driver, Fi->table, zcolumn);
  51. if (ctype == -1) {
  52. G_fatal_error(_("Column <%s> not found in table <%s>"),
  53. zcolumn, Fi->table);
  54. }
  55. if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
  56. G_fatal_error(_("Column must be numeric"));
  57. }
  58. db_begin_transaction(driver);
  59. /* select existing categories (layer) to array (array is sorted) */
  60. G_message(_("Reading categories..."));
  61. ncats = db_select_int(driver, Fi->table, Fi->key, NULL, &cats);
  62. G_debug(3, "Existing categories: %d", ncats);
  63. }
  64. G_message(_("Transforming features..."));
  65. line = 1;
  66. while (1) {
  67. ltype = Vect_read_next_line(In, Points, Cats);
  68. if (ltype == -1) {
  69. G_fatal_error(_("Unable to read vector map"));
  70. }
  71. if (ltype == -2) { /* EOF */
  72. break;
  73. }
  74. G_progress(line, 1000);
  75. if (!(ltype & type))
  76. continue;
  77. if (field != -1 && !Vect_cat_get(Cats, field, &cat))
  78. continue;
  79. /* get first cat */
  80. if (cat == -1) {
  81. G_warning(_("Feature id %d has no category - skipping"), line);
  82. }
  83. else if (Cats->n_cats > 1) {
  84. G_warning(_("Feature id %d has more categories. "
  85. "Using category %d."), line, cat);
  86. }
  87. if (zcolumn && ltype & (GV_POINT | GV_LINE) && cat > -1) {
  88. /* category exist in table ? */
  89. cex = (int *)bsearch((void *)&cat, cats, ncats, sizeof(int),
  90. srch);
  91. /* store height to the attribute table */
  92. if (ctype == DB_C_TYPE_INT)
  93. sprintf(buf, "update %s set %s = %d where cat = %d",
  94. Fi->table, zcolumn, (int)Points->z[0], cat);
  95. else /* double */
  96. sprintf(buf, "update %s set %s = %.8f where cat = %d",
  97. Fi->table, zcolumn, Points->z[0], cat);
  98. G_debug(3, "SQL: %s", buf);
  99. db_set_string(&stmt, buf);
  100. if (cex) {
  101. if (db_execute_immediate(driver, &stmt) == DB_OK) {
  102. /* TODO */
  103. }
  104. }
  105. else { /* cat does not exist in table */
  106. G_warning(_("Record (cat %d) does not exist (not updated)"),
  107. cat);
  108. }
  109. }
  110. Vect_write_line(Out, ltype, Points, Cats);
  111. line++;
  112. }
  113. G_progress(1, 1);
  114. if (zcolumn) {
  115. db_commit_transaction(driver);
  116. G_free(cats);
  117. db_close_database_shutdown_driver(driver);
  118. db_free_string(&stmt);
  119. }
  120. Vect_destroy_line_struct(Points);
  121. Vect_destroy_cats_struct(Cats);
  122. }
  123. int srch(const void *pa, const void *pb)
  124. {
  125. int *p1 = (int *)pa;
  126. int *p2 = (int *)pb;
  127. if (*p1 < *p2)
  128. return -1;
  129. if (*p1 > *p2)
  130. return 1;
  131. return 0;
  132. }