/* **************************************************************************** * * MODULE: d.vect * AUTHOR(S): CERL, Radim Blazek, others * PURPOSE: Display the binary vector (dig) file that the user wants displayed * on top of the current image. * COPYRIGHT: (C) 2004-2006 by the GRASS Development Team * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "plot.h" #include #include #include "local_proto.h" #include /* adopted from r.colors */ static char *icon_files(void) { char *list = NULL, path[4096], path_i[4096]; size_t len = 0, l; DIR *dir, *dir_i; struct dirent *d, *d_i; sprintf(path, "%s/etc/symbol", G_gisbase()); dir = opendir(path); if (!dir) return NULL; /*loop over etc/symbol*/ while ((d = readdir(dir))) { if (d->d_name[0] == '.') continue; sprintf(path_i, "%s/etc/symbol/%s", G_gisbase(), d->d_name); dir_i = opendir(path_i); if (!dir_i) continue; /*loop over each directory in etc/symbols*/ while((d_i = readdir(dir_i))) { if (d_i->d_name[0] == '.') continue; l = strlen(d->d_name) + strlen(d_i->d_name) + 3; list = G_realloc(list, len + l); sprintf(list+len, "%s/%s,", d->d_name, d_i->d_name); len += l - 1; } closedir(dir_i); } closedir(dir); if(len) list[len-1] = 0; return list; } /* test for background color */ int test_bg_color (const char* colorstring) { int ret_bg, r_bg, g_bg, b_bg; int ret, r, g, b; ret_bg = G_str_to_color (DEFAULT_BG_COLOR, &r_bg, &g_bg, &b_bg); ret = G_str_to_color (colorstring, &r, &g, &b); if (ret == 1 && ret_bg == 1) { if (r == r_bg && g == g_bg && b == b_bg) { return 1; } } return 0; } int main (int argc, char **argv) { char *mapset; int ret, level; int i, stat = 0, type, area, display; int chcat = 0; int color, fcolor, r, g, b; int colornum = MAX_COLOR_NUM; int size; int default_width; double width_scale; int quiet; double minreg, maxreg, reg; char map_name[128] ; struct GModule *module; struct Option *map_opt; struct Option *color_opt, *fcolor_opt, *rgbcol_opt; struct Option *type_opt, *display_opt; struct Option *icon_opt, *size_opt; struct Option *where_opt; struct Option *field_opt, *cat_opt, *lfield_opt; struct Option *lcolor_opt, *bgcolor_opt, *bcolor_opt; struct Option *lsize_opt, *font_opt, *xref_opt, *yref_opt; struct Option *attrcol_opt, *maxreg_opt, *minreg_opt; struct Option *width_opt, *wcolumn_opt, *wscale_opt; struct Flag *quiet_flag, *id_flag, *table_acolors_flag, *cats_acolors_flag, *x_flag; struct cat_list *Clist; int *cats, ncat; LATTR lattr; struct Map_info Map; struct field_info *fi; dbDriver *driver; dbHandle handle; struct Cell_head window; BOUND_BOX box; double overlap; SYMBOL *Symb; module = G_define_module(); module->keywords = _("display"); module->description = _("Displays GRASS vector data in the active frame on the " "graphics monitor."); map_opt = G_define_standard_option(G_OPT_V_MAP); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->answer = "point,line,boundary,centroid,area,face" ; type_opt->options = "point,line,boundary,centroid,area,face" ; display_opt = G_define_option() ; display_opt->key = "display" ; display_opt->type = TYPE_STRING ; display_opt->required = NO ; display_opt->multiple = YES ; display_opt->answer = "shape" ; display_opt->options = "shape,cat,topo,dir,attr,zcoor"; display_opt->description= _("Display"); attrcol_opt = G_define_option() ; attrcol_opt->key = "attrcol" ; attrcol_opt->type = TYPE_STRING ; attrcol_opt->required = NO ; attrcol_opt->multiple = NO ; /* or fix attr.c, around line 102 */ attrcol_opt->description= _("Name of column to be displayed"); icon_opt = G_define_option() ; icon_opt->key = "icon" ; icon_opt->type = TYPE_STRING ; icon_opt->required = NO ; icon_opt->multiple = NO ; icon_opt->answer = "basic/x" ; /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */ icon_opt->options = icon_files(); icon_opt->description= _("Point and centroid symbol"); size_opt = G_define_option() ; size_opt->key = "size" ; size_opt->type = TYPE_INTEGER ; size_opt->answer = "8" ; size_opt->description= _("Icon size"); field_opt = G_define_standard_option(G_OPT_V_FIELD) ; field_opt->description= _("Layer number. If -1, all layers are displayed."); cat_opt = G_define_standard_option(G_OPT_V_CATS) ; where_opt = G_define_standard_option(G_OPT_WHERE) ; width_opt = G_define_option() ; width_opt->key = "width"; width_opt->type = TYPE_INTEGER ; width_opt->answer = "0" ; width_opt->description= _("Line width"); wcolumn_opt = G_define_option() ; wcolumn_opt->key = "wcolumn" ; wcolumn_opt->type = TYPE_STRING ; wcolumn_opt->description= _("Name of column for line widths (these values will be scaled by wscale)"); wscale_opt = G_define_option() ; wscale_opt->key = "wscale" ; wscale_opt->type = TYPE_DOUBLE ; wscale_opt->answer = "1" ; wscale_opt->description= _("Scale factor for wcolumn"); color_opt = G_define_option() ; color_opt->key = "color" ; color_opt->type = TYPE_STRING ; color_opt->answer = DEFAULT_FG_COLOR; color_opt->description= _("Line color"); color_opt->gisprompt = GISPROMPT_COLOR; fcolor_opt = G_define_option() ; fcolor_opt->key = "fcolor" ; fcolor_opt->type = TYPE_STRING ; fcolor_opt->answer = "200:200:200" ; fcolor_opt->description= _("Area fill color"); fcolor_opt->gisprompt = GISPROMPT_COLOR; rgbcol_opt = G_define_option(); rgbcol_opt->key = "rgb_column"; rgbcol_opt->type = TYPE_STRING ; rgbcol_opt->required = NO ; rgbcol_opt->multiple = NO ; rgbcol_opt->description= _("Name of color definition column (for use with -a flag)"); rgbcol_opt->answer = "GRASSRGB" ; lfield_opt = G_define_standard_option(G_OPT_V_FIELD) ; lfield_opt->key = "llayer" ; lfield_opt->description= "Layer for labels" ; lcolor_opt = G_define_option() ; lcolor_opt->key = "lcolor" ; lcolor_opt->type = TYPE_STRING ; lcolor_opt->answer = "red" ; lcolor_opt->description= _("Label color"); lcolor_opt->gisprompt = GISPROMPT_COLOR; bgcolor_opt = G_define_option() ; bgcolor_opt->key = "bgcolor" ; bgcolor_opt->type = TYPE_STRING ; bgcolor_opt->answer = "none" ; bgcolor_opt->description= _("Label background color"); bgcolor_opt->gisprompt = GISPROMPT_COLOR; bcolor_opt = G_define_option() ; bcolor_opt->key = "bcolor" ; bcolor_opt->type = TYPE_STRING ; bcolor_opt->answer = "none" ; bcolor_opt->description= _("Label border color"); bcolor_opt->gisprompt = GISPROMPT_COLOR; lsize_opt = G_define_option() ; lsize_opt->key = "lsize" ; lsize_opt->type = TYPE_INTEGER ; lsize_opt->answer = "8" ; lsize_opt->description= _("Label size (pixels)"); font_opt = G_define_option() ; font_opt->key = "font" ; font_opt->type = TYPE_STRING ; font_opt->answer = "romans" ; font_opt->options = "cyrilc,gothgbt,gothgrt,gothitt," "greekc,greekcs,greekp,greeks,italicc,italiccs,italict," "romanc,romancs,romand,romans,romant,scriptc,scripts" ; font_opt->description= _("Font name"); xref_opt = G_define_option() ; xref_opt->key = "xref" ; xref_opt->type = TYPE_STRING ; xref_opt->answer = "left" ; xref_opt->options = "left,center,right"; xref_opt->description= _("Label horizontal justification"); yref_opt = G_define_option() ; yref_opt->key = "yref" ; yref_opt->type = TYPE_STRING ; yref_opt->answer = "center" ; yref_opt->options = "top,center,bottom"; yref_opt->description= _("Label vertical justification"); minreg_opt = G_define_option() ; minreg_opt->key = "minreg" ; minreg_opt->type = TYPE_DOUBLE ; minreg_opt->required = NO ; minreg_opt->description= _("Minimum region size (average from height and width) " "when map is displayed"); maxreg_opt = G_define_option() ; maxreg_opt->key = "maxreg" ; maxreg_opt->type = TYPE_DOUBLE ; maxreg_opt->required = NO ; maxreg_opt->description= _("Maximum region size (average from height and width) " "when map is displayed"); quiet_flag = G_define_flag (); quiet_flag->key = 'v'; quiet_flag->description = _("Run verbosely"); table_acolors_flag = G_define_flag (); table_acolors_flag->key = 'a'; table_acolors_flag->description = _("Get colors from map table column (of form RRR:GGG:BBB)"); cats_acolors_flag = G_define_flag (); cats_acolors_flag->key = 'c'; cats_acolors_flag->description = _("Random colors according to category number (or layer number if 'layer=-1' is given)"); id_flag = G_define_flag (); id_flag->key = 'i'; id_flag->description = _("Use values from 'cats' option as line ID"); x_flag = G_define_flag (); x_flag->key = 'x'; x_flag->description = _("Don't add to list of vectors and commands in monitor (it won't be drawn if the monitor is refreshed)"); /* Initialize the GIS calls */ G_gisinit(argv[0]) ; /* Check command line */ if (G_parser(argc, argv)) exit(-1); G_get_set_window (&window); if (R_open_driver() != 0) G_fatal_error(_("No graphics device selected")); /* Read map options */ /* Check min/max region */ reg = ((window.east - window.west) + (window.north - window.south)) / 2; if ( minreg_opt->answer ) { minreg = atof ( minreg_opt->answer ); if ( reg < minreg ) { fprintf ( stdout, _("Region size is lower than minreg, nothing displayed.\n")); D_add_to_list(G_recreate_command()) ; exit (0); } } if ( maxreg_opt->answer ) { maxreg = atof ( maxreg_opt->answer ); if ( reg > maxreg ) { fprintf ( stdout, _("Region size is greater than maxreg, nothing displayed.\n")); D_add_to_list(G_recreate_command()) ; exit (0); } } strcpy(map_name, map_opt->answer); default_width = atoi(width_opt->answer); if( default_width < 0 ) default_width = 0; width_scale = atof(wscale_opt->answer); color = WHITE; /* test for background color */ if (test_bg_color (color_opt->answer)) { G_warning (_("Line color and background color are the same!")); } ret = G_str_to_color(color_opt->answer, &r, &g, &b); if ( ret == 1 ) { colornum++; R_reset_color (r, g, b, colornum); color = colornum; } else if ( ret == 2 ) { /* none */ color = -1; } else if ( ret == 0 ) { /* error */ G_fatal_error(_("Unknown color: [%s]"), color_opt->answer); } fcolor = WHITE; /* test for background color */ if (test_bg_color (fcolor_opt->answer)) { G_warning (_("Area fill color and background color are the same!")); } ret = G_str_to_color(fcolor_opt->answer, &r, &g, &b); if ( ret == 1 ) { colornum++; R_reset_color (r, g, b, colornum); fcolor = colornum; } else if ( ret == 2 ) { /* none */ fcolor = -1; } else if ( ret == 0 ) { /* error */ G_fatal_error(_("Unknown color: [%s]"), fcolor_opt->answer); } quiet = !quiet_flag->answer; size = atoi (size_opt->answer); Symb = S_read ( icon_opt->answer ); if ( Symb == NULL ) G_warning(_("Cannot read symbol, cannot display points")); else S_stroke ( Symb, size, 0.0, 0 ); /* Make sure map is available */ mapset = G_find_vector2 (map_name, "") ; if (mapset == NULL) G_fatal_error(_("Vector file [%s] not available"), map_name) ; /* if where_opt was specified select categories from db * otherwise parse cat_opt */ Clist = Vect_new_cat_list (); Clist->field = atoi (field_opt->answer); /* open vector */ level = Vect_open_old (&Map, map_name, mapset); if (where_opt->answer) { if ( Clist->field < 1 ) G_fatal_error(_("'layer' must be > 0 for 'where'.")); chcat = 1; if ( (fi = Vect_get_field ( &Map, Clist->field)) == NULL) G_fatal_error(_("Database connection not defined")); if ( fi != NULL ) { driver = db_start_driver(fi->driver); if (driver == NULL) G_fatal_error(_("Cannot open driver %s"), fi->driver) ; db_init_handle (&handle); db_set_handle (&handle, fi->database, NULL); if (db_open_database(driver, &handle) != DB_OK) G_fatal_error(_("Cannot open database %s"), fi->database) ; ncat = db_select_int( driver, fi->table, fi->key, where_opt->answer, &cats); db_close_database(driver); db_shutdown_driver(driver); Vect_array_to_cat_list ( cats, ncat, Clist); } } else if (cat_opt->answer) { if ( Clist->field < 1 ) G_fatal_error(_("'layer' must be > 0 for 'cats'.")); chcat = 1; ret = Vect_str_to_cat_list ( cat_opt->answer, Clist); if ( ret > 0 ) G_warning (_("%d errors in cat option"), ret); } i = 0; type = 0; area = FALSE; while (type_opt->answers[i]) { switch ( type_opt->answers[i][0] ) { case 'p': type |= GV_POINT; break; case 'l': type |= GV_LINE; break; case 'b': type |= GV_BOUNDARY; break; case 'f': type |= GV_FACE; break; case 'c': type |= GV_CENTROID; break; case 'a': area = TRUE; break; } i++; } i = 0; display = 0; while (display_opt->answers[i]) { switch ( display_opt->answers[i][0] ) { case 's': display |= DISP_SHAPE; break; case 'c': display |= DISP_CAT; break; case 't': display |= DISP_TOPO; break; case 'd': display |= DISP_DIR; break; case 'a': display |= DISP_ATTR; break; case 'z': display |= DISP_ZCOOR; break; } i++; } /* Read label options */ lattr.field = atoi (lfield_opt->answer); lattr.color = WHITE; if ( G_str_to_color(lcolor_opt->answer, &r, &g, &b) ) { colornum++; R_reset_color (r, g, b, colornum); lattr.color = colornum; } lattr.bgcolor = 0; if ( G_str_to_color(bgcolor_opt->answer, &r, &g, &b) == 1 ) { colornum++; R_reset_color (r, g, b, colornum); lattr.bgcolor = colornum; } lattr.bcolor = 0; if ( G_str_to_color(bcolor_opt->answer, &r, &g, &b) == 1 ) { colornum++; R_reset_color (r, g, b, colornum); lattr.bcolor = colornum; } lattr.size = atoi(lsize_opt->answer); lattr.font = font_opt->answer; switch ( xref_opt->answer[0] ) { case 'l': lattr.xref = LLEFT; break; case 'c': lattr.xref = LCENTER; break; case 'r': lattr.xref = LRIGHT; break; } switch ( yref_opt->answer[0] ) { case 't': lattr.yref = LTOP; break; case 'c': lattr.yref = LCENTER; break; case 'b': lattr.yref = LBOTTOM; break; } D_setup(0); G_setup_plot (D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east(), D_move_abs, D_cont_abs); if (!quiet) fprintf (stdout,_("Plotting ... ")); fflush (stdout); if ( level >= 2 ) Vect_get_map_box ( &Map, &box ); if ( level >= 2 && ( window.north < box.S || window.south > box.N || window.east < box.W || window.west > G_adjust_easting(box.E, &window) ) ) { G_message(_("The bounding box of the map is outside the current region, nothing drawn.")); stat = 0; } else { overlap = G_window_percentage_overlap(&window, box.N, box.S, box.E, box.W); G_debug ( 1, "overlap = %f \n", overlap ); if ( overlap < 1 ) Vect_set_constraint_region (&Map, window.north, window.south, window.east, window.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX); /* default line width */ if ( !wcolumn_opt->answer ) R_line_width(default_width); if ( area ) { if ( level >= 2 ) { stat = darea ( &Map, Clist, color, fcolor, chcat, (int) id_flag->answer, table_acolors_flag->answer, cats_acolors_flag->answer, &window, rgbcol_opt->answer, default_width, wcolumn_opt->answer, width_scale ); if ( wcolumn_opt->answer ) R_line_width(default_width); } else G_warning(_("Cannot display areas, topology not available")); } if ( display & DISP_SHAPE ) { if ( id_flag->answer && level < 2 ) { G_warning(_("Cannot display lines by id, topology not available")); } else { stat = plot1 ( &Map, type, area, Clist, color, fcolor, chcat, Symb, size, (int) id_flag->answer, table_acolors_flag->answer, cats_acolors_flag->answer, rgbcol_opt->answer, default_width, wcolumn_opt->answer, width_scale) ; if ( wcolumn_opt->answer ) R_line_width(default_width); } } if ( color > -1 ) { R_color(color); if ( display & DISP_DIR ) stat = dir ( &Map, type, Clist, chcat ); } /* reset line width: Do we need to get line width from display * driver (not implemented)? It will help restore previous line * width (not just 0) determined by another module (e.g., * d.linewidth). */ if ( !wcolumn_opt->answer ) R_line_width(0); if ( display & DISP_CAT ) stat = label ( &Map, type, area, Clist, &lattr, chcat); if ( display & DISP_ATTR ) stat = attr ( &Map, type, attrcol_opt->answer, Clist, &lattr, chcat); if ( display & DISP_ZCOOR ) stat = zcoor ( &Map, type, &lattr); if ( display & DISP_TOPO ) { if (level >= 2 ) stat = topo ( &Map, type, area, &lattr); else G_warning(_("Cannot display topology, not available")); } } if ( !x_flag->answer ) { D_add_to_list(G_recreate_command()) ; D_set_dig_name(G_fully_qualified_name(map_name, mapset)); D_add_to_dig_list(G_fully_qualified_name(map_name, mapset)); } R_close_driver(); if (!quiet) fprintf (stdout,_("Done\n")); Vect_close (&Map); Vect_destroy_cat_list (Clist); exit(stat); }