/* *************************************************************** * * * * MODULE: v.digit * * * * AUTHOR(S): Radim Blazek * * * * PURPOSE: Edit vector * * * * COPYRIGHT: (C) 2001 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 "global.h" #include "proto.h" struct symb { char *name; int code; int r, g, b; /* default colors */ }; struct symb default_symb_table[] = { { "background", SYMB_BACKGROUND, 255, 255, 255 }, /* white */ { "highlight", SYMB_HIGHLIGHT, 255, 255, 0 }, /* yellow */ { "point", SYMB_POINT, 0, 0, 0 }, /* black */ { "line", SYMB_LINE, 0, 0, 0 }, /* black */ { "boundary_0", SYMB_BOUNDARY_0, 153, 153, 153 }, /* grey */ { "boundary_1", SYMB_BOUNDARY_1, 255, 125, 0 }, /* orange */ { "boundary_2", SYMB_BOUNDARY_2, 0, 255, 0 }, /* green */ { "centroid_in", SYMB_CENTROID_IN, 0 , 0, 153 }, /* dark blue */ { "centroid_out", SYMB_CENTROID_OUT, 153, 153, 0 }, /* mustard */ { "centroid_dupl", SYMB_CENTROID_DUPL, 255, 0, 255 }, /* magenta */ { "node_1", SYMB_NODE_1, 255, 0, 0 }, /* red */ { "node_2", SYMB_NODE_2, 0, 153, 0 }, /* dark green */ { "", 0, 0, 0, 0 } }; /* Convert symbology name to code */ int get_symb_code ( char *name ) { int i; G_debug ( 2, "get_symb_code(): name = %s", name ); for ( i = 0; default_symb_table[i].name[0] ; i++ ) { if ( strcmp ( name, default_symb_table[i].name ) == 0 ) { G_debug ( 2, "-> code = %d", default_symb_table[i].code ); return ( default_symb_table[i].code ) ; } } G_warning ( "get_symb_code(): symbol name %s does not exist", name ); return (-1); } /* Returns pointer to symbology name */ char * get_symb_name ( int code ) { G_debug ( 2, "get_symb_name(): code = %d", code ); G_debug ( 2, "-> name = %s", default_symb_table[code].name ); return ( default_symb_table[code].name ) ; } /* Init symbology: set defaults */ void symb_init ( void ) { int i, code; for ( i = 0; default_symb_table[i].name[0]; i++ ) { code = default_symb_table[i].code; Symb[code].on = 1; Symb[code].r = default_symb_table[i].r; Symb[code].g = default_symb_table[i].g; Symb[code].b = default_symb_table[i].b; } } /* Synchronize GUI */ void symb_init_gui ( void ) { int i, code; for ( i = 0; default_symb_table[i].name[0]; i++ ) { code = get_symb_code ( default_symb_table[i].name ); i_set_color ( default_symb_table[i].name, Symb[code].r, Symb[code].g, Symb[code].b ); i_set_on ( default_symb_table[i].name, Symb[code].on); } } /* Set driver color */ void symb_set_driver_color ( int code ) { G_debug ( 2, "set color to symb %d: %d %d %d", code, Symb[code].r, Symb[code].g, Symb[code].b ); R_reset_color ( Symb[code].r, Symb[code].g, Symb[code].b, MAX_COLOR_NUM + 1); R_color( MAX_COLOR_NUM + 1 ) ; } /* --- LINES --- */ /* Get line symbology from map */ int symb_line_from_map ( int line ) { int type, area1, area2, nareas; G_debug ( 2, "line_symb_from_map(): line = %d", line ); type = Vect_read_line ( &Map, NULL, NULL, line); switch ( type ) { case GV_POINT: return SYMB_POINT; case GV_LINE: return SYMB_LINE; case GV_BOUNDARY: nareas = 0; Vect_get_line_areas ( &Map, line, &area1, &area2 ); /* Count areas/isles on both sides */ if ( area1 != 0 ) nareas++; if ( area2 != 0 ) nareas++; G_debug ( 2, " boundary = %d nareas = %d", line, nareas ); if ( nareas == 0 ) return SYMB_BOUNDARY_0; else if ( nareas == 1 ) return SYMB_BOUNDARY_1; else return SYMB_BOUNDARY_2; case GV_CENTROID: area1 = Vect_get_centroid_area ( &Map, line ); G_debug ( 2, " centroid = %d area = %d", line, area1 ); if ( area1 == 0 ) return SYMB_CENTROID_OUT; else if ( area1 > 0 ) return SYMB_CENTROID_IN; else return SYMB_CENTROID_DUPL; /* area1 < 0 */ } /* Should not be reached */ return SYMB_HIGHLIGHT; } /* Init line symbology table */ void symb_lines_init ( void ) { int i; G_debug ( 2, "symb_line_init()" ); /* Lines */ aLineSymb = Vect_get_num_lines ( &Map ) + 1000; /* allocated space */ LineSymb = (int *) G_malloc ( (aLineSymb + 1) * sizeof(int) ); for ( i = 1; i <= Vect_get_num_lines(&Map); i++ ) LineSymb[i] = symb_line_from_map ( i ); } /* Set symbology for existing or new line */ void symb_line_set_from_map ( int line ) { G_debug (2, "line_symb_refresh()" ); if ( line > aLineSymb ) { aLineSymb = line + 1000; LineSymb = (int *) G_realloc ( LineSymb, (aLineSymb + 1) * sizeof(int) ); } LineSymb[line] = symb_line_from_map ( line ); } /* Update the symbology of lines changed by last write access to the map */ void symb_updated_lines_set_from_map ( void ) { int i, line; G_debug (2, "symb_updated_lines_set_from_map();"); for (i = 0; i < Vect_get_num_updated_lines(&Map); i++ ) { line = Vect_get_updated_line( &Map, i ); if ( !Vect_line_alive ( &Map, line ) ) continue; symb_line_set_from_map ( line ); } } /* --- NODES --- */ /* Get node symbology from map */ int symb_node_from_map ( int node ) { int i, nl, nlines, line, type; nlines = 0; nl = Vect_get_node_n_lines ( &Map, node ); G_debug ( 2, "node = %d nl = %d", node, nl); for ( i = 0; i < nl; i++ ) { line = abs ( Vect_get_node_line ( &Map, node, i ) ); G_debug ( 2, "i = %d line = %d", i, line); if ( !Vect_line_alive ( &Map, line) ) continue; type = Vect_read_line ( &Map, NULL, NULL, line); if ( type & GV_LINES ) nlines++; } G_debug ( 2, "node = %d nlines = %d", node, nlines); if ( nlines == 0 ) return SYMB_NODE_0; else if ( nlines == 1 ) return SYMB_NODE_1; else return SYMB_NODE_2; } /* Add node symbology for new lines if necessary */ void symb_node_set_from_map ( int node ) { G_debug (2, "line_symb_refresh()" ); if ( node > aNodeSymb ) { aNodeSymb = node + 1000; NodeSymb = (int *) G_realloc ( NodeSymb, (aNodeSymb + 1) * sizeof(int) ); } NodeSymb[node] = symb_node_from_map ( node ); } /* Init node symbology table */ void symb_nodes_init ( void ) { int i; G_debug (2, "symb_node_init()" ); /* Nodes */ aNodeSymb = Vect_get_num_nodes(&Map) + 1000; /* allocated space */ NodeSymb = (int *) G_malloc ( (aNodeSymb + 1) * sizeof(int) ); for ( i = 1; i <= Vect_get_num_nodes(&Map); i++ ) NodeSymb[i] = symb_node_from_map ( i ); } /* Update the symbology of nodes changed by last write access to the map */ void symb_updated_nodes_set_from_map ( void ) { int i, node; G_debug (2, "node_update();"); for ( i = 0; i < Vect_get_num_updated_nodes(&Map); i++ ) { node = Vect_get_updated_node( &Map, i ); if ( !Vect_node_alive ( &Map, node ) ) continue; symb_node_set_from_map ( node ); } } void updated_lines_and_nodes_erase_refresh_display ( void ) { /* Note: this is a problem if new line is point, and there is a raster on the background, its displays * (erase) node over the raster, which is a bit confusing */ display_updated_nodes ( SYMB_BACKGROUND ); /* because the size/shape may decrease for new symbol */ symb_updated_lines_set_from_map(); symb_updated_nodes_set_from_map(); display_updated_nodes ( SYMB_DEFAULT ); display_updated_lines ( SYMB_DEFAULT ); }