Beispiel #1
0
/* *************************************************************** */
void bench_blas_level_3_double(int rows)
{
    struct timeval tstart;
    struct timeval tend;
    double **A, **B, **C, *x, *y;

    x = G_alloc_vector(rows);
    y = G_alloc_vector(rows);

    A = G_alloc_matrix(rows, rows);
    B = G_alloc_matrix(rows, rows);
    C = G_alloc_matrix(rows, rows);

    fill_d_vector_range_1(x, 1, rows);
    fill_d_vector_range_1(y, 1, rows);

    fill_d_vector_range_1(A[0], 1, rows*rows);
    fill_d_vector_range_1(B[0], 1, rows*rows);


    gettimeofday(&tstart, NULL);
#pragma omp parallel default(shared)
{
    G_math_d_aA_B(A, B, 4.0 , C, rows , rows);
}
    gettimeofday(&tend, NULL);
    G_important_message("Computation time G_math_d_aA_B: %g\n", compute_time_difference(tstart, tend));
    gettimeofday(&tstart, NULL);
#pragma omp parallel default(shared)
{
    G_math_d_AB(A, B, C, rows , rows , rows);
}
    gettimeofday(&tend, NULL);
    G_important_message("Computation time G_math_d_AB: %g\n", compute_time_difference(tstart, tend));


    if(x)
      G_free_vector(x);
    if(y)
      G_free_vector(y);

    if(A)
      G_free_matrix(A);
    if(B)
      G_free_matrix(B);
    if(C)
      G_free_matrix(C);

    return;
}
Beispiel #2
0
double get_property(int cat, int line, dbCatValArray *cvarr, double scale, double default_value)
{
    double value;
    dbCatVal *cv;

    cv = NULL;

    if (cat < 0)
	return default_value;
    
    /* Read line width from db for current area # */
    if (db_CatValArray_get_value(cvarr, cat, &cv) != DB_OK) {
	value = default_value;
    }
    else {
	value = scale * (cvarr->ctype ==
			 DB_C_TYPE_INT ? (double) cv->val.i : cv->val.d);
	if (value < 0) {
	    G_important_message(_("Invalid negative value - feature %d with category %d"),
				line, cat);
	    value = default_value;
	}
    }

    return value;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    struct Option *driver, *database, *user, *password;
    struct GModule *module;
    
    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("database"));
    G_add_keyword(_("connection settings"));
    module->description = _("Sets user/password for driver/database.");

    driver = G_define_standard_option(G_OPT_DB_DRIVER);
    driver->options = db_list_drivers();
    driver->required = YES;
    driver->answer = (char *) db_get_default_driver_name();

    database = G_define_standard_option(G_OPT_DB_DATABASE);
    database->required = YES;
    database->answer = (char *) db_get_default_database_name();

    user = G_define_option();
    user->key = "user";
    user->type = TYPE_STRING;
    user->required = NO;
    user->multiple = NO;
    user->description = _("Username");

    password = G_define_option();
    password->key = "password";
    password->type = TYPE_STRING;
    password->required = NO;
    password->multiple = NO;
    password->description = _("Password");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (db_set_login(driver->answer, database->answer, user->answer,
		     password->answer) == DB_FAILED) {
	G_fatal_error(_("Unable to set user/password"));
    }
    
    if (password->answer)
	G_important_message(_("The password was stored in file (%s/dblogin)"), CONFIG_DIR);
    
    exit(EXIT_SUCCESS);
}
Beispiel #4
0
/* print list of running monitors */
void print_list(FILE *fd)
{
    char **list;
    int   i, n;

    list_mon(&list, &n);
    if (n > 0)
	G_message(_("List of running monitors:"));
    else {
	G_important_message(_("No monitors running"));
	return;
    }
    
    for (i = 0; i < n; i++)
	fprintf(fd, "%s\n", list[i]);
}
Beispiel #5
0
void modify_projinfo()
{
    const char *mapset = G_mapset();
    struct Cell_head old_cellhd;
    
    if (strcmp(mapset, "PERMANENT") != 0)
	G_fatal_error(_("You must select the PERMANENT mapset before updating the "
			"current location's projection (current mapset is <%s>)."),
		      mapset);
    
    /* Read projection information from current location first */
    G_get_default_window(&old_cellhd);
    
    char path[GPATH_MAX];
	
    /* Write out the PROJ_INFO, and PROJ_UNITS if available. */
    if (projinfo != NULL) {
	G_file_name(path, "", "PROJ_INFO", "PERMANENT");
	G_write_key_value_file(path, projinfo);
    }
    
    if (projunits != NULL) {
	G_file_name(path, "", "PROJ_UNITS", "PERMANENT");
	G_write_key_value_file(path, projunits);
    }
    
    if ((old_cellhd.zone != cellhd.zone) ||
	(old_cellhd.proj != cellhd.proj)) {
	/* Recreate the default, and current window files if projection
	 * number or zone have changed */
	G__put_window(&cellhd, "", "DEFAULT_WIND");
	G__put_window(&cellhd, "", "WIND");
	G_message(_("Default region was updated to the new projection, but if you have "
		    "multiple mapsets `g.region -d` should be run in each to update the "
		    "region from the default"));
    }
    G_important_message(_("Projection information updated"));
}
Beispiel #6
0
/* write_area - make table of area equivalences and write attribute file */
int write_area(struct area_table *a_list,	/* list of areas */
	       struct equiv_table *e_list,	/* list of equivalences between areas */
	       int n_areas,	/* lengths of e_list, a_list */
	       int n_equiv)
{
    struct line_pnts *points = Vect_new_line_struct();
    int n, i;
    struct area_table *p;
    char *temp_buf;
    int cat;
    int catNum;
    double x, y;

    total_areas = 0;
    if (n_equiv < n_areas) {
	equivs = (int *)G_malloc(n_areas * sizeof(int));
	n = n_equiv;
    }
    else {
	equivs = (int *)G_malloc(n_equiv * sizeof(int));
	n = n_areas;
    }

    for (i = 0; i < n; i++) {
	if ((e_list + i)->mapped)
	    equivs[i] = (e_list + i)->where;
	else {
	    total_areas++;
	    equivs[i] = i;
	}
    }

    if (n < n_areas) {
	for (i = n; i < n_areas; i++) {
	    total_areas++;
	    equivs[i] = i;
	}
    }

    catNum = 1;

    G_important_message(_("Writing areas..."));
    for (i = 0, p = a_list; i < n_areas; i++, p++) {
	G_percent(i, n_areas, 3);

	if (equivs[i] == i && p->width > 0 && !Rast_is_d_null_value(&(p->cat))) {
	    char buf[1000];

	    if (value_flag) {	/* raster value */
		cat = (int)p->cat;
	    }
	    else {		/* sequence */
		cat = catNum;
		catNum++;
	    }

	    x = cell_head.west + (p->col +
				  (p->width / 2.0)) * cell_head.ew_res;
	    y = cell_head.north - (p->row + 0.5) * cell_head.ns_res;

	    switch (data_type) {
	    case CELL_TYPE:
		G_debug(3,
			"vector x = %.3f, y = %.3f, cat = %d; raster cat = %d",
			x, y, cat, (int)p->cat);
		break;
	    case FCELL_TYPE:
		G_debug(3,
			"vector x = %.3f, y = %.3f, cat = %d; raster cat = %f",
			x, y, cat, (float)p->cat);
		break;
	    case DCELL_TYPE:
		G_debug(3,
			"vector x = %.3f, y = %.3f, cat = %d; raster cat = %lf",
			x, y, cat, p->cat);
		break;
	    }

	    Vect_reset_line(points);
	    Vect_append_point(points, x, y, 0.0);

	    Vect_reset_cats(Cats);
	    Vect_cat_set(Cats, 1, cat);

	    Vect_write_line(&Map, GV_CENTROID, points, Cats);

	    if (driver != NULL && !value_flag) {
		sprintf(buf, "insert into %s values (%d, ", Fi->table, cat);
		db_set_string(&sql, buf);
		switch (data_type) {
		case CELL_TYPE:
		    sprintf(buf, "%d", (int)p->cat);
		    break;
		case FCELL_TYPE:
		case DCELL_TYPE:
		    sprintf(buf, "%f", p->cat);
		    break;
		}
		db_append_string(&sql, buf);

		if (has_cats) {
		    temp_buf = Rast_get_d_cat(&p->cat, &RastCats);

		    db_set_string(&label, temp_buf);
		    db_double_quote_string(&label);
		    sprintf(buf, ", '%s'", db_get_string(&label));
		    db_append_string(&sql, buf);
		}

		db_append_string(&sql, ")");
		G_debug(3, "%s", db_get_string(&sql));

		if (db_execute_immediate(driver, &sql) != DB_OK)
		    G_fatal_error(_("Cannot insert new row: %s"),
				  db_get_string(&sql));
	    }
	}
    }
    G_percent(1, 1, 1);
    
    return 0;
}
Beispiel #7
0
void write_rgb_values(const struct Map_info *Map, int layer, const char *column_name,
		      struct Colors *colors)
{
    int ctype, nrec, i;
    int red, grn, blu;
    int *pval;
    char buf[1024];
    struct field_info *fi;
    dbDriver *driver;
    dbString stmt;

    fi = Vect_get_field(Map, layer);
    if (!fi)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      layer);

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    db_set_error_handler_driver(driver);

    db_init_string(&stmt);
    
    ctype = db_column_Ctype(driver, fi->table, column_name);
    if (ctype == -1) {
	sprintf(buf, "ALTER TABLE %s ADD COLUMN %s VARCHAR(11)",
		fi->table, column_name);
	db_set_string(&stmt, buf);
	if (db_execute_immediate(driver, &stmt) != DB_OK)
	    G_fatal_error(_("Unable to add column <%s> to table <%s>"),
			  column_name, fi->table);

	/*
	  db_add_column needs to be implemented for DB drivers first...
	  
	  dbString table;
	  dbColumn column;
	  
	  db_init_column(&column);
	  db_set_column_name(&column, column_name);
	  db_set_column_sqltype(&column, DB_SQL_TYPE_CHARACTER);
	  db_set_column_null_allowed(&column);
	  db_set_column_length(&column, 11);
	  
	  db_init_string(&table);
	  db_set_string(&table, fi->table);
	  if (db_add_column(driver, &table, &column) != DB_OK)
	  G_fatal_error(_("Unable to add column <%s> to table <%s>"),
	  column_name, fi->table);
	  db_free_column(&column);
	*/

	G_important_message(_("Column <%s> added to table <%s>"),
			     column_name, fi->table);
    }
    else if (ctype != DB_C_TYPE_STRING)
	G_fatal_error(_("Data type of column <%s> must be char"), column_name);
	
    nrec = db_select_int(driver, fi->table, fi->key, NULL, &pval);
    if (nrec < 1) {
	G_warning(_("No categories found"));
	return;
    }
    
    db_begin_transaction(driver);
    
    for (i = 0; i < nrec; i++) {
	G_percent(i, nrec, 2);
	if (Rast_get_c_color((const CELL *) &(pval[i]), &red, &grn, &blu,
			     colors) == 0)
	    G_warning(_("No color value defined for category %d"), pval[i]);

	sprintf(buf, "UPDATE %s SET %s='%d:%d:%d' WHERE %s=%d", fi->table,
		   column_name, red, grn, blu, fi->key, pval[i]);
	G_debug(3, "\tSQL: %s", buf);

	db_set_string(&stmt, buf);
	if (db_execute_immediate(driver, &stmt) != DB_OK)
	    G_fatal_error(_("Unable to update RGB values"));
    }
    G_percent(1, 1, 1);
    
    db_commit_transaction(driver);
    
    db_close_database_shutdown_driver(driver);
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    int n, i;
    int skip;
    const char *cur_mapset, *mapset;
    char **ptr;
    char **tokens;
    int no_tokens;
    FILE *fp;
    char path_buf[GPATH_MAX];
    char *path, *fs;
    int operation, nchoices;
    
    char **mapset_name;
    int nmapsets;
    
    struct GModule *module;    
    struct _opt {
        struct Option *mapset, *op, *fs;
        struct Flag *print, *list, *dialog;
    } opt;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("general"));
    G_add_keyword(_("settings"));
    G_add_keyword(_("search path"));
    module->label = _("Modifies/prints the user's current mapset search path.");
    module->description = _("Affects the user's access to data existing "
                            "under the other mapsets in the current location.");

    opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
    opt.mapset->required = YES;
    opt.mapset->multiple = YES;
    opt.mapset->description = _("Name(s) of existing mapset(s) to add/remove or set");
    opt.mapset->guisection = _("Search path");
    
    opt.op = G_define_option();
    opt.op->key = "operation";
    opt.op->type = TYPE_STRING;
    opt.op->required = YES;
    opt.op->multiple = NO;
    opt.op->options = "set,add,remove";
    opt.op->description = _("Operation to be performed");
    opt.op->guisection = _("Search path");
    opt.op->answer = "add";
    
    opt.fs = G_define_standard_option(G_OPT_F_SEP);
    opt.fs->label = _("Field separator for printing (-l and -p flags)");
    opt.fs->answer = "space";
    opt.fs->guisection = _("Print");
    
    opt.list = G_define_flag();
    opt.list->key = 'l';
    opt.list->description = _("List all available mapsets in alphabetical order");
    opt.list->guisection = _("Print");
    opt.list->suppress_required = YES;

    opt.print = G_define_flag();
    opt.print->key = 'p';
    opt.print->description = _("Print mapsets in current search path");
    opt.print->guisection = _("Print");
    opt.print->suppress_required = YES;

    opt.dialog = G_define_flag();
    opt.dialog->key = 's';
    opt.dialog->description = _("Launch mapset selection GUI dialog");
    opt.dialog->suppress_required = YES;
    
    path = NULL;
    mapset_name = NULL;
    nmapsets = nchoices = 0;

    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    operation = OP_UKN;
    if (opt.mapset->answer && opt.op->answer) {
        switch(opt.op->answer[0]) {
        case 's':
            operation = OP_SET;
            break;
        case 'a':
            operation = OP_ADD;
            break;
        case 'r':
            operation = OP_REM;
            break;
        default:
            G_fatal_error(_("Unknown operation '%s'"), opt.op->answer);
            break;
        }
    }
    
    fs = G_option_to_separator(opt.fs);

    /* list available mapsets */
    if (opt.list->answer) {
        if (opt.print->answer)
            G_warning(_("Flag -%c ignored"), opt.print->key);
        if (opt.dialog->answer)
            G_warning(_("Flag -%c ignored"), opt.dialog->key);
        if (opt.mapset->answer)
            G_warning(_("Option <%s> ignored"), opt.mapset->key);
        mapset_name = get_available_mapsets(&nmapsets);
        list_available_mapsets((const char **)mapset_name, nmapsets, fs);
        exit(EXIT_SUCCESS);
    }

    if (opt.print->answer) {
        if (opt.dialog->answer)
            G_warning(_("Flag -%c ignored"), opt.dialog->key);
        if (opt.mapset->answer)
            G_warning(_("Option <%s> ignored"), opt.mapset->key);
        list_accessible_mapsets(fs);
        exit(EXIT_SUCCESS);
    }
    
    /* show GUI dialog */
    if (opt.dialog->answer) {
        if (opt.mapset->answer)
            G_warning(_("Option <%s> ignored"), opt.mapset->key);
        sprintf(path_buf, "%s/gui/wxpython/modules/mapsets_picker.py", G_gisbase());
        G_spawn(getenv("GRASS_PYTHON"), "mapsets_picker.py", path_buf, NULL);
        exit(EXIT_SUCCESS);
    }

    cur_mapset = G_mapset();
    
    /* modify search path */
    if (operation == OP_SET) {
        int cur_found;
        
        cur_found = FALSE;
        for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) {
            mapset = substitute_mapset(*ptr);
            if (G__mapset_permissions(mapset) < 0)
                G_fatal_error(_("Mapset <%s> not found"), mapset);
            if (strcmp(mapset, cur_mapset) == 0)
                cur_found = TRUE;
            nchoices++;
            append_mapset(&path, mapset);
        }
        if (!cur_found)
            G_warning(_("Current mapset (<%s>) must always included in the search path"),
                      cur_mapset);
    }
    else if (operation == OP_ADD) {
        /* add to existing search path */
        const char *oldname;
        
        if (path) {
            G_free(path);
            path = NULL;
        }

        /* read existing mapsets from SEARCH_PATH */
        for (n = 0; (oldname = G_get_mapset_name(n)); n++)
            append_mapset(&path, oldname);

        /* fetch and add new mapsets from param list */
        for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) {

            mapset = substitute_mapset(*ptr);

            if (G_is_mapset_in_search_path(mapset)) {
                G_message(_("Mapset <%s> already in the path"), mapset);
                continue;
            }
            
            if (G__mapset_permissions(mapset) < 0)
                G_fatal_error(_("Mapset <%s> not found"), mapset);
            else
                G_verbose_message(_("Mapset <%s> added to search path"),
                                  mapset);

            nchoices++;
            append_mapset(&path, mapset);
        }
    }
    else if (operation == OP_REM) {
        /* remove from existing search path */
        const char *oldname;
        int found;
        
        if (path) {
            G_free(path);
            path = NULL;
        }
        
        /* read existing mapsets from SEARCH_PATH */
        for (n = 0; (oldname = G_get_mapset_name(n)); n++) {
            found = FALSE;
            
            for (ptr = opt.mapset->answers; *ptr && !found; ptr++)

                mapset = substitute_mapset(*ptr);
            
                if (strcmp(oldname, mapset) == 0)
                    found = TRUE;
            
                if (found) {
                    if (strcmp(oldname, cur_mapset) == 0)
                        G_warning(_("Current mapset (<%s>) must always included in the search path"),
                                  cur_mapset);
                    else
                        G_verbose_message(_("Mapset <%s> removed from search path"),
                                          oldname);
                    continue;
                }
                
                nchoices++;
                append_mapset(&path, oldname);
        }
    }
    /* stuffem sets nchoices */

    if (nchoices == 0) {
        G_important_message(_("Search path not modified"));
        if (path)
            G_free(path);
        
        if (nmapsets) {
            for(nmapsets--; nmapsets >= 0; nmapsets--)
                G_free(mapset_name[nmapsets]);
            G_free(mapset_name);
        }
        
        exit(EXIT_SUCCESS);
    }
    
    /* note I'm assuming that mapsets cannot have ' 's in them */
    tokens = G_tokenize(path, " ");

    fp = G_fopen_new("", "SEARCH_PATH");
    if (!fp)
        G_fatal_error(_("Unable to open SEARCH_PATH for write"));

    /*
     * make sure current mapset is specified in the list if not add it
     * to the head of the list
     */
    
    skip = 0;
    for (n = 0; n < nchoices; n++)
        if (strcmp(cur_mapset, tokens[n]) == 0) {
            skip = 1;
            break;
        }
    if (!skip) {
        fprintf(fp, "%s\n", cur_mapset);
    }

    /*
     * output the list, removing duplicates
     */

    no_tokens = G_number_of_tokens(tokens);

    for (n = 0; n < no_tokens; n++) {
        skip = 0;
        for (i = n; i < no_tokens; i++) {
            if (i != n) {
                if (strcmp(tokens[i], tokens[n]) == 0)
                    skip = 1;
            }
        }

        if (!skip)
            fprintf(fp, "%s\n", tokens[n]);
    }

    fclose(fp);
    G_free_tokens(tokens);

    if (path)
        G_free(path);

    if (nmapsets) {
        for(nmapsets--; nmapsets >= 0; nmapsets--)
            G_free(mapset_name[nmapsets]);
        G_free(mapset_name);
    }

    exit(EXIT_SUCCESS);
}
Beispiel #9
0
int main(int argc, char **argv)
{
    int i;
    int **cats, *ncats, nfields, *fields;
    struct Flag *line_flag;

    /* struct Flag *all_flag; */
    struct Option *in_opt, *out_opt;
    struct Flag *table_flag;
    struct GModule *module;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int node, nnodes;
    COOR *coor;
    int ncoor, acoor;
    int line, nlines, type, ctype, area, nareas;
    int err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("triangulation"));
    module->description = _("Creates a Voronoi diagram from an input vector "
			    "map containing points or centroids.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    /*
       all_flag = G_define_flag ();
       all_flag->key = 'a';
       all_flag->description = _("Use all points (do not limit to current region)");
     */

    line_flag = G_define_flag();
    line_flag->key = 'l';
    line_flag->description =
	_("Output tessellation as a graph (lines), not areas");

    table_flag = G_define_flag();
    table_flag->key = 't';
    table_flag->description = _("Do not create attribute table");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    if (line_flag->answer)
	Type = GV_LINE;
    else
	Type = GV_BOUNDARY;

    All = 0;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /* open files */
    Vect_set_open_level(2);
    Vect_open_old(&In, in_opt->answer, "");

    if (Vect_open_new(&Out, out_opt->answer, 0) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* initialize working region */
    G_get_window(&Window);
    Vect_region_box(&Window, &Box);
    Box.T = 0.5;
    Box.B = -0.5;

    freeinit(&sfl, sizeof(struct Site));

    G_message(_("Reading sites..."));
    readsites();

    siteidx = 0;
    geominit();

    triangulate = 0;
    plot = 0;
    debug = 0;

    G_message(_("Voronoi triangulation..."));
    voronoi(triangulate, nextone);

    /* Close free ends by current region */
    Vect_build_partial(&Out, GV_BUILD_BASE);

    ncoor = 0;
    acoor = 100;
    coor = (COOR *) G_malloc(sizeof(COOR) * acoor);

    nnodes = Vect_get_num_nodes(&Out);
    for (node = 1; node <= nnodes; node++) {
	double x, y;

	if (Vect_get_node_n_lines(&Out, node) < 2) {	/* add coordinates */
	    Vect_get_node_coor(&Out, node, &x, &y, NULL);

	    if (ncoor == acoor - 5) {	/* always space for 5 region corners */
		acoor += 100;
		coor = (COOR *) G_realloc(coor, sizeof(COOR) * acoor);
	    }

	    coor[ncoor].x = x;
	    coor[ncoor].y = y;
	    ncoor++;
	}
    }

    /* Add region corners */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.N;
    ncoor++;
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.N;
    ncoor++;

    /* Sort */
    qsort(coor, ncoor, sizeof(COOR), (void *)cmp);

    /* add last (first corner) */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;

    for (i = 1; i < ncoor; i++) {
	if (coor[i].x == coor[i - 1].x && coor[i].y == coor[i - 1].y)
	    continue;		/* duplicate */

	Vect_reset_line(Points);
	Vect_append_point(Points, coor[i].x, coor[i].y, 0.0);
	Vect_append_point(Points, coor[i - 1].x, coor[i - 1].y, 0.0);
	Vect_write_line(&Out, Type, Points, Cats);
    }

    G_free(coor);

    /* Copy input points as centroids */
    nfields = Vect_cidx_get_num_fields(&In);
    cats = (int **)G_malloc(nfields * sizeof(int *));
    ncats = (int *)G_malloc(nfields * sizeof(int));
    fields = (int *)G_malloc(nfields * sizeof(int));
    for (i = 0; i < nfields; i++) {
	ncats[i] = 0;
	cats[i] =
	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(&In, i) *
			    sizeof(int));
	fields[i] = Vect_cidx_get_field_number(&In, i);
    }

    if (line_flag->answer)
	ctype = GV_POINT;
    else
	ctype = GV_CENTROID;

    nlines = Vect_get_num_lines(&In);

    G_message(_("Writing sites to output..."));

    for (line = 1; line <= nlines; line++) {

	G_percent(line, nlines, 2);

	type = Vect_read_line(&In, Points, Cats, line);
	if (!(type & GV_POINTS))
	    continue;

	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &Box))
	    continue;

	Vect_write_line(&Out, ctype, Points, Cats);


	for (i = 0; i < Cats->n_cats; i++) {
	    int f, j;

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == Cats->field[i]) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		cats[f][ncats[f]] = Cats->cat[i];
		ncats[f]++;
	    }
	}
    }

    /* Copy tables */
    if (!(table_flag->answer)) {
	int ttype, ntabs = 0;
	struct field_info *IFi, *OFi;

	/* Number of output tabs */
	for (i = 0; i < Vect_get_num_dblinks(&In); i++) {
	    int f, j;

	    IFi = Vect_get_dblink(&In, i);

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == IFi->number) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		if (ncats[f] > 0)
		    ntabs++;
	    }
	}

	if (ntabs > 1)
	    ttype = GV_MTABLE;
	else
	    ttype = GV_1TABLE;

	for (i = 0; i < nfields; i++) {
	    int ret;

	    if (fields[i] == 0)
		continue;

	    G_message(_("Layer %d"), fields[i]);

	    /* Make a list of categories */
	    IFi = Vect_get_field(&In, fields[i]);
	    if (!IFi) {		/* no table */
		G_message(_("No table"));
		continue;
	    }

	    OFi =
		Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);

	    ret =
		db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				      OFi->driver,
				      Vect_subst_var(OFi->database, &Out),
				      OFi->table, IFi->key, cats[i],
				      ncats[i]);

	    if (ret == DB_FAILED) {
		G_warning(_("Cannot copy table"));
	    }
	    else {
		Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
				    IFi->key, OFi->database, OFi->driver);
	    }
	}
    }


    Vect_close(&In);

    /* cleaning part 1: count errors */
    Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
    err_boundaries = err_centr_out = err_centr_dupl = err_nocentr = 0;
    nlines = Vect_get_num_lines(&Out);
    for (line = 1; line <= nlines; line++) {

	if (!Vect_line_alive(&Out, line))
	    continue;

	type = Vect_get_line_type(&Out, line);
	if (type == GV_BOUNDARY) {
	    int left, right;

	    Vect_get_line_areas(&Out, line, &left, &right);

	    if (left == 0 || right == 0) {
		G_debug(3, "line = %d left = %d right = %d", line, 
			left, right);
		err_boundaries++;
	    }
	}
	if (type == GV_CENTROID) {
	    area = Vect_get_centroid_area(&Out, line);
	    if (area == 0)
		err_centr_out++;
	    else if (area < 0)
		err_centr_dupl++;
	}
    }

    err_nocentr = 0;
    nareas = Vect_get_num_areas(&Out);
    for (area = 1; area <= nareas; area++) {
	if (!Vect_area_alive(&Out, area))
	    continue;
	line = Vect_get_area_centroid(&Out, area);
	if (line == 0)
	    err_nocentr++;
    }

    /* cleaning part 2: snap */
    if (err_nocentr || err_centr_dupl || err_centr_out) {
	int nmod;

	G_important_message(_("Output needs topological cleaning"));
	Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);
	do {
	    Vect_break_lines(&Out, GV_BOUNDARY, NULL);
	    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
	    nmod =
		Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL);
	} while (nmod > 0);

	err_boundaries = 0;
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		if (left == 0 || right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    err_boundaries++;
		}
	    }
	}
    }
    /* cleaning part 3: remove remaining incorrect boundaries */
    if (err_boundaries) {
	G_important_message(_("Removing incorrect boundaries from output"));
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		/* &&, not ||, no typo */
		if (left == 0 && right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    Vect_delete_line(&Out, line);
		}
	    }
	}
    }

    /* build clean topology */
    Vect_build_partial(&Out, GV_BUILD_NONE);
    Vect_build(&Out);
    Vect_close(&Out);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Beispiel #10
