main.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /****************************************************************
  2. *
  3. * MODULE: v.example
  4. *
  5. * AUTHOR(S): GRASS Development Team, Radim Blazek, Maris Nartiss
  6. *
  7. * PURPOSE: copies vector data from source map to destination map
  8. * prints out all point coordinates and atributes
  9. *
  10. * COPYRIGHT: (C) 2002-2008 by the GRASS Development Team
  11. *
  12. * This program is free software under the
  13. * GNU General Public License (>=v2).
  14. * Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. ****************************************************************/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <grass/gis.h>
  21. #include <grass/vector.h>
  22. #include <grass/dbmi.h>
  23. #include <grass/glocale.h>
  24. int main(int argc, char *argv[])
  25. {
  26. struct Map_info In, Out;
  27. static struct line_pnts *Points;
  28. struct line_cats *Cats;
  29. int i, type, cat, ncols, nrows, col, more, open3d;
  30. char *mapset, sql[200];
  31. struct GModule *module; /* GRASS module for parsing arguments */
  32. struct Option *old, *new;
  33. dbDriver *driver;
  34. dbHandle handle;
  35. dbCursor cursor;
  36. dbTable *table;
  37. dbColumn *column;
  38. dbString table_name, dbsql, valstr;
  39. struct field_info *Fi, *Fin;
  40. /* initialize GIS environment */
  41. /* reads grass env, stores program name to G_program_name() */
  42. G_gisinit(argv[0]);
  43. /* initialize module */
  44. module = G_define_module();
  45. module->keywords = _("vector, keyword2, keyword3");
  46. module->description = _("My first vector module");
  47. /* Define the different options as defined in gis.h */
  48. old = G_define_standard_option(G_OPT_V_INPUT);
  49. new = G_define_standard_option(G_OPT_V_OUTPUT);
  50. /* options and flags parser */
  51. if (G_parser(argc, argv))
  52. exit(EXIT_FAILURE);
  53. /* Create and initialize struct's where to store points/lines and categories */
  54. Points = Vect_new_line_struct();
  55. Cats = Vect_new_cats_struct();
  56. /* Check 1) output is legal vector name; 2) if can find input map;
  57. 3) if input was found in current mapset, check if input != output.
  58. lib/vector/Vlib/legal_vname.c
  59. */
  60. Vect_check_input_output_name(old->answer, new->answer, GV_FATAL_EXIT);
  61. if ((mapset = G_find_vector2(old->answer, "")) == NULL)
  62. G_fatal_error(_("Vector map <%s> not found"), old->answer);
  63. /* Predetermine level at which a map will be opened for reading
  64. lib/vector/Vlib/open.c
  65. */
  66. if (Vect_set_open_level(2))
  67. G_fatal_error(_("Unable to set predetermined vector open level"));
  68. /* Open existing vector for reading
  69. lib/vector/Vlib/open.c
  70. */
  71. if (1 > Vect_open_old(&In, old->answer, mapset))
  72. G_fatal_error(_("Unable to open vector map <%s>"), old->answer);
  73. /* Check if old vector is 3D. We should preserve 3D data. */
  74. if (Vect_is_3d(&In))
  75. open3d = WITH_Z;
  76. else
  77. open3d = WITHOUT_Z;
  78. /* Open new vector for reading/writing */
  79. if (0 > Vect_open_new(&Out, new->answer, open3d)) {
  80. Vect_close(&In);
  81. G_fatal_error(_("Unable to create vector map <%s>"), new->answer);
  82. }
  83. /* Let's get vector layers db connections information */
  84. Fi = Vect_get_field(&In, 1);
  85. if (!Fi) {
  86. Vect_close(&In);
  87. G_fatal_error(_("Database connection not defined for layer %d"), 1);
  88. }
  89. /* Output information usefull for debuging
  90. incluse/vect/dig_structs.h
  91. */
  92. G_debug(1,
  93. "Field number:%d; Name:<%s>; Driver:<%s>; Database:<%s>; Table:<%s>; Key:<%s>;\n",
  94. Fi->number, Fi->name, Fi->driver, Fi->database, Fi->table,
  95. Fi->key);
  96. /* Prepeare strings for use in db_* calls */
  97. db_init_string(&dbsql);
  98. db_init_string(&valstr);
  99. db_init_string(&table_name);
  100. db_init_handle(&handle);
  101. /* Prepearing database for use */
  102. driver = db_start_driver(Fi->driver);
  103. if (driver == NULL) {
  104. Vect_close(&In);
  105. G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
  106. }
  107. db_set_handle(&handle, Fi->database, NULL);
  108. if (db_open_database(driver, &handle) != DB_OK) {
  109. Vect_close(&In);
  110. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  111. Fi->database, driver);
  112. }
  113. db_set_string(&table_name, Fi->table);
  114. if (db_describe_table(driver, &table_name, &table) != DB_OK) {
  115. Vect_close(&In);
  116. G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
  117. }
  118. ncols = db_get_table_number_of_columns(table);
  119. /* Copy header and history data from old to new map */
  120. Vect_copy_head_data(&In, &Out);
  121. Vect_hist_copy(&In, &Out);
  122. Vect_hist_command(&Out);
  123. i = 1;
  124. /* Let's do something with every vector feature in input map... */
  125. /* Read in single line and get it's type */
  126. while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
  127. /* If Points contain line... */
  128. if (type == GV_LINE || type == GV_POINT || type == GV_CENTROID) {
  129. if (Vect_cat_get(Cats, 1, &cat) == 0) {
  130. Vect_cat_set(Cats, 1, i);
  131. i++;
  132. }
  133. }
  134. if (type == GV_POINT) {
  135. /* Print out point coordinates */
  136. printf("No:%d\tX:%f\tY:%f\tZ:%f\tCAT:%d\n", i, *Points->x,
  137. *Points->y, *Points->z, cat);
  138. /* Prepeare SQL query to get point attribute data */
  139. sprintf(sql, "select * from %s where %s=%d", Fi->table, Fi->key,
  140. cat);
  141. G_debug(1, "SQL: \"%s\"", sql);
  142. db_set_string(&dbsql, sql);
  143. /* Now execute query */
  144. if (db_open_select_cursor(driver, &dbsql, &cursor, DB_SEQUENTIAL)
  145. != DB_OK)
  146. G_warning(_("Unable to get attribute data for cat %d"), cat);
  147. else {
  148. /* Result count */
  149. nrows = db_get_num_rows(&cursor);
  150. G_debug(1, "Result count: %d", nrows);
  151. table = db_get_cursor_table(&cursor);
  152. /* Let's output every columns name and value */
  153. while (1) {
  154. if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
  155. G_warning(_("Error while retrieving database record for cat %d"),
  156. cat);
  157. break;
  158. }
  159. if (!more)
  160. break;
  161. for (col = 0; col < ncols; col++) {
  162. column = db_get_table_column(table, col);
  163. db_convert_column_value_to_string(column, &valstr);
  164. printf("%s: %s\t", db_get_column_name(column),
  165. db_get_string(&valstr));
  166. }
  167. printf("\n");
  168. }
  169. db_close_cursor(&cursor);
  170. }
  171. }
  172. /* Only now we write data into new vector */
  173. Vect_write_line(&Out, type, Points, Cats);
  174. }
  175. /* Create database for new vector map */
  176. Fin = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
  177. driver = db_start_driver_open_database(Fin->driver, Fin->database);
  178. G_debug(1,
  179. "Field number:%d; Name:<%s>; Driver:<%s>; Database:<%s>; Table:<%s>; Key:<%s>;\n",
  180. Fin->number, Fin->name, Fin->driver, Fin->database, Fin->table,
  181. Fin->key);
  182. /* Let's copy attribute table data */
  183. if (db_copy_table(Fi->driver, Fi->database, Fi->table,
  184. Fin->driver, Vect_subst_var(Fin->database, &Out),
  185. Fin->table) == DB_FAILED)
  186. G_warning(_("Unable to copy attribute table to vector map <%s>"),
  187. new->answer);
  188. else
  189. Vect_map_add_dblink(&Out, Fin->number, Fin->name, Fin->table, Fi->key,
  190. Fin->database, Fin->driver);
  191. /* Build topology for vector map and close them */
  192. Vect_build(&Out);
  193. Vect_close(&In);
  194. Vect_close(&Out);
  195. db_close_database_shutdown_driver(driver);
  196. /* Don't forget to report to caller sucessfull end of data processing :) */
  197. exit(EXIT_SUCCESS);
  198. }