main.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: v.what
  5. *
  6. * AUTHOR(S): Trevor Wiens - derived from d.what.vect - 15 Jan 2006
  7. * OGR support by Martin Landa <landa.martin gmail.com>
  8. *
  9. * PURPOSE: To select and report attribute information for objects at a
  10. * user specified location. This replaces d.what.vect by removing
  11. * the interactive component to enable its use with the new
  12. * gis.m and future GUI.
  13. *
  14. * COPYRIGHT: (C) 2006-2010, 2011 by the GRASS Development Team
  15. *
  16. * This program is free software under the GNU General
  17. * Public License (>=v2). Read the file COPYING that
  18. * comes with GRASS for details.
  19. *
  20. *****************************************************************************/
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <grass/glocale.h>
  24. #include <grass/gis.h>
  25. #include <grass/vector.h>
  26. #include <grass/display.h>
  27. #include <grass/dbmi.h>
  28. #include <grass/glocale.h>
  29. #include "what.h"
  30. int main(int argc, char **argv)
  31. {
  32. struct {
  33. struct Flag *print, *topo, *shell, *json;
  34. } flag;
  35. struct {
  36. struct Option *map, *field, *coords, *maxdist, *type;
  37. } opt;
  38. struct Cell_head window;
  39. struct GModule *module;
  40. char **vect;
  41. int nvects;
  42. struct Map_info *Map;
  43. char buf[2000];
  44. int i, level, ret, type;
  45. int *field;
  46. double xval, yval, xres, yres, maxd, x;
  47. double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
  48. char nsres[30], ewres[30];
  49. char ch;
  50. /* Initialize the GIS calls */
  51. G_gisinit(argv[0]);
  52. module = G_define_module();
  53. G_add_keyword(_("vector"));
  54. G_add_keyword(_("querying"));
  55. G_add_keyword(_("position"));
  56. module->description = _("Queries a vector map at given locations.");
  57. opt.map = G_define_standard_option(G_OPT_V_MAPS);
  58. opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
  59. opt.field->multiple = YES;
  60. opt.type = G_define_standard_option(G_OPT_V3_TYPE);
  61. opt.type->answer = "point,line,area,face";
  62. opt.coords = G_define_standard_option(G_OPT_M_COORDS);
  63. opt.coords->required = YES;
  64. opt.coords->label = _("Coordinates for query");
  65. opt.coords->description = _("'-' for standard input");
  66. opt.maxdist = G_define_option();
  67. opt.maxdist->type = TYPE_DOUBLE;
  68. opt.maxdist->key = "distance";
  69. opt.maxdist->answer = "0";
  70. opt.maxdist->multiple = NO;
  71. opt.maxdist->description = _("Query threshold distance");
  72. opt.maxdist->guisection = _("Threshold");
  73. flag.topo = G_define_flag();
  74. flag.topo->key = 'd';
  75. flag.topo->description = _("Print topological information (debugging)");
  76. flag.topo->guisection = _("Print");
  77. flag.print = G_define_flag();
  78. flag.print->key = 'a';
  79. flag.print->description = _("Print attribute information");
  80. flag.print->guisection = _("Print");
  81. flag.shell = G_define_flag();
  82. flag.shell->key = 'g';
  83. flag.shell->description = _("Print the stats in shell script style");
  84. flag.shell->guisection = _("Print");
  85. flag.json = G_define_flag();
  86. flag.json->key = 'j';
  87. flag.json->description = _("Print the stats in JSON");
  88. flag.json->guisection = _("Print");
  89. if (G_parser(argc, argv))
  90. exit(EXIT_FAILURE);
  91. /* initialize variables */
  92. vect = NULL;
  93. Map = NULL;
  94. nvects = 0;
  95. field = NULL;
  96. if (opt.map->answers && opt.map->answers[0])
  97. vect = opt.map->answers;
  98. else
  99. G_fatal_error(_("No input vector maps!"));
  100. if (flag.shell->answer && flag.json->answer)
  101. G_fatal_error(_("Flags g and j are mutually exclusive"));
  102. maxd = atof(opt.maxdist->answer);
  103. type = Vect_option_to_types(opt.type);
  104. if (maxd == 0.0) {
  105. /* this code is a translation from d.what.vect which uses display
  106. * resolution to figure out a querying distance
  107. * display resolution is not available here
  108. * using raster resolution instead to determine vector querying
  109. * distance does not really make sense
  110. * maxd = 0 can make sense */
  111. G_get_window(&window);
  112. x = window.proj;
  113. G_format_resolution(window.ew_res, ewres, x);
  114. G_format_resolution(window.ns_res, nsres, x);
  115. EW_DIST1 =
  116. G_distance(window.east, window.north, window.west, window.north);
  117. /* EW Dist at South Edge */
  118. EW_DIST2 =
  119. G_distance(window.east, window.south, window.west, window.south);
  120. /* NS Dist at East edge */
  121. NS_DIST1 =
  122. G_distance(window.east, window.north, window.east, window.south);
  123. /* NS Dist at West edge */
  124. NS_DIST2 =
  125. G_distance(window.west, window.north, window.west, window.south);
  126. xres = ((EW_DIST1 + EW_DIST2) / 2) / window.cols;
  127. yres = ((NS_DIST1 + NS_DIST2) / 2) / window.rows;
  128. if (xres > yres)
  129. maxd = xres;
  130. else
  131. maxd = yres;
  132. }
  133. /* Look at maps given on command line */
  134. if (vect) {
  135. for (i = 0; vect[i]; i++)
  136. ;
  137. nvects = i;
  138. for (i = 0; opt.field->answers[i]; i++)
  139. ;
  140. if (nvects != i)
  141. G_fatal_error(_("Number of given vector maps (%d) differs from number of layers (%d)"),
  142. nvects, i);
  143. Map = (struct Map_info *) G_malloc(nvects * sizeof(struct Map_info));
  144. field = (int *) G_malloc(nvects * sizeof(int));
  145. for (i = 0; i < nvects; i++) {
  146. level = Vect_open_old2(&Map[i], vect[i], "", opt.field->answers[i]);
  147. if (level < 2)
  148. G_fatal_error(_("You must build topology on vector map <%s>"),
  149. vect[i]);
  150. field[i] = Vect_get_field_number(&Map[i], opt.field->answers[i]);
  151. }
  152. }
  153. if (strcmp(opt.coords->answer, "-") == 0) {
  154. /* read them from stdin */
  155. setvbuf(stdin, NULL, _IOLBF, 0);
  156. setvbuf(stdout, NULL, _IOLBF, 0);
  157. while (fgets(buf, sizeof(buf), stdin) != NULL) {
  158. ret = sscanf(buf, "%lf%c%lf", &xval, &ch, &yval);
  159. if (ret == 3 && (ch == ',' || ch == ' ' || ch == '\t')) {
  160. what(Map, nvects, vect, xval, yval, maxd, type, flag.topo->answer,
  161. flag.print->answer, flag.shell->answer, flag.json->answer, field);
  162. }
  163. else {
  164. G_warning(_("Unknown input format, skipping: '%s'"), buf);
  165. continue;
  166. }
  167. }
  168. }
  169. else {
  170. /* use coords given on command line */
  171. for (i = 0; opt.coords->answers[i] != NULL; i += 2) {
  172. xval = atof(opt.coords->answers[i]);
  173. yval = atof(opt.coords->answers[i + 1]);
  174. what(Map, nvects, vect, xval, yval, maxd, type, flag.topo->answer,
  175. flag.print->answer, flag.shell->answer, flag.json->answer, field);
  176. }
  177. }
  178. for (i = 0; i < nvects; i++)
  179. Vect_close(&Map[i]);
  180. exit(EXIT_SUCCESS);
  181. }