0
int main(int argc, char *argv[])
{
    int i, type, stat;
    int day, yr, Out_proj;
    int out_zone = 0;
    int overwrite;		/* overwrite output map */
    const char *mapset;
    const char *omap_name, *map_name, *iset_name, *iloc_name;
    struct pj_info info_in;
    struct pj_info info_out;
    const char *gbase;
    char date[40], mon[4];
    struct GModule *module;
    struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt, *smax;
    struct Key_Value *in_proj_keys, *in_unit_keys;
    struct Key_Value *out_proj_keys, *out_unit_keys;
    struct line_pnts *Points, *Points2;
    struct line_cats *Cats;
    struct Map_info Map;
    struct Map_info Out_Map;
    struct bound_box src_box, tgt_box;
    int nowrap = 0, recommend_nowrap = 0;
    double lmax;
    struct
    {
	struct Flag *list;	/* list files in source location */
	struct Flag *transformz;	/* treat z as ellipsoidal height */
	struct Flag *wrap;		/* latlon output: wrap to 0,360 */
	struct Flag *no_topol;		/* do not build topology */
    } flag;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("projection"));
    G_add_keyword(_("transformation"));
    G_add_keyword(_("import"));
    module->description = _("Re-projects a vector map from one location to the current location.");

    /* set up the options and flags for the command line parser */

    ilocopt = G_define_standard_option(G_OPT_M_LOCATION);
    ilocopt->required = YES;
    ilocopt->label = _("Location containing input vector map");
    ilocopt->guisection = _("Source");
    
    isetopt = G_define_standard_option(G_OPT_M_MAPSET);
    isetopt->label = _("Mapset containing input vector map");
    isetopt->description = _("Default: name of current mapset");
    isetopt->guisection = _("Source");

    mapopt = G_define_standard_option(G_OPT_V_INPUT);
    mapopt->required = NO;
    mapopt->label = _("Name of input vector map to re-project");
    mapopt->description = NULL;
    mapopt->guisection = _("Source");
    
    ibaseopt = G_define_standard_option(G_OPT_M_DBASE);
    ibaseopt->label = _("Path to GRASS database of input location");
    
    smax = G_define_option();
    smax->key = "smax";
    smax->type = TYPE_DOUBLE;
    smax->required = NO;
    smax->answer = "10000";
    smax->label = _("Maximum segment length in meters in output vector map");
    smax->description = _("Increases accuracy of reprojected shapes, disable with smax=0");
    smax->guisection = _("Target");

    omapopt = G_define_standard_option(G_OPT_V_OUTPUT);
    omapopt->required = NO;
    omapopt->description = _("Name for output vector map (default: input)");
    omapopt->guisection = _("Target");

    flag.list = G_define_flag();
    flag.list->key = 'l';
    flag.list->description = _("List vector maps in input mapset and exit");

    flag.transformz = G_define_flag();
    flag.transformz->key = 'z';
    flag.transformz->description = _("3D vector maps only");
    flag.transformz->label =
	_("Assume z coordinate is ellipsoidal height and "
	  "transform if possible");
    flag.transformz->guisection = _("Target");

    flag.wrap = G_define_flag();
    flag.wrap->key = 'w';
    flag.wrap->description = _("Latlon output only, default is -180,180");
    flag.wrap->label =
	_("Disable wrapping to -180,180 for latlon output");
    flag.transformz->guisection = _("Target");

    flag.no_topol = G_define_flag();
    flag.no_topol->key = 'b';
    flag.no_topol->label = _("Do not build vector topology");
    flag.no_topol->description = _("Recommended for massive point projection");

    /* The parser checks if the map already exists in current mapset,
       we switch out the check and do it
       in the module after the parser */
    overwrite = G_check_overwrite(argc, argv);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* start checking options and flags */
    /* set input vector map name and mapset */
    map_name = mapopt->answer;
    if (omapopt->answer)
	omap_name = omapopt->answer;
    else
	omap_name = map_name;
    if (omap_name && !flag.list->answer && !overwrite &&
	G_find_vector2(omap_name, G_mapset()))
	G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"), omapopt->key,
		      omap_name);
    if (isetopt->answer)
	iset_name = isetopt->answer;
    else
	iset_name = G_store(G_mapset());

    iloc_name = ilocopt->answer;

    if (ibaseopt->answer)
	gbase = ibaseopt->answer;
    else
	gbase = G_store(G_gisdbase());

    if (!ibaseopt->answer && strcmp(iloc_name, G_location()) == 0)
	G_fatal_error(_("Input and output locations can not be the same"));

    lmax = atof(smax->answer);
    if (lmax < 0)
	lmax = 0;

    Out_proj = G_projection();
    if (Out_proj == PROJECTION_LL && flag.wrap->answer)
	nowrap = 1;
    
    G_begin_distance_calculations();

    /* Change the location here and then come back */

    select_target_env();
    G_setenv_nogisrc("GISDBASE", gbase);
    G_setenv_nogisrc("LOCATION_NAME", iloc_name);
    stat = G_mapset_permissions(iset_name);
    
    if (stat >= 0) {		/* yes, we can access the mapset */
	/* if requested, list the vector maps in source location - MN 5/2001 */
	if (flag.list->answer) {
	    int i;
	    char **list;
	    G_verbose_message(_("Checking location <%s> mapset <%s>"),
			      iloc_name, iset_name);
	    list = G_list(G_ELEMENT_VECTOR, G_getenv_nofatal("GISDBASE"),
			  G_getenv_nofatal("LOCATION_NAME"), iset_name);
	    if (list[0]) {
		for (i = 0; list[i]; i++) {
		    fprintf(stdout, "%s\n", list[i]);
		}
		fflush(stdout);
	    }
	    else {
		G_important_message(_("No vector maps found"));
	    }
	    exit(EXIT_SUCCESS);	/* leave v.proj after listing */
	}

	if (mapopt->answer == NULL) {
	    G_fatal_error(_("Required parameter <%s> not set"), mapopt->key);
	}

	G_setenv_nogisrc("MAPSET", iset_name);
	/* Make sure map is available */
	mapset = G_find_vector2(map_name, iset_name);
	if (mapset == NULL)
	    G_fatal_error(_("Vector map <%s> in location <%s> mapset <%s> not found"),
			  map_name, iloc_name, iset_name);

	 /*** Get projection info for input mapset ***/
	in_proj_keys = G_get_projinfo();
	if (in_proj_keys == NULL)
	    exit(EXIT_FAILURE);

	/* apparently the +over switch must be set in the input projection,
	 * not the output latlon projection */
	if (Out_proj == PROJECTION_LL && nowrap == 1)
	    G_set_key_value("+over", "defined", in_proj_keys);

	in_unit_keys = G_get_projunits();
	if (in_unit_keys == NULL)
	    exit(EXIT_FAILURE);

	if (pj_get_kv(&info_in, in_proj_keys, in_unit_keys) < 0)
	    exit(EXIT_FAILURE);

	Vect_set_open_level(1);
	G_debug(1, "Open old: location: %s mapset : %s", G_location_path(),
		G_mapset());
	if (Vect_open_old(&Map, map_name, mapset) < 0)
	    G_fatal_error(_("Unable to open vector map <%s>"), map_name);
    }
    else if (stat < 0)
    {				/* allow 0 (i.e. denied permission) */
	/* need to be able to read from others */
	if (stat == 0)
	    G_fatal_error(_("Mapset <%s> in input location <%s> - permission denied"),
			  iset_name, iloc_name);
	else
	    G_fatal_error(_("Mapset <%s> in input location <%s> not found"),
			  iset_name, iloc_name);
    }

    select_current_env();

    /****** get the output projection parameters ******/
    out_proj_keys = G_get_projinfo();
    if (out_proj_keys == NULL)
	exit(EXIT_FAILURE);

    out_unit_keys = G_get_projunits();
    if (out_unit_keys == NULL)
	exit(EXIT_FAILURE);

    if (pj_get_kv(&info_out, out_proj_keys, out_unit_keys) < 0)
	exit(EXIT_FAILURE);

    G_free_key_value(in_proj_keys);
    G_free_key_value(in_unit_keys);
    G_free_key_value(out_proj_keys);
    G_free_key_value(out_unit_keys);

    if (G_verbose() == G_verbose_max()) {
	pj_print_proj_params(&info_in, &info_out);
    }

    /* Initialize the Point / Cat structure */
    Points = Vect_new_line_struct();
    Points2 = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /* test if latlon wrapping to -180,180 should be disabled */
    if (Out_proj == PROJECTION_LL && nowrap == 0) {
	int first = 1, counter = 0;
	double x, y;
	
	/* Cycle through all lines */
	Vect_rewind(&Map);
	while (1) {
	    type = Vect_read_next_line(&Map, Points, Cats);	/* read line */
	    if (type == 0)
		continue;		/* Dead */

	    if (type == -1)
		G_fatal_error(_("Reading input vector map"));
	    if (type == -2)
		break;
		
	    if (first && Points->n_points > 0) {
		first = 0;
		src_box.E = src_box.W = Points->x[0];
		src_box.N = src_box.S = Points->y[0];
		src_box.T = src_box.B = Points->z[0];
	    }
	    for (i = 0; i < Points->n_points; i++) {
		if (src_box.E < Points->x[i])
		    src_box.E = Points->x[i];
		if (src_box.W > Points->x[i])
		    src_box.W = Points->x[i];
		if (src_box.N < Points->y[i])
		    src_box.N = Points->y[i];
		if (src_box.S > Points->y[i])
		    src_box.S = Points->y[i];
	    }
	    counter++;
	}
	if (counter == 0) {
	    G_warning(_("Input vector map <%s> is empty"), omap_name);
	    exit(EXIT_SUCCESS);
	}
	/* NW corner */
	x = src_box.W;
	y = src_box.N;
	if (pj_do_transform(1, &x, &y, NULL,
			    &info_in, &info_out) < 0) {
	    G_fatal_error(_("Error in pj_do_transform"));
	}
	tgt_box.E = x;
	tgt_box.W = x;
	tgt_box.N = y;
	tgt_box.S = y;
	/* SW corner */
	x = src_box.W;
	y = src_box.S;
	if (pj_do_transform(1, &x, &y, NULL,
			    &info_in, &info_out) < 0) {
	    G_fatal_error(_("Error in pj_do_transform"));
	}
	if (tgt_box.W > x)
	    tgt_box.W = x;
	if (tgt_box.E < x)
	    tgt_box.E = x;
	if (tgt_box.N < y)
	    tgt_box.N = y;
	if (tgt_box.S > y)
	    tgt_box.S = y;
	/* NE corner */
	x = src_box.E;
	y = src_box.N;
	if (pj_do_transform(1, &x, &y, NULL,
			    &info_in, &info_out) < 0) {
	    G_fatal_error(_("Error in pj_do_transform"));
	}
	if (tgt_box.W > x) {
	    tgt_box.E = x + 360;
	    recommend_nowrap = 1;
	}
	if (tgt_box.N < y)
	    tgt_box.N = y;
	if (tgt_box.S > y)
	    tgt_box.S = y;
	/* SE corner */
	x = src_box.E;
	y = src_box.S;
	if (pj_do_transform(1, &x, &y, NULL,
			    &info_in, &info_out) < 0) {
	    G_fatal_error(_("Error in pj_do_transform"));
	}
	if (tgt_box.W > x) {
	    if (tgt_box.E < x + 360)
		tgt_box.E = x + 360;
	    recommend_nowrap = 1;
	}
	if (tgt_box.N < y)
	    tgt_box.N = y;
	if (tgt_box.S > y)
	    tgt_box.S = y;
    }

    G_debug(1, "Open new: location: %s mapset : %s", G_location_path(),
	    G_mapset());

    if (Vect_open_new(&Out_Map, omap_name, Vect_is_3d(&Map)) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), omap_name);

    Vect_set_error_handler_io(NULL, &Out_Map); /* register standard i/o error handler */
    
    Vect_copy_head_data(&Map, &Out_Map);
    Vect_hist_copy(&Map, &Out_Map);
    Vect_hist_command(&Out_Map);

    out_zone = info_out.zone;
    Vect_set_zone(&Out_Map, out_zone);

    /* Read and write header info */
    sprintf(date, "%s", G_date());
    sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr);
    if (yr < 2000)
	yr = yr - 1900;
    else
	yr = yr - 2000;
    sprintf(date, "%s %d %d", mon, day, yr);
    Vect_set_date(&Out_Map, date);

    /* line densification works only with vector topology */
    if (Map.format != GV_FORMAT_NATIVE)
	lmax = 0;

    /* Cycle through all lines */
    Vect_rewind(&Map);
    i = 0;
    G_message(_("Reprojecting primitives ..."));
    while (TRUE) {
	++i;
	G_progress(i, 1e3);
	type = Vect_read_next_line(&Map, Points, Cats);	/* read line */
	if (type == 0)
	    continue;		/* Dead */

	if (type == -1)
	    G_fatal_error(_("Reading input vector map"));
	if (type == -2)
	    break;

	Vect_line_prune(Points);
	if (lmax > 0 && (type & GV_LINES) && Points->n_points > 1) {
	    double x1, y1, z1, x2, y2, z2;
	    double dx, dy, dz;
	    double l;
	    int i, n;

	    Vect_reset_line(Points2);
	    for (i = 0; i < Points->n_points - 1; i++) {
		x1 = Points->x[i];
		y1 = Points->y[i];
		z1 = Points->z[i];
		n = i + 1;
		x2 = Points->x[n];
		y2 = Points->y[n];
		z2 = Points->z[n];

		dx = x2 - x1;
		dy = y2 - y1;
		dz = z2 - z1;

		if (pj_do_transform(1, &x1, &y1,
				    flag.transformz->answer ? &z1 : NULL,
				    &info_in, &info_out) < 0) {
		  G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
				Vect_get_full_name(&Map), ilocopt->answer);
		}

		if (pj_do_transform(1, &x2, &y2,
				    flag.transformz->answer ? &z2 : NULL,
				    &info_in, &info_out) < 0) {
		  G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
				Vect_get_full_name(&Map), ilocopt->answer);
		}

		Vect_append_point(Points2, x1, y1, z1);

		l = G_distance(x1, y1, x2, y2);

		if (l > lmax) {
		    int j;
		    double x, y, z;

		    x1 = Points->x[i];
		    y1 = Points->y[i];
		    z1 = Points->z[i];

		    n = ceil(l / lmax);

		    for (j = 1; j < n; j++) {
			x = x1 + dx * j / n;
			y = y1 + dy * j / n;
			z = z1 + dz * j / n;

			if (pj_do_transform(1, &x, &y,
					    flag.transformz->answer ? &z : NULL,
					    &info_in, &info_out) < 0) {
			  G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
					Vect_get_full_name(&Map), ilocopt->answer);
			}
			Vect_append_point(Points2, x, y, z);
		    }
		}
	    }
	    Vect_append_point(Points2, x2, y2, z2);
	    Vect_write_line(&Out_Map, type, Points2, Cats);	/* write line */
	}
	else {
	    if (pj_do_transform(Points->n_points, Points->x, Points->y,
				flag.transformz->answer ? Points->z : NULL,
				&info_in, &info_out) < 0) {
	      G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
			    Vect_get_full_name(&Map), ilocopt->answer);
	    }

	    Vect_write_line(&Out_Map, type, Points, Cats);	/* write line */
	}
    }				/* end lines section */
    G_progress(1, 1);

    /* Copy tables */
    if (Vect_copy_tables(&Map, &Out_Map, 0))
        G_warning(_("Failed to copy attribute table to output map"));

    Vect_close(&Map);

    if (!flag.no_topol->answer)
        Vect_build(&Out_Map);
    Vect_close(&Out_Map);

    if (recommend_nowrap)
	G_important_message(_("Try to disable wrapping to -180,180 "
			      "if topological errors occurred"));

    exit(EXIT_SUCCESS);
}
Beispiel #11
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct {
	struct Flag *r, *w, *l, *g, *a, *n, *c;
    } flag; 

    struct {
	struct Option *map, *field, *colr, *rast, *volume, *rules,
          *attrcol, *rgbcol, *range, *use;
    } opt;

    int layer;
    int overwrite, remove, is_from_stdin, stat, have_colors, convert, use;
    const char *mapset, *cmapset;
    const char *style, *rules, *cmap, *attrcolumn, *rgbcolumn;
    char *name;
    
    struct Map_info Map;
    struct FPRange range;
    struct Colors colors, colors_tmp;
    /* struct Cell_stats statf; */
    
    G_gisinit(argv[0]);
    
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("color table"));
    module->description =
	_("Creates/modifies the color table associated with a vector map.");

    opt.map = G_define_standard_option(G_OPT_V_MAP);

    opt.field = G_define_standard_option(G_OPT_V_FIELD);

    opt.use = G_define_option();
    opt.use->key = "use";
    opt.use->type = TYPE_STRING;
    opt.use->required = YES;
    opt.use->multiple = NO;
    opt.use->options = "attr,cat,z";
    opt.use->description = _("Source values");
    G_asprintf((char **) &(opt.use->descriptions),
	       "attr;%s;cat;%s;z;%s",
	       _("read values from attribute table (requires <column> option)"),
	       _("use category values"),
	       _("use z coordinate (3D points or centroids only)"));
    opt.use->answer = "cat";
    
    opt.attrcol = G_define_standard_option(G_OPT_DB_COLUMN);
    opt.attrcol->label = _("Name of column containing numeric data");
    opt.attrcol->description = _("Required for use=attr");
    opt.attrcol->guisection = _("Define");

    opt.range = G_define_option();
    opt.range->key = "range";
    opt.range->type = TYPE_DOUBLE;
    opt.range->required = NO;
    opt.range->label = _("Manually set range (refers to 'column' option)");
    opt.range->description = _("Ignored when 'rules' given");
    opt.range->key_desc = "min,max";

    opt.colr = G_define_standard_option(G_OPT_M_COLR);
    opt.colr->guisection = _("Define");

    opt.rast = G_define_standard_option(G_OPT_R_INPUT);
    opt.rast->key = "raster";
    opt.rast->required = NO;
    opt.rast->description =
        _("Raster map from which to copy color table");
    opt.rast->guisection = _("Define");

    opt.volume = G_define_standard_option(G_OPT_R3_INPUT);
    opt.volume->key = "raster_3d";
    opt.volume->required = NO;
    opt.volume->description =
        _("3D raster map from which to copy color table");
    opt.volume->guisection = _("Define");

    opt.rules = G_define_standard_option(G_OPT_F_INPUT);
    opt.rules->key = "rules";
    opt.rules->required = NO;
    opt.rules->description = _("Path to rules file");
    opt.rules->guisection = _("Define");

    opt.rgbcol = G_define_standard_option(G_OPT_DB_COLUMN);
    opt.rgbcol->key = "rgb_column";
    opt.rgbcol->label = _("Name of color column to populate RGB values");
    opt.rgbcol->description = _("If not given writes color table");
    
    flag.r = G_define_flag();
    flag.r->key = 'r';
    flag.r->description = _("Remove existing color table");
    flag.r->guisection = _("Remove");

    flag.w = G_define_flag();
    flag.w->key = 'w';
    flag.w->description =
        _("Only write new color table if it does not already exist");

    flag.l = G_define_flag();
    flag.l->key = 'l';
    flag.l->description = _("List available rules then exit");
    flag.l->suppress_required = YES;
    flag.l->guisection = _("Print");

    flag.n = G_define_flag();
    flag.n->key = 'n';
    flag.n->description = _("Invert colors");
    flag.n->guisection = _("Define");

    flag.g = G_define_flag();
    flag.g->key = 'g';
    flag.g->description = _("Logarithmic scaling");
    flag.g->guisection = _("Define");

    flag.a = G_define_flag();
    flag.a->key = 'a';
    flag.a->description = _("Logarithmic-absolute scaling");
    flag.a->guisection = _("Define");

    flag.c = G_define_flag();
    flag.c->key = 'c';
    flag.c->label = _("Convert color rules from RGB values to color table");
    flag.c->description = _("Option 'rgb_column' with valid RGB values required");
	
    /* TODO ?
    flag.e = G_define_flag();
    flag.e->key = 'e';
    flag.e->description = _("Histogram equalization");
    flag.e->guisection = _("Define");
    */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (flag.l->answer) {
	G_list_color_rules(stdout);
	return EXIT_SUCCESS;
    }

    overwrite = !flag.w->answer;
    remove = flag.r->answer;
    name = opt.map->answer;
    style = opt.colr->answer;
    rules = opt.rules->answer;
    attrcolumn = opt.attrcol->answer;
    rgbcolumn = opt.rgbcol->answer;
    convert = flag.c->answer;
    use = USE_CAT;
    if (opt.use->answer) {
        switch (opt.use->answer[0]) {
        case 'a':
            use = USE_ATTR;
            break;
        case 'c':
            use = USE_CAT;
            break;
        case 'z':
            use = USE_Z;
            break;
        default:
            break;
        }
    }
    G_debug(1, "use=%d", use);
    
    if (!name)
        G_fatal_error(_("No vector map specified"));

    if (use == USE_ATTR && !attrcolumn)
        G_fatal_error(_("Option <%s> required"), opt.attrcol->key); 
    if (use != USE_ATTR && attrcolumn) {
        G_important_message(_("Option <%s> given, assuming <use=attr>..."), opt.attrcol->key);
        use = USE_ATTR;
    }

    if (opt.rast->answer && opt.volume->answer)
        G_fatal_error(_("%s= and %s= are mutually exclusive"),
		      opt.rast->key, opt.volume->key);

    cmap = NULL;
    if (opt.rast->answer)
        cmap = opt.rast->answer;
    if (opt.volume->answer)
        cmap = opt.volume->answer;
    
    if (!cmap && !style && !rules && !remove && !convert)
        G_fatal_error(_("One of -%c, -%c or %s=, %s= or %s= "
			"must be specified"), flag.r->key, flag.c->key, 
		      opt.colr->key, opt.rast->key, opt.rules->key);
    
    if (!!style + !!cmap + !!rules > 1)
        G_fatal_error(_("%s=, %s= and %s= are mutually exclusive"),
			opt.colr->key, opt.rules->key, opt.rast->key);

    if (flag.g->answer && flag.a->answer)
        G_fatal_error(_("-%c and -%c are mutually exclusive"),
		      flag.g->key, flag.a->key);

    if (flag.c->answer && !rgbcolumn) 
	G_fatal_error(_("%s= required for -%c"),
		      opt.rgbcol->key, flag.c->key);

    is_from_stdin = rules && strcmp(rules, "-") == 0;
    if (is_from_stdin)
        G_fatal_error(_("Reading rules from standard input is not implemented yet, please provide path to rules file instead."));

    mapset = G_find_vector(name, "");
    if (!mapset)
	G_fatal_error(_("Vector map <%s> not found"), name);
    
    stat = -1;
    if (remove) {
	stat = Vect_remove_colors(name, mapset);
        if (stat < 0)
            G_fatal_error(_("Unable to remove color table of vector map <%s>"), name);
        if (stat == 0)
            G_warning(_("Color table of vector map <%s> not found"), name);
        return EXIT_SUCCESS;
    }

    G_suppress_warnings(TRUE);
    have_colors = Vect_read_colors(name, mapset, NULL);

    if (have_colors > 0 && !overwrite) {
        G_fatal_error(_("Color table exists. Exiting."));
    }

    G_suppress_warnings(FALSE);

    /* open map and get min/max values */
    Vect_set_open_level(1); /* no topology required */
    if (Vect_open_old2(&Map, name, mapset, opt.field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), name);

    Vect_set_error_handler_io(&Map, NULL);
    if (use == USE_Z && !Vect_is_3d(&Map))
        G_fatal_error(_("Vector map <%s> is not 3D"), Vect_get_full_name(&Map));
    
    layer = Vect_get_field_number(&Map, opt.field->answer);
    if (layer < 1)
	G_fatal_error(_("Layer <%s> not found"), opt.field->answer);
    
    if (opt.range->answer) {
	range.min = atof(opt.range->answers[0]);
	range.max = atof(opt.range->answers[1]);
	if (range.min > range.max)
	    G_fatal_error(_("Option <%s>: min must be greater or equal to max"),
			  opt.range->key);
    }

    Rast_init_colors(&colors);
    if (is_from_stdin) {
        G_fatal_error(_("Reading color rules from standard input is currently not supported"));
	/*
        if (!read_color_rules(stdin, &colors, min, max, fp))
            exit(EXIT_FAILURE);
	*/
    } else if (style || rules) {	
	if (style && !G_find_color_rule(style))
	    G_fatal_error(_("Color table <%s> not found"), style);
	
	if (use == USE_CAT) {
	    scan_cats(&Map, layer, style, rules,
		      opt.range->answer ? &range : NULL,
		      &colors);
        }
        else if (use == USE_Z) {
	    scan_z(&Map, layer, style, rules,
		      opt.range->answer ? &range : NULL,
		      &colors);
        }
        else {
	    scan_attr(&Map, layer, attrcolumn, style, rules,
		      opt.range->answer ? &range : NULL,
		      &colors);
	}
    }
    else {
	/* use color from another map (cmap) */
	if (opt.rast->answer) {
            cmapset = G_find_raster2(cmap, "");
            if (!cmapset)
                G_fatal_error(_("Raster map <%s> not found"), cmap);

            if (Rast_read_colors(cmap, cmapset, &colors) < 0)
                G_fatal_error(_("Unable to read color table for raster map <%s>"), cmap);
        } else if (opt.volume->answer) {
            cmapset = G_find_raster3d(cmap, "");
            if (!cmapset)
                G_fatal_error(_("3D raster map <%s> not found"), cmap);

            if (Rast3d_read_colors(cmap, cmapset, &colors) < 0)
                G_fatal_error(_("Unable to read color table for 3D raster map <%s>"), cmap);
        }
    }

    if (flag.n->answer)
        Rast_invert_colors(&colors);

    /* TODO ?
    if (flag.e->answer) {
    if (!have_stats)
    have_stats = get_stats(name, mapset, &statf);
    Rast_histogram_eq_colors(&colors_tmp, &colors, &statf);
    colors = colors_tmp;
    }
    */
    if (flag.g->answer) {
        Rast_log_colors(&colors_tmp, &colors, 100);
        colors = colors_tmp;
    }

    if (flag.a->answer) {
        Rast_abs_log_colors(&colors_tmp, &colors, 100);
        colors = colors_tmp;
    }

    G_important_message(_("Writing color rules..."));
    
    if (style || rules || opt.rast->answer || opt.volume->answer) {
	if (rgbcolumn)
	    write_rgb_values(&Map, layer, rgbcolumn, &colors);
	else
	    Vect_write_colors(name, mapset, &colors);
    }
    
    if (convert) {
	/* convert RGB values to color tables */
	rgb2colr(&Map, layer, rgbcolumn, &colors);
	Vect_write_colors(name, mapset, &colors);
    }
    Vect_close(&Map);
    
    G_message(_("Color table for vector map <%s> set to '%s'"), 
	      G_fully_qualified_name(name, mapset), 
              is_from_stdin || convert ? "rules" : style ? style : rules ? rules :
              cmap);
    
    exit(EXIT_SUCCESS);
}
Beispiel #12
0
int main(int argc, char **argv)
{
    int ret, level;
    int stat, type, display;
    int chcat;
    int has_color, has_fcolor;
    struct color_rgb color, fcolor;
    double size;
    int default_width;
    double width_scale;
    double minreg, maxreg, reg;
    char map_name[GNAME_MAX];
    
    struct GModule *module;
    struct Option *map_opt;
    struct Option *color_opt, *fcolor_opt, *rgbcol_opt, *zcol_opt;
    struct Option *type_opt, *display_opt;
    struct Option *icon_opt, *size_opt, *sizecolumn_opt, *rotcolumn_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, *enc_opt, *xref_opt, *yref_opt;
    struct Option *attrcol_opt, *maxreg_opt, *minreg_opt;
    struct Option *width_opt, *wcolumn_opt, *wscale_opt;
    struct Option *leglab_opt;
    struct Option *icon_line_opt, *icon_area_opt;
    struct Flag *id_flag, *cats_acolors_flag, *sqrt_flag, *legend_flag;
    char *desc;
    
    struct cat_list *Clist;
    LATTR lattr;
    struct Map_info Map;
    struct Cell_head window;
    struct bound_box box;
    double overlap;

    stat = 0;
    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("graphics"));
    G_add_keyword(_("vector"));
    module->description = _("Displays user-specified vector map "
			    "in the active graphics frame.");
    
    map_opt = G_define_standard_option(G_OPT_V_MAP);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
    field_opt->answer = "1";
    field_opt->guisection = _("Selection");

    display_opt = G_define_option();
    display_opt->key = "display";
    display_opt->type = TYPE_STRING;
    display_opt->required = YES;
    display_opt->multiple = YES;
    display_opt->answer = "shape";
    display_opt->options = "shape,cat,topo,vert,dir,zcoor";
    display_opt->description = _("Display");
    desc = NULL;
    G_asprintf(&desc,
	       "shape;%s;cat;%s;topo;%s;vert;%s;dir;%s;zcoor;%s",
	       _("Display geometry of features"),
	       _("Display category numbers of features"),
	       _("Display topology information (nodes, edges)"),
               _("Display vertices of features"),
	       _("Display direction of linear features"),
	       _("Display z-coordinate of features (only for 3D vector maps)"));
    display_opt->descriptions = desc;
    
    /* Query */
    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->answer = "point,line,area,face";
    type_opt->options = "point,line,boundary,centroid,area,face";
    type_opt->guisection = _("Selection");
    
    cat_opt = G_define_standard_option(G_OPT_V_CATS);
    cat_opt->guisection = _("Selection");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
    where_opt->guisection = _("Selection");


    /* Colors */
    color_opt = G_define_standard_option(G_OPT_CN);
    color_opt->label = _("Feature color");
    color_opt->guisection = _("Colors");
    
    fcolor_opt = G_define_standard_option(G_OPT_CN);
    fcolor_opt->key = "fill_color";
    fcolor_opt->answer = "200:200:200";
    fcolor_opt->label = _("Area fill color");
    fcolor_opt->guisection = _("Colors");

    rgbcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    rgbcol_opt->key = "rgb_column";
    rgbcol_opt->guisection = _("Colors");
    rgbcol_opt->label = _("Colorize features according color definition column");
    rgbcol_opt->description = _("Color definition in R:G:B form");
    
    zcol_opt = G_define_standard_option(G_OPT_M_COLR);
    zcol_opt->key = "zcolor";
    zcol_opt->description = _("Colorize point or area features according to z-coordinate");
    zcol_opt->guisection = _("Colors");

    /* Lines */
    width_opt = G_define_option();
    width_opt->key = "width";
    width_opt->type = TYPE_INTEGER;
    width_opt->answer = "0";
    width_opt->guisection = _("Lines");
    width_opt->description = _("Line width");

    wcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    wcolumn_opt->key = "width_column";
    wcolumn_opt->guisection = _("Lines");
    wcolumn_opt->label = _("Name of numeric column containing line width");
    wcolumn_opt->description = _("These values will be scaled by width_scale");

    wscale_opt = G_define_option();
    wscale_opt->key = "width_scale";
    wscale_opt->type = TYPE_DOUBLE;
    wscale_opt->answer = "1";
    wscale_opt->guisection = _("Lines");
    wscale_opt->description = _("Scale factor for width_column");

    /* Symbols */
    icon_opt = G_define_option();
    icon_opt->key = "icon";
    icon_opt->type = TYPE_STRING;
    icon_opt->required = NO;
    icon_opt->multiple = NO;
    icon_opt->guisection = _("Symbols");
    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_DOUBLE;
    size_opt->answer = "5";
    size_opt->guisection = _("Symbols");
    size_opt->label = _("Symbol size");
    size_opt->description =
	_("When used with the size_column option this becomes the scale factor");

    sizecolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    sizecolumn_opt->key = "size_column";
    sizecolumn_opt->guisection = _("Symbols");
    sizecolumn_opt->description =
	_("Name of numeric column containing symbol size");

    rotcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    rotcolumn_opt->key = "rotation_column";
    rotcolumn_opt->guisection = _("Symbols");
    rotcolumn_opt->label =
	_("Name of numeric column containing symbol rotation angle");
    rotcolumn_opt->description =
	_("Measured in degrees CCW from east");

    icon_area_opt = G_define_option();
    icon_area_opt->key = "icon_area";
    icon_area_opt->type = TYPE_STRING;
    icon_area_opt->required = NO;
    icon_area_opt->multiple = NO;
    icon_area_opt->guisection = _("Legend");
    icon_area_opt->answer = "legend/area";
    icon_area_opt->options = icon_files();
    icon_area_opt->description = _("Area/boundary symbol for legend");

    icon_line_opt = G_define_option();
    icon_line_opt->key = "icon_line";
    icon_line_opt->type = TYPE_STRING;
    icon_line_opt->required = NO;
    icon_line_opt->multiple = NO;
    icon_line_opt->guisection = _("Legend");
    icon_line_opt->answer = "legend/line";
    icon_line_opt->options = icon_files();
    icon_line_opt->description = _("Line symbol for legend");

    leglab_opt = G_define_option();
    leglab_opt->key = "legend_label";
    leglab_opt->type = TYPE_STRING;
    leglab_opt->guisection = _("Legend");
    leglab_opt->description = _("Label to display after symbol in vector legend");

    /* Labels */
    lfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    lfield_opt->key = "label_layer";
    lfield_opt->required = NO;
    lfield_opt->guisection = _("Labels");
    lfield_opt->label =
	_("Layer number for labels (default: the given layer number)");
    
    attrcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    attrcol_opt->key = "attribute_column";
    attrcol_opt->multiple = NO;	/* or fix attr.c, around line 102 */
    attrcol_opt->guisection = _("Labels");
    attrcol_opt->description = _("Name of column to be displayed as a label");

    lcolor_opt = G_define_standard_option(G_OPT_C);
    lcolor_opt->key = "label_color";
    lcolor_opt->answer = "red";
    lcolor_opt->label = _("Label color");
    lcolor_opt->guisection = _("Labels");

    bgcolor_opt = G_define_standard_option(G_OPT_CN);
    bgcolor_opt->key = "label_bgcolor";
    bgcolor_opt->answer = "none";
    bgcolor_opt->guisection = _("Labels");
    bgcolor_opt->label = _("Label background color");

    bcolor_opt = G_define_standard_option(G_OPT_CN);
    bcolor_opt->key = "label_bcolor";
    bcolor_opt->type = TYPE_STRING;
    bcolor_opt->answer = "none";
    bcolor_opt->guisection = _("Labels");
    bcolor_opt->label = _("Label border color");

    lsize_opt = G_define_option();
    lsize_opt->key = "label_size";
    lsize_opt->type = TYPE_INTEGER;
    lsize_opt->answer = "8";
    lsize_opt->guisection = _("Labels");
    lsize_opt->description = _("Label size (pixels)");

    font_opt = G_define_option();
    font_opt->key = "font";
    font_opt->type = TYPE_STRING;
    font_opt->guisection = _("Labels");
    font_opt->description = _("Font name");

    enc_opt = G_define_option();
    enc_opt->key = "encoding";
    enc_opt->type = TYPE_STRING;
    enc_opt->guisection = _("Labels");
    enc_opt->description = _("Text encoding");

    xref_opt = G_define_option();
    xref_opt->key = "xref";
    xref_opt->type = TYPE_STRING;
    xref_opt->guisection = _("Labels");
    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->guisection = _("Labels");
    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");

    /* Colors */
    cats_acolors_flag = G_define_flag();
    cats_acolors_flag->key = 'c';
    cats_acolors_flag->guisection = _("Colors");
    cats_acolors_flag->description =
	_("Random colors according to category number "
	  "(or layer number if 'layer=-1' is given)");

    /* Query */
    id_flag = G_define_flag();
    id_flag->key = 'i';
    id_flag->guisection = _("Selection");
    id_flag->description = _("Use values from 'cats' option as feature id");

    sqrt_flag = G_define_flag();
    sqrt_flag->key = 'r';
    sqrt_flag->label = _("Use square root of the value of size_column");
    sqrt_flag->description =
	_("This makes circle areas proportionate to the size_column values "
	  "instead of circle radius");
    sqrt_flag->guisection = _("Symbols");

    legend_flag = G_define_flag();
    legend_flag->key = 's';
    legend_flag->label = _("Do not show this layer in vector legend");
    legend_flag->guisection = _("Legend");

    /* Check command line */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    D_open_driver();
    
    G_get_set_window(&window);
    
    /* 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) {
	    G_important_message(_("Region size is lower than minreg, nothing displayed"));
	    exit(EXIT_SUCCESS);
	}
    }
    if (maxreg_opt->answer) {
	maxreg = atof(maxreg_opt->answer);

	if (reg > maxreg) {
	    G_important_message(_("Region size is greater than maxreg, nothing displayed"));
	    exit(EXIT_SUCCESS);
	}
    }

    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);

    if (cats_acolors_flag->answer && rgbcol_opt->answer) {
	G_warning(_("The -%c flag and <%s> option cannot be used together, "
		    "the -%c flag will be ignored!"), 
                  cats_acolors_flag->key, rgbcol_opt->key, cats_acolors_flag->key);
        cats_acolors_flag->answer = FALSE;
    }

    color = G_standard_color_rgb(WHITE);
    has_color = option_to_color(&color, color_opt->answer);
    fcolor = G_standard_color_rgb(WHITE);
    has_fcolor = option_to_color(&fcolor, fcolor_opt->answer);
    
    size = atof(size_opt->answer);

    /* 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_old2(&Map, map_name, "", field_opt->answer);

    chcat = 0;
    if (where_opt->answer) {
	if (Clist->field < 1)
	    G_fatal_error(_("Option <%s> must be > 0"), field_opt->key);
	chcat = 1;
	option_to_where(&Map, Clist, where_opt->answer);
    }
    else if (cat_opt->answer) {
	if (Clist->field < 1 && !id_flag->answer)
	    G_fatal_error(_("Option <%s> must be > 0"), field_opt->key);
	chcat = 1;
	ret = Vect_str_to_cat_list(cat_opt->answer, Clist);
	if (ret > 0)
	    G_warning(n_("%d error in cat option", "%d errors in cat option", ret), ret);
    }
    
    type = Vect_option_to_types(type_opt);
    
    display = option_to_display(display_opt);

    /* labels */
    options_to_lattr(&lattr, lfield_opt->answer,
		     lcolor_opt->answer, bgcolor_opt->answer, bcolor_opt->answer,
		     atoi(lsize_opt->answer), font_opt->answer, enc_opt->answer,
		     xref_opt->answer, yref_opt->answer);

    D_setup(0);
    D_set_reduction(1.0);

    G_verbose_message(_("Plotting..."));

    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_warning(_("The bounding box of the map is outside the current region, "
		    "nothing drawn"));
    }
    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)
	    D_line_width(default_width);

	if (display & DISP_SHAPE) {
	    stat += display_shape(&Map, type, Clist, &window,
				  has_color ? &color : NULL, has_fcolor ? &fcolor : NULL, chcat,
				  icon_opt->answer, size, sizecolumn_opt->answer,
				  sqrt_flag->answer ? TRUE : FALSE, rotcolumn_opt->answer,
				  id_flag->answer ? TRUE : FALSE, 
				  cats_acolors_flag->answer ? TRUE : FALSE, rgbcol_opt->answer,
				  default_width,  wcolumn_opt->answer, width_scale,
				  zcol_opt->answer);
	    
	    if (wcolumn_opt->answer)
		D_line_width(default_width);
	}

	if (has_color) {
	    D_RGB_color(color.r, color.g, color.b);
	    if (display & DISP_DIR)
		stat += display_dir(&Map, type, Clist, chcat, size);
	}

	if (!legend_flag->answer) {
		write_into_legfile(&Map, type, leglab_opt->answer, map_name,
			   icon_opt->answer, size_opt->answer, 
			   color_opt->answer, fcolor_opt->answer, 
			   width_opt->answer, icon_area_opt->answer,
			   icon_line_opt->answer, sizecolumn_opt->answer);
	}

	/* 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)
	    D_line_width(0);
	
	if (display & DISP_CAT)
	    stat += display_label(&Map, type, Clist, &lattr, chcat);

	if (attrcol_opt->answer)
	    stat += display_attr(&Map, type, attrcol_opt->answer, Clist, &lattr, chcat);

	if (display & DISP_ZCOOR)
	    stat += display_zcoor(&Map, type, &lattr);

	if (display & DISP_VERT)
            stat += display_vert(&Map, type, &lattr, size);

	if (display & DISP_TOPO)
            stat += display_topo(&Map, type, &lattr, size);
    }

    D_save_command(G_recreate_command());
    D_close_driver();

    Vect_close(&Map);
    Vect_destroy_cat_list(Clist);

    if (stat != 0) {
	G_fatal_error(_("Rendering failed"));
    }
    
    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Beispiel #13
0
int main(int argc, char *argv[])
{
    char *terrainmap, *seedmap, *lakemap;
    int rows, cols, in_terran_fd, out_fd, lake_fd, row, col, pases, pass;
    int lastcount, curcount, start_col = 0, start_row = 0;
    double east, north, area = 0, volume = 0;
    FCELL **in_terran, **out_water, water_level, max_depth = 0, min_depth = 0;
    FCELL water_window[3][3];
    struct Option *tmap_opt, *smap_opt, *wlvl_opt, *lake_opt, *sdxy_opt;
    struct Flag *negative_flag, *overwrite_flag;
    struct GModule *module;
    struct Colors colr;
    struct Cell_head window;
    struct History history;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("hazard"));
    G_add_keyword(_("flood"));
    module->description = _("Fills lake at given point to given level.");

    tmap_opt = G_define_standard_option(G_OPT_R_ELEV);

    wlvl_opt = G_define_option();
    wlvl_opt->key = "water_level";
    wlvl_opt->description = _("Water level");
    wlvl_opt->type = TYPE_DOUBLE;
    wlvl_opt->required = YES;

    lake_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    lake_opt->key = "lake";
    lake_opt->required = NO;
    lake_opt->guisection = _("Output");

    sdxy_opt = G_define_standard_option(G_OPT_M_COORDS);
    sdxy_opt->label = _("Seed point coordinates");
    sdxy_opt->description = _("Either this coordinates pair or a seed"
	" map have to be specified");
    sdxy_opt->required = NO;
    sdxy_opt->multiple = NO;
    sdxy_opt->guisection = _("Seed");

    smap_opt = G_define_standard_option(G_OPT_R_MAP);
    smap_opt->key = "seed";
    smap_opt->label =
	_("Input raster map with given starting point(s) (at least 1 cell > 0)");
    smap_opt->description =
	_("Either this parameter or a coordinates pair have to be specified");
    smap_opt->required = NO;
    smap_opt->guisection = _("Seed");

    negative_flag = G_define_flag();
    negative_flag->key = 'n';
    negative_flag->description =
	_("Use negative depth values for lake raster map");

    overwrite_flag = G_define_flag();
    overwrite_flag->key = 'o';
    overwrite_flag->description =
	_("Overwrite seed map with result (lake) map");
    overwrite_flag->guisection = _("Output");

    if (G_parser(argc, argv))	/* Returns 0 if successful, non-zero otherwise */
	exit(EXIT_FAILURE);

    if (smap_opt->answer && sdxy_opt->answer)
	G_fatal_error(_("Both seed map and coordinates cannot be specified"));

    if (!smap_opt->answer && !sdxy_opt->answer)
	G_fatal_error(_("Seed map or seed coordinates must be set!"));

    if (sdxy_opt->answer && !lake_opt->answer)
	G_fatal_error(_("Seed coordinates and output map lake= must be set!"));

    if (lake_opt->answer && overwrite_flag->answer)
	G_fatal_error(_("Both lake and overwrite cannot be specified"));

    if (!lake_opt->answer && !overwrite_flag->answer)
	G_fatal_error(_("Output lake map or overwrite flag must be set!"));

    terrainmap = tmap_opt->answer;
    seedmap = smap_opt->answer;
    sscanf(wlvl_opt->answer, "%f", &water_level);
    lakemap = lake_opt->answer;

    /* If lakemap is set, write to it, else is set overwrite flag and we should write to seedmap. */
    if (lakemap)
	lake_fd = Rast_open_new(lakemap, 1);

    rows = Rast_window_rows();
    cols = Rast_window_cols();

    /* If we use x,y as seed... */
    if (sdxy_opt->answer) {
	G_get_window(&window);
	east = window.east;
	north = window.north;

	G_scan_easting(sdxy_opt->answers[0], &east, G_projection());
	G_scan_northing(sdxy_opt->answers[1], &north, G_projection());
	start_col = (int)Rast_easting_to_col(east, &window);
	start_row = (int)Rast_northing_to_row(north, &window);

	if (start_row < 0 || start_row > rows ||
	    start_col < 0 || start_col > cols)
	    G_fatal_error(_("Seed point outside the current region"));
    }

    /* Open terrain map */
    in_terran_fd = Rast_open_old(terrainmap, "");

    /* Open seed map */
    if (smap_opt->answer)
	out_fd = Rast_open_old(seedmap, "");

    /* Pointers to rows. Row = ptr to 'col' size array. */
    in_terran = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    out_water = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    if (in_terran == NULL || out_water == NULL)
	G_fatal_error(_("G_malloc: out of memory"));


    G_debug(1, "Loading maps...");
    /* foo_rows[row] == array with data (2d array). */
    for (row = 0; row < rows; row++) {
	in_terran[row] = (FCELL *) G_malloc(cols * sizeof(FCELL));
	out_water[row] = (FCELL *) G_calloc(cols, sizeof(FCELL));

	/* In newly created space load data from file. */
	Rast_get_f_row(in_terran_fd, in_terran[row], row);

	if (smap_opt->answer)
	    Rast_get_f_row(out_fd, out_water[row], row);

	G_percent(row + 1, rows, 5);
    }

    /* Set seed point */
    if (sdxy_opt->answer)
	/* Check is water level higher than seed point */
	if (in_terran[start_row][start_col] >= water_level)
	    G_fatal_error(_("Given water level at seed point is below earth surface. "
			   "Increase water level or move seed point."));
    out_water[start_row][start_col] = 1;

    /* Close seed map for reading. */
    if (smap_opt->answer)
	Rast_close(out_fd);

    /* Open output map for writing. */
    if (lakemap)
	out_fd = lake_fd;
    else
	out_fd = Rast_open_new(seedmap, 1);

    /* More pases are renudant. Real pases count is controlled by altered cell count. */
    pases = (int)(rows * cols) / 2;

    G_debug(1,
	    "Starting lake filling at level of %8.4f in %d passes. Percent done:",
	    water_level, pases);

    lastcount = 0;

    for (pass = 0; pass < pases; pass++) {
	G_debug(3, "Pass: %d", pass);
	curcount = 0;
	/* Move from left upper corner to right lower corner. */
	for (row = 0; row < rows; row++) {
	    for (col = 0; col < cols; col++) {
		/* Loading water data into window. */
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		/* Cheking presence of water. */
		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;	/* Cell is higher than water level -> NULL. */
		    }
		}
	    }
	}
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
	curcount = 0;
	/* Move backwards - from lower right corner to upper left corner. */
	for (row = rows - 1; row >= 0; row--) {
	    for (col = cols - 1; col >= 0; col--) {
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;
		    }
		}
	    }
	}
	G_percent(pass + 1, pases, 10);
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
    }				/*pases */

    G_percent(pases, pases, 10);	/* Show 100%. */

    save_map(out_water, out_fd, rows, cols, negative_flag->answer, &min_depth,
	     &max_depth, &area, &volume);

    G_message(_("Lake depth from %f to %f (specified water level is taken as zero)"), min_depth, max_depth);
    G_message(_("Lake area %f square meters"), area);
    G_message(_("Lake volume %f cubic meters"), volume);
    G_important_message(_("Volume is correct only if lake depth (terrain raster map) is in meters"));

    /* Close all files. Lake map gets written only now. */
    Rast_close(in_terran_fd);
    Rast_close(out_fd);

    /* Add blue color gradient from light bank to dark depth */
    Rast_init_colors(&colr);
    if (negative_flag->answer == 1) {
	Rast_add_f_color_rule(&max_depth, 0, 240, 255,
				  &min_depth, 0, 50, 170, &colr);
    }
    else {
	Rast_add_f_color_rule(&min_depth, 0, 240, 255,
				  &max_depth, 0, 50, 170, &colr);
    }

    Rast_write_colors(lakemap, G_mapset(), &colr);

    Rast_short_history(lakemap, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(lakemap, &history);

    return EXIT_SUCCESS;
}
Beispiel #14
0
int read_points(const char *name, const char *field_name, const char *col, std::map<Point, Coord_type, K::Less_xy_2>& function_values,
    std::vector<K::Point_2>& OutPoints)
{
    int nrec, ctype = 0, npoints, field, with_z;
    double x, y, z;
    Point p;

    struct Map_info Map;    
    struct field_info *Fi;
    struct line_pnts *Points;
    struct line_cats *Cats;
    dbDriver *Driver;
    dbCatValArray cvarr;



    Vect_set_open_level(1);	/* without topology */
    if (Vect_open_old2(&Map, name, "", field_name) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), name);

    field = Vect_get_field_number(&Map, field_name);
    with_z = col == NULL && Vect_is_3d(&Map); /* read z-coordinates
                                                 only when column is
                                                 not defined */

    if (!col) {
        if (!with_z)
            G_important_message(_("Input vector map <%s> is 2D - using categories to interpolate"),
                                Vect_get_full_name(&Map));
        else
            G_important_message(_("Input vector map <%s> is 3D - using z-coordinates to interpolate"),
                                Vect_get_full_name(&Map));
    }

    if (col) {
        db_CatValArray_init(&cvarr);

        Fi = Vect_get_field(&Map, field);
        if (Fi == NULL)
            G_fatal_error(_("Database connection not defined for layer %s"), field_name);

        Driver = db_start_driver_open_database(Fi->driver, Fi->database);
        if (Driver == NULL)
            G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver);

        nrec = db_select_CatValArray(Driver, Fi->table, Fi->key, col, NULL, &cvarr);
        G_debug(3, "nrec = %d", nrec);

        ctype = cvarr.ctype;
        if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
            G_fatal_error(_("Column type not supported"));

        if (nrec < 0)
            G_fatal_error(_("Unable to select data from table"));

        G_verbose_message("One record selected from table %d records selected from table", nrec);

        db_close_database_shutdown_driver(Driver);
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();


    /* set constraints */
    Vect_set_constraint_type(&Map, GV_POINTS);
    if (field > 0)
        Vect_set_constraint_field(&Map, field);
    
    /* read points */
    npoints = 0;
    G_message(_("Reading points..."));
    while(TRUE) {
        double dval;
        if (Vect_read_next_line(&Map, Points, Cats) < 0)
            break;

        G_progress(npoints, 1e3);
        
        if (Points->n_points != 1) {
            G_warning(_("Invalid point skipped"));
            continue;
        }
        
        if (!with_z) {
            int cat, ival, ret;

            /* TODO: what to do with multiple cats */
            Vect_cat_get(Cats, field, &cat);
            if (cat < 0) /* skip features without category */
                continue;

            if (col) {
                if (ctype == DB_C_TYPE_INT) {
                    ret = db_CatValArray_get_value_int(&cvarr, cat, &ival);
                    dval = ival;
                }
                else {		/* DB_C_TYPE_DOUBLE */
                    ret = db_CatValArray_get_value_double(&cvarr, cat, &dval);
                }

                if (ret != DB_OK) {
                  G_warning(_("No record for point (cat = %d)"), cat);
                  continue;
                }
            }
            else {
                dval = cat;
            }
        }
        else
            dval = Points->z[0];

        x = Points->x[0];
        y = Points->y[0];
        
        p = Point(x,y);
        OutPoints.push_back(p);
        function_values.insert(std::make_pair(p, dval));       
        
        G_debug(3, "new point added: %f, %f, %f", x, y, dval);
        npoints++;
    }
    G_progress(1, 1);

    if (col)
        db_CatValArray_free(&cvarr);

    Vect_set_release_support(&Map);
    Vect_close(&Map);
    Vect_destroy_line_struct(Points);

    G_debug(1, "read_points(): %d", npoints);
    G_message("%d point loaded", npoints);
    
    return npoints;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;
    struct cat_list *Clist;
    int i, j, ret, option, otype, type, with_z, step, id;
    int n_areas, centr, new_centr, nmodified;
    int open_level;
    double x, y;
    int cat, ocat, scat, *fields, nfields, field;
    struct GModule *module;
    struct Option *in_opt, *out_opt, *option_opt, *type_opt;
    struct Option *cat_opt, *field_opt, *step_opt, *id_opt;
    struct Flag *shell, *notab;
    FREPORT **freps;
    int nfreps, rtype, fld;
    char *desc;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("category"));
    G_add_keyword(_("layer"));
    module->description =
	_("Attaches, deletes or reports vector categories to map geometry.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD);
    field_opt->multiple = YES;
    field_opt->guisection = _("Selection");

    type_opt = G_define_standard_option(G_OPT_V3_TYPE);
    type_opt->answer = "point,line,centroid,face";
    type_opt->guisection = _("Selection");

    id_opt = G_define_standard_option(G_OPT_V_IDS);
    id_opt->label = _("Feature ids (by default all features are processed)");
    id_opt->guisection = _("Selection");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = NO;

    option_opt = G_define_option();
    option_opt->key = "option";
    option_opt->type = TYPE_STRING;
    option_opt->required = YES;
    option_opt->multiple = NO;
    option_opt->options = "add,del,chlayer,sum,report,print,layers,transfer";
    option_opt->description = _("Action to be done");
    desc = NULL;
    G_asprintf(&desc,
	       "add;%s;"
	       "del;%s;"
	       "chlayer;%s;"
	       "sum;%s;"
	       "transfer;%s;"
	       "report;%s;"
	       "print;%s;"
	       "layers;%s",
	       _("add a category to features without category in the given layer"),
	       _("delete category (cat=-1 to delete all categories of given layer)"),
	       _("change layer number (e.g. layer=3,1 changes layer 3 to layer 1)"),
	       _("add the value specified by cat option to the current category value"),
	       _("copy values from one layer to another (e.g. layer=1,2,3 copies values from layer 1 to layer 2 and 3)"),
	       _("print report (statistics), in shell style: layer type count min max"),
	       _("print category values, layers are separated by '|', more cats in the same layer are separated by '/'"),
	       _("print only layer numbers"));
    option_opt->descriptions = desc;
    
    cat_opt = G_define_standard_option(G_OPT_V_CAT);
    cat_opt->answer = "1";

    step_opt = G_define_option();
    step_opt->key = "step";
    step_opt->type = TYPE_INTEGER;
    step_opt->required = NO;
    step_opt->multiple = NO;
    step_opt->answer = "1";
    step_opt->description = _("Category increment");

    shell = G_define_flag();
    shell->key = 'g';
    shell->label = _("Shell script style, currently only for report");
    shell->description = _("Format: layer type count min max");
    
    notab = G_define_standard_flag(G_FLG_V_TABLE);
    notab->description = _("Do not copy attribute table(s)");

    G_gisinit(argv[0]);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* read options */
    option = 0;
    switch (option_opt->answer[0]) {
    case ('a'):
	option = O_ADD;
	break;
    case ('d'):
	option = O_DEL;
	break;
    case ('c'):
	option = O_CHFIELD;
	G_warning(_("Database connection and attribute tables for concerned layers are not changed"));
	break;
    case ('s'):
	option = O_SUM;
	break;
    case ('t'):
        option = O_TRANS;
        break;
    case ('r'):
	option = O_REP;
	break;
    case ('p'):
	option = O_PRN;
	break;
    case ('l'):
	option = O_LYR;
	break;
    }

    if (option == O_LYR) {
	/* print vector layer numbers */
	/* open vector on level 2 head only, this is why this option
	 * is processed here, all other options need (?) to fully open 
	 * the input vector */
	Vect_set_open_level(2);
	if (Vect_open_old_head2(&In, in_opt->answer, "", field_opt->answer) < 2) {
	    G_fatal_error(_("Unable to open vector map <%s> at topological level %d"),
			  Vect_get_full_name(&In), 2);
	}
	if (In.format == GV_FORMAT_NATIVE) {
	    nfields = Vect_cidx_get_num_fields(&In);
	    for (i = 0; i < nfields; i++) {
		if ((field = Vect_cidx_get_field_number(&In, i)) > 0)
		    fprintf(stdout, "%d\n", field);
	    }
	}
	else
	    fprintf(stdout, "%s\n", field_opt->answer);

	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }

    cat = atoi(cat_opt->answer);
    step = atoi(step_opt->answer);
    otype = Vect_option_to_types(type_opt);

    if (cat < 0 && option == O_ADD)
	G_fatal_error(_("Invalid category number (must be equal to or greater than 0). "
			"Normally category number starts at 1."));

    /* collect ids */
    if (id_opt->answer) {
	Clist = Vect_new_cat_list();
	Clist->field = atoi(field_opt->answer);
	ret = Vect_str_to_cat_list(id_opt->answer, Clist);
	if (ret > 0) {
	    G_warning(n_("%d error in id option",
                         "%d errors in id option",
                         ret), ret);
	}
    }
    else {
	Clist = NULL;
    }

    if ((option != O_REP) && (option != O_PRN) && (option != O_LYR)) {
	if (out_opt->answer == NULL)
	    G_fatal_error(_("Output vector wasn't entered"));

	Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				     G_FATAL_EXIT);
    }

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /* do we need topology ? */
    if ((option == O_ADD && (otype & GV_AREA)) ||
	(option == O_REP && (otype & GV_AREA)) ||
        (option == O_TRANS) || /* topo for cidx check */
        (option == O_LYR)) /* topo for cidx check */
	open_level = 2;
    else
	open_level = 1;

    /* open input vector */
    if (open_level > 1) {
	Vect_set_open_level(open_level);
	if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < open_level) {
	    G_warning(_("Unable to open vector map <%s> at topological level %d"),
			  Vect_get_full_name(&In), open_level);
	    open_level = 1;
	}
    }
    if (open_level == 1) {
	Vect_set_open_level(open_level);
	if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < open_level) {
	    G_fatal_error(_("Unable to open vector map <%s> at topological level %d"),
			  Vect_get_full_name(&In), open_level);
	}
    }

    /* read fields */
    i = nfields = 0;
    while (field_opt->answers[i++])
	nfields++;
    fields = (int *)G_malloc(nfields * sizeof(int));
    
    i = 0;
    while (field_opt->answers[i]) {
	fields[i] = Vect_get_field_number(&In, field_opt->answers[i]);
	i++;
    }
    if (nfields > 1 && option != O_PRN && option != O_CHFIELD && option != O_TRANS)
	G_fatal_error(_("Too many layers for this operation"));
    
    if (nfields != 2 && option == O_CHFIELD)
	G_fatal_error(_("2 layers must be specified"));

    if (option == O_TRANS && open_level == 1 && nfields < 2) {
	G_fatal_error(_("2 layers must be specified"));
    }

    if (option == O_TRANS && open_level > 1) {
	/* check if field[>0] already exists */
	if (nfields > 1) {
	    for(i = 1; i < nfields; i++) {
		if (Vect_cidx_get_field_index(&In, fields[i]) != -1)
		    G_warning(_("Categories already exist in layer %d"), fields[i]);
	    }
	}
	/* find next free layer number */
	else if (nfields == 1) {
	    int max = -1;
	    
	    for (i = 0; i < Vect_cidx_get_num_fields(&In); i++) {
		if (max < Vect_cidx_get_field_number(&In, i))
		    max = Vect_cidx_get_field_number(&In, i);
	    }
	    max++;

	    nfields++;
	    fields = (int *)G_realloc(fields, nfields * sizeof(int));
	    fields[nfields - 1] = max;
	}
    }

    if (otype & GV_AREA && option == O_TRANS && !(otype & GV_CENTROID))
	otype |= GV_CENTROID;

    /* open output vector if needed */
    if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
	option == O_SUM || option == O_TRANS) {
	with_z = Vect_is_3d(&In);

	if (0 > Vect_open_new(&Out, out_opt->answer, with_z)) {
	    Vect_close(&In);
	    exit(EXIT_FAILURE);
	}

	Vect_copy_head_data(&In, &Out);
	Vect_hist_copy(&In, &Out);
	Vect_hist_command(&Out);
    }

    id = 0;

    nmodified = 0;

    if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
	option == O_SUM || option == O_TRANS) {
	G_message(_("Processing features..."));
    }

    switch (option) {
    case (O_ADD):
	/* Lines */
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (type & otype && (!Clist ||
				 (Clist &&
				  Vect_cat_in_cat_list(id, Clist) == TRUE))) {
		if ((Vect_cat_get(Cats, fields[0], &ocat)) == 0) {
		    if (ocat < 0) {
			if (Vect_cat_set(Cats, fields[0], cat) > 0) {
			    nmodified++;
			}
			cat += step;
		    }
		}
	    }
	    Vect_write_line(&Out, type, Points, Cats);
	}
	/* Areas */
	if ((otype & GV_AREA) && open_level > 1) {
	    n_areas = Vect_get_num_areas(&In);
	    new_centr = 0;
	    for (i = 1; i <= n_areas; i++) {
		centr = Vect_get_area_centroid(&In, i);
		if (centr > 0)
		    continue;	/* Centroid exists and may be processed as line */
		ret = Vect_get_point_in_area(&In, i, &x, &y);
		if (ret < 0) {
		    G_warning(_("Unable to calculate area centroid"));
		    continue;
		}
		Vect_reset_line(Points);
		Vect_reset_cats(Cats);
		Vect_append_point(Points, x, y, 0.0);
		if (Vect_cat_set(Cats, fields[0], cat) > 0) {
		    nmodified++;
		}
		cat += step;
		Vect_write_line(&Out, GV_CENTROID, Points, Cats);
		new_centr++;
	    }
	    if (new_centr > 0) 
		G_message(n_("%d new centroid placed in output map",
                             "%d new centroids placed in output map",
                             new_centr), new_centr);
	}
	break;

    case (O_TRANS):
	/* Lines */
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (type & otype && (!Clist ||
				 (Clist &&
				  Vect_cat_in_cat_list(id, Clist) == TRUE))) {
		int n = Cats->n_cats;

		scat = -1;
		for (i = 0; i < n; i++) {
		    if (Cats->field[i] == fields[0]) {
			scat = Cats->cat[i];
			for (j = 1; j < nfields; j++) {
			    if (Vect_cat_set(Cats, fields[j], scat) > 0) {
				G_debug(4, "Copy cat %i of field %i to field %i", scat, fields[0], fields[j]);
			    }
			}
		    }
		}
		if (scat != -1)
		    nmodified++;
	    }
	    Vect_write_line(&Out, type, Points, Cats);
	}
	break;

    case (O_DEL):
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (type & otype && (!Clist ||
				 (Clist &&
				  Vect_cat_in_cat_list(id, Clist) == TRUE))) {
		ret = Vect_field_cat_del(Cats, fields[0], cat);
		if (ret > 0) {
		    nmodified++;
		}
	    }
	    Vect_write_line(&Out, type, Points, Cats);
	}
	break;

    case (O_CHFIELD):
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (type & otype && (!Clist ||
				 (Clist &&
				  Vect_cat_in_cat_list(id, Clist) == TRUE))) {
		i = 0;
		while (i < Cats->n_cats) {
		    if (Cats->field[i] == fields[0]) {
			int found = -1;
			
			/* check if cat already exists in layer fields[1] */
			for (j = 0; j < Cats->n_cats; j++) {
			    if (Cats->field[j] == fields[1] &&
				Cats->cat[j] == Cats->cat[i]) {
				found = j;
				break;
			    }
			}
			/* does not exist, change layer */
			if (found < 0) {
			    Cats->field[i] = fields[1];
			    i++;
			}
			/* exists already in fields[1], delete from fields[0] */
			else
			    Vect_field_cat_del(Cats, fields[0], Cats->cat[found]);
			nmodified++;
		    }
		}
	    }
	    Vect_write_line(&Out, type, Points, Cats);
	}
	break;

    case (O_SUM):
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (type & otype && (!Clist ||
				 (Clist &&
				  Vect_cat_in_cat_list(id, Clist) == TRUE))) {
		for (i = 0; i < Cats->n_cats; i++) {
		    if (Cats->field[i] == fields[0]) {
			Cats->cat[i] += cat;
		    }
		}
		nmodified++;
	    }
	    Vect_write_line(&Out, type, Points, Cats);
	}
	break;

    case (O_REP):
	nfreps = 0;
	freps = NULL;
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    if (Clist && Vect_cat_in_cat_list(id, Clist) == FALSE)
		continue;

	    switch (type) {
	    case (GV_POINT):
		rtype = FR_POINT;
		break;
	    case (GV_LINE):
		rtype = FR_LINE;
		break;
	    case (GV_BOUNDARY):
		rtype = FR_BOUNDARY;
		break;
	    case (GV_CENTROID):
		rtype = FR_CENTROID;
		break;
	    case (GV_FACE):
		rtype = FR_FACE;
		break;
	    case (GV_KERNEL):
		rtype = FR_KERNEL;
		break;
	    default:
		rtype = FR_UNKNOWN;
	    }

	    for (i = 0; i < Cats->n_cats; i++) {
		field = Cats->field[i];
		cat = Cats->cat[i];


		ret = FALSE;
		for (j = 0; j < nfreps; j++) {
		    if (freps[j]->field == field) {
			fld = j;
			ret = TRUE;
			break;
		    }
		}
		if (!ret) {	/* field report doesn't exist */
		    nfreps++;
		    freps =
			(FREPORT **) G_realloc(freps,
					       nfreps * sizeof(FREPORT *));
		    fld = nfreps - 1;
		    freps[fld] = (FREPORT *) G_calloc(1, sizeof(FREPORT));
		    freps[fld]->field = field;
		    for (j = 0; j < FRTYPES; j++) {
			/* cat '0' is valid category number */
			freps[fld]->min[j] = -1;
		    }
		    if ((Fi = Vect_get_field(&In, field)) != NULL) {
			freps[fld]->table = G_store(Fi->table);
		    }
		    else {
			freps[fld]->table = '\0';
		    }
		}

		freps[fld]->count[rtype]++;
		freps[fld]->count[FR_ALL]++;

		if (freps[fld]->min[rtype] == -1 ||
		    freps[fld]->min[rtype] > cat)
		    freps[fld]->min[rtype] = cat;

		if ((freps[fld]->max[rtype] == 0) ||
		    freps[fld]->max[rtype] < cat)
		    freps[fld]->max[rtype] = cat;

		if (freps[fld]->min[FR_ALL] == -1 ||
		    freps[fld]->min[FR_ALL] > cat)
		    freps[fld]->min[FR_ALL] = cat;

		if ((freps[fld]->max[FR_ALL] == 0) ||
		    freps[fld]->max[FR_ALL] < cat)
		    freps[fld]->max[FR_ALL] = cat;
	    }
	}
	/* Areas */
	if ((otype & GV_AREA) && open_level > 1 && !Clist) {
	    n_areas = Vect_get_num_areas(&In);
	    for (i = 1; i <= n_areas; i++) {
		int k;

		centr = Vect_get_area_centroid(&In, i);
		if (centr <= 0)
		    continue;	/* Area without centroid */
		    
		Vect_read_line(&In, NULL, Cats, centr);
		for (j = 0; j < Cats->n_cats; j++) {
		    field = Cats->field[j];
		    cat = Cats->cat[j];


		    ret = FALSE;
		    for (k = 0; k < nfreps; k++) {
			if (freps[k]->field == field) {
			    fld = k;
			    ret = TRUE;
			    break;
			}
		    }
		    if (!ret) {	/* field report doesn't exist */
			nfreps++;
			freps =
			    (FREPORT **) G_realloc(freps,
						   nfreps * sizeof(FREPORT *));
			fld = nfreps - 1;
			freps[fld] = (FREPORT *) G_calloc(1, sizeof(FREPORT));
			freps[fld]->field = field;
			for (j = 0; j < FRTYPES; j++) {
			    /* cat '0' is valid category number */
			    freps[fld]->min[k] = -1;
			}
			if ((Fi = Vect_get_field(&In, field)) != NULL) {
			    freps[fld]->table = G_store(Fi->table);
			}
			else {
			    freps[fld]->table = '\0';
			}
		    }

		    freps[fld]->count[FR_AREA]++;

		    if (freps[fld]->min[FR_AREA] == -1 ||
			freps[fld]->min[FR_AREA] > cat)
			freps[fld]->min[FR_AREA] = cat;

		    if ((freps[fld]->max[FR_AREA] == 0) ||
			freps[fld]->max[FR_AREA] < cat)
			freps[fld]->max[FR_AREA] = cat;
		}
	    }
	}
	for (i = 0; i < nfreps; i++) {
	    if (shell->answer) {
		if (freps[i]->count[FR_POINT] > 0)
		    fprintf(stdout, "%d point %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_POINT],
			    (freps[i]->min[FR_POINT] < 0 ? 0 : freps[i]->min[FR_POINT]),
			    freps[i]->max[FR_POINT]);

		if (freps[i]->count[FR_LINE] > 0)
		    fprintf(stdout, "%d line %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_LINE],
			    (freps[i]->min[FR_LINE] < 0 ? 0 : freps[i]->min[FR_LINE]),
			    freps[i]->max[FR_LINE]);

		if (freps[i]->count[FR_BOUNDARY] > 0)
		    fprintf(stdout, "%d boundary %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_BOUNDARY],
			    (freps[i]->min[FR_BOUNDARY] < 0 ? 0 : freps[i]->min[FR_BOUNDARY]),
			    freps[i]->max[FR_BOUNDARY]);

		if (freps[i]->count[FR_CENTROID] > 0)
		    fprintf(stdout, "%d centroid %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_CENTROID],
			    (freps[i]->min[FR_BOUNDARY] < 0 ? 0 : freps[i]->min[FR_BOUNDARY]),
			    freps[i]->max[FR_CENTROID]);

		if (freps[i]->count[FR_AREA] > 0)
		    fprintf(stdout, "%d area %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_AREA],
			    (freps[i]->min[FR_AREA] < 0 ? 0 : freps[i]->min[FR_AREA]),
			    freps[i]->max[FR_AREA]);

		if (freps[i]->count[FR_FACE] > 0)
		    fprintf(stdout, "%d face %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_FACE],
			    (freps[i]->min[FR_FACE] < 0 ? 0 : freps[i]->min[FR_FACE]),
			    freps[i]->max[FR_FACE]);

		if (freps[i]->count[FR_KERNEL] > 0)
		    fprintf(stdout, "%d kernel %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_KERNEL],
			    (freps[i]->min[FR_KERNEL] < 0 ? 0 : freps[i]->min[FR_KERNEL]),
			    freps[i]->max[FR_KERNEL]);

		if (freps[i]->count[FR_ALL] > 0)
		    fprintf(stdout, "%d all %d %d %d\n", freps[i]->field,
			    freps[i]->count[FR_ALL],
			    (freps[i]->min[FR_ALL] < 0 ? 0 : freps[i]->min[FR_ALL]),
			    freps[i]->max[FR_ALL]);
	    }
	    else {
		if (freps[i]->table != '\0') {
		    fprintf(stdout, "%s: %d/%s\n", _("Layer/table"),
			    freps[i]->field, freps[i]->table);
		}
		else {
		    fprintf(stdout, "%s: %d\n", _("Layer"), freps[i]->field);
		}
		fprintf(stdout, _("type       count        min        max\n"));
		fprintf(stdout, "%s    %7d %10d %10d\n", _("point"),
			freps[i]->count[FR_POINT],
			(freps[i]->min[FR_POINT] < 0) ? 0 : freps[i]->min[FR_POINT],
			freps[i]->max[FR_POINT]);
		fprintf(stdout, "%s     %7d %10d %10d\n", _("line"),
			freps[i]->count[FR_LINE],
			(freps[i]->min[FR_LINE] < 0) ? 0 : freps[i]->min[FR_LINE],
			freps[i]->max[FR_LINE]);
		fprintf(stdout, "%s %7d %10d %10d\n", _("boundary"),
			freps[i]->count[FR_BOUNDARY],
			(freps[i]->min[FR_BOUNDARY] < 0) ? 0 : freps[i]->min[FR_BOUNDARY],
			freps[i]->max[FR_BOUNDARY]);
		fprintf(stdout, "%s %7d %10d %10d\n", _("centroid"),
			freps[i]->count[FR_CENTROID],
			(freps[i]->min[FR_CENTROID] < 0) ? 0 : freps[i]->min[FR_CENTROID],
			freps[i]->max[FR_CENTROID]);
		fprintf(stdout, "%s     %7d %10d %10d\n", _("area"),
			freps[i]->count[FR_AREA],
			(freps[i]->min[FR_AREA] < 0) ? 0 : freps[i]->min[FR_AREA],
			freps[i]->max[FR_AREA]);
		fprintf(stdout, "%s     %7d %10d %10d\n", _("face"),
			freps[i]->count[FR_FACE],
			(freps[i]->min[FR_FACE] < 0) ? 0 : freps[i]->min[FR_FACE],
			freps[i]->max[FR_FACE]);
		fprintf(stdout, "%s   %7d %10d %10d\n", _("kernel"),
			freps[i]->count[FR_KERNEL],
			(freps[i]->min[FR_KERNEL] < 0) ? 0 : freps[i]->min[FR_KERNEL],
			freps[i]->max[FR_KERNEL]);
		fprintf(stdout, "%s      %7d %10d %10d\n", _("all"),
			freps[i]->count[FR_ALL],
			(freps[i]->min[FR_ALL] < 0) ? 0 : freps[i]->min[FR_ALL],
			freps[i]->max[FR_ALL]);
	    }
	}
	break;

    case (O_PRN):
	while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
	    id++;
	    int has = 0;

	    if (!(type & otype))
		continue;

	    if (Clist && Vect_cat_in_cat_list(id, Clist) == FALSE)
		continue;

	    /* Check if the line has at least one cat */
	    for (i = 0; i < nfields; i++) {
		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == fields[i]) {
			has = 1;
			break;
		    }
		}
	    }

	    if (!has)
		continue;

	    for (i = 0; i < nfields; i++) {
		int first = 1;

		if (i > 0)
		    fprintf(stdout, "|");
		for (j = 0; j < Cats->n_cats; j++) {
		    if (Cats->field[j] == fields[i]) {
			if (!first)
			    fprintf(stdout, "/");
			fprintf(stdout, "%d", Cats->cat[j]);
			first = 0;
		    }
		}
	    }
	    fprintf(stdout, "\n");
	}
	break;
    }

    if (option == O_ADD || option == O_DEL || option == O_CHFIELD ||
        option == O_SUM || option == O_TRANS){
        if (!notab->answer){
	    G_message(_("Copying attribute table(s)..."));
            if (Vect_copy_tables(&In, &Out, 0))
                G_warning(_("Failed to copy attribute table to output map"));
	}
	Vect_build(&Out);
	Vect_close(&Out);
    }

    if (option == O_TRANS && nmodified > 0)
        for(i = 1; i < nfields; i++)
	    G_important_message(_("Categories copied from layer %d to layer %d"),
		                  fields[0], fields[i]);

    if (option != O_REP && option != O_PRN) 
        G_done_msg(n_("%d feature modified.",
                      "%d features modified.",
                      nmodified), nmodified);
    
    Vect_close(&In);

    exit(EXIT_SUCCESS);
}
Beispiel #16
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *in_opt, *out_opt, *feature_opt, *column_name;
    struct Flag *smooth_flg, *value_flg, *z_flg, *no_topol, *notab_flg;
    int feature, notab_flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("conversion"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("vectorization"));
    module->description = _("Converts a raster map into a vector map.");

    in_opt = G_define_standard_option(G_OPT_R_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    feature_opt = G_define_standard_option(G_OPT_V_TYPE);
    feature_opt->required = YES;
    feature_opt->multiple = NO;
    feature_opt->options = "point,line,area";
    feature_opt->answer = NULL;

    column_name = G_define_standard_option(G_OPT_DB_COLUMN);
    column_name->label = _("Name of attribute column to store value");
    column_name->description = _("Name must be SQL compliant");
    column_name->answer = "value";

    smooth_flg = G_define_flag();
    smooth_flg->key = 's';
    smooth_flg->description = _("Smooth corners of area features");

    value_flg = G_define_flag();
    value_flg->key = 'v';
    value_flg->description =
	_("Use raster values as categories instead of unique sequence (CELL only)");
    value_flg->guisection = _("Attributes");

    z_flg = G_define_flag();
    z_flg->key = 'z';
    z_flg->label = _("Write raster values as z coordinate");
    z_flg->description = _("Table is not created. "
			   "Currently supported only for points.");
    z_flg->guisection = _("Attributes");

    no_topol = G_define_flag();
    no_topol->key = 'b';
    no_topol->label = _("Do not build vector topology");
    no_topol->description = _("Recommended for massive point conversion");

    notab_flg = G_define_standard_flag(G_FLG_V_TABLE);

    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;
    notab_flag = notab_flg->answer;

    if (z_flg->answer && (feature != GV_POINT))
	G_fatal_error(_("z flag is supported only for points"));

    /* Open files */
    input_fd = Rast_open_old(in_opt->answer, "");

    data_type = Rast_get_map_type(input_fd);
    data_size = Rast_cell_size(data_type);
    G_get_window(&cell_head);

    if (value_flag && data_type != CELL_TYPE) {
	if (!notab_flag)
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be written to the table."));
	else if (z_flg->answer)
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be z coordinate."));
	else
	    G_warning(_("Raster is not CELL, '-v' flag ignored, raster values will be lost."));
	value_flag = 0;
    }

    if (!value_flag && notab_flag) {
	G_warning(_("Categories will be unique sequence, raster values will be lost."));
    }

    if (Vect_open_new(&Map, out_opt->answer, z_flg->answer) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    Vect_hist_command(&Map);

    Cats = Vect_new_cats_struct();

    /* Open category labels */
    if (data_type == CELL_TYPE) {
	if (0 == Rast_read_cats(in_opt->answer, "", &RastCats))
	    has_cats = 1;
    }
    else
	has_cats = 0;

    db_init_string(&sql);
    db_init_string(&label);

    /* Create table */
    if ((feature & (GV_AREA | GV_POINT | GV_LINE)) &&
	(!value_flag || (value_flag && has_cats)) && !(z_flg->answer)
	&& !notab_flag) {
	char buf[1000];

	Fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	driver =
	    db_start_driver_open_database(Fi->driver,
					  Vect_subst_var(Fi->database, &Map));
	if (driver == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(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, ", ");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " integer");
	    } else {
		db_append_string(&sql, ",");
		db_append_string(&sql, column_name->answer);
		db_append_string(&sql, " 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(_("Unable to create table: %s"),
			  db_get_string(&sql));

	if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
	    G_warning(_("Unable to create index"));

	if (db_grant_on_table
	    (driver, Fi->table, DB_PRIV_SELECT,
	     DB_GROUP | DB_PUBLIC) != DB_OK)
	    G_fatal_error(_("Unable to 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();
    }
    else if (feature == GV_AREA) {
	alloc_areas_bufs(row_length + 2);
	extract_areas();
    }
    else {			/* GV_POINT */

	extract_points(z_flg->answer);
    }

    Rast_close(input_fd);

    if (!no_topol->answer)
	Vect_build(&Map);


    /* insert cats and optionally 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;
            
            G_important_message(_("Updating attributes..."));
	    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(_("Unable to insert into table: %s"),
				  db_get_string(&sql));

		lastcat = cat;
	    }
	}
    }

    if (has_cats)
	Rast_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);
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    int fd, maskfd;
    CELL *mask;
    DCELL *dcell;
    struct GModule *module;
    struct History history;
    int row, col;
    int searchrow, searchcolumn, pointsfound;
    int *shortlistrows = NULL, *shortlistcolumns = NULL;
    long ncells = 0;
    double north, east;
    double dist;
    double sum1, sum2, interp_value;
    int n;
    double p;
    struct
    {
        struct Option *input, *npoints, *power, *output, *dfield, *col;
    } parm;
    struct
    {
        struct Flag *noindex;
    } flag;
    struct cell_list
    {
        int row, column;
        struct cell_list *next;
    };
    struct cell_list **search_list = NULL, **search_list_start = NULL;
    int max_radius, radius;
    int searchallpoints = 0;
    char *tmpstr1, *tmpstr2;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("IDW"));
    module->description =
        _("Provides surface interpolation from vector point data by Inverse "
          "Distance Squared Weighting.");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);

    parm.dfield = G_define_standard_option(G_OPT_V_FIELD);

    parm.col = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.col->required = NO;
    parm.col->label = _("Name of attribute column with values to interpolate");
    parm.col->description = _("If not given and input is 2D vector map then category values are used. "
                              "If input is 3D vector map then z-coordinates are used.");
    parm.col->guisection = _("Values");

    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);

    parm.npoints = G_define_option();
    parm.npoints->key = "npoints";
    parm.npoints->key_desc = "count";
    parm.npoints->type = TYPE_INTEGER;
    parm.npoints->required = NO;
    parm.npoints->description = _("Number of interpolation points");
    parm.npoints->answer = "12";
    parm.npoints->guisection = _("Settings");

    parm.power = G_define_option();
    parm.power->key = "power";
    parm.power->type = TYPE_DOUBLE;
    parm.power->answer = "2.0";
    parm.power->label = _("Power parameter");
    parm.power->description =
        _("Greater values assign greater influence to closer points");
    parm.power->guisection = _("Settings");

    flag.noindex = G_define_flag();
    flag.noindex->key = 'n';
    flag.noindex->label = _("Don't index points by raster cell");
    flag.noindex->description = _("Slower but uses"
                                  " less memory and includes points from outside region"
                                  " in the interpolation");
    flag.noindex->guisection = _("Settings");

    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    if (sscanf(parm.npoints->answer, "%d", &search_points) != 1 ||
            search_points < 1)
        G_fatal_error(_("Illegal number (%s) of interpolation points"),
                      parm.npoints->answer);

    list =
        (struct list_Point *) G_calloc((size_t) search_points,
                                       sizeof(struct list_Point));

    p = atof(parm.power->answer);

    /* get the window, dimension arrays */
    G_get_window(&window);

    if (!flag.noindex->answer) {
        npoints_currcell = (long **)G_malloc(window.rows * sizeof(long *));
        points =
            (struct Point ***)G_malloc(window.rows * sizeof(struct Point **));


        for (row = 0; row < window.rows; row++) {
            npoints_currcell[row] =
                (long *)G_malloc(window.cols * sizeof(long));
            points[row] =
                (struct Point **)G_malloc(window.cols *
                                          sizeof(struct Point *));

            for (col = 0; col < window.cols; col++) {
                npoints_currcell[row][col] = 0;
                points[row][col] = NULL;
            }
        }
    }

    /* read the elevation points from the input sites file */
    read_sites(parm.input->answer, parm.dfield->answer,
               parm.col->answer, flag.noindex->answer);

    if (npoints == 0)
        G_fatal_error(_("No points found"));
    nsearch = npoints < search_points ? npoints : search_points;

    if (!flag.noindex->answer) {
        /* Arbitrary point to switch between searching algorithms. Could do
         * with refinement PK */
        if ((window.rows * window.cols) / npoints > 400) {
            /* Using old algorithm.... */
            searchallpoints = 1;
            ncells = 0;

            /* Make an array to contain the row and column indices that have
             * sites in them; later will just search through all these. */
            for (searchrow = 0; searchrow < window.rows; searchrow++)
                for (searchcolumn = 0; searchcolumn < window.cols;
                        searchcolumn++)
                    if (npoints_currcell[searchrow][searchcolumn] > 0) {
                        shortlistrows = (int *)G_realloc(shortlistrows,
                                                         (1 +
                                                          ncells) *
                                                         sizeof(int));
                        shortlistcolumns =
                            (int *)G_realloc(shortlistcolumns,
                                             (1 + ncells) * sizeof(int));
                        shortlistrows[ncells] = searchrow;
                        shortlistcolumns[ncells] = searchcolumn;
                        ncells++;
                    }
        }
        else {
            /* Fill look-up table of row and column offsets for
             * doing a circular region growing search looking for sites */
            /* Use units of column width */
            max_radius = (int)(0.5 + sqrt(window.cols * window.cols +
                                          (window.rows * window.ns_res /
                                           window.ew_res) * (window.rows *
                                                   window.ns_res /
                                                   window.ew_res)));

            search_list =
                (struct cell_list **)G_malloc(max_radius *
                                              sizeof(struct cell_list *));
            search_list_start =
                (struct cell_list **)G_malloc(max_radius *
                                              sizeof(struct cell_list *));

            for (radius = 0; radius < max_radius; radius++)
                search_list[radius] = NULL;

            for (row = 0; row < window.rows; row++)
                for (col = 0; col < window.cols; col++) {
                    radius = (int)sqrt(col * col +
                                       (row * window.ns_res / window.ew_res) *
                                       (row * window.ns_res / window.ew_res));
                    if (search_list[radius] == NULL)
                        search_list[radius] =
                            search_list_start[radius] =
                                G_malloc(sizeof(struct cell_list));
                    else
                        search_list[radius] =
                            search_list[radius]->next =
                                G_malloc(sizeof(struct cell_list));

                    search_list[radius]->row = row;
                    search_list[radius]->column = col;
                    search_list[radius]->next = NULL;
                }
        }
    }

    /* allocate buffers, etc. */

    dcell = Rast_allocate_d_buf();

    if ((maskfd = Rast_maskfd()) >= 0)
        mask = Rast_allocate_c_buf();
    else
        mask = NULL;


    fd = Rast_open_new(parm.output->answer, DCELL_TYPE);

    /* GTC Count of window rows */
    G_asprintf(&tmpstr1, n_("%d row", "%d rows", window.rows), window.rows);
    /* GTC Count of window columns */
    G_asprintf(&tmpstr2, n_("%d column", "%d columns", window.cols), window.cols);
    /* GTC First argument is map name, second - message about number of rows, third - columns. */
    G_important_message(_("Interpolating raster map <%s> (%s, %s)..."),
                        parm.output->answer, tmpstr1, tmpstr2);
    G_free(tmpstr1);
    G_free(tmpstr2);

    north = window.north + window.ns_res / 2.0;
    for (row = 0; row < window.rows; row++) {
        G_percent(row, window.rows, 1);

        if (mask)
            Rast_get_c_row(maskfd, mask, row);

        north -= window.ns_res;
        east = window.west - window.ew_res / 2.0;
        for (col = 0; col < window.cols; col++) {
            east += window.ew_res;
            /* don't interpolate outside of the mask */
            if (mask && mask[col] == 0) {
                Rast_set_d_null_value(&dcell[col], 1);
                continue;
            }

            /* If current cell contains more than nsearch points just average
             * all the points in this cell and don't look in any others */

            if (!(flag.noindex->answer) && npoints_currcell[row][col] >= nsearch) {
                sum1 = 0.0;
                for (i = 0; i < npoints_currcell[row][col]; i++)
                    sum1 += points[row][col][i].z;

                interp_value = sum1 / npoints_currcell[row][col];
            }
            else {
                if (flag.noindex->answer)
                    calculate_distances_noindex(north, east);
                else {
                    pointsfound = 0;
                    i = 0;

                    if (searchallpoints == 1) {
                        /* If there aren't many sites just check them all to find
                         * the nearest */
                        for (n = 0; n < ncells; n++)
                            calculate_distances(shortlistrows[n],
                                                shortlistcolumns[n], north,
                                                east, &pointsfound);
                    }
                    else {
                        radius = 0;
                        while (pointsfound < nsearch) {
                            /* Keep widening the search window until we find
                             * enough points */
                            search_list[radius] = search_list_start[radius];
                            while (search_list[radius] != NULL) {
                                /* Always */
                                if (row <
                                        (window.rows - search_list[radius]->row)
                                        && col <
                                        (window.cols -
                                         search_list[radius]->column)) {
                                    searchrow =
                                        row + search_list[radius]->row;
                                    searchcolumn =
                                        col + search_list[radius]->column;
                                    calculate_distances(searchrow,
                                                        searchcolumn, north,
                                                        east, &pointsfound);
                                }

                                /* Only if at least one offset is not 0 */
                                if ((search_list[radius]->row > 0 ||
                                        search_list[radius]->column > 0) &&
                                        row >= search_list[radius]->row &&
                                        col >= search_list[radius]->column) {
                                    searchrow =
                                        row - search_list[radius]->row;
                                    searchcolumn =
                                        col - search_list[radius]->column;
                                    calculate_distances(searchrow,
                                                        searchcolumn, north,
                                                        east, &pointsfound);
                                }

                                /* Only if both offsets are not 0 */
                                if (search_list[radius]->row > 0 &&
                                        search_list[radius]->column > 0) {
                                    if (row <
                                            (window.rows -
                                             search_list[radius]->row) &&
                                            col >= search_list[radius]->column) {
                                        searchrow =
                                            row + search_list[radius]->row;
                                        searchcolumn =
                                            col - search_list[radius]->column;
                                        calculate_distances(searchrow,
                                                            searchcolumn,
                                                            north, east,
                                                            &pointsfound);
                                    }
                                    if (row >= search_list[radius]->row &&
                                            col <
                                            (window.cols -
                                             search_list[radius]->column)) {
                                        searchrow =
                                            row - search_list[radius]->row;
                                        searchcolumn =
                                            col + search_list[radius]->column;
                                        calculate_distances(searchrow,
                                                            searchcolumn,
                                                            north, east,
                                                            &pointsfound);
                                    }
                                }

                                search_list[radius] =
                                    search_list[radius]->next;
                            }
                            radius++;
                        }
                    }
                }

                /* interpolate */
                sum1 = 0.0;
                sum2 = 0.0;
                for (n = 0; n < nsearch; n++) {
                    if ((dist = sqrt(list[n].dist))) {
                        sum1 += list[n].z / pow(dist, p);
                        sum2 += 1.0 / pow(dist, p);
                    }
                    else {
                        /* If one site is dead on the centre of the cell, ignore
                         * all the other sites and just use this value.
                         * (Unlikely when using floating point numbers?) */
                        sum1 = list[n].z;
                        sum2 = 1.0;
                        break;
                    }
                }
                interp_value = sum1 / sum2;
            }
            dcell[col] = (DCELL) interp_value;
        }
        Rast_put_d_row(fd, dcell);
    }
    G_percent(1, 1, 1);

    Rast_close(fd);

    /* writing history file */
    Rast_short_history(parm.output->answer, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(parm.output->answer, &history);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}
Beispiel #18
0
int do_areas(struct Map_info *Map, struct line_pnts *Points,
	     dbCatValArray * Cvarr, int ctype, int use,
	     double value, int value_type)
{
    int i;
    CELL cval, cat;
    DCELL dval;

    if (nareas <= 0)
	return 0;

    G_important_message(_("Reading areas..."));
    for (i = 0; i < nareas; i++) {
	/* Note: in old version (grass5.0) there was a check here if the current area 
	 *        is identical to previous one. I don't see any reason for this in topological vectors */
	G_percent(i, nareas, 2);
	cat = list[i].cat;
	G_debug(3, "Area cat = %d", cat);

	if (ISNULL(&cat)) {	/* No centroid or no category */
	    set_cat(cat);
	}
	else {
	    if (use == USE_ATTR) {
		if (ctype == DB_C_TYPE_INT) {
		    if ((db_CatValArray_get_value_int(Cvarr, cat, &cval)) !=
			DB_OK) {
			G_warning(_("No record for area (cat = %d)"), cat);
			SETNULL(&cval);
		    }
		    set_cat(cval);
		}
		else if (ctype == DB_C_TYPE_DOUBLE) {
		    if ((db_CatValArray_get_value_double(Cvarr, cat, &dval))
			!= DB_OK) {
			G_warning(_("No record for area (cat = %d)"), cat);
			SETDNULL(&dval);
		    }
		    set_dcat(dval);
		}
		else {
		    G_fatal_error(_("Unable to use column specified"));
		}
	    }
	    else if (use == USE_CAT) {
		set_cat(cat);
	    }
	    else {
		if (value_type == CELL_TYPE)
		    set_cat((int)value);
		else
		    set_dcat(value);
	    }
	}

	if (Vect_get_area_points(Map, list[i].index, Points) <= 0) {
	    G_warning(_("Get area %d failed"), list[i].index);
	    return -1;
	}

	G_plot_polygon(Points->x, Points->y, Points->n_points);
    }
    G_percent(1, 1, 1);
    
    return nareas;
}
Beispiel #19
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct {
        struct Option *input, *output, *zshift, *height, *elevation, *hcolumn,
            *type, *field, *cats, *where, *interp, *scale, *null;
    } opt;
    struct {
        struct Flag *trace;
    } flag;
    
    struct Map_info In, Out;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct bound_box map_box;

    struct cat_list *cat_list;
    
    struct Cell_head window;
    
    int field;
    int only_type, cat;
    int fdrast, interp_method, trace;
    double objheight, objheight_default, voffset;
    double scale, null_val;
    
    struct field_info *Fi;
    dbDriver *driver = NULL;
    
    char *comment;
    
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("sampling"));
    G_add_keyword(_("3D"));
    module->label =
	_("Extrudes flat vector features to 3D vector features with defined height.");
    module->description = 
        _("Optionally the height can be derived from sampling of elevation raster map.");
    
    flag.trace = G_define_flag();
    flag.trace->key = 't';
    flag.trace->description = _("Trace elevation");
    flag.trace->guisection = _("Elevation");

    opt.input = G_define_standard_option(G_OPT_V_INPUT);

    opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
    opt.field->guisection = _("Selection");

    opt.cats = G_define_standard_option(G_OPT_V_CATS);
    opt.cats->guisection = _("Selection");
    
    opt.where = G_define_standard_option(G_OPT_DB_WHERE);
    opt.where->guisection = _("Selection");

    opt.type = G_define_standard_option(G_OPT_V_TYPE);
    opt.type->answer = "point,line,area";
    opt.type->options = "point,line,area";
    opt.type->guisection = _("Selection");

    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);

    opt.zshift = G_define_option();
    opt.zshift->key = "zshift";
    opt.zshift->description = _("Shifting value for z coordinates");
    opt.zshift->type = TYPE_DOUBLE;
    opt.zshift->required = NO;
    opt.zshift->answer = "0";
    opt.zshift->guisection = _("Height");

    opt.height = G_define_option();
    opt.height->key = "height";
    opt.height->type = TYPE_DOUBLE;
    opt.height->required = NO;
    opt.height->multiple = NO;
    opt.height->description = _("Fixed height for 3D vector features");
    opt.height->guisection = _("Height");

    opt.hcolumn = G_define_standard_option(G_OPT_DB_COLUMN);
    opt.hcolumn->key = "height_column";
    opt.hcolumn->multiple = NO;
    opt.hcolumn->description = _("Name of attribute column with feature height");
    opt.hcolumn->guisection = _("Height");
 
    /* raster sampling */
    opt.elevation = G_define_standard_option(G_OPT_R_ELEV);
    opt.elevation->required = NO;
    opt.elevation->description = _("Elevation raster map for height extraction");
    opt.elevation->guisection = _("Elevation");

    opt.interp = G_define_standard_option(G_OPT_R_INTERP_TYPE);
    opt.interp->answer = "nearest";
    opt.interp->guisection = _("Elevation");

    opt.scale = G_define_option();
    opt.scale->key = "scale";
    opt.scale->type = TYPE_DOUBLE;
    opt.scale->description = _("Scale factor sampled raster values");
    opt.scale->answer = "1.0";
    opt.scale->guisection = _("Elevation");

    opt.null = G_define_option();
    opt.null->key = "null_value";
    opt.null->type = TYPE_DOUBLE;
    opt.null->description =
	_("Height for sampled raster NULL values");
    opt.null->guisection = _("Elevation");

    G_gisinit(argv[0]);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (!opt.height->answer && !opt.hcolumn->answer) {
	G_fatal_error(_("One of '%s' or '%s' parameters must be set"),
		      opt.height->key, opt.hcolumn->key);
    }

    sscanf(opt.zshift->answer, "%lf", &voffset);
    G_debug(1, "voffset = %f", voffset);
    
    if (opt.height->answer)
	sscanf(opt.height->answer, "%lf", &objheight);
    else
	objheight = 0.;
    G_debug(1, "objheight = %f", objheight);
    objheight_default = objheight;

    only_type = Vect_option_to_types(opt.type);

    /* sampling method */
    interp_method = Rast_option_to_interp_type(opt.interp);

    /* used to scale sampled raster values */
    scale = atof(opt.scale->answer);

    /* is null value defined */
    if (opt.null->answer)
	null_val = atof(opt.null->answer);

    /* trace elevation */
    trace = flag.trace->answer ? TRUE : FALSE;
    
    /* set input vector map name and mapset */
    Vect_check_input_output_name(opt.input->answer, opt.output->answer, G_FATAL_EXIT);

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    Vect_set_open_level(2); /* topology required for input */

    /* opening input vector map */
    if (Vect_open_old2(&In, opt.input->answer, "", opt.field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer);

    Vect_set_error_handler_io(&In, &Out);

    /* creating output vector map */
    if (Vect_open_new(&Out, opt.output->answer, WITH_Z) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			opt.output->answer);

    field = Vect_get_field_number(&In, opt.field->answer);

    if ((opt.hcolumn->answer || opt.cats->answer || opt.where->answer) && field == -1) {
        G_warning(_("Invalid layer number (%d). "
                    "Parameter '%s', '%s' or '%s' specified, assuming layer '1'."),
                  field, opt.hcolumn->key, opt.cats->key, opt.where->key);
        field = 1;
    }

    /* set constraint for cats or where */
    cat_list = NULL;
    if (field > 0)
	cat_list = Vect_cats_set_constraint(&In, field, opt.where->answer,
                                            opt.cats->answer);
    
    
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* opening database connection, if required */
    if (opt.hcolumn->answer) {
        int ctype;
        dbColumn *column;
        
	if ((Fi = Vect_get_field(&In, field)) == NULL)
	    G_fatal_error(_("Database connection not defined for layer %d"),
			  field);

	if ((driver =
	     db_start_driver_open_database(Fi->driver, Fi->database)) == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
        db_set_error_handler_driver(driver);
        
	if (db_get_column(driver, Fi->table, opt.hcolumn->answer, &column) != DB_OK)
	    G_fatal_error(_("Column <%s> does not exist"),
			  opt.hcolumn->answer);
	else
	    db_free_column(column);

	ctype = db_column_Ctype(driver, Fi->table, opt.hcolumn->answer);

	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_STRING &&
	    ctype != DB_C_TYPE_DOUBLE) {
	    G_fatal_error(_("Column <%s>: invalid data type"),
			  opt.hcolumn->answer);
	}
    }

    /* do we work with elevation raster? */
    fdrast = -1;
    if (opt.elevation->answer) {
	/* raster setup */
	G_get_window(&window);

	/* open the elev raster, and check for error condition */
	fdrast = Rast_open_old(opt.elevation->answer, "");
    }

    /* if area */
    if (only_type & GV_AREA) {
        int area, nareas, centroid;
        
        nareas = Vect_get_num_areas(&In);
	G_debug(2, "n_areas = %d", nareas);
	if (nareas > 0)
	    G_message(_("Extruding areas..."));
	for (area = 1; area <= nareas; area++) {
	    G_debug(3, "area = %d", area);
	    G_percent(area, nareas, 2);
            
	    if (!Vect_area_alive(&In, area))
		continue;
            
	    centroid = Vect_get_area_centroid(&In, area);
	    if (!centroid) {
		G_warning(_("Skipping area %d without centroid"), area);
		continue;
	    }

	    Vect_read_line(&In, NULL, Cats, centroid);
	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
		continue;
            
	    /* height attribute */
	    if (opt.hcolumn->answer) {
		cat = Vect_get_area_cat(&In, area, field);
                if (cat == -1) {
                    G_warning(_("No category defined for area %d. Using default fixed height %f."),
                              area, objheight_default);
                    objheight = objheight_default;
                }
                if (get_height(Fi, opt.hcolumn->answer,
                               driver, cat, &objheight) != 0) {
                    G_warning(_("Unable to fetch height from DB for area %d. Using default fixed height %f."),
                              area, objheight_default);
                    objheight = objheight_default;
                }
	    } /* if opt.hcolumn->answer */

	    Vect_get_area_points(&In, area, Points);

	    G_debug(3, "area: %d height: %f", area, objheight);

	    extrude(&In, &Out, Cats, Points,
		    fdrast, trace, interp_method, scale,
                    opt.null->answer ? TRUE : FALSE, null_val,
                    objheight, voffset, &window, GV_AREA,
		    centroid);
	} /* foreach area */

    }

    if (only_type > 0) {
        int line, nlines;
        int type;
        
	G_debug(1, "other than areas");
	/* loop through each line in the dataset */
        nlines = Vect_get_num_lines(&In);
	G_message(_("Extruding features..."));
	for (line = 1; line <= nlines; line++) {
	    /* progress feedback */
	    G_percent(line, nlines, 2);

	    if (!Vect_line_alive(&In, line))
		continue;

	    /* read line */
	    type = Vect_read_line(&In, Points, Cats, line);

	    if (!(type & only_type))
		continue;

	    if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list))
		continue;

	    /* height attribute */
	    if (opt.hcolumn->answer) {
		cat = Vect_get_line_cat(&In, line, field);
                if (cat == -1) {
                    G_warning(_("No category defined for feature %d. Using default fixed height %f."),
                              line, objheight_default);
                    objheight = objheight_default;
                }
                if (get_height(Fi, opt.hcolumn->answer,
                               driver, cat, &objheight) != 0) {
                    G_warning(_("Unable to fetch height from DB for line %d. Using default fixed height %f."),
                              line, objheight_default);
                    objheight = objheight_default;
                }
	    } /* if opt.hcolumn->answer */
            
	    extrude(&In, &Out, Cats, Points,
		    fdrast, trace, interp_method, scale,
                    opt.null->answer ? TRUE : FALSE, null_val,
                    objheight, voffset, &window, type, -1);
	} /* for each line */
    }	  /* else if area */

    if (driver) {
	db_close_database(driver);
	db_shutdown_driver(driver);
    }

    G_important_message(_("Copying attribute table..."));
    if (field < 0)
        Vect_copy_tables(&In, &Out, 0);
    else 
        Vect_copy_table_by_cat_list(&In, &Out, field, field, NULL,
                                    GV_1TABLE, cat_list);
    
    Vect_build(&Out);

    /* header */
    G_asprintf(&comment, "Generated by %s from vector map <%s>",
	       G_program_name(), Vect_get_full_name(&In));
    Vect_set_comment(&Out, comment);
    G_free(comment);

    Vect_get_map_box(&Out, &map_box);

    Vect_close(&In);
    Vect_close(&Out);

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    G_done_msg("T: %f B: %f.", map_box.T, map_box.B);
    
    exit(EXIT_SUCCESS);
}
/* *************************************************************** */
int bench_solvers(int rows) {
    G_math_les *les;
    struct timeval tstart;
    struct timeval tend;

    G_message("\t * benchmarking gmath lu decomposition solver with unsymmetric matrix\n");

    les = create_normal_unsymmetric_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solver_lu(les->A, les->x, les->b, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time gmath lu decomposition: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);

    G_message("\t * benchmarking lu ccmath decomposition solver with unsymmetric matrix\n");

    les = create_normal_unsymmetric_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solv(les->A, les->b, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time ccmath lu decomposition: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);


    G_message("\t * benchmarking gauss elimination solver with unsymmetric matrix\n");

    les = create_normal_unsymmetric_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solver_gauss(les->A, les->x, les->b, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time gauss elimination: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);

    G_message("\t * benchmarking gmath cholesky decomposition solver with symmetric matrix\n");

    les = create_normal_symmetric_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solver_cholesky(les->A, les->x, les->b, les->rows, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time gmath cholesky decomposition: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);

    G_message("\t * benchmarking ccmath cholesky decomposition solver with symmetric matrix\n");

    les = create_normal_symmetric_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solvps(les->A, les->b, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time ccmath cholesky decomposition: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);

    G_message("\t * benchmarking gmath cholesky band matrix decomposition solver with symmetric band matrix\n");

    les = create_symmetric_band_les(rows);
    gettimeofday(&tstart, NULL);
    G_math_solver_cholesky_sband(les->A, les->x, les->b, les->rows, les->rows);
    gettimeofday(&tend, NULL);
    G_important_message("Computation time cholesky band matrix decomposition: %g\n", compute_time_difference(tstart, tend));
    G_math_free_les(les);


    return 1;
}
Beispiel #21
0
/*!
   \brief Build topology 

   \param Map vector map
   \param build build level

   \return 1 on success
   \return 0 on error
 */
