main.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: d.vect
  5. * AUTHOR(S): CERL, Radim Blazek, others
  6. * Updated to GRASS7 by Martin Landa <landa.martin gmail.com>
  7. * PURPOSE: Display the vector map in map display
  8. * COPYRIGHT: (C) 2004-2009, 2011 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General
  11. * Public License (>=v2). Read the file COPYING that
  12. * comes with GRASS for details.
  13. *
  14. *****************************************************************************/
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/types.h>
  18. #include <dirent.h>
  19. #include <grass/gis.h>
  20. #include <grass/raster.h>
  21. #include <grass/display.h>
  22. #include <grass/dbmi.h>
  23. #include <grass/glocale.h>
  24. #include "plot.h"
  25. #include "local_proto.h"
  26. /* adopted from r.colors */
  27. static char *icon_files(void)
  28. {
  29. char *list = NULL, path[4096], path_i[4096];
  30. size_t len = 0, l;
  31. DIR *dir, *dir_i;
  32. struct dirent *d, *d_i;
  33. sprintf(path, "%s/etc/symbol", G_gisbase());
  34. dir = opendir(path);
  35. if (!dir)
  36. return NULL;
  37. /*loop over etc/symbol */
  38. while ((d = readdir(dir))) {
  39. if (d->d_name[0] == '.')
  40. continue;
  41. sprintf(path_i, "%s/etc/symbol/%s", G_gisbase(), d->d_name);
  42. dir_i = opendir(path_i);
  43. if (!dir_i)
  44. continue;
  45. /*loop over each directory in etc/symbols */
  46. while ((d_i = readdir(dir_i))) {
  47. if (d_i->d_name[0] == '.')
  48. continue;
  49. l = strlen(d->d_name) + strlen(d_i->d_name) + 3;
  50. list = G_realloc(list, len + l);
  51. sprintf(list + len, "%s/%s,", d->d_name, d_i->d_name);
  52. len += l - 1;
  53. }
  54. closedir(dir_i);
  55. }
  56. closedir(dir);
  57. if (len)
  58. list[len - 1] = 0;
  59. return list;
  60. }
  61. int main(int argc, char **argv)
  62. {
  63. int ret, level;
  64. int stat, type, display;
  65. int chcat;
  66. int has_color, has_fcolor;
  67. struct color_rgb color, fcolor;
  68. double size;
  69. int default_width;
  70. double width_scale;
  71. double minreg, maxreg, reg;
  72. char map_name[GNAME_MAX];
  73. struct GModule *module;
  74. struct Option *map_opt;
  75. struct Option *color_opt, *fcolor_opt, *rgbcol_opt, *zcol_opt;
  76. struct Option *type_opt, *display_opt;
  77. struct Option *icon_opt, *size_opt, *sizecolumn_opt, *rotcolumn_opt;
  78. struct Option *where_opt;
  79. struct Option *field_opt, *cat_opt, *lfield_opt;
  80. struct Option *lcolor_opt, *bgcolor_opt, *bcolor_opt;
  81. struct Option *lsize_opt, *font_opt, *enc_opt, *xref_opt, *yref_opt;
  82. struct Option *attrcol_opt, *maxreg_opt, *minreg_opt;
  83. struct Option *width_opt, *wcolumn_opt, *wscale_opt;
  84. struct Flag *id_flag, *table_acolors_flag, *cats_acolors_flag,
  85. *zcol_flag, *sqrt_flag;
  86. struct cat_list *Clist;
  87. LATTR lattr;
  88. struct Map_info Map;
  89. struct Cell_head window;
  90. struct bound_box box;
  91. double overlap;
  92. stat = 0;
  93. /* Initialize the GIS calls */
  94. G_gisinit(argv[0]);
  95. module = G_define_module();
  96. G_add_keyword(_("display"));
  97. G_add_keyword(_("vector"));
  98. module->description = _("Displays user-specified vector map "
  99. "in the active graphics frame.");
  100. map_opt = G_define_standard_option(G_OPT_V_MAP);
  101. field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
  102. display_opt = G_define_option();
  103. display_opt->key = "display";
  104. display_opt->type = TYPE_STRING;
  105. display_opt->required = YES;
  106. display_opt->multiple = YES;
  107. display_opt->answer = "shape";
  108. display_opt->options = "shape,cat,topo,dir,attr,zcoor";
  109. display_opt->description = _("Display");
  110. display_opt->descriptions = _("shape;Display geometry of features;"
  111. "cat;Display category numbers of features;"
  112. "topo;Display topology information (nodes, edges);"
  113. "dir;Display direction of linear features;"
  114. "attr;Display selected attribute based on 'attrcolumn';"
  115. "zcoor;Display z-coordinate of features (only for 3D vector maps)");
  116. /* Query */
  117. type_opt = G_define_standard_option(G_OPT_V_TYPE);
  118. type_opt->answer = "point,line,boundary,centroid,area,face";
  119. type_opt->options = "point,line,boundary,centroid,area,face";
  120. type_opt->guisection = _("Selection");
  121. cat_opt = G_define_standard_option(G_OPT_V_CATS);
  122. cat_opt->guisection = _("Selection");
  123. where_opt = G_define_standard_option(G_OPT_DB_WHERE);
  124. where_opt->guisection = _("Selection");
  125. /* Colors */
  126. color_opt = G_define_option();
  127. color_opt->key = "color";
  128. color_opt->type = TYPE_STRING;
  129. color_opt->answer = DEFAULT_FG_COLOR;
  130. color_opt->label = _("Line color");
  131. color_opt->guisection = _("Colors");
  132. color_opt->gisprompt = "old_color,color,color_none";
  133. color_opt->description =
  134. _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
  135. fcolor_opt = G_define_option();
  136. fcolor_opt->key = "fcolor";
  137. fcolor_opt->type = TYPE_STRING;
  138. fcolor_opt->answer = "200:200:200";
  139. fcolor_opt->label = _("Area fill color");
  140. fcolor_opt->guisection = _("Colors");
  141. fcolor_opt->gisprompt = "old_color,color,color_none";
  142. fcolor_opt->description =
  143. _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
  144. rgbcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
  145. rgbcol_opt->key = "rgb_column";
  146. rgbcol_opt->guisection = _("Colors");
  147. rgbcol_opt->description = _("Name of color definition column (for use with -a flag)");
  148. zcol_opt = G_define_option();
  149. zcol_opt->key = "zcolor";
  150. zcol_opt->key_desc = "style";
  151. zcol_opt->type = TYPE_STRING;
  152. zcol_opt->required = NO;
  153. zcol_opt->description = _("Type of color table (for use with -z flag)");
  154. zcol_opt->answer = "terrain";
  155. zcol_opt->guisection = _("Colors");
  156. /* Lines */
  157. width_opt = G_define_option();
  158. width_opt->key = "width";
  159. width_opt->type = TYPE_INTEGER;
  160. width_opt->answer = "0";
  161. width_opt->guisection = _("Lines");
  162. width_opt->description = _("Line width");
  163. wcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
  164. wcolumn_opt->key = "width_column";
  165. wcolumn_opt->guisection = _("Lines");
  166. wcolumn_opt->label = _("Name of numeric column containing line width");
  167. wcolumn_opt->description = _("These values will be scaled by width_scale");
  168. wscale_opt = G_define_option();
  169. wscale_opt->key = "width_scale";
  170. wscale_opt->type = TYPE_DOUBLE;
  171. wscale_opt->answer = "1";
  172. wscale_opt->guisection = _("Lines");
  173. wscale_opt->description = _("Scale factor for width_column");
  174. /* Symbols */
  175. icon_opt = G_define_option();
  176. icon_opt->key = "icon";
  177. icon_opt->type = TYPE_STRING;
  178. icon_opt->required = NO;
  179. icon_opt->multiple = NO;
  180. icon_opt->guisection = _("Symbols");
  181. icon_opt->answer = "basic/x";
  182. /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */
  183. icon_opt->options = icon_files();
  184. icon_opt->description = _("Point and centroid symbol");
  185. size_opt = G_define_option();
  186. size_opt->key = "size";
  187. size_opt->type = TYPE_DOUBLE;
  188. size_opt->answer = "5";
  189. size_opt->guisection = _("Symbols");
  190. size_opt->label = _("Symbol size");
  191. size_opt->description =
  192. _("When used with the size_column option this becomes the scale factor");
  193. sizecolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
  194. sizecolumn_opt->key = "size_column";
  195. sizecolumn_opt->guisection = _("Symbols");
  196. sizecolumn_opt->description =
  197. _("Name of numeric column containing symbol size");
  198. rotcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
  199. rotcolumn_opt->key = "rotation_column";
  200. rotcolumn_opt->guisection = _("Symbols");
  201. rotcolumn_opt->label =
  202. _("Name of numeric column containing symbol rotation angle");
  203. rotcolumn_opt->description =
  204. _("Measured in degrees CCW from east");
  205. /* Labels */
  206. lfield_opt = G_define_standard_option(G_OPT_V_FIELD);
  207. lfield_opt->key = "llayer";
  208. lfield_opt->required = NO;
  209. lfield_opt->guisection = _("Labels");
  210. lfield_opt->description =
  211. _("Layer number for labels (default: the given layer number)");
  212. attrcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
  213. attrcol_opt->key = "attrcolumn";
  214. attrcol_opt->multiple = NO; /* or fix attr.c, around line 102 */
  215. attrcol_opt->guisection = _("Labels");
  216. attrcol_opt->description = _("Name of column to be displayed");
  217. lcolor_opt = G_define_option();
  218. lcolor_opt->key = "lcolor";
  219. lcolor_opt->type = TYPE_STRING;
  220. lcolor_opt->answer = "red";
  221. lcolor_opt->label = _("Label color");
  222. lcolor_opt->guisection = _("Labels");
  223. lcolor_opt->gisprompt = "old_color,color,color";
  224. lcolor_opt->description = _("Either a standard color name or R:G:B triplet");
  225. bgcolor_opt = G_define_option();
  226. bgcolor_opt->key = "bgcolor";
  227. bgcolor_opt->type = TYPE_STRING;
  228. bgcolor_opt->answer = "none";
  229. bgcolor_opt->guisection = _("Labels");
  230. bgcolor_opt->label = _("Label background color");
  231. bgcolor_opt->gisprompt = "old_color,color,color_none";
  232. bgcolor_opt->description =
  233. _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
  234. bcolor_opt = G_define_option();
  235. bcolor_opt->key = "bcolor";
  236. bcolor_opt->type = TYPE_STRING;
  237. bcolor_opt->answer = "none";
  238. bcolor_opt->guisection = _("Labels");
  239. bcolor_opt->label = _("Label border color");
  240. bcolor_opt->gisprompt = "old_color,color,color_none";
  241. bcolor_opt->description =
  242. _("Either a standard GRASS color, R:G:B triplet, or \"none\"");
  243. lsize_opt = G_define_option();
  244. lsize_opt->key = "lsize";
  245. lsize_opt->type = TYPE_INTEGER;
  246. lsize_opt->answer = "8";
  247. lsize_opt->guisection = _("Labels");
  248. lsize_opt->description = _("Label size (pixels)");
  249. font_opt = G_define_option();
  250. font_opt->key = "font";
  251. font_opt->type = TYPE_STRING;
  252. font_opt->guisection = _("Labels");
  253. font_opt->description = _("Font name");
  254. enc_opt = G_define_option();
  255. enc_opt->key = "encoding";
  256. enc_opt->type = TYPE_STRING;
  257. enc_opt->guisection = _("Labels");
  258. enc_opt->description = _("Text encoding");
  259. xref_opt = G_define_option();
  260. xref_opt->key = "xref";
  261. xref_opt->type = TYPE_STRING;
  262. xref_opt->guisection = _("Labels");
  263. xref_opt->answer = "left";
  264. xref_opt->options = "left,center,right";
  265. xref_opt->description = _("Label horizontal justification");
  266. yref_opt = G_define_option();
  267. yref_opt->key = "yref";
  268. yref_opt->type = TYPE_STRING;
  269. yref_opt->guisection = _("Labels");
  270. yref_opt->answer = "center";
  271. yref_opt->options = "top,center,bottom";
  272. yref_opt->description = _("Label vertical justification");
  273. minreg_opt = G_define_option();
  274. minreg_opt->key = "minreg";
  275. minreg_opt->type = TYPE_DOUBLE;
  276. minreg_opt->required = NO;
  277. minreg_opt->description =
  278. _("Minimum region size (average from height and width) "
  279. "when map is displayed");
  280. maxreg_opt = G_define_option();
  281. maxreg_opt->key = "maxreg";
  282. maxreg_opt->type = TYPE_DOUBLE;
  283. maxreg_opt->required = NO;
  284. maxreg_opt->description =
  285. _("Maximum region size (average from height and width) "
  286. "when map is displayed");
  287. /* Colors */
  288. table_acolors_flag = G_define_flag();
  289. table_acolors_flag->key = 'a';
  290. table_acolors_flag->guisection = _("Colors");
  291. table_acolors_flag->description =
  292. _("Get colors from color table or attribute column (see 'rgb_column')");
  293. cats_acolors_flag = G_define_flag();
  294. cats_acolors_flag->key = 'c';
  295. cats_acolors_flag->guisection = _("Colors");
  296. cats_acolors_flag->description =
  297. _("Random colors according to category number "
  298. "(or layer number if 'layer=-1' is given)");
  299. /* Query */
  300. id_flag = G_define_flag();
  301. id_flag->key = 'i';
  302. id_flag->guisection = _("Selection");
  303. id_flag->description = _("Use values from 'cats' option as feature id");
  304. zcol_flag = G_define_flag();
  305. zcol_flag->key = 'z';
  306. zcol_flag->description = _("Colorize features according to z-coordinate (only for 3D vector maps)");
  307. zcol_flag->guisection = _("Colors");
  308. sqrt_flag = G_define_flag();
  309. sqrt_flag->key = 'r';
  310. sqrt_flag->label = _("Use square root of the value of size_column");
  311. sqrt_flag->description =
  312. _("This makes circle areas proportionate to the size_column values "
  313. "instead of circle radius");
  314. sqrt_flag->guisection = _("Symbols");
  315. /* Check command line */
  316. if (G_parser(argc, argv))
  317. exit(EXIT_FAILURE);
  318. if (D_open_driver() != 0)
  319. G_fatal_error(_("No graphics device selected. "
  320. "Use d.mon to select graphics device."));
  321. G_get_set_window(&window);
  322. /* Check min/max region */
  323. reg = ((window.east - window.west) + (window.north - window.south)) / 2;
  324. if (minreg_opt->answer) {
  325. minreg = atof(minreg_opt->answer);
  326. if (reg < minreg) {
  327. G_important_message(_("Region size is lower than minreg, nothing displayed"));
  328. exit(EXIT_SUCCESS);
  329. }
  330. }
  331. if (maxreg_opt->answer) {
  332. maxreg = atof(maxreg_opt->answer);
  333. if (reg > maxreg) {
  334. G_important_message(_("Region size is greater than maxreg, nothing displayed"));
  335. exit(EXIT_SUCCESS);
  336. }
  337. }
  338. strcpy(map_name, map_opt->answer);
  339. default_width = atoi(width_opt->answer);
  340. if (default_width < 0)
  341. default_width = 0;
  342. width_scale = atof(wscale_opt->answer);
  343. if (table_acolors_flag->answer && cats_acolors_flag->answer) {
  344. cats_acolors_flag->answer = '\0';
  345. G_warning(_("The '-c' and '-a' flags cannot be used together, "
  346. "the '-c' flag will be ignored!"));
  347. }
  348. color = G_standard_color_rgb(WHITE);
  349. has_color = option_to_color(&color, color_opt->answer);
  350. fcolor = G_standard_color_rgb(WHITE);
  351. has_fcolor = option_to_color(&fcolor, fcolor_opt->answer);
  352. size = atof(size_opt->answer);
  353. /* if where_opt was specified select categories from db
  354. * otherwise parse cat_opt */
  355. Clist = Vect_new_cat_list();
  356. Clist->field = atoi(field_opt->answer);
  357. /* open vector */
  358. level = Vect_open_old2(&Map, map_name, "", field_opt->answer);
  359. chcat = 0;
  360. if (where_opt->answer) {
  361. if (Clist->field < 1)
  362. G_fatal_error(_("Option <%s> must be > 0"), field_opt->key);
  363. chcat = 1;
  364. option_to_where(&Map, Clist, where_opt->answer);
  365. }
  366. else if (cat_opt->answer) {
  367. if (Clist->field < 1)
  368. G_fatal_error(_("Option <%s> must be > 0"), field_opt->key);
  369. chcat = 1;
  370. ret = Vect_str_to_cat_list(cat_opt->answer, Clist);
  371. if (ret > 0)
  372. G_warning(_("%d errors in cat option"), ret);
  373. }
  374. type = Vect_option_to_types(type_opt);
  375. display = option_to_display(display_opt);
  376. /* labels */
  377. options_to_lattr(&lattr, lfield_opt->answer,
  378. lcolor_opt->answer, bgcolor_opt->answer, bcolor_opt->answer,
  379. atoi(lsize_opt->answer), font_opt->answer, enc_opt->answer,
  380. xref_opt->answer, yref_opt->answer);
  381. D_setup(0);
  382. D_set_reduction(1.0);
  383. G_verbose_message(_("Plotting..."));
  384. if (level >= 2)
  385. Vect_get_map_box(&Map, &box);
  386. if (level >= 2 && (window.north < box.S || window.south > box.N ||
  387. window.east < box.W ||
  388. window.west > G_adjust_easting(box.E, &window))) {
  389. G_message(_("The bounding box of the map is outside the current region, "
  390. "nothing drawn"));
  391. exit(EXIT_SUCCESS);
  392. }
  393. else {
  394. overlap = G_window_percentage_overlap(&window, box.N, box.S,
  395. box.E, box.W);
  396. G_debug(1, "overlap = %f \n", overlap);
  397. if (overlap < 1)
  398. Vect_set_constraint_region(&Map, window.north, window.south,
  399. window.east, window.west,
  400. PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX);
  401. /* default line width */
  402. if (!wcolumn_opt->answer)
  403. D_line_width(default_width);
  404. if (display & DISP_SHAPE) {
  405. stat += display_shape(&Map, type, Clist, &window,
  406. has_color ? &color : NULL, has_fcolor ? &fcolor : NULL, chcat,
  407. icon_opt->answer, size, sizecolumn_opt->answer,
  408. sqrt_flag->answer ? 1 : 0, rotcolumn_opt->answer,
  409. id_flag->answer ? 1 : 0, table_acolors_flag->answer ? 1 : 0,
  410. cats_acolors_flag->answer ? 1 : 0, rgbcol_opt->answer,
  411. default_width, wcolumn_opt->answer, width_scale,
  412. zcol_flag->answer ? 1 : 0, zcol_opt->answer);
  413. if (wcolumn_opt->answer)
  414. D_line_width(default_width);
  415. }
  416. if (has_color) {
  417. D_RGB_color(color.r, color.g, color.b);
  418. if (display & DISP_DIR)
  419. stat += display_dir(&Map, type, Clist, chcat);
  420. }
  421. /* reset line width: Do we need to get line width from display
  422. * driver (not implemented)? It will help restore previous line
  423. * width (not just 0) determined by another module (e.g.,
  424. * d.linewidth). */
  425. if (!wcolumn_opt->answer)
  426. D_line_width(0);
  427. if (display & DISP_CAT)
  428. stat += display_label(&Map, type, Clist, &lattr, chcat);
  429. if (display & DISP_ATTR)
  430. stat += display_attr(&Map, type, attrcol_opt->answer, Clist, &lattr, chcat);
  431. if (display & DISP_ZCOOR)
  432. stat += display_zcoor(&Map, type, &lattr);
  433. if (display & DISP_TOPO)
  434. stat += display_topo(&Map, type, &lattr);
  435. }
  436. D_save_command(G_recreate_command());
  437. D_close_driver();
  438. Vect_close(&Map);
  439. Vect_destroy_cat_list(Clist);
  440. if (stat != 0) {
  441. G_fatal_error(_("Rendering failed"));
  442. }
  443. G_done_msg(" ");
  444. exit(EXIT_SUCCESS);
  445. }