#define MAIN #include #include #include #include #include #include #include "global.h" /* * Attributes for lines are ignored. For points and area by default unique new * category is assigned to each and raster value is written to 'value' column. * Labels are written to 'label' column if exists. If value flag (-v) is used * and type is CELL, raster values are used as categories. */ int main (int argc, char *argv[]) { struct GModule *module; struct Option *in_opt, *out_opt, *feature_opt; struct Flag *smooth_flg, *value_flg, *z_flg, *quiet, *no_topol; char *mapset; int feature; G_gisinit (argv[0]); module = G_define_module(); module->keywords = _("raster"); module->description = _("Converts a raster map into a vector map layer."); in_opt = G_define_option(); in_opt->key = "input"; in_opt->type = TYPE_STRING; in_opt->required = YES; in_opt->multiple = NO; in_opt->gisprompt = "old,cell,raster"; in_opt->description = _("raster input file"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); feature_opt = G_define_option(); feature_opt->key = "feature"; feature_opt->type = TYPE_STRING; feature_opt->required = YES; feature_opt->multiple = NO; feature_opt->options = "point,line,area"; feature_opt->answer = "line"; feature_opt->description = _("Feature type"); smooth_flg = G_define_flag(); smooth_flg->key = 's'; smooth_flg->description = _("Smooth Corners"); value_flg = G_define_flag(); value_flg->key = 'v'; value_flg->description = _("Use raster values as categories instead of unique sequence (CELL only)"); z_flg = G_define_flag(); z_flg->key = 'z'; z_flg->description = _("Write raster values as z coordinate. Table is not created. " "Currently supported only for points"); no_topol = G_define_flag(); no_topol->key = 'b'; no_topol->description = _("Do not build vector topology (use with care for massive point export)"); quiet = G_define_flag(); quiet->key = 'q'; quiet->description = _("Quiet - Do not show progress"); if (G_parser (argc, argv)) exit(EXIT_FAILURE); feature = Vect_option_to_types ( feature_opt ); smooth_flag = (smooth_flg->answer) ? SMOOTH : NO_SMOOTH; value_flag = value_flg->answer; if (z_flg->answer && (feature != GV_POINT)) G_fatal_error (_("z flag is supported only for points")); /* Open files */ if ( (mapset = G_find_cell(in_opt->answer,"")) == NULL ) G_fatal_error (_("Raster '%s' not found"), in_opt->answer); if ( (input_fd = G_open_cell_old(in_opt->answer,mapset)) < 0 ) G_fatal_error (_("Could not open raster '%s'"), in_opt->answer); data_type = G_raster_map_type(in_opt->answer,mapset); data_size = G_raster_size(data_type); G_get_window(&cell_head); if ( value_flag && data_type != CELL_TYPE ) { G_warning (_("Raster is not CELL, '-v' flag ignored, raster values will be written to the table.")); value_flag = 0; } if (z_flg->answer) Vect_open_new (&Map, out_opt->answer, 1); else Vect_open_new (&Map, out_opt->answer, 0); Vect_hist_command ( &Map ); Cats = Vect_new_cats_struct (); /* Open category labels */ if (data_type == CELL_TYPE) { if (0 == G_read_cats(in_opt->answer, mapset, &RastCats)) has_cats = 1; } else has_cats = 0; db_init_string (&sql); db_init_string (&label); /* Create table */ if ( (feature & (GV_AREA | GV_POINT)) && (!value_flag || (value_flag && has_cats)) && !(z_flg->answer) ) { char buf[1000]; Fi = Vect_default_field_info ( &Map, 1, NULL, GV_1TABLE ); Vect_map_add_dblink ( &Map, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver); driver = db_start_driver_open_database ( Fi->driver, Fi->database ); if ( driver == NULL ) G_fatal_error (_("Cannot open database %s by driver %s"), Fi->database, Fi->driver ); /* Create new table */ db_zero_string (&sql); sprintf ( buf, "create table %s ( cat integer", Fi->table ); db_append_string ( &sql, buf ); if ( !value_flag ) { /* add value to the table */ if ( data_type == CELL_TYPE ) db_append_string ( &sql, ", value integer" ); else db_append_string ( &sql, ", value double precision" ); } if ( has_cats ) { int i, len; int clen = 0; /* Get maximum column length */ for ( i = 0; i < RastCats.ncats; i++) { len = strlen ( RastCats.labels[i] ); if ( len > clen ) clen = len; } clen += 10; sprintf ( buf, ", label varchar(%d)", clen ); db_append_string ( &sql, buf ); } db_append_string ( &sql, ")" ); G_debug ( 3, db_get_string ( &sql ) ); if (db_execute_immediate (driver, &sql) != DB_OK ) G_fatal_error (_("Cannot create table: %s"), db_get_string (&sql) ); if ( db_create_index2(driver, Fi->table, "cat" ) != DB_OK ) G_warning (_("Cannot create index")); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP|DB_PUBLIC ) != DB_OK ) G_fatal_error (_("Cannot grant privileges on table %s"), Fi->table ); db_begin_transaction ( driver ); } else { driver = NULL; } /* init variables for lines and areas */ first_read = 1; last_read = 0; direction = FORWARD; row_length = cell_head.cols; n_rows = cell_head.rows; row_count = 0; if ( feature == GV_LINE ) { alloc_lines_bufs(row_length + 2); extract_lines(quiet->answer); } else if ( feature == GV_AREA ) { alloc_areas_bufs(row_length + 2); extract_areas(quiet->answer); } else /* GV_POINT */ { extract_points (z_flg->answer, quiet->answer); } G_close_cell(input_fd); if( ! no_topol->answer ) Vect_build (&Map, stderr); /* insert cats and optionaly labels if raster cats were used */ if ( driver && value_flag ) { char buf[1000]; int c, i, cat, fidx, ncats, lastcat, tp, id; fidx = Vect_cidx_get_field_index ( &Map, 1 ); if ( fidx >= 0 ) { ncats = Vect_cidx_get_num_cats_by_index ( &Map, fidx ) ; lastcat = -1; for ( c = 0; c < ncats; c++) { Vect_cidx_get_cat_by_index ( &Map, fidx, c, &cat, &tp, &id ); if ( lastcat == cat ) continue; /* find label, slow -> TODO faster */ db_set_string ( &label, ""); for ( i = 0; i < RastCats.ncats; i++) { if ( cat == (int) RastCats.q.table[i].dLow ) { /* cats are in dLow/High not in cLow/High !!! */ db_set_string ( &label, RastCats.labels[i]); db_double_quote_string ( &label ); break; } } G_debug ( 3, "cat = %d label = %s", cat, db_get_string(&label) ); sprintf (buf, "insert into %s values ( %d, '%s')", Fi->table, cat, db_get_string(&label) ); db_set_string ( &sql, buf); G_debug ( 3, db_get_string ( &sql ) ); if (db_execute_immediate (driver, &sql) != DB_OK ) G_fatal_error (_("Cannot insert into table: %s"), db_get_string (&sql)); lastcat = cat; } } } if ( has_cats ) G_free_cats(&RastCats); if ( driver != NULL ) { db_commit_transaction ( driver ); db_close_database_shutdown_driver ( driver ); } Vect_close (&Map); G_done_msg(""); exit(EXIT_SUCCESS); }