int Vect_build_nat(struct Map_info *Map, int build)
{
    struct Plus_head *plus;
    int i, s, type, line;
    off_t offset;
    int side, area;
    struct line_cats *Cats;
    struct P_line *Line;
    struct P_area *Area;
    struct bound_box box;
    
    G_debug(3, "Vect_build_nat() build = %d", build);

    plus = &(Map->plus);

    if (build == plus->built)
	return 1;		/* Do nothing */

    /* Check if upgrade or downgrade */
    if (build < plus->built) {
        /* -> downgrade */
	Vect__build_downgrade(Map, build);
        return 1;
    }

    /* -> upgrade */
    if (!Points)
        Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    
    if (plus->built < GV_BUILD_BASE) {
        int npoints, c;
        
	/* 
	 *  We shall go through all primitives in coor file and add
	 *  new node for each end point to nodes structure if the node
	 *  with the same coordinates doesn't exist yet.
	 */

	/* register lines, create nodes */
	Vect_rewind(Map);
	G_message(_("Registering primitives..."));
	i = 0;
	npoints = 0;
	while (TRUE) {
	    /* register line */
	    type = Vect_read_next_line(Map, Points, Cats);

	    /* Note: check for dead lines is not needed, because they
               are skipped by V1_read_next_line() */
	    if (type == -1) {
		G_warning(_("Unable to read vector map"));
		return 0;
	    }
	    else if (type == -2) {
		break;
	    }

	    G_progress(++i, 1e4);
	    
	    npoints += Points->n_points;

	    offset = Map->head.last_offset;

	    G_debug(3, "Register line: offset = %lu", (unsigned long)offset);
	    dig_line_box(Points, &box);
	    line = dig_add_line(plus, type, Points, &box, offset);
	    if (line == 1)
		Vect_box_copy(&(plus->box), &box);
	    else
		Vect_box_extend(&(plus->box), &box);

	    /* Add all categories to category index */
	    if (build == GV_BUILD_ALL) {
		for (c = 0; c < Cats->n_cats; c++) {
		    dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c],
				     line, type);
		}
		if (Cats->n_cats == 0)	/* add field 0, cat 0 */
		    dig_cidx_add_cat(plus, 0, 0, line, type);
	    }
	}
	G_progress(1, 1);

	G_message(_n("One primitive registered", "%d primitives registered", plus->n_lines), plus->n_lines);
	G_message(_n("One vertex registered", "%d vertices registered", npoints), npoints);

	plus->built = GV_BUILD_BASE;
    }

    if (build < GV_BUILD_AREAS)
	return 1;

    if (plus->built < GV_BUILD_AREAS) {
	/* Build areas */
	/* Go through all bundaries and try to build area for both sides */
	G_important_message(_("Building areas..."));
	for (line = 1; line <= plus->n_lines; line++) {
	    G_percent(line, plus->n_lines, 1);

	    /* build */
	    if (plus->Line[line] == NULL) {
		continue;
	    }			/* dead line */
	    Line = plus->Line[line];
	    if (Line->type != GV_BOUNDARY) {
		continue;
	    }

	    for (s = 0; s < 2; s++) {
		if (s == 0)
		    side = GV_LEFT;
		else
		    side = GV_RIGHT;

		G_debug(3, "Build area for line = %d, side = %d", line, side);
		Vect_build_line_area(Map, line, side);
	    }
	}
	G_message(_n("One area built", "%d areas built", plus->n_areas), plus->n_areas);
	G_message(_n("One isle built", "%d isles built", plus->n_isles), plus->n_isles);
	plus->built = GV_BUILD_AREAS;
    }

    if (build < GV_BUILD_ATTACH_ISLES)
	return 1;

    /* Attach isles to areas */
    if (plus->built < GV_BUILD_ATTACH_ISLES) {
	G_important_message(_("Attaching islands..."));
	for (i = 1; i <= plus->n_isles; i++) {
	    G_percent(i, plus->n_isles, 1);
	    Vect_attach_isle(Map, i);
	}
	plus->built = GV_BUILD_ATTACH_ISLES;
    }

    if (build < GV_BUILD_CENTROIDS)
	return 1;

    /* Attach centroids to areas */
    if (plus->built < GV_BUILD_CENTROIDS) {
	int nlines;
	struct P_topo_c *topo;

	G_important_message(_("Attaching centroids..."));

	nlines = Vect_get_num_lines(Map);
	for (line = 1; line <= nlines; line++) {
	    G_percent(line, nlines, 1);

	    Line = plus->Line[line];
	    if (!Line)
		continue;	/* Dead */

	    if (Line->type != GV_CENTROID)
		continue;

	    Vect_read_line(Map, Points, NULL, line);
	    area = Vect_find_area(Map, Points->x[0], Points->y[0]);

	    if (area > 0) {
		G_debug(3, "Centroid (line=%d) in area %d", line, area);

		Area = plus->Area[area];
		topo = (struct P_topo_c *)Line->topo;

		if (Area->centroid == 0) {	/* first */
		    Area->centroid = line;
		    topo->area = area;
		}
		else {		/* duplicate */
		    topo->area = -area;
		}
	    }
	}
	plus->built = GV_BUILD_CENTROIDS;
    }

    /* Add areas to category index */
    for (i = 1; i <= plus->n_areas; i++) {
	int c;

	if (plus->Area[i] == NULL)
	    continue;

	if (plus->Area[i]->centroid > 0) {
	    Vect_read_line(Map, NULL, Cats, plus->Area[i]->centroid);

	    for (c = 0; c < Cats->n_cats; c++) {
		dig_cidx_add_cat(plus, Cats->field[c], Cats->cat[c], i,
				 GV_AREA);
	    }
	}

	if (plus->Area[i]->centroid == 0 || Cats->n_cats == 0)	/* no centroid or no cats */
	    dig_cidx_add_cat(plus, 0, 0, i, GV_AREA);
    }

    Vect_destroy_cats_struct(Cats);
    
    return 1;
}
Beispiel #22
0
int main(int argc, char *argv[])
{
    struct Option *driver, *database, *user, *password, *host, *port;
    struct Flag *print;
    struct GModule *module;
    
    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("database"));
    G_add_keyword(_("connection settings"));
    module->description = _("Sets user/password for DB driver/database.");
    module->overwrite = TRUE;
    
    driver = G_define_standard_option(G_OPT_DB_DRIVER);
    driver->options = db_list_drivers();
    driver->required = YES;
    driver->answer = (char *) db_get_default_driver_name();

    database = G_define_standard_option(G_OPT_DB_DATABASE);
    database->required = YES;
    database->answer = (char *) db_get_default_database_name();

    user = G_define_option();
    user->key = "user";
    user->type = TYPE_STRING;
    user->required = NO;
    user->multiple = NO;
    user->description = _("Username");
    user->guisection = _("Settings");
    
    password = G_define_option();
    password->key = "password";
    password->type = TYPE_STRING;
    password->required = NO;
    password->multiple = NO;
    password->description = _("Password");
    password->guisection = _("Settings");

    host = G_define_option();
    host->key = "host";
    host->type = TYPE_STRING;
    host->required = NO;
    host->multiple = NO;
    host->label = _("Hostname");
    host->description = _("Relevant only for pg and mysql driver");
    host->guisection = _("Settings");

    port = G_define_option();
    port->key = "port";
    port->type = TYPE_STRING;
    port->required = NO;
    port->multiple = NO;
    port->label = _("Port");
    port->description = _("Relevant only for pg and mysql driver");
    port->guisection = _("Settings");

    print = G_define_flag();
    print->key = 'p';
    print->description = _("Print connection settings and exit");
    print->guisection = _("Print");
    
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    if (print->answer) {
        /* print all settings to standard output and exit */
        db_get_login_dump(stdout);
        exit(EXIT_SUCCESS);
    }

    if (db_set_login2(driver->answer, database->answer, user->answer,
                      password->answer, host->answer, port->answer,
                      G_get_overwrite()) == DB_FAILED) {
        G_fatal_error(_("Unable to set user/password"));
    }
    
    if (password->answer)
	G_important_message(_("The password was stored in file (%s%cdblogin)"),
                            G_config_path(), HOST_DIRSEP);
    
    exit(EXIT_SUCCESS);
}
Beispiel #23
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct _param {
        struct Option *dsn, *out, *layer, *spat, *where,
                   *min_area;
        struct Option *snap, *type, *outloc, *cnames;
    } param;
    struct _flag {
        struct Flag *list, *tlist, *no_clean, *z, *notab,
                   *region;
        struct Flag *over, *extend, *formats, *tolower, *no_import;
    } flag;

    int i, j, layer, arg_s_num, nogeom, ncnames;
    float xmin, ymin, xmax, ymax;
    int ncols = 0, type;
    double min_area, snap;
    char buf[2000], namebuf[2000], tempvect[GNAME_MAX];
    char *separator;

    struct Key_Value *loc_proj_info, *loc_proj_units;
    struct Key_Value *proj_info, *proj_units;
    struct Cell_head cellhd, loc_wind, cur_wind;
    char error_msg[8192];

    /* Vector */
    struct Map_info Map, Tmp, *Out;
    int cat;

    /* Attributes */
    struct field_info *Fi;
    dbDriver *driver;
    dbString sql, strval;
    int dim, with_z;

    /* OGR */
    OGRDataSourceH Ogr_ds;
    OGRLayerH Ogr_layer;
    OGRFieldDefnH Ogr_field;
    char *Ogr_fieldname;
    OGRFieldType Ogr_ftype;
    OGRFeatureH Ogr_feature;
    OGRFeatureDefnH Ogr_featuredefn;
    OGRGeometryH Ogr_geometry, Ogr_oRing, poSpatialFilter;
    OGRSpatialReferenceH Ogr_projection;
    OGREnvelope oExt;
    OGRwkbGeometryType Ogr_geom_type;

    int OFTIntegerListlength;

    char *output;
    char **layer_names;		/* names of layers to be imported */
    int *layers;		/* layer indexes */
    int nlayers;		/* number of layers to import */
    char **available_layer_names;	/* names of layers to be imported */
    int navailable_layers;
    int layer_id;
    unsigned int n_features, feature_count;
    int overwrite;
    double area_size;
    int use_tmp_vect;

    xmin = ymin = xmax = ymax = 0.0;
    loc_proj_info = loc_proj_units = NULL;
    Ogr_ds = Ogr_oRing = poSpatialFilter = NULL;
    OFTIntegerListlength = 40;	/* hack due to limitation in OGR */
    area_size = 0.0;
    use_tmp_vect = FALSE;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    module->description = _("Converts vector data into a GRASS vector map using OGR library.");

    param.dsn = G_define_option();
    param.dsn->key = "dsn";
    param.dsn->type = TYPE_STRING;
    param.dsn->required =YES;
    param.dsn->label = _("OGR datasource name");
    param.dsn->description = _("Examples:\n"
                               "\t\tESRI Shapefile: directory containing shapefiles\n"
                               "\t\tMapInfo File: directory containing mapinfo files");

    param.layer = G_define_option();
    param.layer->key = "layer";
    param.layer->type = TYPE_STRING;
    param.layer->required = NO;
    param.layer->multiple = YES;
    param.layer->label =
        _("OGR layer name. If not given, all available layers are imported");
    param.layer->description =
        _("Examples:\n" "\t\tESRI Shapefile: shapefile name\n"
          "\t\tMapInfo File: mapinfo file name");
    param.layer->guisection = _("Selection");

    param.out = G_define_standard_option(G_OPT_V_OUTPUT);
    param.out->required = NO;
    param.out->guisection = _("Output");

    param.spat = G_define_option();
    param.spat->key = "spatial";
    param.spat->type = TYPE_DOUBLE;
    param.spat->multiple = YES;
    param.spat->required = NO;
    param.spat->key_desc = "xmin,ymin,xmax,ymax";
    param.spat->label = _("Import subregion only");
    param.spat->guisection = _("Selection");
    param.spat->description =
        _("Format: xmin,ymin,xmax,ymax - usually W,S,E,N");

    param.where = G_define_standard_option(G_OPT_DB_WHERE);
    param.where->guisection = _("Selection");

    param.min_area = G_define_option();
    param.min_area->key = "min_area";
    param.min_area->type = TYPE_DOUBLE;
    param.min_area->required = NO;
    param.min_area->answer = "0.0001";
    param.min_area->label =
        _("Minimum size of area to be imported (square units)");
    param.min_area->guisection = _("Selection");
    param.min_area->description = _("Smaller areas and "
                                    "islands are ignored. Should be greater than snap^2");

    param.type = G_define_standard_option(G_OPT_V_TYPE);
    param.type->options = "point,line,boundary,centroid";
    param.type->answer = "";
    param.type->description = _("Optionally change default input type");
    param.type->descriptions =
        _("point;import area centroids as points;"
          "line;import area boundaries as lines;"
          "boundary;import lines as area boundaries;"
          "centroid;import points as centroids");
    param.type->guisection = _("Selection");

    param.snap = G_define_option();
    param.snap->key = "snap";
    param.snap->type = TYPE_DOUBLE;
    param.snap->required = NO;
    param.snap->answer = "-1";
    param.snap->label = _("Snapping threshold for boundaries");
    param.snap->description = _("'-1' for no snap");

    param.outloc = G_define_option();
    param.outloc->key = "location";
    param.outloc->type = TYPE_STRING;
    param.outloc->required = NO;
    param.outloc->description = _("Name for new location to create");
    param.outloc->key_desc = "name";

    param.cnames = G_define_option();
    param.cnames->key = "cnames";
    param.cnames->type = TYPE_STRING;
    param.cnames->required = NO;
    param.cnames->multiple = YES;
    param.cnames->description =
        _("List of column names to be used instead of original names, "
          "first is used for category column");
    param.cnames->guisection = _("Attributes");

    flag.list = G_define_flag();
    flag.list->key = 'l';
    flag.list->description = _("List available OGR layers in data source and exit");
    flag.list->suppress_required = YES;
    flag.list->guisection = _("Print");

    flag.tlist = G_define_flag();
    flag.tlist->key = 'a';
    flag.tlist->description = _("List available OGR layers including feature types "
                                "in data source and exit");
    flag.tlist->suppress_required = YES;
    flag.tlist->guisection = _("Print");

    flag.formats = G_define_flag();
    flag.formats->key = 'f';
    flag.formats->description = _("List supported formats and exit");
    flag.formats->suppress_required = YES;
    flag.formats->guisection = _("Print");

    /* if using -c, you lose topological information ! */
    flag.no_clean = G_define_flag();
    flag.no_clean->key = 'c';
    flag.no_clean->description = _("Do not clean polygons (not recommended)");
    flag.no_clean->guisection = _("Output");

    flag.z = G_define_flag();
    flag.z->key = 'z';
    flag.z->description = _("Create 3D output");
    flag.z->guisection = _("Output");

    flag.notab = G_define_flag();
    flag.notab->key = 't';
    flag.notab->description = _("Do not create attribute table");
    flag.notab->guisection = _("Attributes");

    flag.over = G_define_flag();
    flag.over->key = 'o';
    flag.over->description =
        _("Override dataset projection (use location's projection)");

    flag.region = G_define_flag();
    flag.region->key = 'r';
    flag.region->guisection = _("Selection");
    flag.region->description = _("Limit import to the current region");

    flag.extend = G_define_flag();
    flag.extend->key = 'e';
    flag.extend->description =
        _("Extend location extents based on new dataset");

    flag.tolower = G_define_flag();
    flag.tolower->key = 'w';
    flag.tolower->description =
        _("Change column names to lowercase characters");
    flag.tolower->guisection = _("Attributes");

    flag.no_import = G_define_flag();
    flag.no_import->key = 'i';
    flag.no_import->description =
        _("Create the location specified by the \"location\" parameter and exit."
          " Do not import the vector data.");

    /* The parser checks if the map already exists in current mapset, this is
     * wrong if location options is used, so we switch out the check and do it
     * in the module after the parser */
    overwrite = G_check_overwrite(argc, argv);

    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    G_begin_polygon_area_calculations();	/* Used in geom() */

    OGRRegisterAll();

    /* list supported formats */
    if (flag.formats->answer) {
        int iDriver;

        G_message(_("Available OGR Drivers:"));

        for (iDriver = 0; iDriver < OGRGetDriverCount(); iDriver++) {
            OGRSFDriverH poDriver = OGRGetDriver(iDriver);
            const char *pszRWFlag;

            if (OGR_Dr_TestCapability(poDriver, ODrCCreateDataSource))
                pszRWFlag = "rw";
            else
                pszRWFlag = "ro";

            fprintf(stdout, " %s (%s): %s\n",
                    OGR_Dr_GetName(poDriver),
                    pszRWFlag, OGR_Dr_GetName(poDriver));
        }
        exit(EXIT_SUCCESS);
    }

    if (param.dsn->answer == NULL) {
        G_fatal_error(_("Required parameter <%s> not set"), param.dsn->key);
    }

    min_area = atof(param.min_area->answer);
    snap = atof(param.snap->answer);
    type = Vect_option_to_types(param.type);

    ncnames = 0;
    if (param.cnames->answers) {
        i = 0;
        while (param.cnames->answers[i++]) {
            ncnames++;
        }
    }

    /* Open OGR DSN */
    Ogr_ds = NULL;
    if (strlen(param.dsn->answer) > 0)
        Ogr_ds = OGROpen(param.dsn->answer, FALSE, NULL);

    if (Ogr_ds == NULL)
        G_fatal_error(_("Unable to open data source <%s>"), param.dsn->answer);

    /* Make a list of available layers */
    navailable_layers = OGR_DS_GetLayerCount(Ogr_ds);
    available_layer_names =
        (char **)G_malloc(navailable_layers * sizeof(char *));

    if (flag.list->answer || flag.tlist->answer)
        G_message(_("Data source <%s> (format '%s') contains %d layers:"),
                  param.dsn->answer,
                  OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), navailable_layers);
    for (i = 0; i < navailable_layers; i++) {
        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
        Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
        Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);

        available_layer_names[i] =
            G_store((char *)OGR_FD_GetName(Ogr_featuredefn));

        if (flag.tlist->answer)
            fprintf(stdout, "%s (%s)\n", available_layer_names[i],
                    OGRGeometryTypeToName(Ogr_geom_type));
        else if (flag.list->answer)
            fprintf(stdout, "%s\n", available_layer_names[i]);
    }
    if (flag.list->answer || flag.tlist->answer) {
        fflush(stdout);
        exit(EXIT_SUCCESS);
    }

    /* Make a list of layers to be imported */
    if (param.layer->answer) {	/* From option */
        nlayers = 0;
        while (param.layer->answers[nlayers])
            nlayers++;

        layer_names = (char **)G_malloc(nlayers * sizeof(char *));
        layers = (int *)G_malloc(nlayers * sizeof(int));

        for (i = 0; i < nlayers; i++) {
            layer_names[i] = G_store(param.layer->answers[i]);
            /* Find it in the source */
            layers[i] = -1;
            for (j = 0; j < navailable_layers; j++) {
                if (strcmp(available_layer_names[j], layer_names[i]) == 0) {
                    layers[i] = j;
                    break;
                }
            }
            if (layers[i] == -1)
                G_fatal_error(_("Layer <%s> not available"), layer_names[i]);
        }
    }
    else {			/* use list of all layers */
        nlayers = navailable_layers;
        layer_names = available_layer_names;
        layers = (int *)G_malloc(nlayers * sizeof(int));
        for (i = 0; i < nlayers; i++)
            layers[i] = i;
    }

    if (param.out->answer) {
        output = G_store(param.out->answer);
    }
    else {
        if (nlayers < 1)
            G_fatal_error(_("No OGR layers available"));
        output = G_store(layer_names[0]);
        G_message(_("All available OGR layers will be imported into vector map <%s>"), output);
    }

    if (!param.outloc->answer) {	/* Check if the map exists */
        if (G_find_vector2(output, G_mapset()) && !overwrite)
            G_fatal_error(_("Vector map <%s> already exists"),
                          output);
    }

    /* Get first imported layer to use for extents and projection check */
    Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[0]);

    if (flag.region->answer) {
        if (param.spat->answer)
            G_fatal_error(_("Select either the current region flag or the spatial option, not both"));

        G_get_window(&cur_wind);
        xmin = cur_wind.west;
        xmax = cur_wind.east;
        ymin = cur_wind.south;
        ymax = cur_wind.north;
    }
    if (param.spat->answer) {
        /* See as reference: gdal/ogr/ogr_capi_test.c */

        /* cut out a piece of the map */
        /* order: xmin,ymin,xmax,ymax */
        arg_s_num = 0;
        i = 0;
        while (param.spat->answers[i]) {
            if (i == 0)
                xmin = atof(param.spat->answers[i]);
            if (i == 1)
                ymin = atof(param.spat->answers[i]);
            if (i == 2)
                xmax = atof(param.spat->answers[i]);
            if (i == 3)
                ymax = atof(param.spat->answers[i]);
            arg_s_num++;
            i++;
        }
        if (arg_s_num != 4)
            G_fatal_error(_("4 parameters required for 'spatial' parameter"));
    }
    if (param.spat->answer || flag.region->answer) {
        G_debug(2, "cut out with boundaries: xmin:%f ymin:%f xmax:%f ymax:%f",
                xmin, ymin, xmax, ymax);

        /* in theory this could be an irregular polygon */
        poSpatialFilter = OGR_G_CreateGeometry(wkbPolygon);
        Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymax, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmax, ymax, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmax, ymin, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
        OGR_G_AddGeometryDirectly(poSpatialFilter, Ogr_oRing);

        OGR_L_SetSpatialFilter(Ogr_layer, poSpatialFilter);
    }

    if (param.where->answer) {
        /* select by attribute */
        OGR_L_SetAttributeFilter(Ogr_layer, param.where->answer);
    }

    /* fetch boundaries */
    if ((OGR_L_GetExtent(Ogr_layer, &oExt, 1)) == OGRERR_NONE) {
        G_get_window(&cellhd);
        cellhd.north = oExt.MaxY;
        cellhd.south = oExt.MinY;
        cellhd.west = oExt.MinX;
        cellhd.east = oExt.MaxX;
        cellhd.rows = 20;	/* TODO - calculate useful values */
        cellhd.cols = 20;
        cellhd.ns_res = (cellhd.north - cellhd.south) / cellhd.rows;
        cellhd.ew_res = (cellhd.east - cellhd.west) / cellhd.cols;
    }
    else {
        cellhd.north = 1.;
        cellhd.south = 0.;
        cellhd.west = 0.;
        cellhd.east = 1.;
        cellhd.top = 1.;
        cellhd.bottom = 1.;
        cellhd.rows = 1;
        cellhd.rows3 = 1;
        cellhd.cols = 1;
        cellhd.cols3 = 1;
        cellhd.depths = 1;
        cellhd.ns_res = 1.;
        cellhd.ns_res3 = 1.;
        cellhd.ew_res = 1.;
        cellhd.ew_res3 = 1.;
        cellhd.tb_res = 1.;
    }

    /* suppress boundary splitting ? */
    if (flag.no_clean->answer) {
        split_distance = -1.;
    }
    else {
        split_distance = 0.;
        area_size =
            sqrt((cellhd.east - cellhd.west) * (cellhd.north - cellhd.south));
    }

    /* Fetch input map projection in GRASS form. */
    proj_info = NULL;
    proj_units = NULL;
    Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);	/* should not be freed later */

    /* Do we need to create a new location? */
    if (param.outloc->answer != NULL) {
        /* Convert projection information non-interactively as we can't
         * assume the user has a terminal open */
        if (GPJ_osr_to_grass(&cellhd, &proj_info,
                             &proj_units, Ogr_projection, 0) < 0) {
            G_fatal_error(_("Unable to convert input map projection to GRASS "
                            "format; cannot create new location."));
        }
        else {
            G_make_location(param.outloc->answer, &cellhd,
                            proj_info, proj_units, NULL);
            G_message(_("Location <%s> created"), param.outloc->answer);
        }

        /* If the i flag is set, clean up? and exit here */
        if(flag.no_import->answer)
        {
            exit(EXIT_SUCCESS);
        }
    }
    else {
        int err = 0;

        /* Projection only required for checking so convert non-interactively */
        if (GPJ_osr_to_grass(&cellhd, &proj_info,
                             &proj_units, Ogr_projection, 0) < 0)
            G_warning(_("Unable to convert input map projection information to "
                        "GRASS format for checking"));

        /* Does the projection of the current location match the dataset? */
        /* G_get_window seems to be unreliable if the location has been changed */
        G__get_window(&loc_wind, "", "DEFAULT_WIND", "PERMANENT");
        /* fetch LOCATION PROJ info */
        if (loc_wind.proj != PROJECTION_XY) {
            loc_proj_info = G_get_projinfo();
            loc_proj_units = G_get_projunits();
        }

        if (flag.over->answer) {
            cellhd.proj = loc_wind.proj;
            cellhd.zone = loc_wind.zone;
            G_message(_("Over-riding projection check"));
        }
        else if (loc_wind.proj != cellhd.proj
                 || (err =
                         G_compare_projections(loc_proj_info, loc_proj_units,
                                               proj_info, proj_units)) != TRUE) {
            int i_value;

            strcpy(error_msg,
                   _("Projection of dataset does not"
                     " appear to match current location.\n\n"));

            /* TODO: output this info sorted by key: */
            if (loc_wind.proj != cellhd.proj || err != -2) {
                if (loc_proj_info != NULL) {
                    strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n"));
                    for (i_value = 0; i_value < loc_proj_info->nitems;
                            i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                loc_proj_info->key[i_value],
                                loc_proj_info->value[i_value]);
                    strcat(error_msg, "\n");
                }

                if (proj_info != NULL) {
                    strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
                    for (i_value = 0; i_value < proj_info->nitems; i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                proj_info->key[i_value],
                                proj_info->value[i_value]);
                }
                else {
                    strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
                    if (cellhd.proj == PROJECTION_XY)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (unreferenced/unknown)\n",
                                cellhd.proj);
                    else if (cellhd.proj == PROJECTION_LL)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (lat/long)\n",
                                cellhd.proj);
                    else if (cellhd.proj == PROJECTION_UTM)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (UTM), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                    else if (cellhd.proj == PROJECTION_SP)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (State Plane), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                    else
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (unknown), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                }
            }
            else {
                if (loc_proj_units != NULL) {
                    strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n");
                    for (i_value = 0; i_value < loc_proj_units->nitems;
                            i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                loc_proj_units->key[i_value],
                                loc_proj_units->value[i_value]);
                    strcat(error_msg, "\n");
                }

                if (proj_units != NULL) {
                    strcat(error_msg, "Import dataset PROJ_UNITS is:\n");
                    for (i_value = 0; i_value < proj_units->nitems; i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                proj_units->key[i_value],
                                proj_units->value[i_value]);
                }
            }
            sprintf(error_msg + strlen(error_msg),
                    _("\nYou can use the -o flag to %s to override this projection check.\n"),
                    G_program_name());
            strcat(error_msg,
                   _("Consider generating a new location with 'location' parameter"
                     " from input data set.\n"));
            G_fatal_error(error_msg);
        }
        else {
            G_message(_("Projection of input dataset and current location "
                        "appear to match"));
        }
    }

    db_init_string(&sql);
    db_init_string(&strval);

    /* open output vector */
    /* strip any @mapset from vector output name */
    G_find_vector(output, G_mapset());
    Vect_open_new(&Map, output, flag.z->answer != 0);
    Out = &Map;

    n_polygon_boundaries = 0;
    if (!flag.no_clean->answer) {
        /* check if we need a tmp vector */

        /* estimate distance for boundary splitting --> */
        for (layer = 0; layer < nlayers; layer++) {
            layer_id = layers[layer];

            Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
            Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);

            n_features = feature_count = 0;

            n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
            OGR_L_ResetReading(Ogr_layer);

            /* count polygons and isles */
            G_message(_("Counting polygons for %d features (OGR layer <%s>)..."),
                      n_features, layer_names[layer]);
            while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
                G_percent(feature_count++, n_features, 1);	/* show something happens */
                /* Geometry */
                Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
                if (Ogr_geometry != NULL) {
                    poly_count(Ogr_geometry, (type & GV_BOUNDARY));
                }
                OGR_F_Destroy(Ogr_feature);
            }
        }

        G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries);
        if (n_polygon_boundaries > 50) {
            split_distance =
                area_size / log(n_polygon_boundaries);
            /* divisor is the handle: increase divisor to decrease split_distance */
            split_distance = split_distance / 5.;
            G_debug(1, "root of area size: %f", area_size);
            G_verbose_message(_("Boundary splitting distance in map units: %G"),
                              split_distance);
        }
        /* <-- estimate distance for boundary splitting */

        use_tmp_vect = n_polygon_boundaries > 0;

        if (use_tmp_vect) {
            /* open temporary vector, do the work in the temporary vector
             * at the end copy alive lines to output vector
             * in case of polygons this reduces the coor file size by a factor of 2 to 5
             * only needed when cleaning polygons */
            sprintf(tempvect, "%s_tmp", output);
            G_verbose_message(_("Using temporary vector <%s>"), tempvect);
            Vect_open_new(&Tmp, tempvect, flag.z->answer != 0);
            Out = &Tmp;
        }
    }

    Vect_hist_command(&Map);

    /* Points and lines are written immediately with categories. Boundaries of polygons are
     * written to the vector then cleaned and centroids are calculated for all areas in cleaan vector.
     * Then second pass through finds all centroids in each polygon feature and adds its category
     * to the centroid. The result is that one centroids may have 0, 1 ore more categories
     * of one ore more (more input layers) fields. */
    with_z = 0;
    for (layer = 0; layer < nlayers; layer++) {
        layer_id = layers[layer];

        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
        Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);

        /* Add DB link */
        if (!flag.notab->answer) {
            char *cat_col_name = GV_KEY_COLUMN;

            if (nlayers == 1) {	/* one layer only */
                Fi = Vect_default_field_info(&Map, layer + 1, NULL,
                                             GV_1TABLE);
            }
            else {
                Fi = Vect_default_field_info(&Map, layer + 1, NULL,
                                             GV_MTABLE);
            }

            if (ncnames > 0) {
                cat_col_name = param.cnames->answers[0];
            }
            Vect_map_add_dblink(&Map, layer + 1, layer_names[layer], Fi->table,
                                cat_col_name, Fi->database, Fi->driver);

            ncols = OGR_FD_GetFieldCount(Ogr_featuredefn);
            G_debug(2, "%d columns", ncols);

            /* Create table */
            sprintf(buf, "create table %s (%s integer", Fi->table,
                    cat_col_name);
            db_set_string(&sql, buf);
            for (i = 0; i < ncols; i++) {

                Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i);
                Ogr_ftype = OGR_Fld_GetType(Ogr_field);

                G_debug(3, "Ogr_ftype: %i", Ogr_ftype);	/* look up below */

                if (i < ncnames - 1) {
                    Ogr_fieldname = G_store(param.cnames->answers[i + 1]);
                }
                else {
                    /* Change column names to [A-Za-z][A-Za-z0-9_]* */
                    Ogr_fieldname = G_store(OGR_Fld_GetNameRef(Ogr_field));
                    G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname);

                    G_str_to_sql(Ogr_fieldname);

                    G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname);

                }

                /* avoid that we get the 'cat' column twice */
                if (strcmp(Ogr_fieldname, GV_KEY_COLUMN) == 0) {
                    sprintf(namebuf, "%s_", Ogr_fieldname);
                    Ogr_fieldname = G_store(namebuf);
                }

                /* captial column names are a pain in SQL */
                if (flag.tolower->answer)
                    G_str_to_lower(Ogr_fieldname);

                if (strcmp(OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname) != 0) {
                    G_warning(_("Column name changed: '%s' -> '%s'"),
                              OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname);
                }

                /** Simple 32bit integer                     OFTInteger = 0        **/

                /** List of 32bit integers                   OFTIntegerList = 1    **/

                /** Double Precision floating point          OFTReal = 2           **/

                /** List of doubles                          OFTRealList = 3       **/

                /** String of ASCII chars                    OFTString = 4         **/

                /** Array of strings                         OFTStringList = 5     **/

                /** Double byte string (unsupported)         OFTWideString = 6     **/

                /** List of wide strings (unsupported)       OFTWideStringList = 7 **/

                /** Raw Binary data (unsupported)            OFTBinary = 8         **/

                /**                                          OFTDate = 9           **/

                /**                                          OFTTime = 10          **/

                /**                                          OFTDateTime = 11      **/


                if (Ogr_ftype == OFTInteger) {
                    sprintf(buf, ", %s integer", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTIntegerList) {
                    /* hack: treat as string */
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            OFTIntegerListlength);
                    G_warning(_("Writing column <%s> with fixed length %d chars (may be truncated)"),
                              Ogr_fieldname, OFTIntegerListlength);
                }
                else if (Ogr_ftype == OFTReal) {
                    sprintf(buf, ", %s double precision", Ogr_fieldname);
#if GDAL_VERSION_NUM >= 1320
                }
                else if (Ogr_ftype == OFTDate) {
                    sprintf(buf, ", %s date", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTTime) {
                    sprintf(buf, ", %s time", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTDateTime) {
                    sprintf(buf, ", %s datetime", Ogr_fieldname);
#endif
                }
                else if (Ogr_ftype == OFTString) {
                    int fwidth;

                    fwidth = OGR_Fld_GetWidth(Ogr_field);
                    /* TODO: read all records first and find the longest string length */
                    if (fwidth == 0) {
                        G_warning(_("Width for column %s set to 255 (was not specified by OGR), "
                                    "some strings may be truncated!"),
                                  Ogr_fieldname);
                        fwidth = 255;
                    }
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            fwidth);
                }
                else if (Ogr_ftype == OFTStringList) {
                    /* hack: treat as string */
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            OFTIntegerListlength);
                    G_warning(_("Writing column %s with fixed length %d chars (may be truncated)"),
                              Ogr_fieldname, OFTIntegerListlength);
                }
                else {
                    G_warning(_("Column type not supported (%s)"),
                              Ogr_fieldname);
                    buf[0] = 0;
                }
                db_append_string(&sql, buf);
                G_free(Ogr_fieldname);
            }
            db_append_string(&sql, ")");
            G_debug(3, db_get_string(&sql));

            driver =
                db_start_driver_open_database(Fi->driver,
                                              Vect_subst_var(Fi->database,
                                                      &Map));
            if (driver == NULL) {
                G_fatal_error(_("Unable open database <%s> by driver <%s>"),
                              Vect_subst_var(Fi->database, &Map), Fi->driver);
            }

            if (db_execute_immediate(driver, &sql) != DB_OK) {
                db_close_database(driver);
                db_shutdown_driver(driver);
                G_fatal_error(_("Unable to create table: '%s'"),
                              db_get_string(&sql));
            }

            if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK)
                G_warning(_("Unable to create index for table <%s>, key <%s>"),
                          Fi->table, cat_col_name);

            if (db_grant_on_table
                    (driver, Fi->table, DB_PRIV_SELECT,
                     DB_GROUP | DB_PUBLIC) != DB_OK)
                G_fatal_error(_("Unable to grant privileges on table <%s>"),
                              Fi->table);

            db_begin_transaction(driver);
        }

        /* Import feature */
        cat = 1;
        nogeom = 0;
        OGR_L_ResetReading(Ogr_layer);
        n_features = feature_count = 0;

        n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);

        G_important_message(_("Importing %d features (OGR layer <%s>)..."),
                            n_features, layer_names[layer]);
        while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
            G_percent(feature_count++, n_features, 1);	/* show something happens */
            /* Geometry */
            Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
            if (Ogr_geometry == NULL) {
                nogeom++;
            }
            else {
                dim = OGR_G_GetCoordinateDimension(Ogr_geometry);
                if (dim > 2)
                    with_z = 1;

                geom(Ogr_geometry, Out, layer + 1, cat, min_area, type,
                     flag.no_clean->answer);
            }

            /* Attributes */
            if (!flag.notab->answer) {
                sprintf(buf, "insert into %s values ( %d", Fi->table, cat);
                db_set_string(&sql, buf);
                for (i = 0; i < ncols; i++) {
                    Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i);
                    Ogr_ftype = OGR_Fld_GetType(Ogr_field);
                    if (OGR_F_IsFieldSet(Ogr_feature, i)) {
                        if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) {
                            sprintf(buf, ", %s",
                                    OGR_F_GetFieldAsString(Ogr_feature, i));
#if GDAL_VERSION_NUM >= 1320
                            /* should we use OGR_F_GetFieldAsDateTime() here ? */
                        }
                        else if (Ogr_ftype == OFTDate || Ogr_ftype == OFTTime
                                 || Ogr_ftype == OFTDateTime) {
                            char *newbuf;

                            db_set_string(&strval, (char *)
                                          OGR_F_GetFieldAsString(Ogr_feature,
                                                                 i));
                            db_double_quote_string(&strval);
                            sprintf(buf, ", '%s'", db_get_string(&strval));
                            newbuf = G_str_replace(buf, "/", "-");	/* fix 2001/10/21 to 2001-10-21 */
                            sprintf(buf, "%s", newbuf);
#endif
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList) {
                            db_set_string(&strval, (char *)
                                          OGR_F_GetFieldAsString(Ogr_feature,
                                                                 i));
                            db_double_quote_string(&strval);
                            sprintf(buf, ", '%s'", db_get_string(&strval));
                        }

                    }
                    else {
                        /* G_warning (_("Column value not set" )); */
                        if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) {
                            sprintf(buf, ", NULL");
#if GDAL_VERSION_NUM >= 1320
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList ||
                                 Ogr_ftype == OFTDate) {
#else
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList) {
#endif
                            sprintf(buf, ", ''");
                        }
                    }
                    db_append_string(&sql, buf);
                }
                db_append_string(&sql, " )");
                G_debug(3, db_get_string(&sql));

                if (db_execute_immediate(driver, &sql) != DB_OK) {
                    db_close_database(driver);
                    db_shutdown_driver(driver);
                    G_fatal_error(_("Cannot insert new row: %s"),
                                  db_get_string(&sql));
                }
            }

            OGR_F_Destroy(Ogr_feature);
            cat++;
        }
        G_percent(1, 1, 1);	/* finish it */

        if (!flag.notab->answer) {
            db_commit_transaction(driver);
            db_close_database_shutdown_driver(driver);
        }

        if (nogeom > 0)
            G_warning(_("%d %s without geometry"), nogeom,
                      nogeom == 1 ? "feature" : "features");
    }


    separator = "-----------------------------------------------------";
    G_message("%s", separator);

    if (use_tmp_vect) {
        /* TODO: is it necessary to build here? probably not, consumes time */
        /* GV_BUILD_BASE is sufficient to toggle boundary cleaning */
        Vect_build_partial(&Tmp, GV_BUILD_BASE);
    }

    if (use_tmp_vect && !flag.no_clean->answer &&
            Vect_get_num_primitives(Out, GV_BOUNDARY) > 0) {
        int ret, centr, ncentr, otype, n_overlaps, n_nocat;
        CENTR *Centr;
        struct spatial_index si;
        double x, y, total_area, overlap_area, nocat_area;
        struct bound_box box;
        struct line_pnts *Points;
        int nmodif;

        Points = Vect_new_line_struct();

        G_message("%s", separator);

        G_warning(_("Cleaning polygons, result is not guaranteed!"));

        if (snap >= 0) {
            G_message("%s", separator);
            G_message(_("Snapping boundaries (threshold = %.3e)..."), snap);
            Vect_snap_lines(&Tmp, GV_BOUNDARY, snap, NULL);
        }

        /* It is not to clean to snap centroids, but I have seen data with 2 duplicate polygons
         * (as far as decimal places were printed) and centroids were not identical */
        /* Disabled, because overlapping polygons result in many duplicate centroids anyway */
        /*
           fprintf ( stderr, separator );
           fprintf ( stderr, "Snap centroids (threshold 0.000001):\n" );
           Vect_snap_lines ( &Map, GV_CENTROID, 0.000001, NULL, stderr );
         */

        G_message("%s", separator);
        G_message(_("Breaking polygons..."));
        Vect_break_polygons(&Tmp, GV_BOUNDARY, NULL);

        /* It is important to remove also duplicate centroids in case of duplicate input polygons */
        G_message("%s", separator);
        G_message(_("Removing duplicates..."));
        Vect_remove_duplicates(&Tmp, GV_BOUNDARY | GV_CENTROID, NULL);

        /* in non-pathological cases, the bulk of the cleaning is now done */

        /* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
         * are created. We must call Vect_break_lines(), Vect_remove_duplicates()
         * and Vect_clean_small_angles_at_nodes() until no more small angles are found */
        do {
            G_message("%s", separator);
            G_message(_("Breaking boundaries..."));
            Vect_break_lines(&Tmp, GV_BOUNDARY, NULL);

            G_message("%s", separator);
            G_message(_("Removing duplicates..."));
            Vect_remove_duplicates(&Tmp, GV_BOUNDARY, NULL);

            G_message("%s", separator);
            G_message(_("Cleaning boundaries at nodes..."));
            nmodif =
                Vect_clean_small_angles_at_nodes(&Tmp, GV_BOUNDARY, NULL);
        } while (nmodif > 0);

        /* merge boundaries */
        G_message("%s", separator);
        G_message(_("Merging boundaries..."));
        Vect_merge_lines(&Tmp, GV_BOUNDARY, NULL, NULL);

        G_message("%s", separator);
        if (type & GV_BOUNDARY) {	/* that means lines were converted to boundaries */
            G_message(_("Changing boundary dangles to lines..."));
            Vect_chtype_dangles(&Tmp, -1.0, NULL);
        }
        else {
            G_message(_("Removing dangles..."));
            Vect_remove_dangles(&Tmp, GV_BOUNDARY, -1.0, NULL);
        }

        G_message("%s", separator);
        if (type & GV_BOUNDARY) {
            G_message(_("Changing boundary bridges to lines..."));
            Vect_chtype_bridges(&Tmp, NULL);
        }
        else {
            G_message(_("Removing bridges..."));
            Vect_remove_bridges(&Tmp, NULL);
        }

        /* Boundaries are hopefully clean, build areas */
        G_message("%s", separator);
        Vect_build_partial(&Tmp, GV_BUILD_ATTACH_ISLES);

        /* Calculate new centroids for all areas, centroids have the same id as area */
        ncentr = Vect_get_num_areas(&Tmp);
        G_debug(3, "%d centroids/areas", ncentr);

        Centr = (CENTR *) G_calloc(ncentr + 1, sizeof(CENTR));
        Vect_spatial_index_init(&si, 0);
        for (centr = 1; centr <= ncentr; centr++) {
            Centr[centr].valid = 0;
            Centr[centr].cats = Vect_new_cats_struct();
            ret = Vect_get_point_in_area(&Tmp, centr, &x, &y);
            if (ret < 0) {
                G_warning(_("Unable to calculate area centroid"));
                continue;
            }

            Centr[centr].x = x;
            Centr[centr].y = y;
            Centr[centr].valid = 1;
            box.N = box.S = y;
            box.E = box.W = x;
            box.T = box.B = 0;
            Vect_spatial_index_add_item(&si, centr, &box);
        }

        /* Go through all layers and find centroids for each polygon */
        for (layer = 0; layer < nlayers; layer++) {
            G_message("%s", separator);
            G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]);
            layer_id = layers[layer];
            Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
            n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
            OGR_L_ResetReading(Ogr_layer);

            cat = 0;		/* field = layer + 1 */
            G_percent(cat, n_features, 2);
            while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
                cat++;
                G_percent(cat, n_features, 2);
                /* Geometry */
                Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
                if (Ogr_geometry != NULL) {
                    centroid(Ogr_geometry, Centr, &si, layer + 1, cat,
                             min_area, type);
                }

                OGR_F_Destroy(Ogr_feature);
            }
        }

        /* Write centroids */
        G_message("%s", separator);
        G_message(_("Writing centroids..."));

        n_overlaps = n_nocat = 0;
        total_area = overlap_area = nocat_area = 0.0;
        for (centr = 1; centr <= ncentr; centr++) {
            double area;

            G_percent(centr, ncentr, 2);

            area = Vect_get_area_area(&Tmp, centr);
            total_area += area;

            if (!(Centr[centr].valid)) {
                continue;
            }

            if (Centr[centr].cats->n_cats == 0) {
                nocat_area += area;
                n_nocat++;
                continue;
            }

            if (Centr[centr].cats->n_cats > 1) {
                Vect_cat_set(Centr[centr].cats, nlayers + 1,
                             Centr[centr].cats->n_cats);
                overlap_area += area;
                n_overlaps++;
            }

            Vect_reset_line(Points);
            Vect_append_point(Points, Centr[centr].x, Centr[centr].y, 0.0);
            if (type & GV_POINT)
                otype = GV_POINT;
            else
                otype = GV_CENTROID;
            Vect_write_line(&Tmp, otype, Points, Centr[centr].cats);
        }
        if (Centr)
            G_free(Centr);

        Vect_spatial_index_destroy(&si);

        if (n_overlaps > 0) {
            G_warning(_("%d areas represent more (overlapping) features, because polygons overlap "
                        "in input layer(s). Such areas are linked to more than 1 row in attribute table. "
                        "The number of features for those areas is stored as category in layer %d"),
                      n_overlaps, nlayers + 1);
        }

        G_message("%s", separator);

        Vect_hist_write(&Map, separator);
        Vect_hist_write(&Map, "\n");
        sprintf(buf, _("%d input polygons\n"), n_polygons);
        G_message(_("%d input polygons"), n_polygons);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Total area: %G (%d areas)\n"), total_area, ncentr);
        G_message(_("Total area: %G (%d areas)"), total_area, ncentr);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Overlapping area: %G (%d areas)\n"), overlap_area,
                n_overlaps);
        G_message(_("Overlapping area: %G (%d areas)"), overlap_area,
                  n_overlaps);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Area without category: %G (%d areas)\n"), nocat_area,
                n_nocat);
        G_message(_("Area without category: %G (%d areas)"), nocat_area,
                  n_nocat);
        Vect_hist_write(&Map, buf);
        G_message("%s", separator);
    }

    /* needed?
     * OGR_DS_Destroy( Ogr_ds );
     */

    if (use_tmp_vect) {
        /* Copy temporary vector to output vector */
        Vect_copy_map_lines(&Tmp, &Map);
        /* release memory occupied by topo, we may need that memory for main output */
        Vect_set_release_support(&Tmp);
        Vect_close(&Tmp);
        Vect_delete(tempvect);
    }

    Vect_build(&Map);
    Vect_close(&Map);

    /* -------------------------------------------------------------------- */
    /*      Extend current window based on dataset.                         */
    /* -------------------------------------------------------------------- */
    if (flag.extend->answer) {
        G_get_default_window(&loc_wind);

        loc_wind.north = MAX(loc_wind.north, cellhd.north);
        loc_wind.south = MIN(loc_wind.south, cellhd.south);
        loc_wind.west = MIN(loc_wind.west, cellhd.west);
        loc_wind.east = MAX(loc_wind.east, cellhd.east);

        loc_wind.rows = (int)ceil((loc_wind.north - loc_wind.south)
                                  / loc_wind.ns_res);
        loc_wind.south = loc_wind.north - loc_wind.rows * loc_wind.ns_res;

        loc_wind.cols = (int)ceil((loc_wind.east - loc_wind.west)
                                  / loc_wind.ew_res);
        loc_wind.east = loc_wind.west + loc_wind.cols * loc_wind.ew_res;

        G__put_window(&loc_wind, "../PERMANENT", "DEFAULT_WIND");
    }

    if (with_z && !flag.z->answer)
        G_warning(_("Input data contains 3D features. Created vector is 2D only, "
                    "use -z flag to import 3D vector."));

    exit(EXIT_SUCCESS);
}
Beispiel #24
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *start_opt, *select_opt, *stop_opt, *output_opt,
        *width_opt, *height_opt, *bgcolor_opt, *res_opt;
    struct Flag *list_flag, *selected_flag, *select_flag, *release_flag, 
        *cmd_flag, *truecolor_flag, *update_flag, *x_flag, *sfile_flag;
    
    int nopts, ret;
    const char *mon;
    
    G_gisinit(argv[0]);
    
    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("graphics"));
    G_add_keyword(_("monitors"));
    module->description = _("Controls graphics display monitors from the command line.");
    
    start_opt = G_define_option();
    start_opt->key = "start";
    start_opt->type = TYPE_STRING;
    start_opt->description = _("Name of monitor to start");
    start_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    start_opt->guisection = _("Manage");
    
    stop_opt = G_define_option();
    stop_opt->key = "stop";
    stop_opt->type = TYPE_STRING;
    stop_opt->description = _("Name of monitor to stop");
    stop_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    stop_opt->guisection = _("Manage");

    select_opt = G_define_option();
    select_opt->key = "select";
    select_opt->type = TYPE_STRING;
    select_opt->description = _("Name of monitor to select");
    select_opt->options = "wx0,wx1,wx2,wx3,wx4,wx5,wx6,wx7,png,ps,html,cairo";
    select_opt->guisection = _("Manage");

    width_opt = G_define_option();
    width_opt->key = "width";
    width_opt->label = _("Width for display monitor if not set by GRASS_RENDER_WIDTH");
    width_opt->description = _("Default value: 720");
    width_opt->type = TYPE_INTEGER;
    width_opt->key_desc = "value";
    width_opt->guisection = _("Settings");

    height_opt = G_define_option();
    height_opt->key = "height";
    height_opt->label = _("Height for display monitor if not set by GRASS_RENDER_HEIGHT");
    height_opt->description = _("Default value: 480");
    height_opt->type = TYPE_INTEGER;
    height_opt->key_desc = "value";
    height_opt->guisection = _("Settings");

    res_opt = G_define_option();
    res_opt->key = "resolution";
    res_opt->label = _("Dimensions of display monitor versus current size");
    res_opt->description = _("Example: resolution=2 enlarge display monitor twice to 1280x960"); 
    res_opt->type = TYPE_INTEGER;
    res_opt->key_desc = "value";
    res_opt->guisection = _("Settings");

    bgcolor_opt = G_define_standard_option(G_OPT_CN);
    bgcolor_opt->key = "bgcolor";
    bgcolor_opt->label = _("Background color");
    bgcolor_opt->answer = DEFAULT_BG_COLOR;
    bgcolor_opt->guisection = _("Settings");

    output_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    output_opt->required = NO;
    output_opt->label = _("Name for output file (when starting new monitor)");
    output_opt->description = _("Ignored for 'wx' monitors");
    output_opt->guisection = _("Settings");
    
    list_flag = G_define_flag();
    list_flag->key = 'l';
    list_flag->description = _("List running monitors and exit");
    list_flag->guisection = _("Print");

    selected_flag = G_define_flag();
    selected_flag->key = 'p';
    selected_flag->description = _("Print name of currently selected monitor and exit");
    selected_flag->guisection = _("Print");

    cmd_flag = G_define_flag();
    cmd_flag->key = 'c';
    cmd_flag->description = _("Print commands for currently selected monitor and exit");
    cmd_flag->guisection = _("Print");

    sfile_flag = G_define_flag();
    sfile_flag->key = 'g';
    sfile_flag->description =
	_("Print path to support files of currently selected monitor and exit");

    select_flag = G_define_flag();
    select_flag->key = 's';
    select_flag->description = _("Do not automatically select when starting");
    select_flag->guisection = _("Manage");

    release_flag = G_define_flag();
    release_flag->key = 'r';
    release_flag->description = _("Release and stop currently selected monitor and exit");
    release_flag->guisection = _("Manage");

    truecolor_flag = G_define_flag();
    truecolor_flag->key = 't';
    truecolor_flag->description = _("Disable true colors");
    truecolor_flag->guisection = _("Settings");

    update_flag = G_define_flag();
    update_flag->key = 'u';
    update_flag->label = _("Open output file in update mode");
    update_flag->description = _("Requires --overwrite flag");
    update_flag->guisection = _("Settings");

    x_flag = G_define_flag();
    x_flag->key = 'x';
    x_flag->label = _("Launch light-weight wx monitor without toolbars and statusbar");
    x_flag->description = _("Requires 'start=wx0-7'");
    x_flag->guisection = _("Settings");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (x_flag->answer && start_opt->answer && strncmp(start_opt->answer, "wx", 2) != 0)
        G_warning(_("Flag -%c has effect only for wx monitors (%s=wx0-7)"),
                  x_flag->key, start_opt->key);
            
    if (selected_flag->answer || release_flag->answer ||
        cmd_flag->answer || sfile_flag->answer) {
	if (list_flag->answer)
	    G_warning(_("Flag -%c ignored"), list_flag->key);
	mon = G_getenv_nofatal("MONITOR");
	if (mon) {
	    if (selected_flag->answer) {
		G_verbose_message(_("Currently selected monitor:"));
		fprintf(stdout, "%s\n", mon);
	    }
	    else if (cmd_flag->answer) {
		G_message(_("List of commands for monitor <%s>:"), mon);
		list_cmd(mon, stdout);
	    }
            else if (sfile_flag->answer) {
                list_files(mon, stdout);
            }
	    else if (mon) { /* release */
		G_unsetenv("MONITOR");
		G_verbose_message(_("Monitor <%s> released"), mon); 
                ret = stop_mon(mon);
	    }
	}
	else
	    G_important_message(_("No monitor selected"));
	
	exit(EXIT_SUCCESS);
    }

    if (list_flag->answer) {
	print_list(stdout);
	exit(EXIT_SUCCESS);
    }
	
    nopts = 0;
    if (start_opt->answer)
	nopts++;
    if (stop_opt->answer)
	nopts++;
    if (select_opt->answer)
	nopts++;

    if (nopts != 1)
	G_fatal_error(_("Either <%s>, <%s> or <%s> must be given"),
		      start_opt->key, stop_opt->key, select_opt->key);
    
    if (output_opt->answer &&
	(!start_opt->answer || strncmp(start_opt->answer, "wx", 2) == 0))
	G_warning(_("Option <%s> ignored"), output_opt->key);
    
    if (start_opt->answer) {
        int width, height;

        width = width_opt->answer ? atoi(width_opt->answer) : 0;
        height = height_opt->answer ? atoi(height_opt->answer) : 0;
        if (width < 1) {
            char *env_width = getenv("GRASS_RENDER_WIDTH");
            if (env_width)
                width = atoi(env_width);
        }
        if (height < 1) {
            char *env_height = getenv("GRASS_RENDER_HEIGHT");
            if (env_height)
                height = atoi(env_height);
        }
        if (width < 1)
            width = DEFAULT_WIDTH;
        if (height < 1)
            height = DEFAULT_HEIGHT;
        
        if (res_opt->answer) {
            int res;
            
            res = atoi(res_opt->answer);
            width *= res;
            height *= res;
        }

        G_debug(1, "Monitor width/height = %d/%d", width, height);

	ret = start_mon(start_opt->answer, output_opt->answer, !select_flag->answer,
			width, height, bgcolor_opt->answer,
			!truecolor_flag->answer, x_flag->answer, update_flag->answer);
        if (output_opt->answer && !update_flag->answer) {
            D_open_driver();
            D_setup_unity(0);
            D_erase(bgcolor_opt->answer);
            D_close_driver();
        }
    }
    
    if (stop_opt->answer)
	ret = stop_mon(stop_opt->answer);
    
    if (select_opt->answer)
	ret = select_mon(select_opt->answer);
    
    if (ret != 0)
	exit(EXIT_FAILURE);
    
    exit(EXIT_SUCCESS);
}
Beispiel #25
0
void filter_holes(Gfile * out)
{
    int row, col, nrows, ncols;

    void *arast, *brast, *crast;
    int i, pixel[9], cold, warm, shadow, nulo, lim;

    Gfile tmp;

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    if (nrows < 3 || ncols < 3)
        return;

    /* Open to read */
    if ((out->fd = Rast_open_old(out->name, "")) < 0)
        G_fatal_error(_("Unable to open raster map <%s>"), out->name);

    arast = Rast_allocate_buf(CELL_TYPE);
    brast = Rast_allocate_buf(CELL_TYPE);
    crast = Rast_allocate_buf(CELL_TYPE);

    /* Open to write */
    sprintf(tmp.name, "_%d.BBB", getpid());
    tmp.rast = Rast_allocate_buf(CELL_TYPE);
    if ((tmp.fd = Rast_open_new(tmp.name, CELL_TYPE)) < 0)
        G_fatal_error(_("Unable to create raster map <%s>"), tmp.name);

    G_important_message(_("Filling small holes in clouds..."));

    /* Se puede acelerar creandolos nulos y luego arast = brast
       brast = crast y cargando crast solamente
       G_set_f_null_value(cell[2], ncols);
     */

    for (row = 0; row < nrows; row++) {
        G_percent(row, nrows, 2);
        /* Read row values */
        if (row != 0) {
            Rast_get_c_row(out->fd, arast, row - 1);
        }
        Rast_get_c_row(out->fd, brast, row);
        if (row != (nrows - 1)) {
            Rast_get_c_row(out->fd, crast, row + 1);
        }
        /* Analysis of all pixels */
        for (col = 0; col < ncols; col++) {
            pixel[0] = pval(brast, col);
            if (pixel[0] == 0) {
                if (row == 0) {
                    pixel[1] = -1;
                    pixel[2] = -1;
                    pixel[3] = -1;
                    if (col == 0) {
                        pixel[4] = -1;
                        pixel[5] = pval(brast, col + 1);
                        pixel[6] = -1;
                        pixel[7] = pval(crast, col);
                        pixel[8] = pval(crast, col + 1);
                    }
                    else if (col != (ncols - 1)) {
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = pval(brast, col + 1);
                        pixel[6] = pval(crast, col - 1);
                        pixel[7] = pval(crast, col);
                        pixel[8] = pval(crast, col + 1);
                    }
                    else {
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = -1;
                        pixel[6] = pval(crast, col - 1);
                        pixel[7] = pval(crast, col);
                        pixel[8] = -1;
                    }
                }
                else if (row != (nrows - 1)) {
                    if (col == 0) {
                        pixel[1] = -1;
                        pixel[2] = pval(arast, col);
                        pixel[3] = pval(arast, col + 1);
                        pixel[4] = -1;
                        pixel[5] = pval(brast, col + 1);
                        pixel[6] = -1;
                        pixel[7] = pval(crast, col);
                        pixel[8] = pval(crast, col + 1);
                    }
                    else if (col != (ncols - 1)) {
                        pixel[1] = pval(arast, col - 1);
                        pixel[2] = pval(arast, col);
                        pixel[3] = pval(arast, col + 1);
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = pval(brast, col + 1);
                        pixel[6] = pval(crast, col - 1);
                        pixel[7] = pval(crast, col);
                        pixel[8] = pval(crast, col + 1);
                    }
                    else {
                        pixel[1] = pval(arast, col - 1);
                        pixel[2] = pval(arast, col);
                        pixel[3] = -1;
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = -1;
                        pixel[6] = pval(crast, col - 1);
                        pixel[7] = pval(crast, col);
                        pixel[8] = -1;
                    }
                }
                else {
                    pixel[6] = -1;
                    pixel[7] = -1;
                    pixel[8] = -1;
                    if (col == 0) {
                        pixel[1] = -1;
                        pixel[2] = pval(arast, col);
                        pixel[3] = pval(arast, col + 1);
                        pixel[4] = -1;
                        pixel[5] = pval(brast, col + 1);
                    }
                    else if (col != (ncols - 1)) {
                        pixel[1] = pval(arast, col - 1);
                        pixel[2] = pval(arast, col);
                        pixel[3] = pval(arast, col + 1);
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = pval(brast, col + 1);
                    }
                    else {
                        pixel[1] = pval(arast, col - 1);
                        pixel[2] = pval(arast, col);
                        pixel[3] = -1;
                        pixel[4] = pval(brast, col - 1);
                        pixel[5] = -1;
                    }
                }

                cold = warm = shadow = nulo = 0;
                for (i = 1; i < 9; i++) {
                    switch (pixel[i]) {
                    case IS_COLD_CLOUD:
                        cold++;
                        break;
                    case IS_WARM_CLOUD:
                        warm++;
                        break;
                    case IS_SHADOW:
                        shadow++;
                        break;
                    default:
                        nulo++;
                        break;
                    }
                }
                lim = (int)(cold + warm + shadow + nulo) / 2;

                /* Entra pixel[0] = 0 */
                if (nulo < lim) {
                    if (shadow >= (cold + warm))
                        pixel[0] = IS_SHADOW;
                    else
                        pixel[0] =
                            (warm > cold) ? IS_WARM_CLOUD : IS_COLD_CLOUD;
                }
            }
            if (pixel[0] != 0) {
                ((CELL *) tmp.rast)[col] = pixel[0];
            }
            else {
                Rast_set_c_null_value((CELL *) tmp.rast + col, 1);
            }
        }
        Rast_put_row(tmp.fd, tmp.rast, CELL_TYPE);
    }
    G_percent(1, 1, 1);

    G_free(arast);
    G_free(brast);
    G_free(crast);
    Rast_close(out->fd);

    G_free(tmp.rast);
    Rast_close(tmp.fd);

    G_remove("cats", out->name);
    G_remove("cell", out->name);
    G_remove("cellhd", out->name);
    G_remove("cell_misc", out->name);
    G_remove("hist", out->name);

    G_rename("cats", tmp.name, out->name);
    G_rename("cell", tmp.name, out->name);
    G_rename("cellhd", tmp.name, out->name);
    G_rename("cell_misc", tmp.name, out->name);
    G_rename("hist", tmp.name, out->name);

    return;
}
Beispiel #26
0
int main(int argc, char *argv[])
{
    char group[INAME_LEN], extension[INAME_LEN];
    int order;			/* ADDED WITH CRS MODIFICATIONS */
    char *ipolname;		/* name of interpolation method */
    int method;
    int n, i, m, k = 0;
    int got_file = 0, target_overwrite = 0;
    char *overstr;
    struct Cell_head cellhd;

    struct Option *grp,         /* imagery group */
     *val,                      /* transformation order */
     *ifile,			/* input files */
     *ext,			/* extension */
     *tres,			/* target resolution */
     *mem,			/* amount of memory for cache */
     *interpol;			/* interpolation method:
				   nearest neighbor, bilinear, cubic */
    struct Flag *c, *a;
    struct GModule *module;

    G_gisinit(argv[0]);

    module = G_define_module();
    module->keywords = _("imagery, rectify");
    module->description =
	_("Rectifies an image by computing a coordinate "
	  "transformation for each pixel in the image based on the "
	  "control points.");

    grp = G_define_standard_option(G_OPT_I_GROUP);

    ifile = G_define_standard_option(G_OPT_R_INPUTS);
    ifile->required = NO;

    ext = G_define_option();
    ext->key = "extension";
    ext->type = TYPE_STRING;
    ext->required = YES;
    ext->multiple = NO;
    ext->description = _("Output raster map(s) suffix");

    val = G_define_option();
    val->key = "order";
    val->type = TYPE_INTEGER;
    val->required = YES;
    val->description = _("Rectification polynom order (1-3)");

    tres = G_define_option();
    tres->key = "res";
    tres->type = TYPE_DOUBLE;
    tres->required = NO;
    tres->description = _("Target resolution (ignored if -c flag used)");

    mem = G_define_option();
    mem->key = "memory";
    mem->type = TYPE_DOUBLE;
    mem->key_desc = "memory in MB";
    mem->required = NO;
    mem->answer = "300";
    mem->description = _("Amount of memory to use in MB");

    ipolname = make_ipol_list();

    interpol = G_define_option();
    interpol->key = "method";
    interpol->type = TYPE_STRING;
    interpol->required = NO;
    interpol->answer = "nearest";
    interpol->options = ipolname;
    interpol->description = _("Interpolation method to use");

    c = G_define_flag();
    c->key = 'c';
    c->description =
	_("Use current region settings in target location (def.=calculate smallest area)");

    a = G_define_flag();
    a->key = 'a';
    a->description = _("Rectify all raster maps in group");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* get the method */
    for (method = 0; (ipolname = menu[method].name); method++)
	if (strcmp(ipolname, interpol->answer) == 0)
	    break;

    if (!ipolname)
	G_fatal_error(_("<%s=%s> unknown %s"),
		      interpol->key, interpol->answer, interpol->key);
    interpolate = menu[method].method;

    G_strip(grp->answer);
    strcpy(group, grp->answer);
    strcpy(extension, ext->answer);
    order = atoi(val->answer);

    seg_mb = NULL;
    if (mem->answer) {
	if (atoi(mem->answer) > 0)
	    seg_mb = mem->answer;
    }

    if (!ifile->answers)
	a->answer = 1;		/* force all */

    /* Find out how many files on command line */
    if (!a->answer) {
	for (m = 0; ifile->answers[m]; m++) {
	    k = m;
	}
	k++;
    }

    if (order < 1 || order > MAXORDER)
	G_fatal_error(_("Invalid order (%d); please enter 1 to %d"), order,
		      MAXORDER);

    /* determine the number of files in this group */
    if (I_get_group_ref(group, &ref) <= 0)
	G_fatal_error(_("Group <%s> does not exist"), grp->answer);

    if (ref.nfiles <= 0) {
	G_important_message(_("Group <%s> contains no raster maps; run i.group"),
			    grp->answer);
	exit(EXIT_SUCCESS);
    }

    ref_list = (int *)G_malloc(ref.nfiles * sizeof(int));

    if (a->answer) {
	for (n = 0; n < ref.nfiles; n++) {
	    ref_list[n] = 1;
	}
    }
    else {
	char xname[GNAME_MAX], xmapset[GMAPSET_MAX], *name, *mapset;

	for (n = 0; n < ref.nfiles; n++)
		ref_list[n] = 0;

	for (m = 0; m < k; m++) {
	    got_file = 0;
	    if (G__name_is_fully_qualified(ifile->answers[m], xname, xmapset)) {
		name = xname;
		mapset = xmapset;
	    }
	    else {
		name = ifile->answers[m];
		mapset = NULL;
	    }

	    got_file = 0;
	    for (n = 0; n < ref.nfiles; n++) {
		if (mapset) {
		    if (strcmp(name, ref.file[n].name) == 0 &&
		        strcmp(mapset, ref.file[n].mapset) == 0) {
			got_file = 1;
			ref_list[n] = 1;
			break;
		    }
		}
		else {
		    if (strcmp(name, ref.file[n].name) == 0) {
			got_file = 1;
			ref_list[n] = 1;
			break;
		    }
		}
	    }
	    if (got_file == 0)
		err_exit(ifile->answers[m], group);
	}
    }

    /* read the control points for the group */
    get_control_points(group, order);

    /* get the target */
    get_target(group);

    /* Check the GRASS_OVERWRITE environment variable */
    if ((overstr = getenv("GRASS_OVERWRITE")))  /* OK ? */
	target_overwrite = atoi(overstr);

    if (!target_overwrite) {
	/* check if output exists in target location/mapset */
	char result[GNAME_MAX];
	
	select_target_env();
	for (i = 0; i < ref.nfiles; i++) {
	    if (!ref_list[i])
		continue;

	    strcpy(result, ref.file[i].name);
	    strcat(result, extension);
	    
	    if (G_legal_filename(result) < 0)
		G_fatal_error(_("Extension <%s> is illegal"), extension);
		
	    if (G_find_cell(result, G_mapset())) {
		G_warning(_("The following raster map already exists in"));
		G_warning(_("target LOCATION %s, MAPSET %s:"),
			  G_location(), G_mapset());
		G_warning("<%s>", result);
		G_fatal_error(_("Orthorectification cancelled."));
	    }
	}
	
	select_current_env();
    }
    else
	G_debug(1, "Overwriting OK");

    /* do not use current region in target location */
    if (!c->answer) {
	double res = -1;
	
	if (tres->answer) {
	    if (!((res = atof(tres->answer)) > 0))
		G_warning(_("Target resolution must be > 0, ignored"));
	}
	/* Calculate smallest region */
	if (a->answer) {
	    if (G_get_cellhd(ref.file[0].name, ref.file[0].mapset, &cellhd) <
		0)
		G_fatal_error(_("Unable to read header of raster map <%s>"),
			      ref.file[0].name);
	}
	else {
	    if (G_get_cellhd(ifile->answers[0], ref.file[0].mapset, &cellhd) <
		0)
		G_fatal_error(_("Unable to read header of raster map <%s>"),
			      ifile->answers[0]);
	}
	georef_window(&cellhd, &target_window, order, res);
    }

    G_verbose_message(_("Using region: N=%f S=%f, E=%f W=%f"), target_window.north,
	      target_window.south, target_window.east, target_window.west);

    exec_rectify(order, extension, interpol->answer);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}
