main.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /******************************************************************************
  2. * MODULE: v.in.db
  3. *
  4. * AUTHOR(S): Radim Blazek
  5. *
  6. * PURPOSE: Create new vector from db table.
  7. *
  8. * COPYRIGHT: (C) 2000-2007 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General Public
  11. * License (>=v2). Read the file COPYING that comes with GRASS
  12. * for details.
  13. *
  14. ******************************************************************************/
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <unistd.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <grass/gis.h>
  21. #include <grass/dbmi.h>
  22. #include <grass/Vect.h>
  23. #include <grass/glocale.h>
  24. int main(int argc, char *argv[])
  25. {
  26. int i, cat, with_z, more, ctype, ret;
  27. char buf[2000];
  28. int count;
  29. double coor[3];
  30. int ncoor;
  31. int coltype;
  32. struct Option *driver_opt, *database_opt, *table_opt;
  33. struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt,
  34. *outvect;
  35. struct GModule *module;
  36. struct Map_info Map;
  37. struct line_pnts *Points;
  38. struct line_cats *Cats;
  39. dbString sql;
  40. dbDriver *driver;
  41. dbCursor cursor;
  42. dbTable *table;
  43. dbColumn *column;
  44. dbValue *value;
  45. struct field_info *fi;
  46. G_gisinit(argv[0]);
  47. module = G_define_module();
  48. module->keywords = _("vector, import");
  49. module->description =
  50. _
  51. ("Creates new vector (points) map from database table containing coordinates.");
  52. table_opt = G_define_standard_option(G_OPT_TABLE);
  53. table_opt->required = YES;
  54. table_opt->description = _("Input table name");
  55. driver_opt = G_define_standard_option(G_OPT_DRIVER);
  56. driver_opt->options = db_list_drivers();
  57. driver_opt->answer = db_get_default_driver_name();
  58. database_opt = G_define_standard_option(G_OPT_DATABASE);
  59. database_opt->answer = db_get_default_database_name();
  60. xcol_opt = G_define_standard_option(G_OPT_COLUMN);
  61. xcol_opt->key = "x";
  62. xcol_opt->required = YES;
  63. xcol_opt->description = _("Name of column containing x coordinate");
  64. ycol_opt = G_define_standard_option(G_OPT_COLUMN);
  65. ycol_opt->key = "y";
  66. ycol_opt->required = YES;
  67. ycol_opt->description = _("Name of column containing y coordinate");
  68. zcol_opt = G_define_standard_option(G_OPT_COLUMN);
  69. zcol_opt->key = "z";
  70. zcol_opt->description = _("Name of column containing z coordinate");
  71. keycol_opt = G_define_standard_option(G_OPT_COLUMN);
  72. keycol_opt->key = "key";
  73. keycol_opt->required = YES;
  74. keycol_opt->description = _("Name of column containing category number");
  75. keycol_opt->description = _("Must refer to an integer column");
  76. where_opt = G_define_standard_option(G_OPT_WHERE);
  77. outvect = G_define_standard_option(G_OPT_V_OUTPUT);
  78. if (G_parser(argc, argv))
  79. exit(EXIT_FAILURE);
  80. if (zcol_opt->answer) {
  81. with_z = WITH_Z;
  82. ncoor = 3;
  83. }
  84. else {
  85. with_z = WITHOUT_Z;
  86. ncoor = 2;
  87. }
  88. Points = Vect_new_line_struct();
  89. Cats = Vect_new_cats_struct();
  90. db_init_string(&sql);
  91. Vect_open_new(&Map, outvect->answer, with_z);
  92. Vect_hist_command(&Map);
  93. fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
  94. /* Open driver */
  95. driver =
  96. db_start_driver_open_database(driver_opt->answer,
  97. database_opt->answer);
  98. if (driver == NULL) {
  99. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  100. fi->database, fi->driver);
  101. }
  102. /* check if target table already exists */
  103. G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>",
  104. outvect->answer, db_get_default_driver_name(),
  105. db_get_default_database_name());
  106. if (db_table_exists(db_get_default_driver_name(),
  107. db_get_default_database_name(), outvect->answer) == 1)
  108. G_fatal_error(_("Output vector map, table <%s> (driver: <%s>, database: <%s>) "
  109. "already exists"), outvect->answer,
  110. db_get_default_driver_name(),
  111. db_get_default_database_name());
  112. coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer);
  113. if (coltype == -1)
  114. G_fatal_error(_("Missing column <%s> in table <%s>"),
  115. keycol_opt->answer, table_opt->answer);
  116. if (coltype != DB_C_TYPE_INT)
  117. G_fatal_error(_("Data type of key column must be integer"));
  118. /* Open select cursor */
  119. sprintf(buf, "select %s, %s, %s", keycol_opt->answer, xcol_opt->answer,
  120. ycol_opt->answer);
  121. db_set_string(&sql, buf);
  122. if (with_z) {
  123. sprintf(buf, ", %s", zcol_opt->answer);
  124. db_append_string(&sql, buf);
  125. }
  126. sprintf(buf, " from %s", table_opt->answer);
  127. db_append_string(&sql, buf);
  128. if (where_opt->answer) {
  129. sprintf(buf, " WHERE %s", where_opt->answer);
  130. db_append_string(&sql, buf);
  131. }
  132. G_debug(2, "SQL: %s", db_get_string(&sql));
  133. if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) {
  134. G_fatal_error(_("Unable to open select cursor: '%s'"),
  135. db_get_string(&sql));
  136. }
  137. table = db_get_cursor_table(&cursor);
  138. count = 0;
  139. while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
  140. /* key column */
  141. column = db_get_table_column(table, 0);
  142. ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
  143. if (ctype != DB_C_TYPE_INT)
  144. G_fatal_error(_("Key column must be integer"));
  145. value = db_get_column_value(column);
  146. cat = db_get_value_int(value);
  147. for (i = 0; i < ncoor; i++) {
  148. column = db_get_table_column(table, i + 1);
  149. ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
  150. if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
  151. G_fatal_error(_("x/y/z column must be integer or double"));
  152. value = db_get_column_value(column);
  153. if (ctype == DB_C_TYPE_INT)
  154. coor[i] = (double)db_get_value_int(value);
  155. else
  156. coor[i] = db_get_value_double(value);
  157. }
  158. Vect_reset_line(Points);
  159. Vect_reset_cats(Cats);
  160. Vect_append_point(Points, coor[0], coor[1], coor[2]);
  161. Vect_cat_set(Cats, 1, cat);
  162. Vect_write_line(&Map, GV_POINT, Points, Cats);
  163. count++;
  164. }
  165. G_message(_("%d points written to vector map"), count);
  166. db_close_database_shutdown_driver(driver);
  167. /* Copy table */
  168. if (where_opt->answer)
  169. ret =
  170. db_copy_table_where(driver_opt->answer, database_opt->answer,
  171. table_opt->answer, fi->driver, fi->database,
  172. fi->table, where_opt->answer);
  173. else
  174. ret =
  175. db_copy_table(driver_opt->answer, database_opt->answer,
  176. table_opt->answer, fi->driver, fi->database,
  177. fi->table);
  178. if (ret == DB_FAILED) {
  179. G_warning(_("Unable to copy table"));
  180. }
  181. else {
  182. Vect_map_add_dblink(&Map, 1, NULL, fi->table, keycol_opt->answer,
  183. fi->database, fi->driver);
  184. }
  185. if (G_verbose() > G_verbose_min())
  186. Vect_build(&Map, stderr);
  187. else
  188. Vect_build(&Map, NULL);
  189. Vect_close(&Map);
  190. G_done_msg(" ");
  191. return (EXIT_SUCCESS);
  192. }