main.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /****************************************************************
  2. *
  3. * MODULE: v.sample (based on s.sample)
  4. *
  5. * AUTHOR(S): James Darrell McCauley darrell@mccauley-usa.com
  6. * http://mccauley-usa.com/
  7. * OGR support by Martin Landa <landa.martin gmail.com>
  8. *
  9. * PURPOSE: GRASS program to sample a raster map at site locations.
  10. *
  11. * Modification History:
  12. * <04 Jan 1994> - began coding (jdm)
  13. * <06 Jan 1994> - announced version 0.1B on pasture.ecn.purdue.edu (jdm)
  14. * <21 Jan 1994> - changed wording on help screen. Revised to 0.2B (jdm)
  15. * <24 Jan 1994> - got rid of diagnostic messages. Revised to 0.3B (jdm)
  16. * ?? Revised to 0.4B (jdm)
  17. * <19 Dec 1994> - fixed bug in readsites, added html. Revised to 0.5B (jdm)
  18. * <02 Jan 1995> - cleaned Gmakefile, man page, html.
  19. * fixed memory error in bilinear and cubic 0.6B (jdm)
  20. * <25 Feb 1995> - cleaned 'gcc -Wall' warnings 0.7B (jdm)
  21. * <15 Jun 1995> - fixed pointer error for G_{col,row}_to_{easting,northing}.
  22. * 0.8B (jdm)
  23. * <13 Sep 2000> - released under GPL
  24. *
  25. * COPYRIGHT: (C) 2003-2009 by the GRASS Development Team
  26. *
  27. * This program is free software under the GNU General
  28. * Public License (>=v2). Read the file COPYING that
  29. * comes with GRASS for details.
  30. *
  31. **************************************************************/
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <math.h>
  36. #include <grass/gis.h>
  37. #include <grass/raster.h>
  38. #include <grass/glocale.h>
  39. #include <grass/dbmi.h>
  40. #include <grass/vector.h>
  41. int main(int argc, char **argv)
  42. {
  43. double scale, predicted, actual;
  44. INTERP_TYPE method = INTERP_UNKNOWN;
  45. int fdrast; /* file descriptor for raster map is int */
  46. struct Cell_head window;
  47. struct GModule *module;
  48. struct Map_info In, Out;
  49. struct
  50. {
  51. struct Option *input, *output, *rast, *z, *column, *method, *field;
  52. } parm;
  53. int line, nlines;
  54. struct line_pnts *Points;
  55. struct line_cats *Cats;
  56. /* Attributes */
  57. int field, nrecords;
  58. int ctype;
  59. struct field_info *Fi;
  60. dbDriver *Driver;
  61. dbCatValArray cvarr;
  62. char buf[2000];
  63. dbString sql;
  64. G_gisinit(argv[0]);
  65. module = G_define_module();
  66. G_add_keyword(_("vector"));
  67. G_add_keyword(_("sampling"));
  68. G_add_keyword(_("raster"));
  69. module->description =
  70. _("Samples a raster map at vector point locations.");
  71. parm.input = G_define_standard_option(G_OPT_V_INPUT);
  72. parm.input->label = _("Name of input vector point map");
  73. parm.field = G_define_standard_option(G_OPT_V_FIELD);
  74. parm.column = G_define_standard_option(G_OPT_DB_COLUMN);
  75. parm.column->required = YES;
  76. parm.column->description =
  77. _("Name of attribute column to use for comparison");
  78. parm.output = G_define_standard_option(G_OPT_V_OUTPUT);
  79. parm.output->description = _("Name for output vector map to store differences");
  80. parm.rast = G_define_standard_option(G_OPT_R_INPUT);
  81. parm.rast->key = "raster";
  82. parm.rast->description = _("Name of raster map to be sampled");
  83. parm.method = G_define_standard_option(G_OPT_R_INTERP_TYPE);
  84. parm.method->answer = "nearest";
  85. parm.z = G_define_option();
  86. parm.z->key = "zscale";
  87. parm.z->type = TYPE_DOUBLE;
  88. parm.z->required = NO;
  89. parm.z->answer = "1.0";
  90. parm.z->label =
  91. _("Scaling factor for values read from raster map");
  92. parm.z->description =
  93. _("Sampled values will be multiplied by this factor");
  94. if (G_parser(argc, argv))
  95. exit(EXIT_FAILURE);
  96. sscanf(parm.z->answer, "%lf", &scale);
  97. method = Rast_option_to_interp_type(parm.method);
  98. G_get_window(&window);
  99. /* Open input */
  100. Vect_set_open_level(2);
  101. if (Vect_open_old2(&In, parm.input->answer, "", parm.field->answer) < 0)
  102. G_fatal_error(_("Unable to open vector map <%s>"), parm.input->answer);
  103. field = Vect_get_field_number(&In, parm.field->answer);
  104. fdrast = Rast_open_old(parm.rast->answer, "");
  105. /* Read attributes */
  106. Fi = Vect_get_field(&In, field);
  107. if (Fi == NULL)
  108. G_fatal_error(_("Database connection not defined for layer %s"),
  109. parm.field->answer);
  110. Driver = db_start_driver_open_database(Fi->driver, Fi->database);
  111. if (Driver == NULL)
  112. G_fatal_error("Unable to open database <%s> by driver <%s>",
  113. Fi->database, Fi->driver);
  114. db_set_error_handler_driver(Driver);
  115. nrecords = db_select_CatValArray(Driver, Fi->table, Fi->key,
  116. parm.column->answer, NULL, &cvarr);
  117. G_debug(3, "nrecords = %d", nrecords);
  118. ctype = cvarr.ctype;
  119. if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
  120. G_fatal_error(_("Column type <%s> not supported (must be integer or double precision)"),
  121. db_sqltype_name(ctype));
  122. if (nrecords < 0)
  123. G_fatal_error(_("Unable to select data from table"));
  124. G_verbose_message(n_("%d record selected from table",
  125. "%d records selected from table",
  126. nrecords), nrecords);
  127. db_close_database_shutdown_driver(Driver);
  128. /* Open output */
  129. if (Vect_open_new(&Out, parm.output->answer, 0) < 0)
  130. G_fatal_error(_("Unable to create vector map <%s>"),
  131. parm.output->answer);
  132. Vect_hist_copy(&In, &Out);
  133. Vect_hist_command(&Out);
  134. /* Create table */
  135. db_init_string(&sql);
  136. Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
  137. Vect_map_add_dblink(&Out, Fi->number, Fi->name, Fi->table, Fi->key,
  138. Fi->database, Fi->driver);
  139. Driver =
  140. db_start_driver_open_database(Fi->driver,
  141. Vect_subst_var(Fi->database, &Out));
  142. if (Driver == NULL)
  143. G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
  144. Fi->database, Fi->driver);
  145. db_set_error_handler_driver(Driver);
  146. db_begin_transaction(Driver);
  147. sprintf(buf,
  148. "create table %s ( cat integer, pnt_val double precision, rast_val double precision, "
  149. "diff double precision)", Fi->table);
  150. db_set_string(&sql, buf);
  151. if (db_execute_immediate(Driver, &sql) != DB_OK)
  152. G_fatal_error(_("Unable to create table <%s>"), db_get_string(&sql));
  153. if (db_create_index2(Driver, Fi->table, Fi->key) != DB_OK)
  154. G_warning(_("Cannot create index"));
  155. if (db_grant_on_table
  156. (Driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
  157. G_fatal_error(_("Unable to grant privileges on table <%s>"),
  158. Fi->table);
  159. G_message(_("Reading points..."));
  160. Points = Vect_new_line_struct();
  161. Cats = Vect_new_cats_struct();
  162. nlines = Vect_get_num_lines(&In);
  163. for (line = 1; line <= nlines; line++) {
  164. int type, cat, ret, cval;
  165. double dval;
  166. G_debug(3, "line = %d", line);
  167. G_percent(line, nlines, 2);
  168. type = Vect_read_line(&In, Points, Cats, line);
  169. if (!(type & GV_POINT))
  170. continue;
  171. if (field != -1 && !Vect_cat_get(Cats, field, &cat))
  172. continue;
  173. G_debug(4, "cat = %d", cat);
  174. /* find actual value */
  175. if (ctype == DB_C_TYPE_INT) {
  176. ret = db_CatValArray_get_value_int(&cvarr, cat, &cval);
  177. if (ret != DB_OK)
  178. G_warning(_("No record for category %d in table <%s>"), cat,
  179. Fi->table);
  180. actual = cval;
  181. }
  182. else if (ctype == DB_C_TYPE_DOUBLE) {
  183. ret = db_CatValArray_get_value_double(&cvarr, cat, &dval);
  184. if (ret != DB_OK)
  185. G_warning(_("No record for category %d in table <%s>"), cat,
  186. Fi->table);
  187. actual = dval;
  188. }
  189. else {
  190. G_fatal_error(_("Column type not supported"));
  191. }
  192. G_debug(4, "actual = %e", actual);
  193. /* find predicted value */
  194. predicted = Rast_get_sample(fdrast, &window, NULL, Points->y[0],
  195. Points->x[0], 0, method);
  196. if (Rast_is_d_null_value(&predicted))
  197. continue;
  198. predicted *= scale;
  199. G_debug(4, "predicted = %e", predicted);
  200. Vect_reset_cats(Cats);
  201. Vect_cat_set(Cats, 1, cat);
  202. sprintf(buf, "insert into %s values ( %d, %e, %e, %e )",
  203. Fi->table, cat, actual, predicted, predicted - actual);
  204. db_set_string(&sql, buf);
  205. if (db_execute_immediate(Driver, &sql) != DB_OK)
  206. G_fatal_error(_("Unable to insert row: %s"), db_get_string(&sql));
  207. Vect_write_line(&Out, GV_POINT, Points, Cats);
  208. }
  209. db_commit_transaction(Driver);
  210. db_close_database_shutdown_driver(Driver);
  211. Rast_close(fdrast);
  212. Vect_close(&In);
  213. Vect_build(&Out);
  214. Vect_close(&Out);
  215. exit(EXIT_SUCCESS);
  216. }