Beispiel #27
0
/* exact check for each band
 * returns 0 on success
 * -1 if given nodata value was present in data
 * -2 if selected GDAL datatype could not hold all values
 * */
int exact_checks(GDALDataType export_datatype,
		const char *name, const char *mapset,
		struct Cell_head *cellhead, RASTER_MAP_TYPE maptype,
		double nodataval, const char *nodatakey,
		int default_nodataval)
{
    double dfCellMin;
    double dfCellMax;
    int fd;
    int cols = cellhead->cols;
    int rows = cellhead->rows;
    int ret = 0;

    /* Open GRASS raster */
    fd = Rast_open_old(name, mapset);

    /* Create GRASS raster buffer */
    void *bufer = Rast_allocate_buf(maptype);

    if (bufer == NULL) {
	G_warning(_("Unable to allocate buffer for reading raster map"));
	return -1;
    }

    /* the following routine must be kept identical to export_band */

    /* Copy data form GRASS raster to GDAL raster */
    int row, col;
    int n_nulls = 0, nodatavalmatch = 0;

    dfCellMin = TYPE_FLOAT64_MAX;
    dfCellMax = TYPE_FLOAT64_MIN;

    /* Better use selected GDAL datatype instead of 
     * the best match with GRASS raster map types ? */

    if (maptype == FCELL_TYPE) {

	FCELL fnullval = (FCELL) nodataval;

	G_debug(1, "FCELL nodata val: %f", fnullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_f_null_value(&((FCELL *) bufer)[col])) {
		    n_nulls++;
		}
		else {
		    if (((FCELL *) bufer)[col] == fnullval) {
			nodatavalmatch = 1;
		    }
		    if (dfCellMin > ((FCELL *) bufer)[col])
			dfCellMin = ((FCELL *) bufer)[col];
		    if (dfCellMax < ((FCELL *) bufer)[col])
			dfCellMax = ((FCELL *) bufer)[col];
		}
	    }
	    G_percent(row + 1, rows, 2);
	}
    }
    else if (maptype == DCELL_TYPE) {

	DCELL dnullval = (DCELL) nodataval;

	G_debug(1, "DCELL nodata val: %f", dnullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_d_null_value(&((DCELL *) bufer)[col])) {
		    ((DCELL *) bufer)[col] = dnullval;
		    n_nulls++;
		}
		else {
		    if (((DCELL *) bufer)[col] == dnullval) {
			nodatavalmatch = 1;
		    }
		    if (dfCellMin > ((DCELL *) bufer)[col])
			dfCellMin = ((DCELL *) bufer)[col];
		    if (dfCellMax < ((DCELL *) bufer)[col])
			dfCellMax = ((DCELL *) bufer)[col];
		}
	    }
	    G_percent(row + 1, rows, 2);
	}
    }
    else {

	CELL inullval = (CELL) nodataval;

	G_debug(1, "CELL nodata val: %d", inullval);

	for (row = 0; row < rows; row++) {

	    Rast_get_row(fd, bufer, row, maptype);
	    for (col = 0; col < cols; col++) {
		if (Rast_is_c_null_value(&((CELL *) bufer)[col])) {
		    ((CELL *) bufer)[col] = inullval;
		    n_nulls++;
		}
		else {
		    if (((CELL *) bufer)[col] == inullval) {
			nodatavalmatch = 1;
		    }
		    if (dfCellMin > ((CELL *) bufer)[col])
			dfCellMin = ((CELL *) bufer)[col];
		    if (dfCellMax < ((CELL *) bufer)[col])
			dfCellMax = ((CELL *) bufer)[col];
		}
	    }
	    G_percent(row + 1, rows, 2);
	}
    }
    G_debug(1, "min %g max %g", dfCellMin, dfCellMax);

    /* can the GDAL datatype hold the data range to be exported ? */
    /* f-flag does not override */
    if (exact_range_check(dfCellMin, dfCellMax, export_datatype, name)) {
	G_warning("Raster export results in data loss.");
	ret = -2;
    }
    G_message(_("Using GDAL data type <%s>"), GDALGetDataTypeName(export_datatype));

    /* a default nodata value was used and NULL cells were present */
    if (n_nulls && default_nodataval) {
	if (maptype == CELL_TYPE)
	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
				 "The value %d will be used to represent no-data values in the input map. "
				 "You can specify a nodata value with the %s option."),
				(int)nodataval, nodatakey);
	else
	    G_important_message(_("Input raster map contains cells with NULL-value (no-data). "
				 "The value %g will be used to represent no-data values in the input map. "
				 "You can specify a nodata value with the %s option."),
				nodataval, nodatakey);
    }

    /* the nodata value was present in the exported data */
    if (nodatavalmatch && n_nulls) {
	/* default nodataval didn't work */
	if (default_nodataval) {
	    G_warning(_("The default nodata value is present in raster"
			"band <%s> and would lead to data loss. Please specify a "
			"custom nodata value with the %s parameter."),
		      name, nodatakey);
	}
	/* user-specified nodataval didn't work */
	else {
	    G_warning(_("The user given nodata value %g is present in raster"
			"band <%s> and would lead to data loss. Please specify a "
			"different nodata value with the %s parameter."),
		      nodataval, name, nodatakey);
	}
	ret = -1;
    }

    Rast_close(fd);

    G_free(bufer);

    return ret;
}
Beispiel #28
0
int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
	      const char *style, const char *rules,
	      const struct FPRange *range, struct Colors *colors)
{
    int ctype, is_fp, nrec;
    double fmin, fmax;
    
    struct field_info *fi;
    struct Colors vcolors;
    dbDriver *driver;
    dbCatValArray cvarr;

    Rast_init_colors(colors);
    
    fi = Vect_get_field(Map, layer);
    if (!fi)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      layer);

    driver = db_start_driver_open_database(fi->driver, fi->database);
    if (!driver)
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      fi->database, fi->driver);
    db_set_error_handler_driver(driver);

    ctype = db_column_Ctype(driver, fi->table, column_name);
    if (ctype == -1)
	G_fatal_error(_("Column <%s> not found in table <%s>"),
		      column_name, fi->table);
    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Column <%s> is not numeric"), column_name);

    is_fp = ctype == DB_C_TYPE_DOUBLE;

    nrec = db_select_CatValArray(driver, fi->table, fi->key, column_name,
				 NULL, &cvarr);
    if (nrec < 1) {
	G_important_message(_("No data selected"));
	return 0;
    }
    
    /* color table for values */
    db_CatValArray_sort_by_value(&cvarr);
    if (is_fp) {
	fmin = cvarr.value[0].val.d;
	fmax = cvarr.value[cvarr.n_values-1].val.d;

	if (range) {
	    if (range->min >= fmin && range->min <= fmax)
		fmin = range->min;
	    else
		G_warning(_("Min value (%f) is out of range %f,%f"),
			  range->min, fmin, fmax);
	    
	    if (range->max <= fmax && range->max >= fmin)
		fmax = range->max;
	    else
		G_warning(_("Max value (%f) is out of range %f,%f"),
			  range->max, fmin, fmax);
	}
    }
    else {
	fmin = cvarr.value[0].val.i;
	fmax = cvarr.value[cvarr.n_values-1].val.i;
	
	if (range) {
	    if (range->min >= fmin && range->min <= fmax)
		fmin = range->min;
	    else
		G_warning(_("Min value (%d) is out of range %d,%d"),
			  (int) range->min, (int) fmin, (int) fmax);
	    
	    if (range->max <= fmax && range->max >= fmin)
		fmax = range->max;
	    else
		G_warning(_("Max value (%d) is out of range %d,%d"),
			  (int) range->max, (int) fmin, (int) fmax);
	}
    }
    if (style)
	make_colors(&vcolors, style, (DCELL) fmin, (DCELL) fmax, is_fp);
    else if (rules)
	load_colors(&vcolors, rules, (DCELL) fmin, (DCELL) fmax, is_fp);

    /* color table for categories */
    color_rules_to_cats(&cvarr, is_fp, &vcolors, colors);

    db_close_database(driver);

    return is_fp;
}
Beispiel #29
0
int main(int argc, char **argv)
{
    char *mapname,		/* ptr to name of output layer  */
     *setname,			/* ptr to name of input mapset  */
     *ipolname;			/* name of interpolation method */

    int fdi,			/* input map file descriptor    */
      fdo,			/* output map file descriptor   */
      method,			/* position of method in table  */
      permissions,		/* mapset permissions           */
      cell_type,		/* output celltype              */
      cell_size,		/* size of a cell in bytes      */
      row, col,			/* counters                     */
      irows, icols,		/* original rows, cols          */
      orows, ocols, have_colors,	/* Input map has a colour table */
      overwrite,		/* Overwrite                    */
      curr_proj;		/* output projection (see gis.h) */

    void *obuffer,		/* buffer that holds one output row     */
     *obufptr;			/* column ptr in output buffer  */
    struct cache *ibuffer;	/* buffer that holds the input map      */
    func interpolate;		/* interpolation routine        */

    double xcoord1, xcoord2,	/* temporary x coordinates      */
      ycoord1, ycoord2,		/* temporary y coordinates      */
      col_idx,			/* column index in input matrix */
      row_idx,			/* row index in input matrix    */
      onorth, osouth,		/* save original border coords  */
      oeast, owest, inorth, isouth, ieast, iwest;
    char north_str[30], south_str[30], east_str[30], west_str[30];

    struct Colors colr;		/* Input map colour table       */
    struct History history;

    struct pj_info iproj,	/* input map proj parameters    */
      oproj;			/* output map proj parameters   */

    struct Key_Value *in_proj_info,	/* projection information of    */
     *in_unit_info,		/* input and output mapsets     */
     *out_proj_info, *out_unit_info;

    struct GModule *module;

    struct Flag *list,		/* list files in source location */
     *nocrop,			/* don't crop output map        */
     *print_bounds,		/* print output bounds and exit */
     *gprint_bounds;		/* same but print shell style	*/

    struct Option *imapset,	/* name of input mapset         */
     *inmap,			/* name of input layer          */
     *inlocation,		/* name of input location       */
     *outmap,			/* name of output layer         */
     *indbase,			/* name of input database       */
     *interpol,			/* interpolation method:
				   nearest neighbor, bilinear, cubic */
     *memory,			/* amount of memory for cache   */
     *res;			/* resolution of target map     */
    struct Cell_head incellhd,	/* cell header of input map     */
      outcellhd;		/* and output map               */


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("projection"));
    G_add_keyword(_("transformation"));
    module->description =
	_("Re-projects a raster map from given location to the current location.");

    inmap = G_define_standard_option(G_OPT_R_INPUT);
    inmap->description = _("Name of input raster map to re-project");
    inmap->required = NO;
    inmap->guisection = _("Source");

    inlocation = G_define_option();
    inlocation->key = "location";
    inlocation->type = TYPE_STRING;
    inlocation->required = YES;
    inlocation->description = _("Location containing input raster map");
    inlocation->gisprompt = "old,location,location";
    inlocation->key_desc = "name";

    imapset = G_define_standard_option(G_OPT_M_MAPSET);
    imapset->label = _("Mapset containing input raster map");
    imapset->description = _("default: name of current mapset");
    imapset->guisection = _("Source");

    indbase = G_define_option();
    indbase->key = "dbase";
    indbase->type = TYPE_STRING;
    indbase->required = NO;
    indbase->description = _("Path to GRASS database of input location");
    indbase->gisprompt = "old,dbase,dbase";
    indbase->key_desc = "path";
    indbase->guisection = _("Source");

    outmap = G_define_standard_option(G_OPT_R_OUTPUT);
    outmap->required = NO;
    outmap->description = _("Name for output raster map (default: same as 'input')");
    outmap->guisection = _("Target");

    ipolname = make_ipol_list();
    
    interpol = G_define_option();
    interpol->key = "method";
    interpol->type = TYPE_STRING;
    interpol->required = NO;
    interpol->answer = "nearest";
    interpol->options = ipolname;
    interpol->description = _("Interpolation method to use");
    interpol->guisection = _("Target");
    interpol->descriptions = make_ipol_desc();

    memory = G_define_option();
    memory->key = "memory";
    memory->type = TYPE_INTEGER;
    memory->required = NO;
    memory->description = _("Cache size (MiB)");

    res = G_define_option();
    res->key = "resolution";
    res->type = TYPE_DOUBLE;
    res->required = NO;
    res->description = _("Resolution of output raster map");
    res->guisection = _("Target");

    list = G_define_flag();
    list->key = 'l';
    list->description = _("List raster maps in input location and exit");

    nocrop = G_define_flag();
    nocrop->key = 'n';
    nocrop->description = _("Do not perform region cropping optimization");

    print_bounds = G_define_flag();
    print_bounds->key = 'p';
    print_bounds->description =
	_("Print input map's bounds in the current projection and exit");
    print_bounds->guisection = _("Target");
    
    gprint_bounds = G_define_flag();
    gprint_bounds->key = 'g';
    gprint_bounds->description =
	_("Print input map's bounds in the current projection and exit (shell style)");
    gprint_bounds->guisection = _("Target");

    /* The parser checks if the map already exists in current mapset,
       we switch out the check and do it
       in the module after the parser */
    overwrite = G_check_overwrite(argc, argv);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    /* get the method */
    for (method = 0; (ipolname = menu[method].name); method++)
	if (strcmp(ipolname, interpol->answer) == 0)
	    break;

    if (!ipolname)
	G_fatal_error(_("<%s=%s> unknown %s"),
		      interpol->key, interpol->answer, interpol->key);
    interpolate = menu[method].method;

    mapname = outmap->answer ? outmap->answer : inmap->answer;
    if (mapname && !list->answer && !overwrite &&
	G_find_raster(mapname, G_mapset()))
	G_fatal_error(_("option <%s>: <%s> exists."), "output", mapname);

    setname = imapset->answer ? imapset->answer : G_store(G_mapset());
    if (strcmp(inlocation->answer, G_location()) == 0 &&
        (!indbase->answer || strcmp(indbase->answer, G_gisdbase()) == 0))
#if 0
	G_fatal_error(_("Input and output locations can not be the same"));
#else
	G_warning(_("Input and output locations are the same"));
#endif
    G_get_window(&outcellhd);

    if(gprint_bounds->answer && !print_bounds->answer)
	print_bounds->answer = gprint_bounds->answer;
    curr_proj = G_projection();

    /* Get projection info for output mapset */
    if ((out_proj_info = G_get_projinfo()) == NULL)
	G_fatal_error(_("Unable to get projection info of output raster map"));

    if ((out_unit_info = G_get_projunits()) == NULL)
	G_fatal_error(_("Unable to get projection units of output raster map"));

    if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0)
	G_fatal_error(_("Unable to get projection key values of output raster map"));

    /* Change the location           */
    G__create_alt_env();
    G__setenv("GISDBASE", indbase->answer ? indbase->answer : G_gisdbase());
    G__setenv("LOCATION_NAME", inlocation->answer);

    permissions = G__mapset_permissions(setname);
    if (permissions < 0)	/* can't access mapset       */
	G_fatal_error(_("Mapset <%s> in input location <%s> - %s"),
		      setname, inlocation->answer,
		      permissions == 0 ? _("permission denied")
		      : _("not found"));

    /* if requested, list the raster maps in source location - MN 5/2001 */
    if (list->answer) {
	int i;
	char **list;
	G_verbose_message(_("Checking location <%s> mapset <%s>"),
			  inlocation->answer, setname);
	list = G_list(G_ELEMENT_RASTER, G__getenv("GISDBASE"),
		      G__getenv("LOCATION_NAME"), setname);
	for (i = 0; list[i]; i++) {
	    fprintf(stdout, "%s\n", list[i]);
	}
	fflush(stdout);
	exit(EXIT_SUCCESS);	/* leave r.proj after listing */
    }

    if (!inmap->answer)
	G_fatal_error(_("Required parameter <%s> not set"), inmap->key);

    if (!G_find_raster(inmap->answer, setname))
	G_fatal_error(_("Raster map <%s> in location <%s> in mapset <%s> not found"),
		      inmap->answer, inlocation->answer, setname);

    /* Read input map colour table */
    have_colors = Rast_read_colors(inmap->answer, setname, &colr);

    /* Get projection info for input mapset */
    if ((in_proj_info = G_get_projinfo()) == NULL)
	G_fatal_error(_("Unable to get projection info of input map"));

    if ((in_unit_info = G_get_projunits()) == NULL)
	G_fatal_error(_("Unable to get projection units of input map"));

    if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
	G_fatal_error(_("Unable to get projection key values of input map"));

    G_free_key_value(in_proj_info);
    G_free_key_value(in_unit_info);
    G_free_key_value(out_proj_info);
    G_free_key_value(out_unit_info);
    if (G_verbose() > G_verbose_std())
	pj_print_proj_params(&iproj, &oproj);

    /* this call causes r.proj to read the entire map into memeory */
    Rast_get_cellhd(inmap->answer, setname, &incellhd);

    Rast_set_input_window(&incellhd);

    if (G_projection() == PROJECTION_XY)
	G_fatal_error(_("Unable to work with unprojected data (xy location)"));

    /* Save default borders so we can show them later */
    inorth = incellhd.north;
    isouth = incellhd.south;
    ieast = incellhd.east;
    iwest = incellhd.west;
    irows = incellhd.rows;
    icols = incellhd.cols;

    onorth = outcellhd.north;
    osouth = outcellhd.south;
    oeast = outcellhd.east;
    owest = outcellhd.west;
    orows = outcellhd.rows;
    ocols = outcellhd.cols;


    if (print_bounds->answer) {
	G_message(_("Input map <%s@%s> in location <%s>:"),
	    inmap->answer, setname, inlocation->answer);

	if (pj_do_proj(&iwest, &isouth, &iproj, &oproj) < 0)
	    G_fatal_error(_("Error in pj_do_proj (projection of input coordinate pair)"));
	if (pj_do_proj(&ieast, &inorth, &iproj, &oproj) < 0)
	    G_fatal_error(_("Error in pj_do_proj (projection of input coordinate pair)"));

	G_format_northing(inorth, north_str, curr_proj);
	G_format_northing(isouth, south_str, curr_proj);
	G_format_easting(ieast, east_str, curr_proj);
	G_format_easting(iwest, west_str, curr_proj);

	if(gprint_bounds->answer) {
	    fprintf(stdout, "n=%s s=%s w=%s e=%s rows=%d cols=%d\n",
		north_str, south_str, west_str, east_str, irows, icols);
	}
	else {
	    fprintf(stdout, "Source cols: %d\n", icols);
	    fprintf(stdout, "Source rows: %d\n", irows);
	    fprintf(stdout, "Local north: %s\n",  north_str);
	    fprintf(stdout, "Local south: %s\n", south_str);
	    fprintf(stdout, "Local west: %s\n", west_str);
	    fprintf(stdout, "Local east: %s\n", east_str);
	}

	/* somehow approximate local ewres, nsres ?? (use 'g.region -m' on lat/lon side) */

	exit(EXIT_SUCCESS);
    }


    /* Cut non-overlapping parts of input map */
    if (!nocrop->answer)
	bordwalk(&outcellhd, &incellhd, &oproj, &iproj);

    /* Add 2 cells on each side for bilinear/cubic & future interpolation methods */
    /* (should probably be a factor based on input and output resolution) */
    incellhd.north += 2 * incellhd.ns_res;
    incellhd.east += 2 * incellhd.ew_res;
    incellhd.south -= 2 * incellhd.ns_res;
    incellhd.west -= 2 * incellhd.ew_res;
    if (incellhd.north > inorth)
	incellhd.north = inorth;
    if (incellhd.east > ieast)
	incellhd.east = ieast;
    if (incellhd.south < isouth)
	incellhd.south = isouth;
    if (incellhd.west < iwest)
	incellhd.west = iwest;

    Rast_set_input_window(&incellhd);

    /* And switch back to original location */

    G__switch_env();

    /* Adjust borders of output map */

    if (!nocrop->answer)
	bordwalk(&incellhd, &outcellhd, &iproj, &oproj);

#if 0
    outcellhd.west = outcellhd.south = HUGE_VAL;
    outcellhd.east = outcellhd.north = -HUGE_VAL;
    for (row = 0; row < incellhd.rows; row++) {
	ycoord1 = Rast_row_to_northing((double)(row + 0.5), &incellhd);
	for (col = 0; col < incellhd.cols; col++) {
	    xcoord1 = Rast_col_to_easting((double)(col + 0.5), &incellhd);
	    pj_do_proj(&xcoord1, &ycoord1, &iproj, &oproj);
	    if (xcoord1 > outcellhd.east)
		outcellhd.east = xcoord1;
	    if (ycoord1 > outcellhd.north)
		outcellhd.north = ycoord1;
	    if (xcoord1 < outcellhd.west)
		outcellhd.west = xcoord1;
	    if (ycoord1 < outcellhd.south)
		outcellhd.south = ycoord1;
	}
    }
#endif

    if (res->answer != NULL)	/* set user defined resolution */
	outcellhd.ns_res = outcellhd.ew_res = atof(res->answer);

    G_adjust_Cell_head(&outcellhd, 0, 0);
    Rast_set_output_window(&outcellhd);

    G_message(" ");
    G_message(_("Input:"));
    G_message(_("Cols: %d (%d)"), incellhd.cols, icols);
    G_message(_("Rows: %d (%d)"), incellhd.rows, irows);
    G_message(_("North: %f (%f)"), incellhd.north, inorth);
    G_message(_("South: %f (%f)"), incellhd.south, isouth);
    G_message(_("West: %f (%f)"), incellhd.west, iwest);
    G_message(_("East: %f (%f)"), incellhd.east, ieast);
    G_message(_("EW-res: %f"), incellhd.ew_res);
    G_message(_("NS-res: %f"), incellhd.ns_res);
    G_message(" ");

    G_message(_("Output:"));
    G_message(_("Cols: %d (%d)"), outcellhd.cols, ocols);
    G_message(_("Rows: %d (%d)"), outcellhd.rows, orows);
    G_message(_("North: %f (%f)"), outcellhd.north, onorth);
    G_message(_("South: %f (%f)"), outcellhd.south, osouth);
    G_message(_("West: %f (%f)"), outcellhd.west, owest);
    G_message(_("East: %f (%f)"), outcellhd.east, oeast);
    G_message(_("EW-res: %f"), outcellhd.ew_res);
    G_message(_("NS-res: %f"), outcellhd.ns_res);
    G_message(" ");

    /* open and read the relevant parts of the input map and close it */
    G__switch_env();
    Rast_set_input_window(&incellhd);
    fdi = Rast_open_old(inmap->answer, setname);
    cell_type = Rast_get_map_type(fdi);
    ibuffer = readcell(fdi, memory->answer);
    Rast_close(fdi);

    G__switch_env();
    Rast_set_output_window(&outcellhd);

    if (strcmp(interpol->answer, "nearest") == 0) {
	fdo = Rast_open_new(mapname, cell_type);
	obuffer = (CELL *) Rast_allocate_output_buf(cell_type);
    }
    else {
	fdo = Rast_open_fp_new(mapname);
	cell_type = FCELL_TYPE;
	obuffer = (FCELL *) Rast_allocate_output_buf(cell_type);
    }

    cell_size = Rast_cell_size(cell_type);

    xcoord1 = xcoord2 = outcellhd.west + (outcellhd.ew_res / 2);
    /**/ ycoord1 = ycoord2 = outcellhd.north - (outcellhd.ns_res / 2);
    /**/ G_important_message(_("Projecting..."));
    G_percent(0, outcellhd.rows, 2);

    for (row = 0; row < outcellhd.rows; row++) {
	obufptr = obuffer;

	for (col = 0; col < outcellhd.cols; col++) {
	    /* project coordinates in output matrix to       */
	    /* coordinates in input matrix                   */
	    if (pj_do_proj(&xcoord1, &ycoord1, &oproj, &iproj) < 0)
		Rast_set_null_value(obufptr, 1, cell_type);
	    else {
		/* convert to row/column indices of input matrix */
		col_idx = (xcoord1 - incellhd.west) / incellhd.ew_res;
		row_idx = (incellhd.north - ycoord1) / incellhd.ns_res;

		/* and resample data point               */
		interpolate(ibuffer, obufptr, cell_type,
			    &col_idx, &row_idx, &incellhd);
	    }

	    obufptr = G_incr_void_ptr(obufptr, cell_size);
	    xcoord2 += outcellhd.ew_res;
	    xcoord1 = xcoord2;
	    ycoord1 = ycoord2;
	}

	Rast_put_row(fdo, obuffer, cell_type);

	xcoord1 = xcoord2 = outcellhd.west + (outcellhd.ew_res / 2);
	ycoord2 -= outcellhd.ns_res;
	ycoord1 = ycoord2;
	G_percent(row, outcellhd.rows - 1, 2);
    }

    Rast_close(fdo);

    if (have_colors > 0) {
	Rast_write_colors(mapname, G_mapset(), &colr);
	Rast_free_colors(&colr);
    }

    Rast_short_history(mapname, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(mapname, &history);

    G_done_msg(NULL);
    exit(EXIT_SUCCESS);
}
Beispiel #30
0
int main(int argc, char *argv[])
{
    /* variables */
    DCELL *data_buf;
    CELL *clump_buf;
    CELL i, max;

    int row, col, rows, cols;
    int out_mode, use_MASK, *n, *e;
    long int *count;
    int fd_data, fd_clump;

    const char *datamap, *clumpmap, *centroidsmap;
    
    double avg, vol, total_vol, east, north, *sum;

    struct Cell_head window;

    struct Map_info *fd_centroids;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct field_info *Fi;

    char buf[DB_SQL_MAX];
    dbString sql;
    dbDriver *driver;

    struct GModule *module;
    struct {
        struct Option *input, *clump, *centroids, *output;
    } opt;
    struct {
        struct Flag *report;
    } flag;

    /* define parameters and flags */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("volume"));
    G_add_keyword(_("clumps"));
    module->label =
	_("Calculates the volume of data \"clumps\".");
    module->description = _("Optionally produces a GRASS vector points map "
                            "containing the calculated centroids of these clumps.");

    opt.input = G_define_standard_option(G_OPT_R_INPUT);
    opt.input->description =
	_("Name of input raster map representing data that will be summed within clumps");

    opt.clump = G_define_standard_option(G_OPT_R_INPUT);
    opt.clump->key = "clump";
    opt.clump->required = NO;
    opt.clump->label =
        _("Name of input clump raster map");
    opt.clump->description = _("Preferably the output of r.clump. "
                               "If no clump map is given than MASK is used.");

    opt.centroids = G_define_standard_option(G_OPT_V_OUTPUT);
    opt.centroids->key = "centroids";
    opt.centroids->required = NO;
    opt.centroids->description = _("Name for output vector points map to contain clump centroids");

    opt.output = G_define_standard_option(G_OPT_F_OUTPUT);
    opt.output->required = NO;
    opt.output->label =
	_("Name for output file to hold the report");
    opt.output->description =
	_("If no output file given report is printed to standard output");

    flag.report = G_define_flag();
    flag.report->key = 'f';
    flag.report->description = _("Generate unformatted report (items separated by colon)");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* get arguments */
    datamap = opt.input->answer;
    
    clumpmap = NULL;
    if (opt.clump->answer)
	clumpmap = opt.clump->answer;
    
    centroidsmap = NULL;
    fd_centroids = NULL;
    Points = NULL;
    Cats = NULL;
    driver = NULL;
    if (opt.centroids->answer) {
	centroidsmap = opt.centroids->answer;
        fd_centroids = G_malloc(sizeof(struct Map_info));
    }
    
    out_mode = (!flag.report->answer);

    /*
     * see if MASK or a separate "clumpmap" raster map is to be used
     * -- it must(!) be one of those two choices.
     */
    use_MASK = 0;
    if (!clumpmap) {
	clumpmap = "MASK";
	use_MASK = 1;
        if (!G_find_raster2(clumpmap, G_mapset()))
            G_fatal_error(_("No MASK found. If no clump map is given than the MASK is required. "
                            "You need to define a clump raster map or create a MASK by r.mask command."));
        G_important_message(_("No clump map given, using MASK"));
    }
    
    /* open input and clump raster maps */
    fd_data = Rast_open_old(datamap, "");
    fd_clump = Rast_open_old(clumpmap, use_MASK ? G_mapset() : "");
    
    /* initialize vector map (for centroids) if needed */
    if (centroidsmap) {
	if (Vect_open_new(fd_centroids, centroidsmap, WITHOUT_Z) < 0)
	    G_fatal_error(_("Unable to create vector map <%s>"), centroidsmap);
        
        Points = Vect_new_line_struct();
        Cats = Vect_new_cats_struct();
        
        /* initialize data structures */
        Vect_append_point(Points, 0., 0., 0.);
        Vect_cat_set(Cats, 1, 1);
    }
    
    /* initialize output file */
    if (opt.output->answer && strcmp(opt.output->answer, "-") != 0) {
	if (freopen(opt.output->answer, "w", stdout) == NULL) {
	    perror(opt.output->answer);
	    exit(EXIT_FAILURE);
	}
    }

    /* initialize data accumulation arrays */
    max = Rast_get_max_c_cat(clumpmap, use_MASK ? G_mapset() : "");

    sum = (double *)G_malloc((max + 1) * sizeof(double));
    count = (long int *)G_malloc((max + 1) * sizeof(long int));

    G_zero(sum, (max + 1) * sizeof(double));
    G_zero(count, (max + 1) * sizeof(long int));
    
    data_buf = Rast_allocate_d_buf();
    clump_buf = Rast_allocate_c_buf();
    
    /* get window size */
    G_get_window(&window);
    rows = window.rows;
    cols = window.cols;

    /* now get the data -- first pass */
    for (row = 0; row < rows; row++) {
	G_percent(row, rows, 2);
	Rast_get_d_row(fd_data, data_buf, row);
	Rast_get_c_row(fd_clump, clump_buf, row);
	for (col = 0; col < cols; col++) {
	    i = clump_buf[col];
	    if (i > max)
		G_fatal_error(_("Invalid category value %d (max=%d): row=%d col=%d"),
                              i, max, row, col);
	    if (i < 1) {
                G_debug(3, "row=%d col=%d: zero or negs ignored", row, col);
		continue;	/* ignore zeros and negs */
            }
	    if (Rast_is_d_null_value(&data_buf[col])) {
                G_debug(3, "row=%d col=%d: NULL ignored", row, col);
		continue;
            }
            
	    sum[i] += data_buf[col];
	    count[i]++;
	}
    }
    G_percent(1, 1, 1);
    
    /* free some buffer space */
    G_free(data_buf);
    G_free(clump_buf);

    /* data lists for centroids of clumps */
    e = (int *)G_malloc((max + 1) * sizeof(int));
    n = (int *)G_malloc((max + 1) * sizeof(int));

    i = centroids(fd_clump, e, n, 1, max);

    /* close raster maps */
    Rast_close(fd_data);
    Rast_close(fd_clump);
    
    /* got everything, now do output */
    if (centroidsmap) {
        G_message(_("Creating vector point map <%s>..."), centroidsmap);
        /* set comment */
	sprintf(buf, _("From '%s' on raster map <%s> using clumps from <%s>"),
                argv[0], datamap, clumpmap);
        Vect_set_comment(fd_centroids, buf);

        /* create attribute table */        
        Fi = Vect_default_field_info(fd_centroids, 1, NULL, GV_1TABLE);
        
        driver = db_start_driver_open_database(Fi->driver,
                                               Vect_subst_var(Fi->database, fd_centroids));
	if (driver == NULL) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Vect_subst_var(Fi->database, fd_centroids), Fi->driver);
	}
        db_set_error_handler_driver(driver);
        
	db_begin_transaction(driver);
        
        db_init_string(&sql);
	sprintf(buf, "create table %s (cat integer, volume double precision, "
                "average double precision, sum double precision, count integer)",
                Fi->table);
	db_set_string(&sql, buf);
	Vect_map_add_dblink(fd_centroids, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	G_debug(3, "%s", db_get_string(&sql));
	if (db_execute_immediate(driver, &sql) != DB_OK) {
	    G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql));
	}
    }

    /* print header */
    if (out_mode) {
	fprintf(stdout, _("\nVolume report on data from <%s> using clumps on <%s> raster map"),
                datamap, clumpmap);
        fprintf(stdout, "\n\n");
	fprintf(stdout,
		_("Category   Average   Data   # Cells        Centroid             Total\n"));
	fprintf(stdout,
		_("Number     in clump  Total  in clump   Easting     Northing     Volume"));
        fprintf(stdout, "\n%s\n", SEP);
    }
    total_vol = 0.0;

    /* print output, write centroids */
    for (i = 1; i <= max; i++) {
	if (count[i]) {
	    avg = sum[i] / (double)count[i];
	    vol = sum[i] * window.ew_res * window.ns_res;
	    total_vol += vol;
	    east = window.west + (e[i] + 0.5) * window.ew_res;
	    north = window.north - (n[i] + 0.5) * window.ns_res;
	    if (fd_centroids) { /* write centroids if requested */
                Points->x[0] = east;
                Points->y[0] = north;
                Cats->cat[0] = i;
                Vect_write_line(fd_centroids, GV_POINT, Points, Cats);
	
                sprintf(buf, "insert into %s values (%d, %f, %f, %f, %ld)",
                        Fi->table, i, vol, avg, sum[i], count[i]);
                db_set_string(&sql, buf);

                if (db_execute_immediate(driver, &sql) != DB_OK)
                    G_fatal_error(_("Cannot insert new row: %s"),
                                  db_get_string(&sql));
	    }
	    if (out_mode)
		fprintf(stdout,
			"%8d%10.2f%10.0f %7ld  %10.2f  %10.2f %16.2f\n", i,
			avg, sum[i], count[i], east, north, vol);
	    else
		fprintf(stdout, "%d:%.2f:%.0f:%ld:%.2f:%.2f:%.2f\n",
			i, avg, sum[i], count[i], east, north, vol);
	}
    }

    /* write centroid attributes and close the map*/
    if (fd_centroids) {
        db_commit_transaction(driver);
        Vect_close(fd_centroids);
    }
    
    /* print total value */
    if (total_vol > 0.0 && out_mode) {
        fprintf(stdout, "%s\n", SEP);
	fprintf(stdout, "%60s = %14.2f", _("Total Volume"), total_vol);
        fprintf(stdout, "\n");
    }

    exit(EXIT_SUCCESS);
}