コード例 #1
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    int nlines;
    double textsize;
    char *dxf_file;
    struct Map_info In;
    struct GModule *module;
    struct Option *input, *output, *field;

    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("export"));
    G_add_keyword(_("DXF"));
    module->description =
	_("Exports vector map to DXF file format.");

    input = G_define_standard_option(G_OPT_V_INPUT);

    field = G_define_standard_option(G_OPT_V_FIELD_ALL);
    
    output = G_define_standard_option(G_OPT_F_OUTPUT);
    output->required = YES;
    output->description = _("Name for DXF output file");

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

    overwrite = module->overwrite;

    /* open input vector */
    dxf_file = G_store(output->answer);

    Vect_set_open_level(2);
    if (Vect_open_old2(&In, input->answer, "", field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), input->answer);

    dxf_open(dxf_file);		/* open output */

    textsize = do_limits(&In);	/* does header in dxf_fp */
    make_layername();
    dxf_entities();
    nlines = add_plines(&In, Vect_get_field_number(&In, field->answer),
			textsize);	/* puts plines in dxf_fp */

    dxf_endsec();
    dxf_eof();			/* puts final stuff in dxf_fp, closes file */

    G_done_msg(_("%d features written to '%s'."), nlines, dxf_file);

    G_free(dxf_file);

    exit(EXIT_SUCCESS);
}
コード例 #2
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    int i, j, centroid, otype, count;
    int nlines, nareas;
    int field;
    struct GModule *module;
    struct Option *in_opt, *field_opt, *out_opt, *type_opt;
    struct Option *size_opt, *zmod_opt, *objmod_opt;
    FILE *fd;

    /* Vector */
    struct Map_info In;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int type;

    G_gisinit(argv[0]);

    /* Module options */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("export"));
    module->description =
	_("Converts GRASS x,y,z points to POV-Ray x,z,y format.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
    
    type_opt = G_define_standard_option(G_OPT_V3_TYPE);
    type_opt->answer = "point,line,area,face";

    out_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    out_opt->required = YES;
    out_opt->description = _("Name for output POV file");

    size_opt = G_define_option();
    size_opt->key = "size";
    size_opt->type = TYPE_STRING;
    size_opt->required = NO;
    size_opt->answer = "10";
    size_opt->label = _("Radius of sphere for points and tube for lines");
    size_opt->description = _("May be also variable, e.g. grass_r.");

    zmod_opt = G_define_option();
    zmod_opt->key = "zmod";
    zmod_opt->type = TYPE_STRING;
    zmod_opt->required = NO;
    zmod_opt->description = _("Modifier for z coordinates");
    zmod_opt->description = _("This string is appended to each z coordinate. "
			      "Examples: '*10', '+1000', '*10+100', '*exaggeration'");

    objmod_opt = G_define_option();
    objmod_opt->key = "objmod";
    objmod_opt->type = TYPE_STRING;
    objmod_opt->required = NO;
    objmod_opt->label = _("Object modifier (OBJECT_MODIFIER in POV-Ray documentation)");
    objmod_opt->description = _("Example: \"pigment { color red 0 green 1 blue 0 }\"");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* Check output type */
    otype = Vect_option_to_types(type_opt);

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

    /* open input vector */
    Vect_set_open_level(2);
    if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);
    
    field = Vect_get_field_number(&In, field_opt->answer);
    
    /* Open output file */
    if ((fd = fopen(out_opt->answer, "w")) == NULL) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create output file <%s>"), out_opt->answer);
    }

    if (zmod_opt->answer == NULL)
	    zmod_opt->answer = G_store("");
    if (objmod_opt->answer == NULL)
	    objmod_opt->answer = G_store("");

    nlines = Vect_get_num_lines(&In);
    nareas = Vect_get_num_areas(&In);
    count = 0;
    /* Lines */
    if ((otype &
	 (GV_POINTS | GV_LINES | GV_BOUNDARY | GV_CENTROID | GV_FACE |
	  GV_KERNEL))) {
	for (i = 1; i <= nlines; i++) {
	    G_percent(i, nlines, 2);
	    type = Vect_read_line(&In, Points, Cats, i);
	    G_debug(2, "line = %d type = %d", i, type);
	    
	    if (field != -1 && Vect_cat_get(Cats, field, NULL) == 0)
		continue;
	    
	    if (!(otype & type)) {
		continue;
	    }
	    
	    switch (type) {
	    case GV_POINT:
	    case GV_CENTROID:
	    case GV_KERNEL:
		fprintf(fd, "sphere { <%f, %f %s, %f>, %s\n%s\n}\n",
			Points->x[0], Points->z[0], zmod_opt->answer,
			Points->y[0], size_opt->answer, objmod_opt->answer);
		count++;
		break;
	    case GV_LINE:
	    case GV_BOUNDARY:
		if (Points->n_points < 2)
		    break;	/* At least 2 points */

		fprintf(fd, "sphere_sweep { linear_spline %d,\n",
			Points->n_points);
		for (j = 0; j < Points->n_points; j++) {
		    fprintf(fd, " <%f, %f %s, %f>, %s\n",
			    Points->x[j], Points->z[j], zmod_opt->answer,
			    Points->y[j], size_opt->answer);
		}
		fprintf(fd, " %s\n}\n", objmod_opt->answer);
		count++;
		break;
	    case GV_FACE:
		if (Points->n_points < 3)
		    break;	/* At least 3 points */

		Vect_append_point(Points, Points->x[0], Points->y[0], Points->z[0]);	/* close */
		fprintf(fd, "polygon { %d, \n", Points->n_points);
		for (j = 0; j < Points->n_points; j++) {
		    fprintf(fd, " <%f, %f %s, %f>\n",
			    Points->x[j], Points->z[j], zmod_opt->answer,
			    Points->y[j]);
		}
		fprintf(fd, " %s\n}\n", objmod_opt->answer);
		count++;
		break;
	    }
	}
    }

    /* Areas (run always to count features of different type) */
    if (otype & GV_AREA && nareas > 0) {
	G_message(_("Processing areas..."));
	for (i = 1; i <= nareas; i++) {
	    G_percent(i, nareas, 2);
	    /* TODO : Use this later for attributes from database: */
	    centroid = Vect_get_area_centroid(&In, i);
	    if (centroid > 0) {
		Vect_read_line(&In, NULL, Cats, centroid);
		if (field != -1 && Vect_cat_get(Cats, field, NULL) < 0)
		    continue;
	    }
	    G_debug(2, "area = %d centroid = %d", i, centroid);

	    /* Geometry */
	    /* Area */
	    Vect_get_area_points(&In, i, Points);
	    if (Points->n_points > 2) {
		for (j = 0; j < Points->n_points; j++) {
		    fprintf(fd, "polygon { %d, \n", Points->n_points);
		    for (j = 0; j < Points->n_points; j++) {
			fprintf(fd, " <%f, %f %s, %f>\n",
				Points->x[j], Points->z[j], zmod_opt->answer,
				Points->y[j]);
		    }
		    fprintf(fd, " %s\n}\n", objmod_opt->answer);
		}

		/* TODO: Isles */
		/*
		   for ( k = 0; k < Vect_get_area_num_isles (&In, i); k++ ) {
		   Vect_get_isle_points ( &In, Vect_get_area_isle (&In, i, k), Points );
		   for ( j = 0; j < Points->n_points; j++ ) {
		   }
		   }
		 */
		count++;
	    }
	}
    }

    fclose(fd);
    Vect_close(&In);

    /* Summary */
    G_done_msg(n_("%d feature written.",
                  "%d features written.",
                  count), count);

    exit(EXIT_SUCCESS);
}
コード例 #3
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *in_opt, *layer_opt, *out_opt, *length_opt, *units_opt, *vertices_opt;
    
    struct Map_info In, Out;
    struct line_pnts *Points, *Points2;
    struct line_cats *Cats;

    int line, nlines, layer;
    double length = -1;
    int vertices = 0;
    double (*line_length) ();
    int latlon = 0;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    module->description = _("Splits vector lines to shorter segments.");
    
    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    length_opt = G_define_option();
    length_opt->key = "length";
    length_opt->type = TYPE_DOUBLE;
    length_opt->required = NO;
    length_opt->multiple = NO;
    length_opt->description = _("Maximum segment length");

    units_opt = G_define_option();
    units_opt->key = "units";
    units_opt->type = TYPE_STRING;
    units_opt->required = NO;
    units_opt->multiple = NO;
    units_opt->options = "meters,kilometers,feet,miles,nautmiles";
    units_opt->answer = "meters";
    units_opt->description = _("Length units");
    
    vertices_opt = G_define_option();
    vertices_opt->key = "vertices";
    vertices_opt->type = TYPE_INTEGER;
    vertices_opt->required = NO;
    vertices_opt->multiple = NO;
    vertices_opt->description = _("Maximum number of vertices in segment");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    
    if ((length_opt->answer && vertices_opt->answer) ||
	!(length_opt->answer || vertices_opt->answer))
	G_fatal_error(_("Use either length or vertices"));

    line_length = NULL;

    if (length_opt->answer) {
	length = atof(length_opt->answer);
	if (length <= 0)
	    G_fatal_error(_("Length must be positive but is %g"), length);

	/* convert length to meters */
	if (strcmp(units_opt->answer, "meters") == 0)
	    /* do nothing */ ;
	else if (strcmp(units_opt->answer, "kilometers") == 0)
	    length *= FROM_KILOMETERS;
	else if (strcmp(units_opt->answer, "feet") == 0)
	    length *= FROM_FEET;
	else if (strcmp(units_opt->answer, "miles") == 0)
	    length *= FROM_MILES;
	else if (strcmp(units_opt->answer, "nautmiles") == 0)
	    length *= FROM_NAUTMILES;
	else
	    G_fatal_error(_("Unknown unit %s"), units_opt->answer); 

	/* set line length function */
	if ((latlon = (G_projection() == PROJECTION_LL)) == 1)
	    line_length = Vect_line_geodesic_length;
	else {
	    double factor;
	    
	    line_length = Vect_line_length;
	    
	    /* convert length to map units */
	    if ((factor = G_database_units_to_meters_factor()) == 0)
		G_fatal_error(_("Can not get projection units"));
	    else {
		/* meters to units */
		length = length / factor;
	    }
	}
	G_verbose_message(_("length in %s: %g"), (latlon ? "meters" : "map units"), length);
    }

    if (vertices_opt->answer) {
	vertices = atoi(vertices_opt->answer);
	if (vertices < 2)
	    G_fatal_error(_("Number of vertices must be at least 2"));
    }
    
    Vect_set_open_level(2);
    Vect_open_old2(&In, in_opt->answer, "", layer_opt->answer);
    layer = Vect_get_field_number(&In, layer_opt->answer);
    
    Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In));
    
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);
    Vect_copy_tables(&In, &Out, layer);
    
    Points = Vect_new_line_struct();
    Points2 = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    nlines = Vect_get_num_lines(&In);

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

	G_percent(line, nlines, 1);

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

	ltype = Vect_read_line(&In, Points, Cats, line);

	if (layer != -1 && !Vect_cat_get(Cats, layer, NULL))
	  continue;

	if (ltype & GV_LINES) {
	    if (length > 0) {
		double l, from, to, step;

		l = line_length(Points);

		if (l <= length) {
		    Vect_write_line(&Out, ltype, Points, Cats);
		}
		else {
		    int n, i;

		    n = ceil(l / length);
		    if (latlon)
			l = Vect_line_length(Points);

		    step = l / n;
		    from = 0.;

		    for (i = 0; i < n; i++) {
			int ret;
			double x, y, z;

			if (i == n - 1) {
			    to = l;	/* to be sure that it goes to end */
			}
			else {
			    to = from + step;
			}

			ret = Vect_line_segment(Points, from, to, Points2);
			if (ret == 0) {
			    G_warning(_("Unable to make line segment: %f - %f (line length = %f)"),
				      from, to, l);
			    continue;
			}

			/* To be sure that the coordinates are identical */
			if (i > 0) {
			    Points2->x[0] = x;
			    Points2->y[0] = y;
			    Points2->z[0] = z;
			}
			if (i == n - 1) {
			    Points2->x[Points2->n_points - 1] =
				Points->x[Points->n_points - 1];
			    Points2->y[Points2->n_points - 1] =
				Points->y[Points->n_points - 1];
			    Points2->z[Points2->n_points - 1] =
				Points->z[Points->n_points - 1];
			}

			Vect_write_line(&Out, ltype, Points2, Cats);

			/* last point */
			x = Points2->x[Points2->n_points - 1];
			y = Points2->y[Points2->n_points - 1];
			z = Points2->z[Points2->n_points - 1];

			from += step;
		    }
		}
	    }
	    else {
		int start = 0;	/* number of coordinates written */

		while (start < Points->n_points - 1) {
		    int i, v;

		    Vect_reset_line(Points2);
		    for (i = 0; i < vertices; i++) {
			v = start + i;
			if (v == Points->n_points)
			    break;

			Vect_append_point(Points2, Points->x[v], Points->y[v],
					  Points->z[v]);
		    }

		    Vect_write_line(&Out, ltype, Points2, Cats);

		    start = v;
		}
	    }
	}
	else {
	    Vect_write_line(&Out, ltype, Points, Cats);
	}
    }

    Vect_close(&In);
    Vect_build(&Out);
    Vect_close(&Out);
    
    exit(EXIT_SUCCESS);
}
コード例 #4
0
ファイル: main.c プロジェクト: GRASS-GIS/grass-ci
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);
}
コード例 #5
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char **argv)
{
    double radius;
    double fisher, david, douglas, lloyd, lloydip, morisita;
    int i, nquads, *counts;

    struct Cell_head window;
    struct GModule *module;
    struct
    {
	struct Option *input, *field, *output, *n, *r;
    } parm;
    struct
    {
	struct Flag *g;
    } flag;
    COOR *quads;

    struct Map_info Map;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("point pattern"));
    module->description = _("Indices for quadrat counts of vector point lists.");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);

    parm.field = G_define_standard_option(G_OPT_V_FIELD_ALL);
    
    parm.output = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.output->required = NO;
    parm.output->description =
	_("Name for output quadrat centers map (number of points is written as category)");

    parm.n = G_define_option();
    parm.n->key = "nquadrats";
    parm.n->type = TYPE_INTEGER;
    parm.n->required = YES;
    parm.n->description = _("Number of quadrats");

    parm.r = G_define_option();
    parm.r->key = "radius";
    parm.r->type = TYPE_DOUBLE;
    parm.r->required = YES;
    parm.r->description = _("Quadrat radius");

    flag.g = G_define_flag();
    flag.g->key = 'g';
    flag.g->description = _("Print results in shell script style");

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

    sscanf(parm.n->answer, "%d", &nquads);
    sscanf(parm.r->answer, "%lf", &radius);

    G_get_window(&window);

    /* Open input */
    Vect_set_open_level(2);
    if (Vect_open_old2(&Map, parm.input->answer, "", parm.field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), parm.input->answer);

    /* Get the quadrats */
    G_message(_("Finding quadrats..."));

    quads = find_quadrats(nquads, radius, window);

    /* Get the counts per quadrat */
    G_message(_("Counting points quadrats..."));

    counts = (int *)G_malloc(nquads * (sizeof(int)));
    count_sites(quads, nquads, counts, radius, &Map,
		Vect_get_field_number(&Map, parm.field->answer));

    Vect_close(&Map);

    /* output if requested */
    if (parm.output->answer) {
	struct Map_info Out;
	struct line_pnts *Points;
	struct line_cats *Cats;

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

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

	Vect_hist_command(&Out);

	for (i = 0; i < nquads; i++) {
	    Vect_reset_line(Points);
	    Vect_reset_cats(Cats);

	    Vect_append_point(Points, quads[i].x, quads[i].y, 0.0);
	    Vect_cat_set(Cats, 1, counts[i]);

	    Vect_write_line(&Out, GV_POINT, Points, Cats);
	}

	Vect_build(&Out);
	Vect_close(&Out);

    }

    /* Indices if requested */
    qindices(counts, nquads, &fisher, &david, &douglas, &lloyd, &lloydip,
	     &morisita);

    if (!flag.g->answer) {
	fprintf(stdout,
		"-----------------------------------------------------------\n");
	fprintf(stdout,
		"Index                                           Realization\n");
	fprintf(stdout,
		"-----------------------------------------------------------\n");
	fprintf(stdout,
		"Fisher el al (1922) Relative Variance            %g\n",
		fisher);
	fprintf(stdout,
		"David & Moore (1954) Index of Cluster Size       %g\n",
		david);
	fprintf(stdout,
		"Douglas (1975) Index of Cluster Frequency        %g\n",
		douglas);
	fprintf(stdout,
		"Lloyd (1967) \"mean crowding\"                     %g\n",
		lloyd);
	fprintf(stdout,
		"Lloyd (1967) Index of patchiness                 %g\n",
		lloydip);
	fprintf(stdout,
		"Morisita's (1959) I (variability b/n patches)    %g\n",
		morisita);
	fprintf(stdout,
		"-----------------------------------------------------------\n");
    }
    else {
	fprintf(stdout, "fisher=%g\n", fisher);
	fprintf(stdout, "david=%g\n", david);
	fprintf(stdout, "douglas=%g\n", douglas);
	fprintf(stdout, "lloyd=%g\n", lloyd);
	fprintf(stdout, "lloydip=%g\n", lloydip);
	fprintf(stdout, "morisita=%g\n", morisita);
    }



    exit(EXIT_SUCCESS);
}
コード例 #6
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *map_opt, *field_opt, *fs_opt, *vs_opt, *nv_opt, *col_opt,
	*where_opt, *file_opt;
    struct Flag *c_flag, *v_flag, *r_flag;
    dbDriver *driver;
    dbString sql, value_string;
    dbCursor cursor;
    dbTable *table;
    dbColumn *column;
    dbValue *value;
    struct field_info *Fi;
    int ncols, col, more;
    struct Map_info Map;
    char query[1024];
    struct ilist *list_lines;

    struct bound_box *min_box, *line_box;
    int i, line, area, init_box, cat;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("database"));
    G_add_keyword(_("attribute table"));
    module->description = _("Prints vector map attributes.");

    map_opt = G_define_standard_option(G_OPT_V_MAP);
    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_standard_option(G_OPT_DB_COLUMNS);

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    fs_opt = G_define_standard_option(G_OPT_F_SEP);
    fs_opt->description = _("Output field separator");
    fs_opt->guisection = _("Format");

    vs_opt = G_define_standard_option(G_OPT_F_SEP);
    vs_opt->key = "vs";
    vs_opt->description = _("Output vertical record separator");
    vs_opt->answer = NULL;
    vs_opt->guisection = _("Format");

    nv_opt = G_define_option();
    nv_opt->key = "nv";
    nv_opt->type = TYPE_STRING;
    nv_opt->required = NO;
    nv_opt->description = _("Null value indicator");
    nv_opt->guisection = _("Format");

    file_opt = G_define_standard_option(G_OPT_F_OUTPUT); 
    file_opt->key = "file";
    file_opt->required = NO; 
    file_opt->description = 
	_("Name for output file (if omitted or \"-\" output to stdout)"); 
    
    r_flag = G_define_flag();
    r_flag->key = 'r';
    r_flag->description =
	_("Print minimal region extent of selected vector features instead of attributes");

    c_flag = G_define_flag();
    c_flag->key = 'c';
    c_flag->description = _("Do not include column names in output");
    c_flag->guisection = _("Format");

    v_flag = G_define_flag();
    v_flag->key = 'v';
    v_flag->description = _("Vertical output (instead of horizontal)");
    v_flag->guisection = _("Format");

    G_gisinit(argv[0]);

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

    /* set input vector map name and mapset */
    if (file_opt->answer && strcmp(file_opt->answer, "-") != 0) { 
	if (NULL == freopen(file_opt->answer, "w", stdout)) { 
	    G_fatal_error(_("Unable to open file <%s> for writing"), file_opt->answer); 
	} 
    } 
    
    if (r_flag->answer) {
	min_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	G_zero((void *)min_box, sizeof(struct bound_box));

	line_box = (struct bound_box *) G_malloc(sizeof(struct bound_box));
	list_lines = Vect_new_list();
    }
    else {
      min_box = line_box = NULL;
      list_lines = NULL;
    }

    db_init_string(&sql);
    db_init_string(&value_string);

    /* open input vector */
    if (!r_flag->answer)
	Vect_open_old_head2(&Map, map_opt->answer, "", field_opt->answer);
    else {
	if (2 > Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer)) {
	    Vect_close(&Map);
	    G_fatal_error(_("Unable to open vector map <%s> at topology level. "
			   "Flag '%c' requires topology level."),
			  map_opt->answer, r_flag->key);
	}
    }

    if ((Fi = Vect_get_field2(&Map, field_opt->answer)) == NULL)
	G_fatal_error(_("Database connection not defined for layer <%s>"),
		      field_opt->answer);

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

    if (col_opt->answer)
	sprintf(query, "SELECT %s FROM ", col_opt->answer);
    else
	sprintf(query, "SELECT * FROM ");

    db_set_string(&sql, query);
    db_append_string(&sql, Fi->table);

    if (where_opt->answer) {
	char *buf = NULL;

	buf = G_malloc((strlen(where_opt->answer) + 8));
	sprintf(buf, " WHERE %s", where_opt->answer);
	db_append_string(&sql, buf);
	G_free(buf);
    }

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open select cursor"));

    table = db_get_cursor_table(&cursor);
    ncols = db_get_table_number_of_columns(table);

    /* column names if horizontal output (ignore for -r) */
    if (!v_flag->answer && !c_flag->answer && !r_flag->answer) {
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    if (col)
		fprintf(stdout, "%s", fs_opt->answer);
	    fprintf(stdout, "%s", db_get_column_name(column));
	}
	fprintf(stdout, "\n");
    }

    init_box = 1;

    /* fetch the data */
    while (1) {
	if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
	    G_fatal_error(_("Unable to fetch data from table <%s>"),
			  Fi->table);

	if (!more)
	    break;

	cat = -1;
	for (col = 0; col < ncols; col++) {
	    column = db_get_table_column(table, col);
	    value = db_get_column_value(column);

	    if (cat < 0 && strcmp(Fi->key, db_get_column_name(column)) == 0) {
		cat = db_get_value_int(value);
		if (r_flag->answer)
		    break;
	    }

	    if (r_flag->answer)
		continue;

	    db_convert_column_value_to_string(column, &value_string);

	    if (!c_flag->answer && v_flag->answer)
		fprintf(stdout, "%s%s", db_get_column_name(column),
			fs_opt->answer);

	    if (col && !v_flag->answer)
		fprintf(stdout, "%s", fs_opt->answer);

	    if (nv_opt->answer && db_test_value_isnull(value))
		fprintf(stdout, "%s", nv_opt->answer);
	    else
		fprintf(stdout, "%s", db_get_string(&value_string));

	    if (v_flag->answer)
		fprintf(stdout, "\n");
	}

	if (r_flag->answer) {
	    /* get minimal region extent */
	    Vect_cidx_find_all(&Map, Vect_get_field_number(&Map, field_opt->answer), -1, cat, list_lines);
	    for (i = 0; i < list_lines->n_values; i++) {
		line = list_lines->value[i];
		area = Vect_get_centroid_area(&Map, line);
		if (area > 0) {
		    if (!Vect_get_area_box(&Map, area, line_box))
			G_fatal_error(_("Unable to get bounding box of area %d"),
				      area);
		}
		else {
		    if (!Vect_get_line_box(&Map, line, line_box))
			G_fatal_error(_("Unable to get bounding box of line %d"),
				      line);
		}
		if (init_box) {
		    Vect_box_copy(min_box, line_box);
		    init_box = 0;
		}
		else {
		    Vect_box_extend(min_box, line_box);
		}
	    }
	}
	else {
	    if (!v_flag->answer)
		fprintf(stdout, "\n");
	    else if (vs_opt->answer)
		fprintf(stdout, "%s\n", vs_opt->answer);
	}
    }

    if (r_flag->answer) {
	fprintf(stdout, "n=%f\n", min_box->N);
	fprintf(stdout, "s=%f\n", min_box->S);
	fprintf(stdout, "w=%f\n", min_box->W);
	fprintf(stdout, "e=%f\n", min_box->E);
	if (Vect_is_3d(&Map)) {
	    fprintf(stdout, "t=%f\n", min_box->T);
	    fprintf(stdout, "b=%f\n", min_box->B);
	}
	fflush(stdout);

	G_free((void *)min_box);
	G_free((void *)line_box);

	Vect_destroy_list(list_lines);
    }

    db_close_cursor(&cursor);
    db_close_database_shutdown_driver(driver);
    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
コード例 #7
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    struct Map_info In, Out, Error;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int i, type, iter;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out, *error_out, *thresh_opt, *method_opt,
	*look_ahead_opt;
    struct Option *iterations_opt, *cat_opt, *alpha_opt, *beta_opt, *type_opt;
    struct Option *field_opt, *where_opt, *reduction_opt, *slide_opt;
    struct Option *angle_thresh_opt, *degree_thresh_opt,
	*closeness_thresh_opt;
    struct Option *betweeness_thresh_opt;
    struct Flag *notab_flag, *loop_support_flag;
    int with_z;
    int total_input, total_output;	/* Number of points in the input/output map respectively */
    double thresh, alpha, beta, reduction, slide, angle_thresh;
    double degree_thresh, closeness_thresh, betweeness_thresh;
    int method;
    int look_ahead, iterations;
    int loop_support;
    int layer;
    int n_lines;
    int simplification, mask_type;
    struct cat_list *cat_list = NULL;
    char *s, *descriptions;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("generalization"));
    G_add_keyword(_("simplification"));
    G_add_keyword(_("smoothing"));
    G_add_keyword(_("displacement"));
    G_add_keyword(_("network generalization"));
    module->description = _("Performs vector based generalization.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "line,boundary,area";
    type_opt->answer = "line,boundary,area";
    type_opt->guisection = _("Selection");
    
    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    error_out = G_define_standard_option(G_OPT_V_OUTPUT);
    error_out->key = "error";
    error_out->required = NO;
    error_out->description =
	_("Error map of all lines and boundaries not being generalized due to topology issues or over-simplification");

    method_opt = G_define_option();
    method_opt->key = "method";
    method_opt->type = TYPE_STRING;
    method_opt->required = YES;
    method_opt->multiple = NO;
    method_opt->options =
	"douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes,network,displacement";
    descriptions = NULL;
    G_asprintf(&descriptions,
               "douglas;%s;"
               "douglas_reduction;%s;"
               "lang;%s;"
               "reduction;%s;"
               "reumann;%s;"
               "boyle;%s;"
               "sliding_averaging;%s;"
               "distance_weighting;%s;"
               "chaiken;%s;"
               "hermite;%s;"
               "snakes;%s;"
               "network;%s;"
               "displacement;%s;",
               _("Douglas-Peucker Algorithm"),
               _("Douglas-Peucker Algorithm with reduction parameter"),
               _("Lang Simplification Algorithm"),
               _("Vertex Reduction Algorithm eliminates points close to each other"),
               _("Reumann-Witkam Algorithm"),
               _("Boyle's Forward-Looking Algorithm"),
               _("McMaster's Sliding Averaging Algorithm"),
               _("McMaster's Distance-Weighting Algorithm"),
               _("Chaiken's Algorithm"),
               _("Interpolation by Cubic Hermite Splines"),
               _("Snakes method for line smoothing"),
               _("Network generalization"),
               _("Displacement of lines close to each other"));
    method_opt->descriptions = G_store(descriptions);
    
    method_opt->description = _("Generalization algorithm");

    thresh_opt = G_define_option();
    thresh_opt->key = "threshold";
    thresh_opt->type = TYPE_DOUBLE;
    thresh_opt->required = YES;
    thresh_opt->options = "0-1000000000";
    thresh_opt->description = _("Maximal tolerance value");

    look_ahead_opt = G_define_option();
    look_ahead_opt->key = "look_ahead";
    look_ahead_opt->type = TYPE_INTEGER;
    look_ahead_opt->required = NO;
    look_ahead_opt->answer = "7";
    look_ahead_opt->description = _("Look-ahead parameter");

    reduction_opt = G_define_option();
    reduction_opt->key = "reduction";
    reduction_opt->type = TYPE_DOUBLE;
    reduction_opt->required = NO;
    reduction_opt->answer = "50";
    reduction_opt->options = "0-100";
    reduction_opt->description =
	_("Percentage of the points in the output of 'douglas_reduction' algorithm");
    
    slide_opt = G_define_option();
    slide_opt->key = "slide";
    slide_opt->type = TYPE_DOUBLE;
    slide_opt->required = NO;
    slide_opt->answer = "0.5";
    slide_opt->options = "0-1";
    slide_opt->description =
	_("Slide of computed point toward the original point");

    angle_thresh_opt = G_define_option();
    angle_thresh_opt->key = "angle_thresh";
    angle_thresh_opt->type = TYPE_DOUBLE;
    angle_thresh_opt->required = NO;
    angle_thresh_opt->answer = "3";
    angle_thresh_opt->options = "0-180";
    angle_thresh_opt->description =
	_("Minimum angle between two consecutive segments in Hermite method");

    degree_thresh_opt = G_define_option();
    degree_thresh_opt->key = "degree_thresh";
    degree_thresh_opt->type = TYPE_INTEGER;
    degree_thresh_opt->required = NO;
    degree_thresh_opt->answer = "0";
    degree_thresh_opt->description =
	_("Degree threshold in network generalization");

    closeness_thresh_opt = G_define_option();
    closeness_thresh_opt->key = "closeness_thresh";
    closeness_thresh_opt->type = TYPE_DOUBLE;
    closeness_thresh_opt->required = NO;
    closeness_thresh_opt->answer = "0";
    closeness_thresh_opt->options = "0-1";
    closeness_thresh_opt->description =
	_("Closeness threshold in network generalization");

    betweeness_thresh_opt = G_define_option();
    betweeness_thresh_opt->key = "betweeness_thresh";
    betweeness_thresh_opt->type = TYPE_DOUBLE;
    betweeness_thresh_opt->required = NO;
    betweeness_thresh_opt->answer = "0";
    betweeness_thresh_opt->description =
	_("Betweeness threshold in network generalization");

    alpha_opt = G_define_option();
    alpha_opt->key = "alpha";
    alpha_opt->type = TYPE_DOUBLE;
    alpha_opt->required = NO;
    alpha_opt->answer = "1.0";
    alpha_opt->description = _("Snakes alpha parameter");

    beta_opt = G_define_option();
    beta_opt->key = "beta";
    beta_opt->type = TYPE_DOUBLE;
    beta_opt->required = NO;
    beta_opt->answer = "1.0";
    beta_opt->description = _("Snakes beta parameter");

    iterations_opt = G_define_option();
    iterations_opt->key = "iterations";
    iterations_opt->type = TYPE_INTEGER;
    iterations_opt->required = NO;
    iterations_opt->answer = "1";
    iterations_opt->description = _("Number of iterations");

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

    loop_support_flag = G_define_flag();
    loop_support_flag->key = 'l';
    loop_support_flag->label = _("Disable loop support");
    loop_support_flag->description = _("Do not modify end points of lines forming a closed loop");

    notab_flag = G_define_standard_flag(G_FLG_V_TABLE);
    notab_flag->description = _("Do not copy attributes");
    notab_flag->guisection = _("Attributes");
    
    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    thresh = atof(thresh_opt->answer);
    look_ahead = atoi(look_ahead_opt->answer);
    alpha = atof(alpha_opt->answer);
    beta = atof(beta_opt->answer);
    reduction = atof(reduction_opt->answer);
    iterations = atoi(iterations_opt->answer);
    slide = atof(slide_opt->answer);
    angle_thresh = atof(angle_thresh_opt->answer);
    degree_thresh = atof(degree_thresh_opt->answer);
    closeness_thresh = atof(closeness_thresh_opt->answer);
    betweeness_thresh = atof(betweeness_thresh_opt->answer);

    mask_type = type_mask(type_opt);
    G_debug(3, "Method: %s", method_opt->answer);

    s = method_opt->answer;

    if (strcmp(s, "douglas") == 0)
	method = DOUGLAS;
    else if (strcmp(s, "lang") == 0)
	method = LANG;
    else if (strcmp(s, "reduction") == 0)
	method = VERTEX_REDUCTION;
    else if (strcmp(s, "reumann") == 0)
	method = REUMANN;
    else if (strcmp(s, "boyle") == 0)
	method = BOYLE;
    else if (strcmp(s, "distance_weighting") == 0)
	method = DISTANCE_WEIGHTING;
    else if (strcmp(s, "chaiken") == 0)
	method = CHAIKEN;
    else if (strcmp(s, "hermite") == 0)
	method = HERMITE;
    else if (strcmp(s, "snakes") == 0)
	method = SNAKES;
    else if (strcmp(s, "douglas_reduction") == 0)
	method = DOUGLAS_REDUCTION;
    else if (strcmp(s, "sliding_averaging") == 0)
	method = SLIDING_AVERAGING;
    else if (strcmp(s, "network") == 0)
	method = NETWORK;
    else if (strcmp(s, "displacement") == 0) {
	method = DISPLACEMENT;
	/* we can displace only the lines */
	mask_type = GV_LINE;
    }
    else {
	G_fatal_error(_("Unknown method"));
	exit(EXIT_FAILURE);
    }


    /* simplification or smoothing? */
    switch (method) {
    case DOUGLAS:
    case DOUGLAS_REDUCTION:
    case LANG:
    case VERTEX_REDUCTION:
    case REUMANN:
	simplification = 1;
	break;
    default:
	simplification = 0;
	break;
    }


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

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (Vect_open_old2(&In, map_in->answer, "", field_opt->answer) < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    if (Vect_get_num_primitives(&In, mask_type) == 0) {
	G_warning(_("No lines found in input map <%s>"), map_in->answer);
	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }
    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }

    if (error_out->answer) {
        if (0 > Vect_open_new(&Error, error_out->answer, with_z)) {
	    Vect_close(&In);
	    G_fatal_error(_("Unable to create error vector map <%s>"), error_out->answer);
        }
    }


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

    total_input = total_output = 0;

    layer = Vect_get_field_number(&In, field_opt->answer);
    /* parse filter options */
    if (layer > 0)
	cat_list = Vect_cats_set_constraint(&In, layer, 
			      where_opt->answer, cat_opt->answer);

    if (method == DISPLACEMENT) {
	/* modifies only lines, all other features including boundaries are preserved */
	/* options where, cats, and layer are respected */
	G_message(_("Displacement..."));
	snakes_displacement(&In, &Out, thresh, alpha, beta, 1.0, 10.0,
			    iterations, cat_list, layer);
    }

    /* TODO: rearrange code below. It's really messy */
    if (method == NETWORK) {
	/* extracts lines of selected type, all other features are discarded */
	/* options where, cats, and layer are ignored */
	G_message(_("Network generalization..."));
	total_output =
	    graph_generalization(&In, &Out, mask_type, degree_thresh, 
	                         closeness_thresh, betweeness_thresh);
    }

    /* copy tables here because method == NETWORK is complete and 
     * tables for Out may be needed for parse_filter_options() below */
    if (!notab_flag->answer) {
	if (method == NETWORK)
	    copy_tables_by_cats(&In, &Out);
	else
	    Vect_copy_tables(&In, &Out, -1);
    }
    else if (where_opt->answer && method < NETWORK) {
	G_warning(_("Attributes are needed for 'where' option, copying table"));
	Vect_copy_tables(&In, &Out, -1);
    }

    /* smoothing/simplification */
    if (method < NETWORK) {
	/* modifies only lines of selected type, all other features are preserved */
	int not_modified_boundaries = 0, n_oversimplified = 0;
	struct line_pnts *APoints;  /* original Points */

	set_topo_debug();

	Vect_copy_map_lines(&In, &Out);
	Vect_build_partial(&Out, GV_BUILD_CENTROIDS);

	G_message("-----------------------------------------------------");
	G_message(_("Generalization (%s)..."), method_opt->answer);
	G_message(_("Using threshold: %g %s"), thresh, G_database_unit_name(1));
	G_percent_reset();

	APoints = Vect_new_line_struct();

	n_lines = Vect_get_num_lines(&Out);
	for (i = 1; i <= n_lines; i++) {
	    int after = 0;

	    G_percent(i, n_lines, 1);

	    type = Vect_read_line(&Out, APoints, Cats, i);

	    if (!(type & GV_LINES) || !(mask_type & type))
		continue;

	    if (layer > 0) {
		if ((type & GV_LINE) &&
		    !Vect_cats_in_constraint(Cats, layer, cat_list))
		    continue;
		else if ((type & GV_BOUNDARY)) {
		    int do_line = 0;
		    int left, right;
		    
		    do_line = Vect_cats_in_constraint(Cats, layer, cat_list);

		    if (!do_line) {
			
			/* check if any of the centroids is selected */
			Vect_get_line_areas(&Out, i, &left, &right);
			if (left < 0)
			    left = Vect_get_isle_area(&Out, abs(left));
			if (right < 0)
			    right = Vect_get_isle_area(&Out, abs(right));

			if (left > 0) {
			    Vect_get_area_cats(&Out, left, Cats);
			    do_line = Vect_cats_in_constraint(Cats, layer, cat_list);
			}
			
			if (!do_line && right > 0) {
			    Vect_get_area_cats(&Out, right, Cats);
			    do_line = Vect_cats_in_constraint(Cats, layer, cat_list);
			}
		    }
		    if (!do_line)
			continue;
		}
	    }

	    Vect_line_prune(APoints);

	    if (APoints->n_points < 2)
		/* Line of length zero, delete if boundary ? */
		continue;

	    total_input += APoints->n_points;

	    /* copy points */
	    Vect_reset_line(Points);
	    Vect_append_points(Points, APoints, GV_FORWARD);
	    
	    loop_support = 0;
	    if (!loop_support_flag->answer) {
		int n1, n2;

		Vect_get_line_nodes(&Out, i, &n1, &n2);
		if (n1 == n2) {
		    if (Vect_get_node_n_lines(&Out, n1) == 2) {
			if (abs(Vect_get_node_line(&Out, n1, 0)) == i &&
			    abs(Vect_get_node_line(&Out, n1, 1)) == i)
			    loop_support = 1;
		    }
		}
	    }
		
	    for (iter = 0; iter < iterations; iter++) {
		switch (method) {
		case DOUGLAS:
		    douglas_peucker(Points, thresh, with_z);
		    break;
		case DOUGLAS_REDUCTION:
		    douglas_peucker_reduction(Points, thresh, reduction,
					      with_z);
		    break;
		case LANG:
		    lang(Points, thresh, look_ahead, with_z);
		    break;
		case VERTEX_REDUCTION:
		    vertex_reduction(Points, thresh, with_z);
		    break;
		case REUMANN:
		    reumann_witkam(Points, thresh, with_z);
		    break;
		case BOYLE:
		    boyle(Points, look_ahead, loop_support, with_z);
		    break;
		case SLIDING_AVERAGING:
		    sliding_averaging(Points, slide, look_ahead, loop_support, with_z);
		    break;
		case DISTANCE_WEIGHTING:
		    distance_weighting(Points, slide, look_ahead, loop_support, with_z);
		    break;
		case CHAIKEN:
		    chaiken(Points, thresh, loop_support, with_z);
		    break;
		case HERMITE:
		    hermite(Points, thresh, angle_thresh, loop_support, with_z);
		    break;
		case SNAKES:
		    snakes(Points, alpha, beta, loop_support, with_z);
		    break;
		}
	    }

	    if (loop_support == 0) { 
		/* safety check, BUG in method if not passed */
		if (APoints->x[0] != Points->x[0] || 
		    APoints->y[0] != Points->y[0] ||
		    APoints->z[0] != Points->z[0])
		    G_fatal_error(_("Method '%s' did not preserve first point"), method_opt->answer);
		    
		if (APoints->x[APoints->n_points - 1] != Points->x[Points->n_points - 1] || 
		    APoints->y[APoints->n_points - 1] != Points->y[Points->n_points - 1] ||
		    APoints->z[APoints->n_points - 1] != Points->z[Points->n_points - 1])
		    G_fatal_error(_("Method '%s' did not preserve last point"), method_opt->answer);
	    }
	    else {
		/* safety check, BUG in method if not passed */
		if (Points->x[0] != Points->x[Points->n_points - 1] || 
		    Points->y[0] != Points->y[Points->n_points - 1] ||
		    Points->z[0] != Points->z[Points->n_points - 1])
		    G_fatal_error(_("Method '%s' did not preserve loop"), method_opt->answer);
	    }

	    Vect_line_prune(Points);

	    /* oversimplified line */
	    if (Points->n_points < 2) {
		after = APoints->n_points;
		n_oversimplified++;
                if (error_out->answer)
		    Vect_write_line(&Error, type, APoints, Cats);
	    }
	    /* check for topology corruption */
	    else if (type == GV_BOUNDARY) {
		if (!check_topo(&Out, i, APoints, Points, Cats)) {
		    after = APoints->n_points;
		    not_modified_boundaries++;
                    if (error_out->answer)
		        Vect_write_line(&Error, type, APoints, Cats);
		}
		else
		    after = Points->n_points;
	    }
	    else {
		/* type == GV_LINE */
		Vect_rewrite_line(&Out, i, type, Points, Cats);
		after = Points->n_points;
	    }

	    total_output += after;
	}
	if (not_modified_boundaries > 0)
	    G_warning(_("%d boundaries were not modified because modification would damage topology"),
		      not_modified_boundaries);
	if (n_oversimplified > 0)
	    G_warning(_("%d lines/boundaries were not modified due to over-simplification"),
		      n_oversimplified);
	G_message("-----------------------------------------------------");

	/* make sure that clean topo is built at the end */
	Vect_build_partial(&Out, GV_BUILD_NONE);
        if (error_out->answer)
	    Vect_build_partial(&Error, GV_BUILD_NONE);
    }

    Vect_build(&Out);
    if (error_out->answer)
        Vect_build(&Error);

    Vect_close(&In);
    Vect_close(&Out);
    if (error_out->answer)
        Vect_close(&Error);

    G_message("-----------------------------------------------------");
    if (total_input != 0 && total_input != total_output)
	G_done_msg(_("Number of vertices for selected features %s from %d to %d (%d%% remaining)"),
                   simplification ? _("reduced") : _("changed"), 
                   total_input, total_output,
                   (total_output * 100) / total_input);
    else
        G_done_msg(" ");

    exit(EXIT_SUCCESS);
}
コード例 #8
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct Map_info In, Out, Buf;
    struct line_pnts *Points;
    struct line_cats *Cats, *BCats;
    char bufname[GNAME_MAX];
    struct GModule *module;
    struct Option *in_opt, *out_opt, *type_opt, *dista_opt, *distb_opt,
	*angle_opt;
    struct Flag *straight_flag, *nocaps_flag;
    struct Option *tol_opt, *bufcol_opt, *scale_opt, *field_opt;

    int verbose;
    double da, db, dalpha, tolerance, unit_tolerance;
    int type;
    int i, ret, nareas, area, nlines, line;
    char *Areas, *Lines;
    int field;
    struct buf_contours *arr_bc;
    struct buf_contours_pts arr_bc_pts;
    int buffers_count = 0, line_id;
    struct spatial_index si;
    struct bound_box bbox;

    /* Attributes if sizecol is used */
    int nrec, ctype;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray cvarr;
    double size_val, scale;


    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("buffer"));
    module->description =
	_("Creates a buffer around vector features of given type.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

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

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "point,line,boundary,centroid,area";
    type_opt->answer = "point,line,area";
    type_opt->guisection = _("Selection");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    
    dista_opt = G_define_option();
    dista_opt->key = "distance";
    dista_opt->type = TYPE_DOUBLE;
    dista_opt->required = NO;
    dista_opt->description =
	_("Buffer distance along major axis in map units");
    dista_opt->guisection = _("Distance");

    distb_opt = G_define_option();
    distb_opt->key = "minordistance";
    distb_opt->type = TYPE_DOUBLE;
    distb_opt->required = NO;
    distb_opt->description =
	_("Buffer distance along minor axis in map units");
    distb_opt->guisection = _("Distance");

    angle_opt = G_define_option();
    angle_opt->key = "angle";
    angle_opt->type = TYPE_DOUBLE;
    angle_opt->required = NO;
    angle_opt->answer = "0";
    angle_opt->description = _("Angle of major axis in degrees");
    angle_opt->guisection = _("Distance");

    bufcol_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    bufcol_opt->key = "bufcolumn";
    bufcol_opt->description =
	_("Name of column to use for buffer distances");
    bufcol_opt->guisection = _("Distance");

    scale_opt = G_define_option();
    scale_opt->key = "scale";
    scale_opt->type = TYPE_DOUBLE;
    scale_opt->required = NO;
    scale_opt->answer = "1.0";
    scale_opt->description = _("Scaling factor for attribute column values");
    scale_opt->guisection = _("Distance");

    tol_opt = G_define_option();
    tol_opt->key = "tolerance";
    tol_opt->type = TYPE_DOUBLE;
    tol_opt->required = NO;
    tol_opt->answer = "0.01";
    tol_opt->description =
	_("Maximum distance between theoretical arc and polygon segments as multiple of buffer");
    tol_opt->guisection = _("Distance");

    straight_flag = G_define_flag();
    straight_flag->key = 's';
    straight_flag->description = _("Make outside corners straight");

    nocaps_flag = G_define_flag();
    nocaps_flag->key = 'c';
    nocaps_flag->description = _("Don't make caps at the ends of polylines");

    G_gisinit(argv[0]);
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    type = Vect_option_to_types(type_opt);

    if ((dista_opt->answer && bufcol_opt->answer) ||
	(!(dista_opt->answer || bufcol_opt->answer)))
	G_fatal_error(_("Select a buffer distance/minordistance/angle "
			"or column, but not both."));

    if (bufcol_opt->answer)
	G_warning(_("The bufcol option may contain bugs during the cleaning "
		    "step. If you encounter problems, use the debug "
		    "option or clean manually with v.clean tool=break; "
		    "v.category step=0; v.extract -d type=area"));

    if (field_opt->answer)
	field = Vect_get_field_number(&In, field_opt->answer);
    else
	field = -1;
	
    if (bufcol_opt->answer && field == -1)
	G_fatal_error(_("The bufcol option requires a valid layer."));

    tolerance = atof(tol_opt->answer);
    if (tolerance <= 0)
	G_fatal_error(_("The tolerance must be > 0."));

    if (adjust_tolerance(&tolerance))
	G_warning(_("The tolerance was reset to %g"), tolerance);

    scale = atof(scale_opt->answer);
    if (scale <= 0.0)
	G_fatal_error("Illegal scale value");

    da = db = dalpha = 0;
    if (dista_opt->answer) {
	da = atof(dista_opt->answer);

	if (distb_opt->answer)
	    db = atof(distb_opt->answer);
	else
	    db = da;

	if (angle_opt->answer)
	    dalpha = atof(angle_opt->answer);
	else
	    dalpha = 0;

	unit_tolerance = tolerance * MIN(da, db);
	G_verbose_message(_("The tolerance in map units = %g"), unit_tolerance);
    }

    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 GV_FATAL_EXIT);

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

    Vect_set_open_level(2); /* topology required */

    if (1 > Vect_open_old2(&In, in_opt->answer, "", field_opt->answer))
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

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

    /* open tmp vector for buffers, needed for cleaning */
    sprintf(bufname, "%s_tmp_%d", out_opt->answer, getpid());
    if (0 > Vect_open_new(&Buf, bufname, 0)) {
	Vect_close(&In);
	Vect_close(&Out);
	Vect_delete(out_opt->answer);
	exit(EXIT_FAILURE);
    }
    Vect_build_partial(&Buf, GV_BUILD_BASE);

    /* check and load attribute column data */
    if (bufcol_opt->answer) {
	db_CatValArray_init(&cvarr);

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

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

	/* Note do not check if the column exists in the table because it may be expression */

	/* TODO: only select values we need instead of all in column */
	nrec =
	    db_select_CatValArray(Driver, Fi->table, Fi->key,
				  bufcol_opt->answer, NULL, &cvarr);
	if (nrec < 0)
	    G_fatal_error(_("Unable to select data from table <%s>"),
			  Fi->table);
	G_debug(2, "%d records selected from table", nrec);

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

	db_close_database_shutdown_driver(Driver);

	/* Output cats/values list */
	for (i = 0; i < cvarr.n_values; i++) {
	    if (ctype == DB_C_TYPE_INT) {
		G_debug(4, "cat = %d val = %d", cvarr.value[i].cat,
			cvarr.value[i].val.i);
	    }
	    else if (ctype == DB_C_TYPE_DOUBLE) {
		G_debug(4, "cat = %d val = %f", cvarr.value[i].cat,
			cvarr.value[i].val.d);
	    }
	}
    }

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


    /* Create buffers' boundaries */
    nlines = nareas = 0;
    if ((type & GV_POINTS) || (type & GV_LINES))
	nlines += Vect_get_num_primitives(&In, type);
    if (type & GV_AREA)
	nareas = Vect_get_num_areas(&In);
    
    if (nlines + nareas == 0) {
	G_warning(_("No features available for buffering. "
	            "Check type option and features available in the input vector."));
	exit(EXIT_SUCCESS);
    }

    buffers_count = 1;
    arr_bc = G_malloc((nlines + nareas + 1) * sizeof(struct buf_contours));

    Vect_spatial_index_init(&si, 0);

    /* Lines (and Points) */
    if ((type & GV_POINTS) || (type & GV_LINES)) {
	int ltype;

	if (nlines > 0)
	    G_message(_("Buffering lines..."));
	for (line = 1; line <= nlines; line++) {
	    int cat;

	    G_debug(2, "line = %d", line);
	    G_percent(line, nlines, 2);
	    
	    if (!Vect_line_alive(&In, line))
		continue;

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

	    if (field > 0 && !Vect_cat_get(Cats, field, &cat))
		continue;

	    if (bufcol_opt->answer) {
		ret = db_CatValArray_get_value_di(&cvarr, cat, &size_val);
		if (ret != DB_OK) {
		    G_warning(_("No record for category %d in table <%s>"),
			      cat, Fi->table);
		    continue;
		}

		if (size_val < 0.0) {
		    G_warning(_("Attribute is of invalid size (%.3f) for category %d"),
			      size_val, cat);
		    continue;
		}

		if (size_val == 0.0)
		    continue;

		da = size_val * scale;
		db = da;
		dalpha = 0;
		unit_tolerance = tolerance * MIN(da, db);

		G_debug(2, "    dynamic buffer size = %.2f", da);
		G_debug(2, _("The tolerance in map units: %g"),
			unit_tolerance);
	    }
	    
	    Vect_line_prune(Points);
	    if (ltype & GV_POINTS || Points->n_points == 1) {
		Vect_point_buffer2(Points->x[0], Points->y[0], da, db, dalpha,
				   !(straight_flag->answer), unit_tolerance,
				   &(arr_bc_pts.oPoints));

		Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
		line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
		Vect_destroy_line_struct(arr_bc_pts.oPoints);
		/* add buffer to spatial index */
		Vect_get_line_box(&Buf, line_id, &bbox);
		Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		arr_bc[buffers_count].outer = line_id;
		arr_bc[buffers_count].inner_count = 0;
		arr_bc[buffers_count].inner = NULL;
		buffers_count++;

	    }
	    else {
		Vect_line_buffer2(Points, da, db, dalpha,
				  !(straight_flag->answer),
				  !(nocaps_flag->answer), unit_tolerance,
				  &(arr_bc_pts.oPoints),
				  &(arr_bc_pts.iPoints),
				  &(arr_bc_pts.inner_count));

		Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
		line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
		Vect_destroy_line_struct(arr_bc_pts.oPoints);
		/* add buffer to spatial index */
		Vect_get_line_box(&Buf, line_id, &bbox);
		Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		arr_bc[buffers_count].outer = line_id;

		arr_bc[buffers_count].inner_count = arr_bc_pts.inner_count;
		if (arr_bc_pts.inner_count > 0) {
		    arr_bc[buffers_count].inner = G_malloc(arr_bc_pts.inner_count * sizeof(int));
		    for (i = 0; i < arr_bc_pts.inner_count; i++) {
			Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.iPoints[i], BCats);
			line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.iPoints[i], Cats);
			Vect_destroy_line_struct(arr_bc_pts.iPoints[i]);
			/* add buffer to spatial index */
			Vect_get_line_box(&Buf, line_id, &bbox);
			Vect_spatial_index_add_item(&si, buffers_count, &bbox);
			arr_bc[buffers_count].inner[i] = line_id;
		    }
		    G_free(arr_bc_pts.iPoints);
		}
		buffers_count++;
	    }
	}
    }

    /* Areas */
    if (type & GV_AREA) {
	int centroid;

	if (nareas > 0) 
	    G_message(_("Buffering areas..."));
	for (area = 1; area <= nareas; area++) {
	    int cat;

	    G_percent(area, nareas, 2);
	    
	    if (!Vect_area_alive(&In, area))
		continue;
	    
	    centroid = Vect_get_area_centroid(&In, area);
	    if (centroid == 0)
		continue;

	    Vect_read_line(&In, NULL, Cats, centroid);
	    if (field > 0 && !Vect_cat_get(Cats, field, &cat))
		continue;

	    if (bufcol_opt->answer) {
		ret = db_CatValArray_get_value_di(&cvarr, cat, &size_val);
		if (ret != DB_OK) {
		    G_warning(_("No record for category %d in table <%s>"),
			      cat, Fi->table);
		    continue;
		}

		if (size_val < 0.0) {
		    G_warning(_("Attribute is of invalid size (%.3f) for category %d"),
			      size_val, cat);
		    continue;
		}

		if (size_val == 0.0)
		    continue;

		da = size_val * scale;
		db = da;
		dalpha = 0;
		unit_tolerance = tolerance * MIN(da, db);

		G_debug(2, "    dynamic buffer size = %.2f", da);
		G_debug(2, _("The tolerance in map units: %g"),
			unit_tolerance);
	    }

	    Vect_area_buffer2(&In, area, da, db, dalpha,
			      !(straight_flag->answer),
			      !(nocaps_flag->answer), unit_tolerance,
			      &(arr_bc_pts.oPoints),
			      &(arr_bc_pts.iPoints),
			      &(arr_bc_pts.inner_count));

	    Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.oPoints, BCats);
	    line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.oPoints, Cats);
	    Vect_destroy_line_struct(arr_bc_pts.oPoints);
	    /* add buffer to spatial index */
	    Vect_get_line_box(&Buf, line_id, &bbox);
	    Vect_spatial_index_add_item(&si, buffers_count, &bbox);
	    arr_bc[buffers_count].outer = line_id;

	    arr_bc[buffers_count].inner_count = arr_bc_pts.inner_count;
	    if (arr_bc_pts.inner_count > 0) {
		arr_bc[buffers_count].inner = G_malloc(arr_bc_pts.inner_count * sizeof(int));
		for (i = 0; i < arr_bc_pts.inner_count; i++) {
		    Vect_write_line(&Out, GV_BOUNDARY, arr_bc_pts.iPoints[i], BCats);
		    line_id = Vect_write_line(&Buf, GV_BOUNDARY, arr_bc_pts.iPoints[i], Cats);
		    Vect_destroy_line_struct(arr_bc_pts.iPoints[i]);
		    /* add buffer to spatial index */
		    Vect_get_line_box(&Buf, line_id, &bbox);
		    Vect_spatial_index_add_item(&si, buffers_count, &bbox);
		    arr_bc[buffers_count].inner[i] = line_id;
		}
		G_free(arr_bc_pts.iPoints);
	    }
	    buffers_count++;
	}
    }

    verbose = G_verbose();

    G_message(_("Cleaning buffers..."));
    
    /* Break lines */
    G_message(_("Building parts of topology..."));
    Vect_build_partial(&Out, GV_BUILD_BASE);

    G_message(_("Snapping boundaries..."));
    Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);

    G_message(_("Breaking polygons..."));
    Vect_break_polygons(&Out, GV_BOUNDARY, NULL);

    G_message(_("Removing duplicates..."));
    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);

    do {
	G_message(_("Breaking boundaries..."));
	Vect_break_lines(&Out, GV_BOUNDARY, NULL);

	G_message(_("Removing duplicates..."));
	Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);

	G_message(_("Cleaning boundaries at nodes"));

    } while (Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL) > 0);

    /* Dangles and bridges don't seem to be necessary if snapping is small enough. */
    /* Still needed for larger buffer distances ? */

    /*
    G_message(_("Removing dangles..."));
    Vect_remove_dangles(&Out, GV_BOUNDARY, -1, NULL);

    G_message (_("Removing bridges..."));
    Vect_remove_bridges(&Out, NULL);
    */

    G_message(_("Attaching islands..."));
    Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES);

    /* Calculate new centroids for all areas */
    nareas = Vect_get_num_areas(&Out);
    Areas = (char *)G_calloc(nareas + 1, sizeof(char));
    G_message(_("Calculating centroids for areas..."));
    G_percent(0, nareas, 2);
    for (area = 1; area <= nareas; area++) {
	double x, y;

	G_percent(area, nareas, 2);

	G_debug(3, "area = %d", area);

	if (!Vect_area_alive(&Out, area))
	    continue;

	ret = Vect_get_point_in_area(&Out, area, &x, &y);
	if (ret < 0) {
	    G_warning(_("Cannot calculate area centroid"));
	    continue;
	}

	ret = point_in_buffer(arr_bc, &si, &Buf, x, y);

	if (ret) {
	    G_debug(3, "  -> in buffer");
	    Areas[area] = 1;
	}
    }

    /* Make a list of boundaries to be deleted (both sides inside) */
    nlines = Vect_get_num_lines(&Out);
    G_debug(3, "nlines = %d", nlines);
    Lines = (char *)G_calloc(nlines + 1, sizeof(char));

    G_message(_("Generating list of boundaries to be deleted..."));
    for (line = 1; line <= nlines; line++) {
	int j, side[2], areas[2];

	G_percent(line, nlines, 2);

	G_debug(3, "line = %d", line);

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

	Vect_get_line_areas(&Out, line, &side[0], &side[1]);

	for (j = 0; j < 2; j++) {
	    if (side[j] == 0) {	/* area/isle not build */
		areas[j] = 0;
	    }
	    else if (side[j] > 0) {	/* area */
		areas[j] = side[j];
	    }
	    else {		/* < 0 -> island */
		areas[j] = Vect_get_isle_area(&Out, abs(side[j]));
	    }
	}

	G_debug(3, " areas = %d , %d -> Areas = %d, %d", areas[0], areas[1],
		Areas[areas[0]], Areas[areas[1]]);
	if (Areas[areas[0]] && Areas[areas[1]])
	    Lines[line] = 1;
    }
    G_free(Areas);

    /* Delete boundaries */
    G_message(_("Deleting boundaries..."));
    for (line = 1; line <= nlines; line++) {
	G_percent(line, nlines, 2);
	
	if (!Vect_line_alive(&Out, line))
	    continue;

	if (Lines[line]) {
	    G_debug(3, " delete line %d", line);
	    Vect_delete_line(&Out, line);
	}
	else {
	    /* delete incorrect boundaries */
	    int side[2];

	    Vect_get_line_areas(&Out, line, &side[0], &side[1]);
	    
	    if (!side[0] && !side[1])
		Vect_delete_line(&Out, line);
	}
    }

    G_free(Lines);

    /* Create new centroids */
    Vect_reset_cats(Cats);
    Vect_cat_set(Cats, 1, 1);
    nareas = Vect_get_num_areas(&Out);

    G_message(_("Calculating centroids for areas..."));    
    for (area = 1; area <= nareas; area++) {
	double x, y;

	G_percent(area, nareas, 2);

	G_debug(3, "area = %d", area);

	if (!Vect_area_alive(&Out, area))
	    continue;

	ret = Vect_get_point_in_area(&Out, area, &x, &y);
	if (ret < 0) {
	    G_warning(_("Cannot calculate area centroid"));
	    continue;
	}

	ret = point_in_buffer(arr_bc, &si, &Buf, x, y);

	if (ret) {
	    Vect_reset_line(Points);
	    Vect_append_point(Points, x, y, 0.);
	    Vect_write_line(&Out, GV_CENTROID, Points, Cats);
	}
    }

    /* free arr_bc[] */
    /* will only slow down the module
       for (i = 0; i < buffers_count; i++) {
       Vect_destroy_line_struct(arr_bc[i].oPoints);
       for (j = 0; j < arr_bc[i].inner_count; j++)
       Vect_destroy_line_struct(arr_bc[i].iPoints[j]);
       G_free(arr_bc[i].iPoints);
       } */

    Vect_spatial_index_destroy(&si);
    Vect_close(&Buf);
    Vect_delete(bufname);

    G_set_verbose(verbose);

    Vect_close(&In);

    Vect_build_partial(&Out, GV_BUILD_NONE);
    Vect_build(&Out);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
コード例 #9
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char **argv)
{
    int field, type, vertex_type;
    double dmax;
    char buf[DB_SQL_MAX];

    struct {
        struct Option *input, *output, *type, *dmax, *lfield, *use;
    } opt;
    struct {
        struct Flag *table, *inter;
    } flag;
    struct GModule *module;
    struct Map_info In, Out;
    struct line_cats *LCats;
    struct line_pnts *LPoints;

    dbDriver *driver;
    struct field_info *Fi;

    dbString stmt;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword("3D");
    G_add_keyword(_("node"));
    G_add_keyword(_("vertex"));
    module->description =
	_("Creates points along input lines in new vector map with 2 layers.");

    opt.input = G_define_standard_option(G_OPT_V_INPUT);

    opt.lfield = G_define_standard_option(G_OPT_V_FIELD);
    opt.lfield->key = "llayer";
    opt.lfield->answer = "1";
    opt.lfield->label = "Line layer number or name";
    opt.lfield->guisection = _("Selection");

    opt.type = G_define_standard_option(G_OPT_V3_TYPE);
    opt.type->answer = "point,line,boundary,centroid,face";
    opt.type->guisection = _("Selection");

    opt.output = G_define_standard_option(G_OPT_V_OUTPUT);

    opt.use = G_define_option();
    opt.use->key = "use";
    opt.use->type = TYPE_STRING;
    opt.use->required = NO;
    opt.use->description = _("Use line nodes or vertices only");
    opt.use->options = "node,vertex";

    opt.dmax = G_define_option();
    opt.dmax->key = "dmax";
    opt.dmax->type = TYPE_DOUBLE;
    opt.dmax->required = NO;
    opt.dmax->answer = "100";
    opt.dmax->description = _("Maximum distance between points in map units");

    flag.inter = G_define_flag();
    flag.inter->key = 'i';
    flag.inter->description = _("Interpolate points between line vertices (only for use=vertex)");
    

    flag.table = G_define_standard_flag(G_FLG_V_TABLE);

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

    LCats = Vect_new_cats_struct();
    LPoints = Vect_new_line_struct();
    db_init_string(&stmt);

    type = Vect_option_to_types(opt.type);
    dmax = atof(opt.dmax->answer);

    vertex_type = 0;
    if (opt.use->answer) {
        if (opt.use->answer[0] == 'n')
            vertex_type = GV_NODE;
        else
            vertex_type = GV_VERTEX;
    }
    
    Vect_check_input_output_name(opt.input->answer, opt.output->answer,
				 G_FATAL_EXIT);

    /* Open input lines */
    Vect_set_open_level(2);

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

    Vect_set_error_handler_io(&In, &Out);
    
    field = Vect_get_field_number(&In, opt.lfield->answer);
    
    /* Open output segments */
    if (Vect_open_new(&Out, opt.output->answer, Vect_is_3d(&In)) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"),
			opt.output->answer);

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

    /* Table */
    Fi = NULL;
    if (!flag.table->answer) {
	struct field_info *Fin;

	/* copy input table */
	Fin = Vect_get_field(&In, field);
	if (Fin) {		/* table defined */
	    int ret;

	    Fi = Vect_default_field_info(&Out, 1, NULL, GV_MTABLE);
	    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, Fin->key,
				Fi->database, Fi->driver);

	    ret = db_copy_table(Fin->driver, Fin->database, Fin->table,
				Fi->driver, Vect_subst_var(Fi->database,
							   &Out), Fi->table);

	    if (ret == DB_FAILED) {
		G_fatal_error(_("Unable to copy table <%s>"),
			      Fin->table);
	    }
	}

	Fi = Vect_default_field_info(&Out, 2, NULL, GV_MTABLE);
	Vect_map_add_dblink(&Out, 2, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			    Fi->driver);

	/* Open driver */
	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);
        db_set_error_handler_driver(driver);

	if (field == -1) 
            sprintf(buf,
                "create table %s ( cat int, along double precision )",
                Fi->table);
         else
            sprintf(buf,
		"create table %s ( cat int, lcat int, along double precision )",
		Fi->table);
	db_append_string(&stmt, buf);

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

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

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

    if (type & (GV_POINTS | GV_LINES | GV_FACE)) {
        int line, nlines, nskipped;

        nskipped = 0;
	nlines = Vect_get_num_lines(&In);
	for (line = 1; line <= nlines; line++) {
	    int ltype, cat;

	    G_debug(3, "line = %d", line);
	    G_percent(line, nlines, 2);
            
	    ltype = Vect_read_line(&In, LPoints, LCats, line);
	    if (!(ltype & type))
		continue;
            if (!Vect_cat_get(LCats, field, &cat) && field != -1) {
                nskipped++;
		continue;
            }

            /* Assign CAT for layer 0 objects (i.e. boundaries) */
            if (field == -1)
                cat = -1;

	    if (LPoints->n_points <= 1) {
		write_point(&Out, LPoints->x[0], LPoints->y[0], LPoints->z[0],
			    cat, 0.0, driver, Fi);
	    }
	    else {		/* lines */
		write_line(&Out, LPoints, cat, vertex_type,
			   flag.inter->answer, dmax, driver, Fi);
	    }
	}

        if (nskipped > 0)
            G_warning(_("%d features without category in layer <%d> skipped. "
                        "Note that features without category (usually boundaries) are not "
                        "skipped when '%s=-1' is given."),
                      nskipped, field, opt.lfield->key);
    }

    if (type == GV_AREA) {
	int area, nareas, centroid, cat;

	nareas = Vect_get_num_areas(&In);
	for (area = 1; area <= nareas; area++) {
	    int i, isle, nisles;

	    G_percent(area, nareas, 2);
            
	    centroid = Vect_get_area_centroid(&In, area);
	    cat = -1;
	    if (centroid > 0) {
		Vect_read_line(&In, NULL, LCats, centroid);
		if (!Vect_cat_get(LCats, field, &cat))
		  continue;
	    }

	    Vect_get_area_points(&In, area, LPoints);

	    write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
		       dmax, driver, Fi);

	    nisles = Vect_get_area_num_isles(&In, area);

	    for (i = 0; i < nisles; i++) {
		isle = Vect_get_area_isle(&In, area, i);
		Vect_get_isle_points(&In, isle, LPoints);

		write_line(&Out, LPoints, cat, vertex_type,
			   flag.inter->answer, dmax, driver, Fi);
	    }
	}
    }

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

    Vect_build(&Out);

    /* Free, close ... */
    Vect_close(&In);

    G_done_msg(_("%d points written to output vector map."),
               Vect_get_num_primitives(&Out, GV_POINT));

    Vect_close(&Out);
    
    exit(EXIT_SUCCESS);
}
コード例 #10
0
/*!
   \brief Creates perimeters from vector areas of given category.

   \param Map vector map
   \param layer_name layer name (within vector map)
   \param category vector category (cat column value)
   \param[out] perimeters list of perimeters
   \param band_region region which determines perimeter cells

   \return number of areas of given cat
   \return -1 on error
 */
int vector2perimeters(struct Map_info *Map, const char *layer_name,
		      int category, IClass_perimeter_list * perimeters,
		      struct Cell_head *band_region)
{
    struct line_pnts *points;

    int nareas, nareas_cat, layer;

    int i, cat, ret;

    int j;

    G_debug(3, "iclass_vector2perimeters():layer = %s, category = %d",
	    layer_name, category);

    layer = Vect_get_field_number(Map, layer_name);
    nareas = Vect_get_num_areas(Map);
    if (nareas == 0)
	return 0;

    nareas_cat = 0;
    /* find out, how many areas have given category */
    for (i = 1; i <= nareas; i++) {
	if (!Vect_area_alive(Map, i))
	    continue;
	cat = Vect_get_area_cat(Map, i, layer);
	if (cat < 0) {
	    /* no centroid, no category */
	}
	else if (cat == category) {
	    nareas_cat++;
	}
    }
    if (nareas_cat == 0)
	return 0;

    perimeters->nperimeters = nareas_cat;
    perimeters->perimeters =
	(IClass_perimeter *) G_calloc(nareas_cat, sizeof(IClass_perimeter));

    j = 0;			/* area with cat */
    for (i = 1; i <= nareas; i++) {
	if (!Vect_area_alive(Map, i))
	    continue;
	cat = Vect_get_area_cat(Map, i, layer);
	if (cat < 0) {
	    /* no centroid, no category */
	}
	else if (cat == category) {
	    j++;

	    points = Vect_new_line_struct();	/* Vect_destroy_line_struct */
	    ret = Vect_get_area_points(Map, i, points);

	    if (ret <= 0) {
		Vect_destroy_line_struct(points);
		free_perimeters(perimeters);
		G_warning(_("Get area %d failed"), i);
		return -1;
	    }
	    if (make_perimeter
		(points, &perimeters->perimeters[j - 1], band_region) <= 0) {
		Vect_destroy_line_struct(points);
		free_perimeters(perimeters);
		G_warning(_("Perimeter computation failed"));
		return -1;
	    }
	    Vect_destroy_line_struct(points);
	}

    }

    /* Vect_close(&Map); */

    return nareas_cat;
}
コード例 #11
0
ファイル: main.c プロジェクト: rkrug/grass-ci
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points, *PPoints;
    struct line_cats *Cats, *TCats;
    struct ilist *slist;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *catf_opt, *fieldf_opt, *wheref_opt;
    struct Option *catt_opt, *fieldt_opt, *wheret_opt, *typet_opt;
    struct Option *afield_opt, *nfield_opt, *abcol, *afcol, *ncol, *atype_opt;
    struct Flag *geo_f, *segments_f;
    int with_z, geo, segments;
    int atype, ttype;
    struct varray *varrayf, *varrayt;
    int flayer, tlayer;
    int afield, nfield;
    dglGraph_s *graph;
    struct ilist *nodest;
    int i, j, nnodes, nlines;
    int *dst, *nodes_to_features;
    int from_nr;			/* 'from' features not reachable */
    dglInt32_t **nxt;
    struct line_cats **on_path;
    char *segdir;
    char buf[2000];

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("shortest path"));
    module->label = _("Computes shortest distance via the network between "
		      "the given sets of features.");
    module->description =
	_("Finds the shortest paths from each 'from' point to the nearest 'to' feature "
	 "and various information about this relation are uploaded to the attribute table.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);
    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    atype_opt = G_define_standard_option(G_OPT_V_TYPE);
    atype_opt->key = "arc_type";
    atype_opt->options = "line,boundary";
    atype_opt->answer = "line,boundary";
    atype_opt->label = _("Arc type");
    atype_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    fieldf_opt = G_define_standard_option(G_OPT_V_FIELD);
    fieldf_opt->key = "from_layer";
    fieldf_opt->label = _("From layer number or name");
    fieldf_opt->guisection = _("From");

    catf_opt = G_define_standard_option(G_OPT_V_CATS);
    catf_opt->key = "from_cats";
    catf_opt->label = _("From category values");
    catf_opt->guisection = _("From");

    wheref_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheref_opt->key = "from_where";
    wheref_opt->label =
	_("From WHERE conditions of SQL statement without 'where' keyword");
    wheref_opt->guisection = _("From");

    fieldt_opt = G_define_standard_option(G_OPT_V_FIELD);
    fieldt_opt->key = "to_layer";
    fieldt_opt->description = _("To layer number or name");
    fieldt_opt->guisection = _("To");

    typet_opt = G_define_standard_option(G_OPT_V_TYPE);
    typet_opt->key = "to_type";
    typet_opt->options = "point,line,boundary";
    typet_opt->answer = "point";
    typet_opt->description = _("To feature type");
    typet_opt->guisection = _("To");

    catt_opt = G_define_standard_option(G_OPT_V_CATS);
    catt_opt->key = "to_cats";
    catt_opt->label = _("To category values");
    catt_opt->guisection = _("To");

    wheret_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheret_opt->key = "to_where";
    wheret_opt->label =
	_("To WHERE conditions of SQL statement without 'where' keyword");
    wheret_opt->guisection = _("To");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "node_column";
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

    segments_f = G_define_flag();
#if 0
    /* use this to sync with v.net.path */
    segments_f->key = 's';
    segments_f->description = _("Write output as original input segments, "
				"not each path as one line.");
#else
    segments_f->key = 'l';
    segments_f->description = _("Write each output path as one line, "
				"not as original input segments.");
#endif

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    atype = Vect_option_to_types(atype_opt);
    ttype = Vect_option_to_types(typet_opt);

    Points = Vect_new_line_struct();
    PPoints = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    TCats = Vect_new_cats_struct();
    slist = G_new_ilist();

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }


    if (geo_f->answer) {
	geo = 1;
	if (G_projection() != PROJECTION_LL)
	    G_warning(_("The current projection is not longitude-latitude"));
    }
    else
	geo = 0;

#if 0
    /* use this to sync with v.net.path */
    segments = segments_f->answer;
#else
    segments = !segments_f->answer;
#endif

    nnodes = Vect_get_num_nodes(&In);
    nlines = Vect_get_num_lines(&In);

    dst = (int *)G_calloc(nnodes + 1, sizeof(int));
    nxt = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    nodes_to_features = (int *)G_calloc(nnodes + 1, sizeof(int));
    on_path =
	(struct line_cats **)G_calloc(nlines + 1, sizeof(struct line_cats *));
    segdir = (char *)G_calloc(nlines + 1, sizeof(char));

    if (!dst || !nxt || !nodes_to_features || !on_path || !segdir)
	G_fatal_error(_("Out of memory"));

    for (i = 1; i <= nlines; i++) {
	on_path[i] = Vect_new_cats_struct();
	segdir[i] = 0;
    }

    /*initialise varrays and nodes list appropriatelly */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    flayer = atoi(fieldf_opt->answer);
    tlayer = atoi(fieldt_opt->answer);

    if (NetA_initialise_varray(&In, flayer, GV_POINT, wheref_opt->answer,
			   catf_opt->answer, &varrayf) <= 0) {
	G_fatal_error(_("No 'from' features selected. "
			"Please check options '%s', '%s', '%s'."),
			fieldf_opt->key, wheref_opt->key, catf_opt->key);
    }

    if (NetA_initialise_varray(&In, tlayer, ttype, wheret_opt->answer,
			   catt_opt->answer, &varrayt) <= 0) {
	G_fatal_error(_("No 'to' features selected. "
			"Please check options '%s', '%s', '%s'."),
			fieldt_opt->key, wheret_opt->key, catt_opt->key);
    }

    nodest = Vect_new_list();
    NetA_varray_to_nodes(&In, varrayt, nodest, nodes_to_features);
    
    if (nodest->n_values == 0)
	G_fatal_error(_("No 'to' features"));
    
    if (0 != Vect_net_build_graph(&In, atype, afield, nfield, afcol->answer, abcol->answer,
                                   ncol->answer, geo, 2))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));

    graph = Vect_net_get_graph(&In);

    G_message(_("Distances to 'to' features ..."));

    NetA_distance_to_points(graph, nodest, dst, nxt);

    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    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);
    db_set_error_handler_driver(driver);

    sprintf(buf,
	    "create table %s ( cat integer, tcat integer, dist double precision)",
	    Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%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));
    }

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

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

    db_begin_transaction(driver);

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

    G_message(_("Tracing paths from 'from' features ..."));
    from_nr = 0;
    for (i = 1; i <= nlines; i++) {
	if (varrayf->c[i]) {
	    int type = Vect_read_line(&In, Points, Cats, i);
	    int node, tcat, cat;
	    double cost;
	    dglInt32_t *vertex, vertex_id;

	    if (!Vect_cat_get(Cats, flayer, &cat))
		continue;
		
	    if (type & GV_POINTS) {
		node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
	    }
	    else {
		Vect_get_line_nodes(&In, i, &node, NULL);
	    }
	    if (node < 1)
		continue;
	    if (dst[node] < 0) {
		/* unreachable */
		from_nr++;
 		continue;
	    }
	    cost = dst[node] / (double)In.dgraph.cost_multip;
	    vertex = dglGetNode(graph, node);
	    vertex_id = node;
	    slist->n_values = 0;
	    while (nxt[vertex_id] != NULL) {
		int edge_id;

		edge_id = (int) dglEdgeGet_Id(graph, nxt[vertex_id]);
		if (segments) {
		    Vect_cat_set(on_path[abs(edge_id)], 1, cat);
		    if (edge_id < 0) {
			segdir[abs(edge_id)] = 1;
		    }
		}
		else
		    G_ilist_add(slist, edge_id);

		vertex = dglEdgeGet_Tail(graph, nxt[vertex_id]);
		vertex_id = dglNodeGet_Id(graph, vertex);
	    }
	    G_debug(3, "read line %d, vertex id %d", nodes_to_features[vertex_id], (int)vertex_id);
	    Vect_read_line(&In, NULL, TCats, nodes_to_features[vertex_id]);
	    if (!Vect_cat_get(TCats, tlayer, &tcat))
		continue;

	    Vect_write_line(&Out, type, Points, Cats);
	    sprintf(buf, "insert into %s values (%d, %d, %f)", Fi->table, cat,
		    tcat, cost);
	    db_set_string(&sql, buf);
	    G_debug(3, "%s", db_get_string(&sql));
	    if (db_execute_immediate(driver, &sql) != DB_OK) {
		G_fatal_error(_("Cannot insert new record: %s"),
			      db_get_string(&sql));
	    };

	    if (!segments) {
		Vect_reset_line(PPoints);
		for (j = 0; j < slist->n_values; j++) {
		    Vect_read_line(&In, Points, NULL, abs(slist->value[j]));
		    if (slist->value[j] > 0)
			Vect_append_points(PPoints, Points,
					   GV_FORWARD);
		    else
			Vect_append_points(PPoints, Points,
					   GV_BACKWARD);
		    PPoints->n_points--;
		}
		PPoints->n_points++;
		Vect_reset_cats(Cats);
		Vect_cat_set(Cats, 1, cat);
		Vect_write_line(&Out, GV_LINE, PPoints, Cats);
	    }

	}
    }

    if (segments) {
	for (i = 1; i <= nlines; i++) {
	    if (on_path[i]->n_cats > 0) {
		int type; 
		
		if (segdir[i]) {
		    type = Vect_read_line(&In, PPoints, NULL, i);
		    Vect_reset_line(Points);
		    Vect_append_points(Points, PPoints, GV_BACKWARD);
		}
		else
		    type = Vect_read_line(&In, Points, NULL, i);

		Vect_write_line(&Out, type, Points, on_path[i]);
	    }
	}
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_build(&Out);

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

    for (i = 1; i <= nlines; i++)
	Vect_destroy_cats_struct(on_path[i]);
    G_free(on_path);
    G_free(nodes_to_features);
    G_free(dst);
    G_free(nxt);
    G_free(segdir);

    if (from_nr)
	G_warning(n_("%d 'from' feature was not reachable",
                     "%d 'from' features were not reachable",
                     from_nr), from_nr);

    exit(EXIT_SUCCESS);
}
コード例 #12
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
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);
}
コード例 #13
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    int npmin;
    int ii;
    double x_orig, y_orig, dnorm, deltx, delty, xm, ym;
    char dmaxchar[200];
    char dminchar[200];

    struct quaddata *data;
    struct multfunc *functions;
    struct multtree *tree;
    int open_check, with_z;
    char buf[1024];

    struct GModule *module;
    struct
    {
	struct Option *input, *field, *zcol, *wheresql, *scol, *elev, *slope,
	    *aspect, *pcurv, *tcurv, *mcurv, *treefile, *overfile, *maskmap,
	    *dmin, *dmax, *zmult, *fi, *rsm, *segmax, *npmin, *cvdev, *devi,
	    *theta, *scalex;
    } parm;
    struct
    {
	struct Flag *deriv, *cprght, *cv;
    } flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("3D"));
    module->label = _("Performs surface interpolation from vector points map by splines.");
    module->description =
	_("Spatial approximation and topographic analysis from given "
	  "point or isoline data in vector format to floating point "
	  "raster format using regularized spline with tension.");

    flag.cv = G_define_flag();
    flag.cv->key = 'c';
    flag.cv->description =
	_("Perform cross-validation procedure without raster approximation");
    flag.cv->guisection = _("Parameters");

    flag.cprght = G_define_flag();
    flag.cprght->key = 't';
    flag.cprght->description = _("Use scale dependent tension");
    flag.cprght->guisection = _("Parameters");

    flag.deriv = G_define_flag();
    flag.deriv->key = 'd';
    flag.deriv->description =
	_("Output partial derivatives instead of topographic parameters");
    flag.deriv->guisection = _("Outputs");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);
    
    parm.field = G_define_standard_option(G_OPT_V_FIELD);
    parm.field->answer = "1";
    parm.field->guisection = _("Selection");

    parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.zcol->key = "zcolumn";
    parm.zcol->required = NO;
    parm.zcol->label =
	_("Name of the attribute column with values to be used for approximation");
    parm.zcol->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.zcol->guisection = _("Parameters");

    parm.wheresql = G_define_standard_option(G_OPT_DB_WHERE);
    parm.wheresql->guisection = _("Selection");

    parm.elev = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.elev->key = "elevation";
    parm.elev->required = NO;
    parm.elev->description = _("Name for output surface elevation raster map");
    parm.elev->guisection = _("Outputs");

    parm.slope = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.slope->key = "slope";
    parm.slope->required = NO;
    parm.slope->description = _("Name for output slope raster map");
    parm.slope->guisection = _("Outputs");

    parm.aspect = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.aspect->key = "aspect";
    parm.aspect->required = NO;
    parm.aspect->description = _("Name for output aspect raster map");
    parm.aspect->guisection = _("Outputs");

    parm.pcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.pcurv->key = "pcurvature";
    parm.pcurv->required = NO;
    parm.pcurv->description = _("Name for output profile curvature raster map");
    parm.pcurv->guisection = _("Outputs");

    parm.tcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.tcurv->key = "tcurvature";
    parm.tcurv->required = NO;
    parm.tcurv->description = _("Name for output tangential curvature raster map");
    parm.tcurv->guisection = _("Outputs");

    parm.mcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.mcurv->key = "mcurvature";
    parm.mcurv->required = NO;
    parm.mcurv->description = _("Name for output mean curvature raster map");
    parm.mcurv->guisection = _("Outputs");

    parm.devi = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.devi->key = "deviations";
    parm.devi->required = NO;
    parm.devi->description = _("Name for output deviations vector point map");
    parm.devi->guisection = _("Outputs");

    parm.cvdev = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.cvdev->key = "cvdev";
    parm.cvdev->required = NO;
    parm.cvdev->description =
	_("Name for output cross-validation errors vector point map");
    parm.cvdev->guisection = _("Outputs");

    parm.treefile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.treefile->key = "treeseg";
    parm.treefile->required = NO;
    parm.treefile->description =
	_("Name for output vector map showing quadtree segmentation");
    parm.treefile->guisection = _("Outputs");

    parm.overfile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.overfile->key = "overwin";
    parm.overfile->required = NO;
    parm.overfile->description =
	_("Name for output vector map showing overlapping windows");
    parm.overfile->guisection = _("Outputs");

    parm.maskmap = G_define_standard_option(G_OPT_R_INPUT);
    parm.maskmap->key = "mask";
    parm.maskmap->required = NO;
    parm.maskmap->description = _("Name of raster map used as mask");
    parm.maskmap->guisection = _("Parameters");

    parm.fi = G_define_option();
    parm.fi->key = "tension";
    parm.fi->type = TYPE_DOUBLE;
    parm.fi->answer = TENSION;
    parm.fi->required = NO;
    parm.fi->description = _("Tension parameter");
    parm.fi->guisection = _("Parameters");

    parm.rsm = G_define_option();
    parm.rsm->key = "smooth";
    parm.rsm->type = TYPE_DOUBLE;
    parm.rsm->required = NO;
    parm.rsm->description = _("Smoothing parameter");
    parm.rsm->guisection = _("Parameters");

    parm.scol = G_define_option();
    parm.scol->key = "smooth_column";
    parm.scol->type = TYPE_STRING;
    parm.scol->required = NO;
    parm.scol->description =
	_("Name of the attribute column with smoothing parameters");
    parm.scol->guisection = _("Parameters");

    parm.segmax = G_define_option();
    parm.segmax->key = "segmax";
    parm.segmax->type = TYPE_INTEGER;
    parm.segmax->answer = MAXSEGM;
    parm.segmax->required = NO;
    parm.segmax->description = _("Maximum number of points in a segment");
    parm.segmax->guisection = _("Parameters");

    parm.npmin = G_define_option();
    parm.npmin->key = "npmin";
    parm.npmin->type = TYPE_INTEGER;
    parm.npmin->answer = MINPOINTS;
    parm.npmin->required = NO;
    parm.npmin->description =
	_("Minimum number of points for approximation in a segment (>segmax)");
    parm.npmin->guisection = _("Parameters");

    parm.dmin = G_define_option();
    parm.dmin->key = "dmin";
    parm.dmin->type = TYPE_DOUBLE;
    parm.dmin->required = NO;
    parm.dmin->description =
	_("Minimum distance between points (to remove almost identical points)");
    parm.dmin->guisection = _("Parameters");

    parm.dmax = G_define_option();
    parm.dmax->key = "dmax";
    parm.dmax->type = TYPE_DOUBLE;
    parm.dmax->required = NO;
    parm.dmax->description =
	_("Maximum distance between points on isoline (to insert additional points)");
    parm.dmax->guisection = _("Parameters");

    parm.zmult = G_define_option();
    parm.zmult->key = "zscale";
    parm.zmult->type = TYPE_DOUBLE;
    parm.zmult->answer = ZMULT;
    parm.zmult->required = NO;
    parm.zmult->description =
	_("Conversion factor for values used for approximation");
    parm.zmult->guisection = _("Parameters");

    parm.theta = G_define_option();
    parm.theta->key = "theta";
    parm.theta->type = TYPE_DOUBLE;
    parm.theta->required = NO;
    parm.theta->description =
	_("Anisotropy angle (in degrees counterclockwise from East)");
    parm.theta->guisection = _("Parameters");

    parm.scalex = G_define_option();
    parm.scalex->key = "scalex";
    parm.scalex->type = TYPE_DOUBLE;
    parm.scalex->required = NO;
    parm.scalex->description = _("Anisotropy scaling factor");
    parm.scalex->guisection = _("Parameters");

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

    G_get_set_window(&cellhd);

    ew_res = cellhd.ew_res;
    ns_res = cellhd.ns_res;
    n_cols = cellhd.cols;
    n_rows = cellhd.rows;
    x_orig = cellhd.west;
    y_orig = cellhd.south;
    xm = cellhd.east;
    ym = cellhd.north;
    if (ew_res < ns_res)
	dmin = ew_res / 2;
    else
	dmin = ns_res / 2;
    disk = n_rows * n_cols * sizeof(int);
    sdisk = n_rows * n_cols * sizeof(short int);
    sprintf(dmaxchar, "%f", dmin * 5);
    sprintf(dminchar, "%f", dmin);

    if (!parm.dmin->answer) {
	parm.dmin->answer = G_store(dminchar);
	parm.dmin->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmin->answers[0] = G_store(dminchar);
	parm.dmin->answers[1] = NULL;
    }
    if (!parm.dmax->answer) {
	parm.dmax->answer = G_store(dmaxchar);
	parm.dmax->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmax->answers[0] = G_store(dmaxchar);
	parm.dmax->answers[1] = NULL;
    }
    
    input = parm.input->answer;
    zcol = parm.zcol->answer;
    scol = parm.scol->answer;
    wheresql = parm.wheresql->answer;
    maskmap = parm.maskmap->answer;
    elev = parm.elev->answer;
    devi = parm.devi->answer;
    cvdev = parm.cvdev->answer;
    slope = parm.slope->answer;
    aspect = parm.aspect->answer;
    pcurv = parm.pcurv->answer;
    tcurv = parm.tcurv->answer;
    mcurv = parm.mcurv->answer;
    treefile = parm.treefile->answer;
    overfile = parm.overfile->answer;

    if (devi) {
	if (Vect_legal_filename(devi) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  devi);
    }
    if (cvdev) {
	if (Vect_legal_filename(cvdev) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  cvdev);
    }
    if (treefile) {
	if (Vect_legal_filename(treefile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  treefile);
    }
    if (overfile) {
	if (Vect_legal_filename(overfile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  overfile);
    }
    /*    if (treefile)
       Vect_check_input_output_name(input, treefile, G_FATAL_EXIT);

       if (overfile)
       Vect_check_input_output_name(input, overfile, G_FATAL_EXIT);
     */
    if ((elev == NULL) && (pcurv == NULL) && (tcurv == NULL)
	&& (mcurv == NULL)
	&& (slope == NULL) && (aspect == NULL) && (devi == NULL)
	&& (cvdev == NULL))
	G_warning(_("You are not outputting any raster or vector maps"));
    
    cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL));
    cond1 = ((slope != NULL) || (aspect != NULL) || cond2);
    deriv = flag.deriv->answer;
    dtens = flag.cprght->answer;
    cv = flag.cv->answer;

    if ((cv && cvdev == NULL) || (!(cv) && cvdev != NULL))
	G_fatal_error(_("Both cross-validation options (-c flag and cvdev vector output) must be specified"));

    if ((elev != NULL || cond1 || cond2 || devi != NULL) && cv)
	G_fatal_error(_("The cross-validation cannot be computed simultaneously with output raster or devi file"));

    ertre = 0.1;
    sscanf(parm.dmax->answer, "%lf", &dmax);
    sscanf(parm.dmin->answer, "%lf", &dmin);
    sscanf(parm.fi->answer, "%lf", &fi);
    sscanf(parm.segmax->answer, "%d", &KMAX);
    sscanf(parm.npmin->answer, "%d", &npmin);
    sscanf(parm.zmult->answer, "%lf", &zmult);

    /* if (fi=0.000000)  G_fatal_error("Tension must be > 0.000000") */

    if (parm.theta->answer)
	sscanf(parm.theta->answer, "%lf", &theta);

    if (parm.scalex->answer) {
	sscanf(parm.scalex->answer, "%lf", &scalex);
	if (!parm.theta->answer)
	    G_fatal_error(_("Using anisotropy - both theta and scalex have to be specified"));
    }

    if (parm.rsm->answer) {
	sscanf(parm.rsm->answer, "%lf", &rsm);
	if (rsm < 0.0)
	    G_fatal_error("Smoothing must be a positive value");
	if (scol != NULL)
	    G_warning(_("Both smatt and smooth options specified - using constant"));
    }
    else {
	sscanf(SMOOTH, "%lf", &rsm);
	if (scol != NULL)
	    rsm = -1;		/* used in InterpLib to indicate variable smoothing */
    }


    if (npmin > MAXPOINTS - 50) {
	G_warning(_("The computation will last too long - lower npmin is suggested"));
	KMAX2 = 2 * npmin;	/* was: KMAX2 = npmin + 50; */
    }
    else
	KMAX2 = 2 * npmin;	/* was: KMAX2 = MAXPOINTS; fixed by JH in 12/01 */

    /* handling of KMAX2 in GRASS4 v.surf.rst
       if (npmin > MAXPOINTS - 50)
       KMAX2 = npmin + 50;
       else
       KMAX2 = MAXPOINTS;
     */

    dmin = dmin * dmin;
    KMIN = npmin;

    az = G_alloc_vector(n_cols + 1);
    if (!az) {
	G_fatal_error(_("Not enough memory for %s"), "az");
    }
    if (cond1) {
	adx = G_alloc_vector(n_cols + 1);
	if (!adx) {
	    G_fatal_error(_("Not enough memory for %s"), "adx");
	}
	ady = G_alloc_vector(n_cols + 1);
	if (!ady) {
	    G_fatal_error(_("Not enough memory for %s"), "ady");
	}
	if (cond2) {
	    adxx = G_alloc_vector(n_cols + 1);
	    if (!adxx) {
		G_fatal_error(_("Not enough memory for %s"), "adxx");
	    }
	    adyy = G_alloc_vector(n_cols + 1);
	    if (!adyy) {
		G_fatal_error(_("Not enough memory for %s"), "adyy");
	    }
	    adxy = G_alloc_vector(n_cols + 1);
	    if (!adxy) {
		G_fatal_error(_("Not enough memory for %s"), "adxy");
	    }
	}
    }
    if ((data =
	 quad_data_new(x_orig, y_orig, xm, ym, n_rows, n_cols, 0,
		       KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "quaddata");
    if ((functions =
	 MT_functions_new(quad_compare, quad_divide_data, quad_add_data,
			  quad_intersect, quad_division_check,
			  quad_get_points)) == NULL)

	G_fatal_error(_("Unable to create %s"), "quadfunc");

    if ((tree = MT_tree_new(data, NULL, NULL, 0)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree");
    root = tree;

    if ((info = MT_tree_info_new(root, functions, dmin, KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree info");

    open_check = Vect_open_old2(&Map, input, "", parm.field->answer);
    if (open_check < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), input);
    /*    if (open_check < 2)
          G_fatal_error(_("You first need to run v.build on vector map <%s>"), input);
    */

    /* get value used for approximation */
    with_z = !parm.zcol->answer && Vect_is_3d(&Map);
    field = Vect_get_field_number(&Map, parm.field->answer);
    if (!with_z && field < 1)
	G_fatal_error(_("Layer <%s> not found"), parm.field->answer);

    if (Vect_is_3d(&Map)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (parm.zcol->answer)
            G_verbose_message(_("Input is 2D: using attribute values for approximation"));
        else
            G_verbose_message(_("Input is 2D: using category values for approximation"));
    }
        
    /* we can't read the input file's timestamp as they don't exist in   */
    /*   the new vector format. Even so, a TimeStamp structure is needed */
    /*   for IL_init_params_2d(), so we set it to NULL.                  */
    /* If anyone is ever motivated to add it, the Plus_head struct has   */
    /*  'long coor_mtime' and dig_head has 'char *date; char *source_date;' */
    /*   which could be read in.                                         */

    if (devi != NULL || cvdev != NULL) {

	Pnts = Vect_new_line_struct();
	Cats2 = Vect_new_cats_struct();
	db_init_string(&sql2);

	if (devi != NULL) {
	    if (Vect_open_new(&Map2, devi, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), devi);
	} else {
	    if (Vect_open_new(&Map2, cvdev, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), cvdev);
	}
	Vect_hist_command(&Map2);
	ff = Vect_default_field_info(&Map2, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map2, 1, NULL, ff->table, GV_KEY_COLUMN, ff->database,
			    ff->driver);

	/* Create new table */
	db_zero_string(&sql2);
	sprintf(buf, "create table %s ( ", ff->table);
	db_append_string(&sql2, buf);
	db_append_string(&sql2, "cat integer");
	db_append_string(&sql2, ", flt1 double precision");
	db_append_string(&sql2, ")");
	G_debug(1, "%s", db_get_string(&sql2));
	driver2 = db_start_driver_open_database(ff->driver, ff->database);
	if (driver2 == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  ff->database, ff->driver);
        db_set_error_handler_driver(driver2);

	if (db_execute_immediate(driver2, &sql2) != DB_OK) {
	    G_fatal_error(_("Unable to create table '%s'"),
			  db_get_string(&sql2));
	}
	db_begin_transaction(driver2);
	count = 1;

    }

    ertot = 0.;
    
    create_temp_files();

    IL_init_params_2d(&params, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, n_rows,
		      n_cols, az, adx, ady, adxx, adyy, adxy, fi, KMAX2,
		      SCIK1, SCIK2, SCIK3, rsm, elev, slope, aspect, pcurv,
		      tcurv, mcurv, dmin, x_orig, y_orig, deriv, theta,
		      scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx,
		      Tmp_fd_yy, Tmp_fd_xy, devi, NULL, cv,
		      parm.wheresql->answer);

    IL_init_func_2d(&params, IL_grid_calc_2d, IL_matrix_create,
		    IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst,
		    IL_crstg, IL_write_temp_2d);

    totsegm =
	IL_vector_input_data_2d(&params, &Map, with_z ? 0 : field,
				zcol, scol,
				info, &xmin, &xmax,
				&ymin, &ymax, &zmin, &zmax, &NPOINT, &dmax);
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    /*Vect_set_release_support(&Map); */
    Vect_close(&Map);

    if (treefile != NULL) {
	if (0 > Vect_open_new(&TreeMap, treefile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to open vector map <%s>"), treefile);
	}
	Vect_hist_command(&TreeMap);

	/*
	   sprintf (TreeMap.head.your_name, "grass");
	   sprintf (TreeMap.head.map_name, "Quad tree for %s", input);
	   TreeMap.head.orig_scale = 100000;
	   TreeMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &TreeMap);
	Vect_build(&TreeMap);
	Vect_close(&TreeMap);
    }

    disk = disk + totsegm * sizeof(int) * 4;
    sdisk = sdisk + totsegm * sizeof(int) * 4;
    if (elev != NULL)
	ddisk += disk;
    if (slope != NULL)
	sddisk += sdisk;
    if (aspect != NULL)
	sddisk += sdisk;
    if (pcurv != NULL)
	ddisk += disk;
    if (tcurv != NULL)
	ddisk += disk;
    if (mcurv != NULL)
	ddisk += disk;
    ddisk += sddisk;
    G_verbose_message(_("Processing all selected output files "
			"will require %d bytes of disk space for temp files"), ddisk);

    deltx = xmax - xmin;
    delty = ymax - ymin;
    dnorm = sqrt((deltx * delty * KMIN) / NPOINT);

    if (dtens) {
	params.fi = params.fi * dnorm / 1000.;
	G_verbose_message("dnorm = %f, rescaled tension = %f", dnorm, params.fi);
    }
    
    bitmask = IL_create_bitmask(&params);
    
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    ertot = 0.;
    G_message(_("Processing segments..."));    
    if (IL_interp_segments_2d(&params, info, info->root, bitmask,
			      zmin, zmax, &zminac, &zmaxac, &gmin, &gmax,
			      &c1min, &c1max, &c2min, &c2max, &ertot, totsegm,
			      n_cols, dnorm) < 0) {
	clean();
	G_fatal_error(_("Interp_segmets failed"));
    }

    G_free_vector(az);
    if (cond1) {
	G_free_vector(adx);
	G_free_vector(ady);
	if (cond2) {
	    G_free_vector(adxx);
	    G_free_vector(adyy);
	    G_free_vector(adxy);
	}
    }
    ii = IL_output_2d(&params, &cellhd, zmin, zmax, zminac, zmaxac, c1min,
		      c1max, c2min, c2max, gmin, gmax, ertot, input, dnorm,
		      dtens, 1, NPOINT);
    if (ii < 0) {
	clean();
	G_fatal_error(_("Unable to write raster maps - try to increase resolution"));
    }

    G_free(zero_array_cell);
    if (elev != NULL)
	fclose(Tmp_fd_z);
    if (slope != NULL)
	fclose(Tmp_fd_dx);
    if (aspect != NULL)
	fclose(Tmp_fd_dy);
    if (pcurv != NULL)
	fclose(Tmp_fd_xx);
    if (tcurv != NULL)
	fclose(Tmp_fd_yy);
    if (mcurv != NULL)
	fclose(Tmp_fd_xy);

    if (overfile != NULL) {
	if (0 > Vect_open_new(&OverMap, overfile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to create vector map <%s>"), overfile);
	}
	Vect_hist_command(&OverMap);

	/*
	   sprintf (OverMap.head.your_name, "grass");
	   sprintf (OverMap.head.map_name, "Overlap segments for %s", input);
	   OverMap.head.orig_scale = 100000;
	   OverMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &OverMap);
	Vect_build(&OverMap);
	Vect_close(&OverMap);
    }

    if (elev != NULL)
	unlink(Tmp_file_z);
    if (slope != NULL)
	unlink(Tmp_file_dx);
    if (aspect != NULL)
	unlink(Tmp_file_dy);
    if (pcurv != NULL)
	unlink(Tmp_file_xx);
    if (tcurv != NULL)
	unlink(Tmp_file_yy);
    if (mcurv != NULL)
	unlink(Tmp_file_xy);

    if (cvdev != NULL || devi != NULL) {
	db_commit_transaction(driver2);
	db_close_database_shutdown_driver(driver2);
	Vect_build(&Map2);
	Vect_close(&Map2);
    }

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
コード例 #14
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Map_info Map;

    FILE *ascii, *att;
    char *input, *output, *delim, **columns, *where, *field_name, *cats;
    int format, dp, field, ret, region, old_format, header, type;
    int ver, pnt;

    struct cat_list *clist;
    
    clist = NULL;
    
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("export"));
    G_add_keyword("ASCII");
    module->label =
	_("Exports a vector map to a GRASS ASCII vector representation.");
    module->description = _("By default only features with category are exported. "
                            "To export all features use 'layer=-1'.");

    parse_args(argc, argv, &input, &output, &format, &dp, &delim,
	       &field_name, &columns, &where, &region, &old_format, &header,
	       &cats, &type);
    
    if (format == GV_ASCII_FORMAT_STD && columns) {
      G_warning(_("Parameter '%s' ignored in standard mode"), "column");
    }

    ver = 5;
    pnt = 0;
    if (old_format)
	ver = 4;
    
    if (ver == 4 && format == GV_ASCII_FORMAT_POINT) {
      G_fatal_error(_("Format '%s' is not supported for old version"), "point");
    }
    
    if (ver == 4 && strcmp(output, "-") == 0) {
        G_fatal_error(_("Parameter '%s' must be given for old version"), "output");
    }

    /* open with topology only if needed */
    if (format == GV_ASCII_FORMAT_WKT ||
        (format == GV_ASCII_FORMAT_STD && (where || clist))) {
	if (Vect_open_old2(&Map, input, "", field_name) < 2) /* topology required for areas */
	    G_warning(_("Unable to open vector map <%s> at topology level. "
			"Areas will not be processed."),
		      input);
    }
    else {
	Vect_set_open_level(1); /* topology not needed */ 
	if (Vect_open_old2(&Map, input, "", field_name) < 0) 
	    G_fatal_error(_("Unable to open vector map <%s>"), input); 
        if (Vect_maptype(&Map) != GV_FORMAT_NATIVE) {
            /* require topological level for external formats
               centroids are read from topo */
            Vect_close(&Map);
            Vect_set_open_level(2);
            if (Vect_open_old2(&Map, input, "", field_name) < 0) 
                G_fatal_error(_("Unable to open vector map <%s>"), input); 
        }
    }

    field = Vect_get_field_number(&Map, field_name);
    if (cats) {
        clist = Vect_new_cat_list();
        
        clist->field = field;
        if (clist->field < 1)
            G_fatal_error(_("Layer <%s> not found"), field_name);
        ret = Vect_str_to_cat_list(cats, clist);
        if (ret > 0)
            G_fatal_error(_n("%d error in <%s> option",
                             "%d errors in <%s> option",
                             ret),
                          ret, "cats");
    }

    if (strcmp(output, "-") != 0) {
	if (ver == 4) {
	    ascii = G_fopen_new("dig_ascii", output);
	}
	else if (strcmp(output, "-") == 0) {
	    ascii = stdout;
	}
	else {
	    ascii = fopen(output, "w");
	}

	if (ascii == NULL) {
	    G_fatal_error(_("Unable to open file <%s>"), output);
	}
    }
    else {
	ascii = stdout;
    }

    if (format == GV_ASCII_FORMAT_STD) {
	Vect_write_ascii_head(ascii, &Map);
	fprintf(ascii, "VERTI:\n");
    }

    /* Open dig_att */
    att = NULL;
    if (ver == 4 && !pnt) {
	if (G_find_file("dig_att", output, G_mapset()) != NULL)
	    G_fatal_error(_("dig_att file already exist"));

	if ((att = G_fopen_new("dig_att", output)) == NULL)
	    G_fatal_error(_("Unable to open dig_att file <%s>"),
			  output);
    }

    if (where || columns || clist)
	G_message(_("Fetching data..."));
    ret = Vect_write_ascii(ascii, att, &Map, ver, format, dp, delim,
			   region, type, field, clist, (const char *)where,
			   (const char **)columns, header);

    if (ret < 1) {
	if (format == GV_ASCII_FORMAT_POINT) {
	    G_warning(_("No points found, nothing to be exported"));
	}
	else {
	    G_warning(_("No features found, nothing to be exported"));
	}
    }
    
    if (ascii != NULL)
	fclose(ascii);
    if (att != NULL)
	fclose(att);

    Vect_close(&Map);

    if (cats)
        Vect_destroy_cat_list(clist);
    
    exit(EXIT_SUCCESS);
}
コード例 #15
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *map_opt, *field_opt, *col_opt, *where_opt;
    struct Option *algo_opt, *nbclass_opt;
    struct Flag *shell_flag;
    struct Map_info Map;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray Cvarr;
    int ofield;
    int nrec, ctype, nbclass, nbreaks, *frequencies;
    int ret, i;
    double finfo;
    double *classbreaks, min, max, *data;
    struct GASTATS stats;
    char *desc;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("classification"));
    G_add_keyword(_("attribute table"));
    G_add_keyword(_("statistics"));
    module->description =
	_("Classifies attribute data, e.g. for thematic mapping");

    map_opt = G_define_standard_option(G_OPT_V_MAP);

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = YES;
    col_opt->description = _("Column name or expression");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    algo_opt = G_define_option();
    algo_opt->key = "algorithm";
    algo_opt->type = TYPE_STRING;
    algo_opt->required = YES;
    algo_opt->multiple = NO;
    algo_opt->options = "int,std,qua,equ,dis";
    algo_opt->description = _("Algorithm to use for classification");
    desc = NULL;
    G_asprintf(&desc,
	       "int;%s;"
	       "std;%s;"
	       "qua;%s;"
	       "equ;%s",
	       /* "dis;%s" */
	       _("simple intervals"),
	       _("standard deviations"),
	       _("quantiles"),
	       _("equiprobable (normal distribution)"));
	       /* _("discontinuities"));currently disabled because of bugs */
    algo_opt->descriptions = desc;

    nbclass_opt = G_define_option();
    nbclass_opt->key = "nbclasses";
    nbclass_opt->type = TYPE_INTEGER;
    nbclass_opt->required = YES;
    nbclass_opt->multiple = NO;
    nbclass_opt->description = _("Number of classes to define");

    shell_flag = G_define_flag();
    shell_flag->key = 'g';
    shell_flag->description =
	_("Print only class breaks (without min and max)");

    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    
    /* open input vector */
    Vect_set_open_level(2);
    if (Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), map_opt->answer);

    ofield = Vect_get_field_number(&Map, field_opt->answer);

    /* Read attributes */
    db_CatValArray_init(&Cvarr);
    Fi = Vect_get_field(&Map, ofield);

    if (Fi == NULL) {
	G_fatal_error(_("Unable to get layer info for vector map"));
    }
    Vect_close(&Map);

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

    /* Note: do not check if the column exists in the table because it may be an expression */

    nrec =
	db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer,
			      where_opt->answer, &Cvarr);
    G_debug(2, "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"));

    db_close_database_shutdown_driver(Driver);

    ret = db_CatValArray_sort_by_value(&Cvarr);
    if (ret == DB_FAILED)
	G_fatal_error(_("Unable to sort array of values"));


    data = (double *)G_malloc((nrec) * sizeof(double));
    for (i = 0; i < nrec; i++)
	data[i] = 0.0;

    if (ctype == DB_C_TYPE_INT) {
	for (i = 0; i < nrec; i++)
	    data[i] = Cvarr.value[i].val.i;
    }
    else {
	for (i = 0; i < nrec; i++)
	    data[i] = Cvarr.value[i].val.d;
    }



    nbclass = atoi(nbclass_opt->answer);
    nbreaks = nbclass - 1;	/* we need one less classbreaks (min and max exluded) than classes */

    classbreaks = (double *)G_malloc((nbreaks) * sizeof(double));
    for (i = 0; i < nbreaks; i++)
	classbreaks[i] = 0;

    /* Get classbreaks for given algorithm and number of classbreaks.
     * finfo takes any info coming from the classification algorithms
     * equ algorithm can alter number of class breaks */
    finfo =
	class_apply_algorithm(algo_opt->answer, data, nrec, &nbreaks,
			      classbreaks);


    if (G_strcasecmp(algo_opt->answer, "dis") == 0 && finfo < 3.84148)
	G_warning(_("The discontinuities algorithm indicates that some "
		    "class breaks are not statistically significant at "
		    "alpha=0.05. You are advised to reduce the number of classes."));

    /*output to be piped to other modules ? */
    if (shell_flag->answer) {

	for (i = 0; i < nbreaks - 1; i++)
	    fprintf(stdout, "%f,", classbreaks[i]);
	fprintf(stdout, "%f", classbreaks[nbreaks - 1]);
	fprintf(stdout, "\n");

    }
    else {

	frequencies = (int *)G_malloc((nbreaks + 1) * sizeof(int));
	for (i = 0; i < nbreaks + 1; i++)
	    frequencies[i] = 0;

	ret =
	    class_frequencies(data, nrec, nbreaks, classbreaks, frequencies);
	basic_stats(data, nrec, &stats);

	min = data[0];
	max = data[nrec - 1];

	/* as equ algorithm can modify number of breaks we recalculate number of
	 * classes
	 */
	fprintf(stdout, _("\nClassification of %s into %i classes\n"),
		col_opt->answer, nbreaks + 1);
	fprintf(stdout, _("Using algorithm: *** %s ***\n"), algo_opt->answer);
	fprintf(stdout, _("Mean: %f\tStandard deviation = %f\n"), stats.mean,
		stats.stdev);

	if (G_strcasecmp(algo_opt->answer, "dis") == 0) {
	    fprintf(stdout, _("Lowest chi2 = %f\n"), finfo);
	}
	if (G_strcasecmp(algo_opt->answer, "std") == 0)
	    fprintf(stdout, _("Stdev multiplied by %.4f to define step\n"),
		    finfo);
	fprintf(stdout, "\n");
	fprintf(stdout, _("%15s%15s%15s\n\n"), "From (excl.)", "To (incl.)",
		"Frequency");
	fprintf(stdout, "%15.5f%15.5f%15i\n", min, classbreaks[0],
		frequencies[0]);

	for (i = 1; i < nbreaks; i++) {
	    fprintf(stdout, "%15.5f%15.5f%15i\n",
		    classbreaks[i - 1], classbreaks[i], frequencies[i]);
	}
	fprintf(stdout, "%15.5f%15.5f%15i\n",
		classbreaks[nbreaks - 1], max, frequencies[nbreaks]);

	fprintf(stdout, _("\nNote: Minimum of first class is including\n\n"));
    }
    
    fflush(stdout);
    
    exit(EXIT_SUCCESS);
}
コード例 #16
0
ファイル: trans2.c プロジェクト: rashadkm/grass_cmake
/*!
   \brief transform 2d vector features to 3d

   \param In input vector
   \param Out output vector
   \param type feature type to be transformed
   \param height fixed height (used only if column is NULL)
   \param field layer number
   \param column attribute column used for height
 */
void trans2d(struct Map_info *In, struct Map_info *Out, int type,
	    double height, const char *field_name, const char *column)
{
    int i, ltype, line, field;
    int cat;
    int ret, ctype;

    struct line_pnts *Points;
    struct line_cats *Cats;

    dbCatValArray cvarr;

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

    db_CatValArray_init(&cvarr);

    field = Vect_get_field_number(In, field_name);
    
    if (column) {
	struct field_info *Fi;

	dbDriver *driver;

        if (field == -1) {
            G_warning(_("Invalid layer number %d, assuming 1"), field);
            field = 1;
        }

	Fi = Vect_get_field(In, field);
	if (!Fi) {
	    G_fatal_error(_("Database connection not defined for layer <%s>"),
                          field_name);
	}

	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);
        
	/* column type must numeric */
	ctype = db_column_Ctype(driver, Fi->table, column);
	if (ctype == -1) {
	    G_fatal_error(_("Column <%s> not found in table <%s>"),
                          column, Fi->table);
	}
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
	    G_fatal_error(_("Column must be numeric"));
	}

        G_message(_("Fetching height from <%s> column..."), column);
	db_select_CatValArray(driver, Fi->table, Fi->key,
			      column, NULL, &cvarr);

	G_debug(3, "%d records selected", cvarr.n_values);

	db_close_database_shutdown_driver(driver);
    }

    G_message(_("Transforming features..."));
    line = 1;
    while (1) {
	ltype = Vect_read_next_line(In, Points, Cats);
	if (ltype == -1) {
	    G_fatal_error(_("Unable to read vector map"));
	}
	if (ltype == -2) {	/* EOF */
	    break;
	}

        G_progress(line, 1000);
        
	if (!(ltype & type))
	    continue;

	if (field != -1 && !Vect_cat_get(Cats, field, &cat))
	    continue;
	
	if (column) {
	    Vect_cat_get(Cats, field, &cat);
	    if (cat < 0) {
		G_warning(_("Skipping feature without category"));
		continue;
	    }

	    if (ctype == DB_C_TYPE_DOUBLE)
		ret = db_CatValArray_get_value_double(&cvarr, cat, &height);
	    else {		/* integer */

		int height_i;

		ret = db_CatValArray_get_value_int(&cvarr, cat, &height_i);
		height = (double)height_i;
	    }

	    if (ret != DB_OK)
		G_warning(_("Unable to get height for feature category %d"),
			  cat);
	}

	for (i = 0; i < Points->n_points; i++) {
	    Points->z[i] = height;
	}

	Vect_write_line(Out, ltype, Points, Cats);

	line++;
    }
    G_progress(1, 1);
    
    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);
}
コード例 #17
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    int i, j, precision, field, type, nlines;
    int do_attr = 0, attr_cols[8], attr_size = 0, db_open = 0, cnt = 0;

    double width, radius;
    struct Option *in_opt, *out_opt, *prec_opt, *type_opt, *attr_opt,
	*field_opt;
    struct GModule *module;
    struct Map_info In;
    struct bound_box box;

    /* vector */
    struct line_pnts *Points;
    struct line_cats *Cats;

    /* attribs */
    dbDriver *Driver = NULL;
    dbHandle handle;
    dbTable *Table;
    dbString dbstring;
    struct field_info *Fi;

    /* init */
    G_gisinit(argv[0]);

    /* parse command-line */
    module = G_define_module();
    module->description = _("Exports a vector map to SVG file.");
    G_add_keyword(_("vector"));
    G_add_keyword(_("export"));

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);

    out_opt = G_define_standard_option(G_OPT_F_OUTPUT);
    out_opt->description = _("Name for SVG output file");

    type_opt = G_define_option();
    type_opt->key = "type";
    type_opt->type = TYPE_STRING;
    type_opt->required = YES;
    type_opt->multiple = NO;
    type_opt->answer = "poly";
    type_opt->options = "poly,line,point";
    type_opt->label = _("Output type");
    type_opt->description = _("Defines which feature-type will be extracted");

    prec_opt = G_define_option();
    prec_opt->key = "precision";
    prec_opt->type = TYPE_INTEGER;
    prec_opt->required = NO;
    prec_opt->answer = "6";
    prec_opt->multiple = NO;
    prec_opt->description = _("Coordinate precision");

    attr_opt = G_define_standard_option(G_OPT_DB_COLUMNS);
    attr_opt->key = "attribute";
    attr_opt->required = NO;
    attr_opt->multiple = YES;
    attr_opt->description = _("Attribute(s) to include in output SVG");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

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

    if (type_opt->answer[0] == 'l') {
        type = TYPE_LINE;
    }
    else {
        if (type_opt->answer[2] == 'l')
            type = TYPE_POLY;
        else
            type = TYPE_POINT;
    }
            
    /* override coordinate precision if any */
    precision = atof(prec_opt->answer);
    if (precision < 0) {
	G_fatal_error(_("Precision must not be negative"));
    }
    if (precision > 15) {
	G_fatal_error(_("Precision must not be higher than 15"));
    }

    /* open input vector */
    Vect_set_open_level(2);
    if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    /* parse field number */
    field = Vect_get_field_number(&In, field_opt->answer);

    /* open db-driver to attribs */
    db_init_string(&dbstring);

    /* check for requested field */
    Fi = Vect_get_field(&In, field);
    if (Fi != NULL) {
	Driver = db_start_driver(Fi->driver);
	if (Driver == NULL) {
	    G_fatal_error(_("Unable to start driver <%s>"), Fi->driver);
	}

	/* open db */
	db_init_handle(&handle);
	db_set_handle(&handle, Fi->database, NULL);
	if (db_open_database(Driver, &handle) != DB_OK) {
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  Fi->database, Fi->driver);
	}

	db_set_string(&dbstring, Fi->table);
	if (db_describe_table(Driver, &dbstring, &Table) != DB_OK) {
	    G_fatal_error(_("Unable to describe table <%s>"), Fi->table);
	}

	/* define column-indices for columns to extract */
	dbColumn *Column;

	for (i = 0; i < db_get_table_number_of_columns(Table); i++) {
	    Column = db_get_table_column(Table, i);
	    if (attr_opt->answer != NULL) {
		for (j = 0; attr_opt->answers[j] != NULL; j++) {
		    if (G_strcasecmp(attr_opt->answers[j],
				     db_get_column_name(Column)) == 0) {
			attr_cols[attr_size] = i;
			attr_size += 1;
			break;
		    }
		}
	    }
	}
	do_attr = 1;
	db_open = 1;
    }

    /* parse bounding box and define default stroke-width, radius */
    Vect_get_map_box(&In, &box);
    if ((box.E - box.W) >= (box.N - box.S)) {
	radius = (box.E - box.W) * RADIUS_SCALE;
	width = (box.E - box.W) * WIDTH_SCALE;
    }
    else {
	radius = (box.N - box.S) * RADIUS_SCALE;
	width = (box.N - box.S) * WIDTH_SCALE;
    }

    /* open output SVG-file and print SVG-header with viewBox and Namenspaces */
    if ((fpsvg = fopen(out_opt->answer, "w")) == NULL) {
	G_fatal_error(_("Unable to create SVG file <%s>"), out_opt->answer);
    }

    fprintf(fpsvg, "<svg xmlns=\"%s\" xmlns:xlink=\"%s\" xmlns:gg=\"%s\" ",
	    SVG_NS, XLINK_NS, GRASS_NS);
    fprintf(fpsvg, "viewBox=\"%.*f %.*f %.*f %.*f\">\n",
	    precision, box.W,
	    precision, box.N * -1,
	    precision, box.E - box.W, precision, box.N - box.S);
    fprintf(fpsvg, "<title>v.out.svg %s %s</title>\n", in_opt->answer,
	    out_opt->answer);

    nlines = Vect_get_num_lines(&In);
    
    /* extract areas if any or requested */
    if (type == TYPE_POLY) {
	if (Vect_get_num_areas(&In) == 0) {
	    G_warning(_("No areas found, skipping %s"), "type=poly");
	}
	else {
            int nareas;
            
            nareas = Vect_get_num_areas(&In);
	    /* extract area as paths */
	    fprintf(fpsvg,
		    " <g id=\"%s\" fill=\"#CCC\" stroke=\"#000\" stroke-width=\"%.*f\" >\n",
		    G_Areas, precision, width);
	    for (i = 1; i <= nareas; i++) {
		G_percent(i, nareas, 5);

		/* skip areas without centroid */
		if (Vect_get_area_centroid(&In, i) == 0) {
		    G_warning(_("Skipping area %d without centroid"), i);
		    continue;
		}

		/* extract attribs, parse area */
		Vect_get_area_cats(&In, i, Cats);
		fprintf(fpsvg, "  <path ");
		if (Cats->n_cats > 0) {
		    mk_attribs(Cats->cat[0], Fi, Driver, Table, attr_cols,
			       attr_size, do_attr);
		}
		fprintf(fpsvg, "d=\"");

		Vect_get_area_points(&In, i, Points);
		mk_path(Points, precision);

		/* append islands if any within current path */
		for (j = 0; j < Vect_get_area_num_isles(&In, i); j++) {
		    Vect_get_isle_points(&In, Vect_get_area_isle(&In, i, j),
					 Points);
		    mk_path(Points, precision);
		}
		fprintf(fpsvg, "\" />\n");
		cnt += 1;
	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d areas extracted"), cnt);
	}
    }
    
    /* extract points if requested */
    if (type == TYPE_POINT) {
	if (Vect_get_num_primitives(&In, GV_POINTS) == 0) {
	    G_warning(_("No points found, skipping %s"), "type=point");
	}
	else {
	    /* extract points as circles */
	    fprintf(fpsvg, " <g id=\"%s\" fill=\"#FC0\" stroke=\"#000\" "
		    "stroke-width=\"%.*f\" >\n", G_Points, precision, width);
	    for (i = 1; i <= nlines; i++) {
		G_percent(i, nlines, 5);
                
		if (!(Vect_read_line(&In, Points, Cats, i) & GV_POINTS))
                    continue;
                
		if (field != -1 && !Vect_cat_get(Cats, field, NULL))
		    continue;
                
		for (j = 0; j < Points->n_points; j++) {
		    fprintf(fpsvg, "  <circle ");
		    if (Cats->n_cats > 0) {
			mk_attribs(Cats->cat[j], Fi, Driver, Table, attr_cols,
				   attr_size, do_attr);
		    }
		    fprintf(fpsvg, "cx=\"%.*f\" cy=\"%.*f\" r=\"%.*f\" />\n",
			    precision, Points->x[j],
			    precision, Points->y[j] * -1, precision, radius);
		    cnt += 1;
		}

	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d points extracted"), cnt);
	}
    }
    
    /* extract lines if requested */
    if (type == TYPE_LINE) {
	if (Vect_get_num_primitives(&In, GV_LINES) == 0) {
	    G_warning(_("No lines found, skipping %s"), "type=line");
	}
	else {
	    /* extract lines as paths */
	    fprintf(fpsvg, " <g id=\"%s\" fill=\"none\" stroke=\"#000\" "
		    "stroke-width=\"%.*f\" >\n", G_Lines, precision, width);
	    for (i = 1; i <= nlines; i++) {
		G_percent(i, nlines, 5);
                
		if (!(Vect_read_line(&In, Points, Cats, i) & GV_LINES))
                    continue;
                
                if (field != -1 && !Vect_cat_get(Cats, field, NULL))
		    continue;
                
		fprintf(fpsvg, "  <path ");
		if (Cats->n_cats > 0) {
		    mk_attribs(Cats->cat[0], Fi, Driver, Table,
			       attr_cols, attr_size, do_attr);
		}

		fprintf(fpsvg, "d=\"");
		mk_path(Points, precision);
		fprintf(fpsvg, "\" />\n");
		cnt += 1;
	    }
	    fprintf(fpsvg, " </g>\n");
	    G_message(_("%d lines extracted"), cnt);
	}
    }
    /* finish code */
    fprintf(fpsvg, "</svg>\n");

    if (db_open == 1) {
	/* close database handle */
	db_close_database(Driver);
	db_shutdown_driver(Driver);
    }

    /* close SVG-file */
    fclose(fpsvg);
    
    exit(EXIT_SUCCESS);
}
コード例 #18
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *input, *output, *field;
    struct Flag *all, *flat;
    struct Cell_head window;

    char *sitefile;

    struct Map_info Map;
    struct Point *points;	/* point loaded from site file */
    int *hull;			/* index of points located on the convex hull */
    int numSitePoints, numHullPoints;

    int MODE2D;
    
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    module->description =
	_("Produces a convex hull for a given vector map.");
    
    input = G_define_standard_option(G_OPT_V_INPUT);
    
    field = G_define_standard_option(G_OPT_V_FIELD_ALL);

    output = G_define_standard_option(G_OPT_V_OUTPUT);
    
    all = G_define_flag();
    all->key = 'a';
    all->description =
	_("Use all vector points (do not limit to current region)");

    flat = G_define_flag();
    flat->key = 'f';
    flat->description =
	_("Create a 'flat' 2D hull even if the input is 3D points");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    sitefile = input->answer;

    Vect_check_input_output_name(input->answer, output->answer,
				 GV_FATAL_EXIT);
    
    Vect_set_open_level(1);
    if (Vect_open_old2(&Map, sitefile, "", field->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), sitefile);
    
    /* load site coordinates */
    G_get_window(&window);
    numSitePoints = loadSiteCoordinates(&Map, &points, all->answer, &window,
					Vect_get_field_number(&Map, field->answer));
    if (numSitePoints < 0)
	G_fatal_error(_("Error loading vector points from <%s>"), sitefile);
    
    if (numSitePoints < 3)
	G_fatal_error(_("Convex hull calculation requires at least three points (%d found)"), numSitePoints);
    
    G_verbose_message(_("%d points read from vector map <%s>"), sitefile);
    
    /* create a 2D or a 3D hull? */
    MODE2D = 1;
    if (Vect_is_3d(&Map)) {
	MODE2D = 0;
    }
    if (flat->answer) {
	MODE2D = 1;
    }

    /* create vector map */
    if (0 > Vect_open_new(&Map, output->answer, MODE2D ? WITHOUT_Z : WITH_Z)) {
	G_fatal_error(_("Unable to create vector map <%s>"), output->answer);
    }
    
    Vect_hist_command(&Map);

    if (MODE2D) {
	/* compute convex hull */
	numHullPoints = convexHull(points, numSitePoints, &hull);

	/* output vector map */
	outputHull(&Map, points, hull, numHullPoints);
    }
    else {
	/* this does everything for the 3D hull including vector map creation */
	convexHull3d(points, numSitePoints, &Map);
    }
    
    /* clean up and bye bye */
    Vect_build(&Map);
    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
コード例 #19
0
ファイル: main.c プロジェクト: rkrug/grass-ci
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *method_opt, *afield_opt, *nfield_opt, *abcol,
                  *afcol, *ncol;
    struct Flag *add_f;
    int with_z;
    int afield, nfield, mask_type;
    dglGraph_s *graph;
    int *component, nnodes, type, i, nlines, components, max_cat;
    char buf[2000], *covered;
    char *desc;

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("components"));
    module->description =
	_("Computes strongly and weakly connected components in the network.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_option();
    ncol->key = "node_column";
    ncol->type = TYPE_STRING;
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    method_opt = G_define_option();
    method_opt->key = "method";
    method_opt->type = TYPE_STRING;
    method_opt->required = YES;
    method_opt->multiple = NO;
    method_opt->options = "weak,strong";
    desc = NULL;
    G_asprintf(&desc,
	       "weak;%s;strong;%s",
	       _("Weakly connected components"),
	       _("Strongly connected components"));
    method_opt->descriptions = desc;
    method_opt->description = _("Type of components");

    add_f = G_define_flag();
    add_f->key = 'a';
    add_f->description = _("Add points on nodes");

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    /* TODO: make an option for this */
    mask_type = GV_LINE | GV_BOUNDARY;

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

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }

    /* parse filter option and select appropriate lines */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer,
                                  abcol->answer, ncol->answer, 0, 2))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));

    graph = Vect_net_get_graph(&In);
    nnodes = Vect_get_num_nodes(&In);
    component = (int *)G_calloc(nnodes + 1, sizeof(int));
    covered = (char *)G_calloc(nnodes + 1, sizeof(char));
    if (!component || !covered) {
	G_fatal_error(_("Out of memory"));
	exit(EXIT_FAILURE);
    }
    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    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);

    sprintf(buf, "create table %s ( cat integer, comp integer)", Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%s", db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	db_close_database_shutdown_driver(driver);
	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(_("Cannot create index"));

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

    db_begin_transaction(driver);

    if (method_opt->answer[0] == 'w') {
	G_message(_("Computing weakly connected components..."));
	components = NetA_weakly_connected_components(graph, component);
    }
    else {
	G_message(_("Computing strongly connected components..."));
	components = NetA_strongly_connected_components(graph, component);
    }

    G_debug(3, "Components: %d", components);

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

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

    nlines = Vect_get_num_lines(&In);
    max_cat = 1;
    G_percent(0, nlines, 4);
    for (i = 1; i <= nlines; i++) {
	int comp, cat;

	G_percent(i, nlines, 4);
	type = Vect_read_line(&In, Points, Cats, i);
	if (!Vect_cat_get(Cats, afield, &cat))
	    continue;
	if (type == GV_LINE || type == GV_BOUNDARY) {
	    int node1, node2;

	    Vect_get_line_nodes(&In, i, &node1, &node2);
	    if (component[node1] == component[node2]) {
		comp = component[node1];
	    }
	    else {
		continue;
	    }
	}
	else if (type == GV_POINT) {
	    int node;

	    /* Vect_get_line_nodes(&In, i, &node, NULL); */
	    node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
	    if (!node)
		continue;
	    comp = component[node];
	    covered[node] = 1;
	}
	else
	    continue;
	
	cat = max_cat++;
	Vect_reset_cats(Cats);
	Vect_cat_set(Cats, 1, cat);
	Vect_write_line(&Out, type, Points, Cats);
	insert_new_record(driver, Fi, &sql, cat, comp);
    }

    /*add points on nodes not covered by any point in the network */
    if (add_f->answer) {
	for (i = 1; i <= nnodes; i++)
	    if (!covered[i]) {
		Vect_reset_cats(Cats);
		Vect_cat_set(Cats, 1, max_cat);
		NetA_add_point_on_node(&In, &Out, i, Cats);
		insert_new_record(driver, Fi, &sql, max_cat++, component[i]);
	    }
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    Vect_close(&In);

    Vect_build(&Out);
    Vect_close(&Out);

    G_done_msg(_("Found %d components."), components);

    exit(EXIT_SUCCESS);
}
コード例 #20
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char *argv[])
{
    struct Map_info In, Out;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out;
    struct Option *afield_opt, *nfield_opt, *afcol, *ncol;
    struct Flag *geo_f;
    int with_z;
    int afield, nfield, mask_type;
    dglGraph_s *graph;
    int i, edges, geo;
    struct ilist *tree_list;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("spanning tree"));
    module->description =
	_("Computes minimum spanning tree for the network.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);
    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "alayer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "nlayer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "afcolumn";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "ncolumn";
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    /* TODO: make an option for this */
    mask_type = GV_LINE | GV_BOUNDARY;

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

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }

    if (geo_f->answer) {
	geo = 1;
	if (G_projection() != PROJECTION_LL)
	    G_warning(_("The current projection is not longitude-latitude"));
    }
    else
	geo = 0;

    /* parse filter option and select appropriate lines */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, NULL,
                                  ncol->answer, geo, 0))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));

    graph = Vect_net_get_graph(&In);

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

    tree_list = Vect_new_list();
    edges = NetA_spanning_tree(graph, tree_list);
    G_debug(3, "Edges: %d", edges);
    for (i = 0; i < edges; i++) {
	int type =
	    Vect_read_line(&In, Points, Cats, abs(tree_list->value[i]));
	Vect_write_line(&Out, type, Points, Cats);
    }
    Vect_destroy_list(tree_list);

    Vect_build(&Out);

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

    exit(EXIT_SUCCESS);
}
コード例 #21
0
ファイル: main.c プロジェクト: rkrug/grass-ci
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variable declarations */
    int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion_row, subregion_col;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross;	/* booleans */
    double stepN, stepE, lambda, mean;
    double N_extension, E_extension, edgeE, edgeN;

    const char *mapset, *drv, *db, *vector, *map;
    char table_name[GNAME_MAX], title[64];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int dim_vect, nparameters, BW;
    int *lineVect;		/* Vector restoring primitive's ID */
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    SEGMENT out_seg, mask_seg;
    const char *out_file, *mask_file;
    int out_fd, mask_fd;
    double seg_size;
    int seg_mb, segments_in_memory;
    int have_mask;

    /* Structs declarations */
    int raster;
    struct Map_info In, In_ext, Out;
    struct History history;

    struct GModule *module;
    struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt,
               *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt,
               *memory_opt, *solver, *error, *iter;
    struct Flag *cross_corr_flag, *spline_step_flag;

    struct Reg_dimens dims;
    struct Cell_head elaboration_reg, original_reg;
    struct bound_box general_box, overlap_box, original_box;

    struct Point *observ;
    struct line_cats *Cats;
    dbCatValArray cvarr;

    int with_z;
    int nrec, ctype = 0;
    struct field_info *Fi;
    dbDriver *driver, *driver_cats;

    /*----------------------------------------------------------------*/
    /* Options declarations */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("LIDAR"));
    module->description =
        _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization.");

    cross_corr_flag = G_define_flag();
    cross_corr_flag->key = 'c';
    cross_corr_flag->description =
        _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
        _("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->label = _("Name of input vector point map");

    dfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    dfield_opt->guisection = _("Settings");

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = NO;
    col_opt->label =
        _("Name of the attribute column with values to be used for approximation");
    col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used.");
    col_opt->guisection = _("Settings");

    in_ext_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_ext_opt->key = "sparse_input";
    in_ext_opt->required = NO;
    in_ext_opt->label =
        _("Name of input vector map with sparse points");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = NO;
    out_opt->guisection = _("Outputs");

    out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_map_opt->key = "raster_output";
    out_map_opt->required = NO;
    out_map_opt->guisection = _("Outputs");

    mask_opt = G_define_standard_option(G_OPT_R_INPUT);
    mask_opt->key = "mask";
    mask_opt->label = _("Raster map to use for masking (applies to raster output only)");
    mask_opt->description = _("Only cells that are not NULL and not zero are interpolated");
    mask_opt->required = NO;

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "4";
    stepE_opt->description =
        _("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "4";
    stepN_opt->description =
        _("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    type_opt = G_define_option();
    type_opt->key = "method";
    type_opt->description = _("Spline interpolation algorithm");
    type_opt->type = TYPE_STRING;
    type_opt->options = "bilinear,bicubic";
    type_opt->answer = "bilinear";
    type_opt->guisection = _("Settings");
    G_asprintf((char **) &(type_opt->descriptions),
               "bilinear;%s;bicubic;%s",
               _("Bilinear interpolation"),
               _("Bicubic interpolation"));

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_i";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)");
    lambda_f_opt->answer = "0.01";
    lambda_f_opt->guisection = _("Settings");

    solver = N_define_standard_option(N_OPT_SOLVER_SYMM);
    solver->options = "cholesky,cg";
    solver->answer = "cholesky";

    iter = N_define_standard_option(N_OPT_MAX_ITERATIONS);

    error = N_define_standard_option(N_OPT_ITERATION_ERROR);

    memory_opt = G_define_option();
    memory_opt->key = "memory";
    memory_opt->type = TYPE_INTEGER;
    memory_opt->required = NO;
    memory_opt->answer = "300";
    memory_opt->label = _("Maximum memory to be used (in MB)");
    memory_opt->description = _("Cache size for raster rows");

    /*----------------------------------------------------------------*/
    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    vector = out_opt->answer;
    map = out_map_opt->answer;

    if (vector && map)
        G_fatal_error(_("Choose either vector or raster output, not both"));

    if (!vector && !map && !cross_corr_flag->answer)
        G_fatal_error(_("No raster or vector or cross-validation output"));

    if (!strcmp(type_opt->answer, "linear"))
        bilin = P_BILINEAR;
    else
        bilin = P_BICUBIC;

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);

    flag_auxiliar = FALSE;

    drv = db_get_default_driver_name();
    if (!drv) {
        if (db_set_default_connection() != DB_OK)
            G_fatal_error(_("Unable to set default DB connection"));
        drv = db_get_default_driver_name();
    }
    db = db_get_default_database_name();
    if (!db)
        G_fatal_error(_("No default DB defined"));

    /* Set auxiliary table's name */
    if (vector) {
        if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
            sprintf(table_name, "%s_aux", xname);
        }
        else
            sprintf(table_name, "%s_aux", out_opt->answer);
    }

    /* Something went wrong in a previous v.surf.bspline execution */
    if (db_table_exists(drv, db, table_name)) {
        /* Start driver and open db */
        driver = db_start_driver_open_database(drv, db);
        if (driver == NULL)
            G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
                          drv);
        db_set_error_handler_driver(driver);

        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Old auxiliary table could not be dropped"));
        db_close_database_shutdown_driver(driver);
    }

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
        G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
        G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                      in_opt->answer);

    bspline_field = 0; /* assume 3D input */
    bspline_column = col_opt->answer;

    with_z = !bspline_column && Vect_is_3d(&In);

    if (Vect_is_3d(&In)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (!bspline_column)
            G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key);
    }

    if (!with_z) {
        bspline_field = Vect_get_field_number(&In, dfield_opt->answer);
    }

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
        double dens, dist;
        if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
            fprintf(stdout, _("Estimated point density: %.4g"), dens);
            fprintf(stdout, _("Estimated mean distance between points: %.4g"), dist);
        }
        else {
            fprintf(stdout, _("No points in current region"));
        }

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

    /*----------------------------------------------------------------*/
    /* Cross-correlation begins */
    if (cross_corr_flag->answer) {
        G_debug(1, "CrossCorrelation()");
        cross = cross_correlation(&In, stepE, stepN);

        if (cross != TRUE)
            G_fatal_error(_("Cross validation didn't finish correctly"));
        else {
            G_debug(1, "Cross validation finished correctly");

            Vect_close(&In);

            G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN);
            exit(EXIT_SUCCESS);
        }
    }

    /* Open input ext vector */
    ext = FALSE;
    if (in_ext_opt->answer) {
        ext = TRUE;
        G_message(_("Vector map <%s> of sparse points will be interpolated"),
                  in_ext_opt->answer);

        if ((mapset = G_find_vector2(in_ext_opt->answer, "")) == NULL)
            G_fatal_error(_("Vector map <%s> not found"), in_ext_opt->answer);

        Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
        if (1 > Vect_open_old(&In_ext, in_ext_opt->answer, mapset))
            G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                          in_opt->answer);
    }

    /* Open output map */
    /* vector output */
    if (vector && !map) {
        if (strcmp(drv, "dbf") == 0)
            G_fatal_error(_("Sorry, the <%s> driver is not compatible with "
                            "the vector output of this module. "
                            "Try with raster output or another driver."), drv);

        Vect_check_input_output_name(in_opt->answer, out_opt->answer,
                                     G_FATAL_EXIT);
        grid = FALSE;

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

        /* Copy vector Head File */
        if (ext == FALSE) {
            Vect_copy_head_data(&In, &Out);
            Vect_hist_copy(&In, &Out);
        }
        else {
            Vect_copy_head_data(&In_ext, &Out);
            Vect_hist_copy(&In_ext, &Out);
        }
        Vect_hist_command(&Out);

        G_verbose_message(_("Points in input vector map <%s> will be interpolated"),
                          vector);
    }


    /* read z values from attribute table */
    if (bspline_field > 0) {
        G_message(_("Reading values from attribute table..."));
        db_CatValArray_init(&cvarr);
        Fi = Vect_get_field(&In, bspline_field);
        if (Fi == NULL)
            G_fatal_error(_("Cannot read layer info"));

        driver_cats = db_start_driver_open_database(Fi->driver, Fi->database);
        /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */

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

        nrec =
            db_select_CatValArray(driver_cats, Fi->table, Fi->key,
                                  col_opt->answer, 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(_("%d records selected from table"), nrec);

        db_close_database_shutdown_driver(driver_cats);
    }

    /*----------------------------------------------------------------*/
    /* Interpolation begins */
    G_debug(1, "Interpolation()");

    /* Open driver and database */
    driver = db_start_driver_open_database(drv, db);
    if (driver == NULL)
        G_fatal_error(_("No database connection for driver <%s> is defined. "
                        "Run db.connect."), drv);
    db_set_error_handler_driver(driver);

    /* Create auxiliary table */
    if (vector) {
        if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) {
            P_Drop_Aux_Table(driver, table_name);
            G_fatal_error(_("Interpolation: Creating table: "
                            "It was impossible to create table <%s>."),
                          table_name);
        }
        /* db_create_index2(driver, table_name, "ID"); */
        /* sqlite likes that ??? */
        db_close_database_shutdown_driver(driver);
        driver = db_start_driver_open_database(drv, db);
    }

    /* raster output */
    raster = -1;
    Rast_set_fp_type(DCELL_TYPE);
    if (!vector && map) {
        grid = TRUE;
        raster = Rast_open_fp_new(out_map_opt->answer);

        G_verbose_message(_("Cells for raster map <%s> will be interpolated"),
                          map);
    }

    /* Setting regions and boxes */
    G_debug(1, "Interpolation: Setting regions and boxes");
    G_get_window(&original_reg);
    G_get_window(&elaboration_reg);
    Vect_region_box(&original_reg, &original_box);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

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

    /* Alloc raster matrix */
    have_mask = 0;
    out_file = mask_file = NULL;
    out_fd = mask_fd = -1;
    if (grid == TRUE) {
        int row;
        DCELL *drastbuf;

        seg_mb = atoi(memory_opt->answer);
        if (seg_mb < 3)
            G_fatal_error(_("Memory in MB must be >= 3"));

        if (mask_opt->answer)
            seg_size = sizeof(double) + sizeof(char);
        else
            seg_size = sizeof(double);

        seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20);
        segments_in_memory = seg_mb / seg_size + 0.5;
        G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE);

        out_file = G_tempfile();
        out_fd = creat(out_file, 0666);
        if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1)
            G_fatal_error(_("Can not create temporary file"));
        close(out_fd);

        out_fd = open(out_file, 2);
        if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1)
            G_fatal_error(_("Can not initialize temporary file"));

        /* initialize output */
        G_message(_("Initializing output..."));

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        Rast_set_d_null_value(drastbuf, ncols);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            Segment_put_row(&out_seg, drastbuf, row);
        }
        G_percent(row, nrows, 2);

        if (mask_opt->answer) {
            int row, col, maskfd;
            DCELL dval, *drastbuf;
            char mask_val;

            G_message(_("Load masking map"));

            mask_file = G_tempfile();
            mask_fd = creat(mask_file, 0666);
            if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1)
                G_fatal_error(_("Can not create temporary file"));
            close(mask_fd);

            mask_fd = open(mask_file, 2);
            if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1)
                G_fatal_error(_("Can not initialize temporary file"));

            maskfd = Rast_open_old(mask_opt->answer, "");
            drastbuf = Rast_allocate_buf(DCELL_TYPE);

            for (row = 0; row < nrows; row++) {
                G_percent(row, nrows, 2);
                Rast_get_d_row(maskfd, drastbuf, row);
                for (col = 0; col < ncols; col++) {
                    dval = drastbuf[col];
                    if (Rast_is_d_null_value(&dval) || dval == 0)
                        mask_val = 0;
                    else
                        mask_val = 1;

                    Segment_put(&mask_seg, &mask_val, row, col);
                }
            }

            G_percent(row, nrows, 2);
            G_free(drastbuf);
            Rast_close(maskfd);

            have_mask = 1;
        }
    }

    /*------------------------------------------------------------------
      | Subdividing and working with tiles:
      | Each original region will be divided into several subregions.
      | Each one will be overlaped by its neighbouring subregions.
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);		/* Set dim struct to zero */

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
        dims.overlap = OVERLAP_SIZE * stepN;
    else
        dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(bilin, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("Adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
        nsubregion_col = 0;
    if (nsubregion_row < 0)
        nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    /* Creating line and categories structs */
    Cats = Vect_new_cats_struct();
    Vect_cat_set(Cats, 1, 0);

    subregion_row = 0;
    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each subregion row */
        subregion_row++;
        P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                      GENERAL_ROW);

        if (elaboration_reg.north > original_reg.north) {	/* First row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          FIRST_ROW);
        }

        if (elaboration_reg.south <= original_reg.south) {	/* Last row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          LAST_ROW);
            last_row = TRUE;
        }

        nsply =
            ceil((elaboration_reg.north -
                  elaboration_reg.south) / stepN) + 0.5;
        G_debug(1, "Interpolation: nsply = %d", nsply);
        /*
        if (nsply > NSPLY_MAX)
            nsply = NSPLY_MAX;
        */
        elaboration_reg.east = original_reg.west;
        last_column = FALSE;
        subregion_col = 0;

        /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */
        /*     I'm not sure about pthreads, but you can tell OpenMP to start all at the
        	same time and it will keep num_workers supplied with the next job as free
        	cpus become available */
        while (last_column == FALSE) {	/* For each subregion column */
            int npoints = 0;
            /* needed for sparse points interpolation */
            int npoints_ext, *lineVect_ext = NULL;
            double **obsVect_ext;	/*, mean_ext = .0; */
            struct Point *observ_ext;

            subregion_col++;
            subregion++;
            if (nsubregions > 1)
                G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          GENERAL_COLUMN);

            if (elaboration_reg.west < original_reg.west) {	/* First column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, FIRST_COLUMN);
            }

            if (elaboration_reg.east >= original_reg.east) {	/* Last column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, LAST_COLUMN);
                last_column = TRUE;
            }
            nsplx =
                ceil((elaboration_reg.east -
                      elaboration_reg.west) / stepE) + 0.5;
            G_debug(1, "Interpolation: nsplx = %d", nsplx);
            /*
            if (nsplx > NSPLX_MAX)
            nsplx = NSPLX_MAX;
            */
            G_debug(1, "Interpolation: (%d,%d): subregion bounds",
                    subregion_row, subregion_col);
            G_debug(1, "Interpolation: \t\tNORTH:%.2f\t",
                    elaboration_reg.north);
            G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f",
                    elaboration_reg.west, elaboration_reg.east);
            G_debug(1, "Interpolation: \t\tSOUTH:%.2f",
                    elaboration_reg.south);

#ifdef DEBUG_SUBREGIONS
            fprintf(stdout, "B 5\n");
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, "C 1 1\n");
            fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2,
                    (elaboration_reg.south + elaboration_reg.north) / 2);
            fprintf(stdout, " 1 %d\n", subregion);
#endif



            /* reading points in interpolation region */
            dim_vect = nsplx * nsply;
            observ_ext = NULL;
            if (grid == FALSE && ext == TRUE) {
                observ_ext =
                    P_Read_Vector_Region_Map(&In_ext,
                                             &elaboration_reg,
                                             &npoints_ext, dim_vect,
                                             1);
            }
            else
                npoints_ext = 1;

            if (grid == TRUE && have_mask) {
                /* any unmasked cells in general region ? */
                mean = 0;
                observ_ext =
                    P_Read_Raster_Region_masked(&mask_seg, &original_reg,
                                                original_box, general_box,
                                                &npoints_ext, dim_vect, mean);
            }

            observ = NULL;
            if (npoints_ext > 0) {
                observ =
                    P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
                                             dim_vect, bspline_field);
            }
            else
                npoints = 1;

            G_debug(1,
                    "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d",
                    subregion_row, subregion_col, npoints);
            if (npoints > 0)
                G_verbose_message(_("%d points found in this subregion"), npoints);
            /* only interpolate if there are any points in current subregion */
            if (npoints > 0 && npoints_ext > 0) {
                int i;

                nparameters = nsplx * nsply;
                BW = P_get_BandWidth(bilin, nsply);

                /* Least Squares system */
                N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
                TN = G_alloc_vector(nparameters);	/* vector */
                parVect = G_alloc_vector(nparameters);	/* Parameters vector */
                obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
                Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
                lineVect = G_alloc_ivector(npoints);	/*  */

                for (i = 0; i < npoints; i++) {	/* Setting obsVect vector & Q matrix */
                    double dval;

                    Q[i] = 1;	/* Q=I */
                    lineVect[i] = observ[i].lineID;
                    obsVect[i][0] = observ[i].coordX;
                    obsVect[i][1] = observ[i].coordY;

                    /* read z coordinates from attribute table */
                    if (bspline_field > 0) {
                        int cat, ival, ret;

                        cat = observ[i].cat;
                        if (cat < 0)
                            continue;

                        if (ctype == DB_C_TYPE_INT) {
                            ret =
                                db_CatValArray_get_value_int(&cvarr, cat,
                                                             &ival);
                            obsVect[i][2] = ival;
                            observ[i].coordZ = ival;
                        }
                        else {	/* DB_C_TYPE_DOUBLE */
                            ret =
                                db_CatValArray_get_value_double(&cvarr, cat,
                                                                &dval);
                            obsVect[i][2] = dval;
                            observ[i].coordZ = dval;
                        }
                        if (ret != DB_OK) {
                            G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"),
                                      subregion_row, subregion_col, cat);
                            continue;
                        }
                    }
                    /* use z coordinates of 3D vector */
                    else {
                        obsVect[i][2] = observ[i].coordZ;
                    }
                }

                /* Mean calculation for every point */
                mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

                G_debug(1, "Interpolation: (%d,%d): mean=%lf",
                        subregion_row, subregion_col, mean);

                G_free(observ);

                for (i = 0; i < npoints; i++)
                    obsVect[i][2] -= mean;

                /* Bilinear interpolation */
                if (bilin) {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bilinear interpolation...",
                            subregion_row, subregion_col);
                    normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                   nsply, elaboration_reg.west,
                                   elaboration_reg.south, npoints,
                                   nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }
                /* Bicubic interpolation */
                else {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bicubic interpolation...",
                            subregion_row, subregion_col);
                    normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                     nsply, elaboration_reg.west,
                                     elaboration_reg.south, npoints,
                                     nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }

                if(G_strncasecmp(solver->answer, "cg", 2) == 0)
                    G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer));
                else
                    G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);


                G_free_matrix(N);
                G_free_vector(TN);
                G_free_vector(Q);

                if (grid == TRUE) {	/* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */
                    G_debug(1, "Interpolation: (%d,%d): Regular_Points...",
                            subregion_row, subregion_col);

                    if (!have_mask) {
                        P_Regular_Points(&elaboration_reg, &original_reg, general_box,
                                         overlap_box, &out_seg, parVect,
                                         stepN, stepE, dims.overlap, mean,
                                         nsplx, nsply, nrows, ncols, bilin);
                    }
                    else {
                        P_Sparse_Raster_Points(&out_seg,
                                               &elaboration_reg, &original_reg,
                                               general_box, overlap_box,
                                               observ_ext, parVect,
                                               stepE, stepN,
                                               dims.overlap, nsplx, nsply,
                                               npoints_ext, bilin, mean);
                    }
                }
                else {		/* OBSERVATION POINTS INTERPOLATION */
                    if (ext == FALSE) {
                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect, parVect,
                                        lineVect, stepE, stepN,
                                        dims.overlap, nsplx, nsply, npoints,
                                        bilin, Cats, driver, mean,
                                        table_name);
                    }
                    else {	/* FLAG_EXT == TRUE */

                        /* done that earlier */
                        /*
                        int npoints_ext, *lineVect_ext = NULL;
                        double **obsVect_ext;
                        struct Point *observ_ext;

                        observ_ext =
                            P_Read_Vector_Region_Map(&In_ext,
                        			     &elaboration_reg,
                        			     &npoints_ext, dim_vect,
                        			     1);
                        */

                        obsVect_ext = G_alloc_matrix(npoints_ext, 3);	/* Observation vector_ext */
                        lineVect_ext = G_alloc_ivector(npoints_ext);

                        for (i = 0; i < npoints_ext; i++) {	/* Setting obsVect_ext vector & Q matrix */
                            obsVect_ext[i][0] = observ_ext[i].coordX;
                            obsVect_ext[i][1] = observ_ext[i].coordY;
                            obsVect_ext[i][2] = observ_ext[i].coordZ - mean;
                            lineVect_ext[i] = observ_ext[i].lineID;
                        }

                        G_free(observ_ext);

                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect_ext, parVect,
                                        lineVect_ext, stepE, stepN,
                                        dims.overlap, nsplx, nsply,
                                        npoints_ext, bilin, Cats, driver,
                                        mean, table_name);

                        G_free_matrix(obsVect_ext);
                        G_free_ivector(lineVect_ext);
                    }		/* END FLAG_EXT == TRUE */
                }		/* END GRID == FALSE */
                G_free_vector(parVect);
                G_free_matrix(obsVect);
                G_free_ivector(lineVect);
            }
            else {
                if (observ)
                    G_free(observ);
                if (observ_ext)
                    G_free(observ_ext);
                if (npoints == 0)
                    G_warning(_("No data within this subregion. "
                                "Consider increasing spline step values."));
            }
        }			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    G_verbose_message(_("Writing output..."));
    /* Writing the output raster map */
    if (grid == TRUE) {
        int row, col;
        DCELL *drastbuf, dval;


        if (have_mask) {
            Segment_release(&mask_seg);	/* release memory  */
            close(mask_fd);
            unlink(mask_file);
        }

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            for (col = 0; col < ncols; col++) {
                Segment_get(&out_seg, &dval, row, col);
                drastbuf[col] = dval;
            }
            Rast_put_d_row(raster, drastbuf);
        }

        Rast_close(raster);

        Segment_release(&out_seg);	/* release memory  */
        close(out_fd);
        unlink(out_file);
        /* set map title */
        sprintf(title, "%s interpolation with Tykhonov regularization",
                type_opt->answer);
        Rast_put_cell_title(out_map_opt->answer, title);
        /* write map history */
        Rast_short_history(out_map_opt->answer, "raster", &history);
        Rast_command_history(&history);
        Rast_write_history(out_map_opt->answer, &history);
    }
    /* Writing to the output vector map the points from the overlapping zones */
    else if (flag_auxiliar == TRUE) {
        if (ext == FALSE)
            P_Aux_to_Vector(&In, &Out, driver, table_name);
        else
            P_Aux_to_Vector(&In_ext, &Out, driver, table_name);

        /* Drop auxiliary table */
        G_debug(1, "%s: Dropping <%s>", argv[0], table_name);
        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Auxiliary table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    if (ext != FALSE)
        Vect_close(&In_ext);
    if (vector)
        Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
コード例 #22
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
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);
}
コード例 #23
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char **argv)
{
    struct Option *input_opt, *output_opt, *afield_opt, *nfield_opt,
	*tfield_opt, *tucfield_opt, *afcol, *abcol, *ncol, *type_opt;
    struct Option *max_dist, *file_opt;
    struct Flag *geo_f, *segments_f, *turntable_f;
    struct GModule *module;
    struct Map_info In, Out;
    int type, afield, nfield, tfield, tucfield, geo;
    double maxdist;

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

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("shortest path"));
    module->description = _("Finds shortest path on vector network.");

    input_opt = G_define_standard_option(G_OPT_V_INPUT);
    output_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->required = YES;
    afield_opt->label = _("Arc layer");

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->key = "arc_type";
    type_opt->options = "line,boundary";
    type_opt->answer = "line,boundary";
    type_opt->required = YES;
    type_opt->label = _("Arc type");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->required = YES;
    nfield_opt->label = _("Node layer");

    file_opt = G_define_standard_option(G_OPT_F_INPUT);
    file_opt->key = "file";
    file_opt->required = NO;
    file_opt->description = _("Name of file containing start and end points. "
			      "If not given, read from stdin");

    afcol = G_define_option();
    afcol->key = "arc_column";
    afcol->type = TYPE_STRING;
    afcol->required = NO;
    afcol->description = _("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_option();
    abcol->key = "arc_backward_column";
    abcol->type = TYPE_STRING;
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_option();
    ncol->key = "node_column";
    ncol->type = TYPE_STRING;
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    max_dist = G_define_option();
    max_dist->key = "dmax";
    max_dist->type = TYPE_DOUBLE;
    max_dist->required = NO;
    max_dist->answer = "1000";
    max_dist->label = _("Maximum distance to the network");
    max_dist->description = _("If start/end are given as coordinates. "
			      "If start/end point is outside this threshold, "
			      "the path is not found "
			      "and error message is printed. To speed up the process, keep this "
			      "value as low as possible.");

    turntable_f = G_define_flag();
    turntable_f->key = 't';
    turntable_f->description = _("Use turntable");
    turntable_f->guisection = _("Turntable");

    tfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tfield_opt->key = "turn_layer";
    tfield_opt->answer = "3";
    tfield_opt->label = _("Layer with turntable");
    tfield_opt->description =
	_("Relevant only with -t flag");
    tfield_opt->guisection = _("Turntable");

    tucfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tucfield_opt->key = "turn_cat_layer";
    tucfield_opt->answer = "4";
    tucfield_opt->label = _("Layer with unique categories used in turntable");
    tucfield_opt->description =
	_("Relevant only with -t flag");
    tucfield_opt->guisection = _("Turntable");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

    segments_f = G_define_flag();
    segments_f->key = 's';
    segments_f->description = _("Write output as original input segments, "
				"not each path as one line.");

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

    type = Vect_option_to_types(type_opt);
    maxdist = atof(max_dist->answer);

    if (geo_f->answer) {
	geo = 1;
	if (G_projection() != PROJECTION_LL)
	    G_warning(_("The current projection is not longitude-latitude"));
    }
    else
	geo = 0;

    Vect_check_input_output_name(input_opt->answer, output_opt->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);
    if (Vect_open_old(&In, input_opt->answer, "") < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), input_opt->answer);

    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);
    tfield = Vect_get_field_number(&In, tfield_opt->answer);
    tucfield = Vect_get_field_number(&In, tucfield_opt->answer);

    if (1 > Vect_open_new(&Out, output_opt->answer, Vect_is_3d(&In))) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"),
		      output_opt->answer);
    }
    Vect_hist_command(&Out);

    if (turntable_f->answer)
	Vect_net_ttb_build_graph(&In, type, afield, nfield, tfield, tucfield,
				 afcol->answer, abcol->answer, ncol->answer,
				 geo, 0);
    else
	Vect_net_build_graph(&In, type, afield, nfield, afcol->answer,
			     abcol->answer, ncol->answer, geo, 0);

    path(&In, &Out, file_opt->answer, nfield, maxdist, segments_f->answer,
	 tucfield, turntable_f->answer);

    Vect_close(&In);

    Vect_build(&Out);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
コード例 #24
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;
}
コード例 #25
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char **argv)
{
    struct Flag *printattributes, *topo_flag, *shell_flag;
    struct Option *map_opt, *field_opt, *coords_opt, *maxdistance;
    struct Cell_head window;
    struct GModule *module;
    char buf[2000];
    int i, level, ret;
    int *field;
    double xval, yval, xres, yres, maxd, x;
    double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
    char nsres[30], ewres[30];
    char ch;

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

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    module->description = _("Queries a vector map at given locations.");

    map_opt = G_define_standard_option(G_OPT_V_MAPS);

    field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
    
    coords_opt = G_define_standard_option(G_OPT_M_EN);
    coords_opt->label = _("Coordinates for query");
    coords_opt->description = _("If not given read from standard input");

    maxdistance = G_define_option();
    maxdistance->type = TYPE_DOUBLE;
    maxdistance->key = "distance";
    maxdistance->answer = "0";
    maxdistance->multiple = NO;
    maxdistance->description = _("Query threshold distance");

    topo_flag = G_define_flag();
    topo_flag->key = 'd';
    topo_flag->description = _("Print topological information (debugging)");
    topo_flag->guisection = _("Print");

    printattributes = G_define_flag();
    printattributes->key = 'a';
    printattributes->description = _("Print attribute information");
    printattributes->guisection = _("Print");

    shell_flag = G_define_flag();
    shell_flag->key = 'g';
    shell_flag->description = _("Print the stats in shell script style");
    shell_flag->guisection = _("Print");

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

    if (map_opt->answers && map_opt->answers[0])
	vect = map_opt->answers;

    maxd = atof(maxdistance->answer);

    /*  
     *  fprintf(stdout, maxdistance->answer);
     *  fprintf(stdout, "Maxd is %f", maxd);
     *  fprintf(stdout, xcoord->answer);
     *  fprintf(stdout, "xval is %f", xval);
     *  fprintf(stdout, ycoord->answer);
     *  fprintf(stdout, "yval is %f", yval);
     */

    if (maxd == 0.0) {
	G_get_window(&window);
	x = window.proj;
	G_format_resolution(window.ew_res, ewres, x);
	G_format_resolution(window.ns_res, nsres, x);
	EW_DIST1 =
	    G_distance(window.east, window.north, window.west, window.north);
	/* EW Dist at South Edge */
	EW_DIST2 =
	    G_distance(window.east, window.south, window.west, window.south);
	/* NS Dist at East edge */
	NS_DIST1 =
	    G_distance(window.east, window.north, window.east, window.south);
	/* NS Dist at West edge */
	NS_DIST2 =
	    G_distance(window.west, window.north, window.west, window.south);
	xres = ((EW_DIST1 + EW_DIST2) / 2) / window.cols;
	yres = ((NS_DIST1 + NS_DIST2) / 2) / window.rows;
	if (xres > yres)
	    maxd = xres;
	else
	    maxd = yres;
    }

    /* Look at maps given on command line */
    if (vect) {

	for (i = 0; vect[i]; i++)
	    ;
	nvects = i;

	for (i = 0; field_opt->answers[i]; i++)
	    ;
	
	if (nvects != i)
	    G_fatal_error(_("Number of given vector maps (%d) differs from number of layers (%d)"),
			  nvects, i);
	
	Map = (struct Map_info *) G_malloc(nvects * sizeof(struct Map_info));
	field = (int *) G_malloc(nvects * sizeof(int));
	
	for (i = 0; i < nvects; i++) {
	    level = Vect_open_old2(&Map[i], vect[i], "", field_opt->answers[i]);
	    if (level < 2)
		G_fatal_error(_("You must build topology on vector map <%s>"),
			      vect[i]);
	    field[i] = Vect_get_field_number(&Map[i], field_opt->answers[i]);
	}
    }

    if (!coords_opt->answer) {
	/* read them from stdin */
	setvbuf(stdin, NULL, _IOLBF, 0);
	setvbuf(stdout, NULL, _IOLBF, 0);
	while (fgets(buf, sizeof(buf), stdin) != NULL) {
	    ret = sscanf(buf, "%lf%c%lf", &xval, &ch, &yval);
	    if (ret == 3 && (ch == ',' || ch == ' ' || ch == '\t')) {
		what(xval, yval, maxd, topo_flag->answer,
		     printattributes->answer, shell_flag->answer, field);
	    }
	    else {
		G_warning(_("Unknown input format, skipping: '%s'"), buf);
		continue;
	    }
	}
    }
    else {
	/* use coords given on command line */
	for (i = 0; coords_opt->answers[i] != NULL; i += 2) {
	    xval = atof(coords_opt->answers[i]);
	    yval = atof(coords_opt->answers[i + 1]);
	    what(xval, yval, maxd, topo_flag->answer,
		 printattributes->answer, shell_flag->answer, field);
	}
    }

    for (i = 0; i < nvects; i++)
	Vect_close(&Map[i]);

    exit(EXIT_SUCCESS);
}
コード例 #26
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct GParams params;
    struct Map_info Map;
    struct Map_info **BgMap;	/* backgroud vector maps */
    int nbgmaps;		/* number of registrated background maps */
    enum mode action_mode;
    FILE *ascii;

    int i;
    int move_first, snap;
    int ret, layer;
    double move_x, move_y, move_z, thresh[3];

    struct line_pnts *coord;

    struct ilist *List;

    struct cat_list *Clist;

    ascii = NULL;
    List = NULL;
    BgMap = NULL;
    nbgmaps = 0;
    coord = NULL;
    Clist = NULL;

    G_gisinit(argv[0]);

    module = G_define_module();
    module->overwrite = TRUE;
    G_add_keyword(_("vector"));
    G_add_keyword(_("editing"));
    G_add_keyword(_("geometry"));
    module->description = _("Edits a vector map, allows adding, deleting "
			    "and modifying selected vector features.");

    if (!parser(argc, argv, &params, &action_mode))
	exit(EXIT_FAILURE);

    /* get list of categories */
    Clist = Vect_new_cat_list();
    if (params.cat->answer && Vect_str_to_cat_list(params.cat->answer, Clist)) {
	G_fatal_error(_("Unable to get category list <%s>"),
		      params.cat->answer);
    }

    /* open input file */
    if (params.in->answer) {
	if (strcmp(params.in->answer, "-") != 0) {
	    ascii = fopen(params.in->answer, "r");
	    if (ascii == NULL)
		G_fatal_error(_("Unable to open file <%s>"),
			      params.in->answer);
	}
	else {
	    ascii = stdin;
	}
    }
    if (!ascii && action_mode == MODE_ADD)
	G_fatal_error(_("Required parameter <%s> not set"), params.in->key);
    
    if (action_mode == MODE_CREATE) {
	int overwrite;

	overwrite = G_check_overwrite(argc, argv);
	if (G_find_vector2(params.map->answer, G_mapset())) {
	    if (!overwrite)
		G_fatal_error(_("Vector map <%s> already exists"),
			      params.map->answer);
	}

	/* 3D vector maps? */
	ret = Vect_open_new(&Map, params.map->answer, WITHOUT_Z);
	if (Vect_maptype(&Map) == GV_FORMAT_OGR_DIRECT) {
	    int type;
	    type = Vect_option_to_types(params.type);
	    if (type != GV_POINT && type != GV_LINE &&
		type != GV_BOUNDARY)
		G_fatal_error(_("Supported feature type for OGR layer: "
				"%s, %s or %s"), "point", "line", "boundary");
	    V2_open_new_ogr(&Map, type);
	}
	if (ret == -1) {
	    G_fatal_error(_("Unable to create vector map <%s>"),
			  params.map->answer);
	}

	G_debug(1, "Map created");

	if (ascii) {
	    /* also add new vector features */
	    action_mode = MODE_ADD;
	}
    }
    else {			/* open selected vector file */
	if (action_mode == MODE_ADD)	/* write */
	    ret = Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer);
	else			/* read-only -- select features */
	    ret = Vect_open_old2(&Map, params.map->answer, G_mapset(), params.fld->answer);

	if (ret < 2)
	    G_fatal_error(_("Unable to open vector map <%s> at topological level %d"),
			  params.map->answer, 2);
    }

    G_debug(1, "Map opened");

    /* open backgroud maps */
    if (params.bmaps->answer) {
	i = 0;

	while (params.bmaps->answers[i]) {
	    const char *bmap = params.bmaps->answers[i];
	    const char *mapset = G_find_vector2(bmap, "");
	    if (!mapset)
		G_fatal_error(_("Vector map <%s> not found"), bmap);

	    if (strcmp(
		    G_fully_qualified_name(params.map->answer, G_mapset()),
		    G_fully_qualified_name(bmap, mapset)) == 0) {
		G_fatal_error(_("Unable to open vector map <%s> as the background map. "
			       "It is given as vector map to be edited."),
			      bmap);
	    }
	    nbgmaps++;
	    BgMap = (struct Map_info **)G_realloc(
		BgMap, nbgmaps * sizeof(struct Map_info *));
	    BgMap[nbgmaps - 1] =
		(struct Map_info *)G_malloc(sizeof(struct Map_info));
	    if (Vect_open_old(BgMap[nbgmaps - 1], bmap, "") == -1)
		G_fatal_error(_("Unable to open vector map <%s>"), bmap);
	    G_verbose_message(_("Background vector map <%s> registered"), bmap);
	    i++;
	}
    }

    layer = Vect_get_field_number(&Map, params.fld->answer);
    i = 0;
    while (params.maxdist->answers[i]) {
	switch (i) {
	case THRESH_COORDS:
	    thresh[THRESH_COORDS] =
		max_distance(atof(params.maxdist->answers[THRESH_COORDS]));
	    thresh[THRESH_SNAP] = thresh[THRESH_QUERY] =
		thresh[THRESH_COORDS];
	    break;
	case THRESH_SNAP:
	    thresh[THRESH_SNAP] =
		max_distance(atof(params.maxdist->answers[THRESH_SNAP]));
	    break;
	case THRESH_QUERY:
	    thresh[THRESH_QUERY] =
		atof(params.maxdist->answers[THRESH_QUERY]);
	    break;
	default:
	    break;
	}
	i++;
    }

    move_first = params.move_first->answer ? 1 : 0;
    snap = NO_SNAP;
    if (strcmp(params.snap->answer, "node") == 0)
	snap = SNAP;
    else if (strcmp(params.snap->answer, "vertex") == 0)
	snap = SNAPVERTEX;
    if (snap != NO_SNAP && thresh[THRESH_SNAP] <= 0) {
	G_warning(_("Threshold for snapping must be > 0. No snapping applied."));
	snap = NO_SNAP;
    }
    
    if (action_mode != MODE_CREATE && action_mode != MODE_ADD) {
	/* select lines */
	List = Vect_new_list();
	G_message(_("Selecting features..."));
	if (action_mode == MODE_COPY && BgMap && BgMap[0]) {
	    List = select_lines(BgMap[0], action_mode, &params, thresh, List);
	}
	else {
	    List = select_lines(&Map, action_mode, &params, thresh, List);
	}
    }

    if ((action_mode != MODE_CREATE && action_mode != MODE_ADD &&
	 action_mode != MODE_SELECT)) {
	if (List->n_values < 1) {
	    G_warning(_("No features selected, nothing to edit"));
	    action_mode = MODE_NONE;
	    ret = 0;
	}
	else {
	    /* reopen the map for updating */
	    if (action_mode == MODE_ZBULK && !Vect_is_3d(&Map)) {
		Vect_close(&Map);
		G_fatal_error(_("Vector map <%s> is not 3D. Tool '%s' requires 3D vector map. "
			       "Please convert the vector map "
			       "to 3D using e.g. %s."), params.map->answer,
			      params.tool->answer, "v.extrude");
	    }
	    Vect_close(&Map);

	    Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer);
	}
    }

    /* coords option -> array */
    if (params.coord->answers) {
	coord = Vect_new_line_struct();
	int i = 0;
	double east, north;

	while (params.coord->answers[i]) {
	    east = atof(params.coord->answers[i]);
	    north = atof(params.coord->answers[i + 1]);
	    Vect_append_point(coord, east, north, 0.0);
	    i += 2;
	}
    }

    /* perform requested editation */
    switch (action_mode) {
    case MODE_CREATE:
	break;
    case MODE_ADD:
	if (!params.header->answer)
	    Vect_read_ascii_head(ascii, &Map);
	int num_lines;
	num_lines = Vect_get_num_lines(&Map);
	
	ret = Vect_read_ascii(ascii, &Map);
	G_message(_("%d features added"), ret);
	if (ret > 0) {
	    int iline;
	    struct ilist *List_added;
	    
	    List_added = Vect_new_list();
	    for (iline = num_lines + 1; iline <= Vect_get_num_lines(&Map); iline++)
		Vect_list_append(List_added, iline);
	    
	    G_verbose_message(_("Threshold value for snapping is %.2f"),
			      thresh[THRESH_SNAP]);
	    if (snap != NO_SNAP) { /* apply snapping */
		/* snap to vertex ? */
		Vedit_snap_lines(&Map, BgMap, nbgmaps, List_added,
				 thresh[THRESH_SNAP],
				 snap == SNAP ? FALSE : TRUE); 
	    }
	    if (params.close->answer) {	/* close boundaries */
		int nclosed;

		nclosed = close_lines(&Map, GV_BOUNDARY, thresh[THRESH_SNAP]);
		G_message(_("%d boundaries closed"), nclosed);
	    }
	    Vect_destroy_list(List_added);
	}
	break;
    case MODE_DEL:
	ret = Vedit_delete_lines(&Map, List);
	G_message(_("%d features deleted"), ret);
	break;
    case MODE_MOVE:
	move_x = atof(params.move->answers[0]);
	move_y = atof(params.move->answers[1]);
	move_z = atof(params.move->answers[2]);
	G_verbose_message(_("Threshold value for snapping is %.2f"),
			  thresh[THRESH_SNAP]);
	ret = Vedit_move_lines(&Map, BgMap, nbgmaps, List, move_x, move_y, move_z, snap, thresh[THRESH_SNAP]);
	G_message(_("%d features moved"), ret);
	break;
    case MODE_VERTEX_MOVE:
	move_x = atof(params.move->answers[0]);
	move_y = atof(params.move->answers[1]);
	move_z = atof(params.move->answers[2]);
	G_verbose_message(_("Threshold value for snapping is %.2f"),
			  thresh[THRESH_SNAP]);
	ret = Vedit_move_vertex(&Map, BgMap, nbgmaps, List, coord, thresh[THRESH_COORDS], thresh[THRESH_SNAP], move_x, move_y, move_z, move_first, snap);
	G_message(_("%d vertices moved"), ret);
	break;
    case MODE_VERTEX_ADD:
	ret = Vedit_add_vertex(&Map, List, coord, thresh[THRESH_COORDS]);
	G_message(_("%d vertices added"), ret);
	break;
    case MODE_VERTEX_DELETE:
	ret = Vedit_remove_vertex(&Map, List, coord, thresh[THRESH_COORDS]);
	G_message(_("%d vertices removed"), ret);
	break;
    case MODE_BREAK:
	if (params.coord->answer) {
	    ret = Vedit_split_lines(&Map, List,
				    coord, thresh[THRESH_COORDS], NULL);
	}
	else {
	    ret = Vect_break_lines_list(&Map, List, NULL, GV_LINES, NULL);
	}
	G_message(_("%d lines broken"), ret);
	break;
    case MODE_CONNECT:
	G_verbose_message(_("Threshold value for snapping is %.2f"),
			  thresh[THRESH_SNAP]);
	ret = Vedit_connect_lines(&Map, List, thresh[THRESH_SNAP]);
	G_message(_("%d lines connected"), ret);
	break;
    case MODE_MERGE:
	ret = Vedit_merge_lines(&Map, List);
	G_message(_("%d lines merged"), ret);
	break;
    case MODE_SELECT:
	ret = print_selected(List);
	break;
    case MODE_CATADD:
	ret = Vedit_modify_cats(&Map, List, layer, 0, Clist);
	G_message(_("%d features modified"), ret);
	break;
    case MODE_CATDEL:
	ret = Vedit_modify_cats(&Map, List, layer, 1, Clist);
	G_message(_("%d features modified"), ret);
	break;
    case MODE_COPY:
	if (BgMap && BgMap[0]) {
	    if (nbgmaps > 1)
		G_warning(_("Multiple background maps were given. "
			    "Selected features will be copied only from "
			    "vector map <%s>."),
			  Vect_get_full_name(BgMap[0]));

	    ret = Vedit_copy_lines(&Map, BgMap[0], List);
	}
	else {
	    ret = Vedit_copy_lines(&Map, NULL, List);
	}
	G_message(_("%d features copied"), ret);
	break;
    case MODE_SNAP:
	G_verbose_message(_("Threshold value for snapping is %.2f"),
			  thresh[THRESH_SNAP]);
	ret = snap_lines(&Map, List, thresh[THRESH_SNAP]);
	break;
    case MODE_FLIP:
	ret = Vedit_flip_lines(&Map, List);
	G_message(_("%d lines flipped"), ret);
	break;
    case MODE_NONE:
	break;
    case MODE_ZBULK:{
	    double start, step;
	    double x1, y1, x2, y2;

	    start = atof(params.zbulk->answers[0]);
	    step = atof(params.zbulk->answers[1]);

	    x1 = atof(params.bbox->answers[0]);
	    y1 = atof(params.bbox->answers[1]);
	    x2 = atof(params.bbox->answers[2]);
	    y2 = atof(params.bbox->answers[3]);

	    ret = Vedit_bulk_labeling(&Map, List,
				      x1, y1, x2, y2, start, step);

	    G_message(_("%d lines labeled"), ret);
	    break;
	}
    case MODE_CHTYPE:{
	    ret = Vedit_chtype_lines(&Map, List);

	    if (ret > 0) {
		G_message(_("%d features converted"), ret);
	    }
	    else {
		G_message(_("No feature modified"));
	    }
	    break;
	}
    default:
	G_warning(_("Operation not implemented"));
	ret = -1;
	break;
    }
    
    Vect_hist_command(&Map);

    /* build topology only if requested or if tool!=select */
    if (!(action_mode == MODE_SELECT || params.topo->answer == 1 ||
	 !MODE_NONE)) {
	Vect_build_partial(&Map, GV_BUILD_NONE);
	Vect_build(&Map);
    }

    if (List)
	Vect_destroy_list(List);

    Vect_close(&Map);

    G_debug(1, "Map closed");

    /* close background maps */
    for (i = 0; i < nbgmaps; i++) {
	Vect_close(BgMap[i]);
	G_free((void *)BgMap[i]);
    }
    G_free((void *)BgMap);

    if (coord)
	Vect_destroy_line_struct(coord);

    if (Clist)
	Vect_destroy_cat_list(Clist);

    G_done_msg(" ");

    if (ret > -1) {
	exit(EXIT_SUCCESS);
    }
    else {
	exit(EXIT_FAILURE);
    }
}
コード例 #27
0
ファイル: trans3.c プロジェクト: AsherBond/MondocosmOS
/*!
   \brief transform 3d vector features to 2d (z-coordinate is omitted)

   \param In input vector
   \param Out output vector
   \param type feature type to be transformed
   \param field layer number
   \param zcolumn attribute column where to store height

   \return number of writen features
   \return -1 on error
 */
int trans3d(struct Map_info *In, struct Map_info *Out, int type,
	    const char *field_name, const char *zcolumn)
{
    int ltype, line;
    int ctype;
    int field;
    
    struct line_pnts *Points;
    struct line_cats *Cats;

    struct field_info *Fi;
    dbDriver *driver;
    dbString stmt;
    char buf[2000];
    int ncats, *cats, cat, *cex;

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

    db_init_string(&stmt);

    field = Vect_get_field_number(In, field_name);

    if (zcolumn) {
	Fi = Vect_get_field(Out, field);
	if (!Fi) {
	    G_warning(_("Database connection not defined for layer <%s>"),
		      field_name);
	    return -1;
	}

	driver = db_start_driver_open_database(Fi->driver, Fi->database);
	if (!driver) {
	    G_warning(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
	    return -1;
	}

	/* column type must numeric */
	ctype = db_column_Ctype(driver, Fi->table, zcolumn);
	if (ctype == -1) {
	    G_warning(_("Column <%s> not found in table <%s>"),
		      zcolumn, Fi->table);
	    return -1;
	}
	if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) {
	    G_warning(_("Column must be numeric"));
	    return -1;
	}

	db_begin_transaction(driver);

	/* select existing categories (layer) to array (array is sorted) */
	ncats = db_select_int(driver, Fi->table, Fi->key, NULL, &cats);
	G_debug(3, "Existing categories: %d", ncats);
    }

    line = 1;
    while (1) {
	ltype = Vect_read_next_line(In, Points, Cats);
	if (ltype == -1) {
	    G_warning(_("Unable to read vector map"));
	    return -1;
	}
	if (ltype == -2) {	/* EOF */
	    break;
	}

	if (G_verbose() > G_verbose_min() && (line - 1) % 1000 == 0) {
	    fprintf(stderr, "%7d\b\b\b\b\b\b\b", (line - 1));
	}

	if (!(ltype & type))
	    continue;

	if (field != -1 && !Vect_cat_get(Cats, field, &cat))
	    continue;

	/* get first cat */
	if (cat == -1) {
	    G_warning(_("Feature id %d has no category - skipping"), line);
	}
	else if (Cats->n_cats > 1) {
	    G_warning(_("Feature id %d has more categories. "
			"Using category %d."), line, field, cat);
	}

	if (zcolumn && ltype == GV_POINT && cat > -1) {
	    /* category exist in table ? */
	    cex = (int *)bsearch((void *)&cat, cats, ncats, sizeof(int),
				 srch);

	    /* store height to the attribute table */
	    if (ctype == DB_C_TYPE_INT)
		sprintf(buf, "update %s set %s = %d where cat = %d",
			Fi->table, zcolumn, (int)Points->z[0], cat);
	    else		/* double */
		sprintf(buf, "update %s set %s = %.8f where cat = %d",
			Fi->table, zcolumn, Points->z[0], cat);

	    G_debug(3, "SQL: %s", buf);
	    db_set_string(&stmt, buf);

	    if (cex) {
		if (db_execute_immediate(driver, &stmt) == DB_OK) {
		    /* TODO */
		}
	    }
	    else {		/* cat does not exist in table */
		G_warning(_("Record (cat %d) does not exist (not updated)"),
			  cat);
	    }
	}

	Vect_write_line(Out, ltype, Points, Cats);
	line++;
    }

    if (G_verbose() > G_verbose_min())
	fprintf(stderr, "\r");

    if (zcolumn) {
	db_commit_transaction(driver);

	G_free(cats);

	db_close_database_shutdown_driver(driver);
	db_free_string(&stmt);
    }

    Vect_destroy_line_struct(Points);
    Vect_destroy_cats_struct(Cats);

    return line - 1;
}
コード例 #28
0
ファイル: main.c プロジェクト: caomw/grass
int main(int argc, char **argv)
{
    int i, j, ret, centre, line, centre1, centre2, tfield, tucfield;
    int nlines, nnodes, type, ltype, afield, nfield, geo, cat;
    int node, node1, node2;
    double cost, e1cost, e2cost, n1cost, n2cost, s1cost, s2cost, l, l1;
    struct Option *map, *output;
    struct Option *afield_opt, *nfield_opt, *afcol, *abcol, *ncol, *type_opt,
	*term_opt, *cost_opt, *tfield_opt, *tucfield_opt;
    struct Flag *geo_f, *turntable_f;
    struct GModule *module;
    struct Map_info Map, Out;
    struct cat_list *catlist;
    CENTER *Centers = NULL;
    int acentres = 0, ncentres = 0;
    NODE *Nodes;
    struct line_cats *Cats;
    struct line_pnts *Points, *SPoints;
    int niso, aiso;
    double *iso;
    int npnts1, apnts1 = 0, npnts2, apnts2 = 0;
    ISOPOINT *pnts1 = NULL, *pnts2 = NULL;
    int next_iso;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("isolines"));
    module->label = _("Splits net by cost isolines.");
    module->description =
	_
	("Splits net to bands between cost isolines (direction from center). "
	 "Center node must be opened (costs >= 0). "
	 "Costs of center node are used in calculation.");

    map = G_define_standard_option(G_OPT_V_INPUT);
    output = G_define_standard_option(G_OPT_V_OUTPUT);

    term_opt = G_define_standard_option(G_OPT_V_CATS);
    term_opt->key = "ccats";
    term_opt->required = YES;
    term_opt->description =
	_("Categories of centers (points on nodes) to which net "
	  "will be allocated, "
	  "layer for this categories is given by nlayer option");

    cost_opt = G_define_option();
    cost_opt->key = "costs";
    cost_opt->type = TYPE_INTEGER;
    cost_opt->multiple = YES;
    cost_opt->required = YES;
    cost_opt->description = _("Costs for isolines");

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "alayer";
    afield_opt->answer = "1";
    afield_opt->required = YES;
    afield_opt->label = _("Arc layer");

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "line,boundary";
    type_opt->answer = "line,boundary";
    type_opt->required = YES;
    type_opt->label = _("Arc type");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "nlayer";
    nfield_opt->answer = "2";
    nfield_opt->required = YES;
    nfield_opt->label = _("Node layer");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "afcolumn";
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "abcolumn";
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "ncolumn";
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    turntable_f = G_define_flag();
    turntable_f->key = 't';
    turntable_f->description = _("Use turntable");
    turntable_f->guisection = _("Turntable");

    tfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tfield_opt->key = "tlayer";
    tfield_opt->answer = "3";
    tfield_opt->label = _("Layer with turntable");
    tfield_opt->description =
	_("Relevant only with -t flag");
    tfield_opt->guisection = _("Turntable");

    tucfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    tucfield_opt->key = "tuclayer";
    tucfield_opt->answer = "4";
    tucfield_opt->label = _("Layer with unique categories used in turntable");
    tucfield_opt->description =
	_("Relevant only with -t flag");
    tucfield_opt->guisection = _("Turntable");

    geo_f = G_define_flag();
    geo_f->key = 'g';
    geo_f->description =
	_("Use geodesic calculation for longitude-latitude locations");

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

    Vect_check_input_output_name(map->answer, output->answer, G_FATAL_EXIT);

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

    type = Vect_option_to_types(type_opt);

    catlist = Vect_new_cat_list();
    Vect_str_to_cat_list(term_opt->answer, catlist);

    /* Iso costs */
    aiso = 1;
    iso = (double *)G_malloc(aiso * sizeof(double));
    /* Set first iso to 0 */
    iso[0] = 0;
    niso = 1;
    i = 0;
    while (cost_opt->answers[i]) {
	if (niso == aiso) {
	    aiso += 1;
	    iso = (double *)G_realloc(iso, aiso * sizeof(double));
	}
	iso[niso] = atof(cost_opt->answers[i]);
	if (iso[niso] <= 0)
	    G_fatal_error(_("Wrong iso cost: %f"), iso[niso]);

	if (iso[niso] <= iso[niso - 1])
	    G_fatal_error(_("Iso cost: %f less than previous"), iso[niso]);

	G_verbose_message(_("Iso cost %d: %f"), niso, iso[niso]);
	niso++;
	i++;
    }

    /* Should not happen: */
    if (niso < 2)
	G_warning(_
		  ("Not enough costs, everything reachable falls to first band"));

    if (geo_f->answer)
	geo = 1;
    else
	geo = 0;

    Vect_set_open_level(2);
    if (Vect_open_old(&Map, map->answer, "") < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), map->answer);

    afield = Vect_get_field_number(&Map, afield_opt->answer);
    nfield = Vect_get_field_number(&Map, nfield_opt->answer);
    tfield = Vect_get_field_number(&Map, tfield_opt->answer);
    tucfield = Vect_get_field_number(&Map, tucfield_opt->answer);

    /* Build graph */
    if (turntable_f->answer)
	Vect_net_ttb_build_graph(&Map, type, afield, nfield, tfield, tucfield,
				 afcol->answer, abcol->answer, ncol->answer,
				 geo, 0);
    else
	Vect_net_build_graph(&Map, type, afield, nfield, afcol->answer,
			     abcol->answer, ncol->answer, geo, 0);

    nnodes = Vect_get_num_nodes(&Map);
    nlines = Vect_get_num_lines(&Map);

    /* Create list of centres based on list of categories */
    for (i = 1; i <= nlines; i++) {
	ltype = Vect_get_line_type(&Map, i);
	if (!(ltype & GV_POINT))
	    continue;

	Vect_read_line(&Map, Points, Cats, i);
	node =
	    Vect_find_node(&Map, Points->x[0], Points->y[0], Points->z[0], 0,
			   0);
	if (!node) {
	    G_warning(_("Point is not connected to the network"));
	    continue;
	}
	if (!(Vect_cat_get(Cats, nfield, &cat)))
	    continue;
	if (Vect_cat_in_cat_list(cat, catlist)) {
	    Vect_net_get_node_cost(&Map, node, &n1cost);
	    if (n1cost == -1) {	/* closed */
		G_warning(_("Centre at closed node (costs = -1) ignored"));
	    }
	    else {
		if (acentres == ncentres) {
		    acentres += 1;
		    Centers =
			(CENTER *) G_realloc(Centers,
					     acentres * sizeof(CENTER));
		}
		Centers[ncentres].cat = cat;
		Centers[ncentres].node = node;
		G_debug(2, "centre = %d node = %d cat = %d", ncentres,
			node, cat);
		ncentres++;
	    }
	}
    }

    G_message(_("Number of centres: %d (nlayer %d)"), ncentres, nfield);

    if (ncentres == 0)
	G_warning(_
		  ("Not enough centres for selected nlayer. Nothing will be allocated."));

    /* alloc and reset space for all nodes */
    if (turntable_f->answer) {
	/* if turntable is used we are looking for lines as destinations, instead of the intersections (nodes) */
	Nodes = (NODE *) G_calloc((nlines * 2 + 2), sizeof(NODE));
	for (i = 2; i <= (nlines * 2 + 2); i++) {
	    Nodes[i].centre = -1;/* NOTE: first two items of Nodes are not used */
	}

    }
    else {
	Nodes = (NODE *) G_calloc((nnodes + 1), sizeof(NODE));
	for (i = 1; i <= nnodes; i++) {
	    Nodes[i].centre = -1;
	}
    }

    apnts1 = 1;
    pnts1 = (ISOPOINT *) G_malloc(apnts1 * sizeof(ISOPOINT));

    apnts2 = 1;
    pnts2 = (ISOPOINT *) G_malloc(apnts2 * sizeof(ISOPOINT));

    /* Fill Nodes by neares centre and costs from that centre */
    for (centre = 0; centre < ncentres; centre++) {
	node1 = Centers[centre].node;
	Vect_net_get_node_cost(&Map, node1, &n1cost);
	G_debug(2, "centre = %d node = %d cat = %d", centre, node1,
		Centers[centre].cat);
	G_message(_("Calculating costs from centre %d..."), centre + 1);
	if (turntable_f->answer)
	    for (line = 1; line <= nlines; line++) {
		G_debug(5, "  node1 = %d line = %d", node1, line);
		Vect_net_get_node_cost(&Map, line, &n2cost);
		/* closed, left it as not attached */

		if (Vect_read_line(&Map, Points, Cats, line) < 0)
		    continue;
		if (Vect_get_line_type(&Map, line) != GV_LINE)
		    continue;
		if (!Vect_cat_get(Cats, tucfield, &cat))
		    continue;

		for (j = 0; j < 2; j++) {
		    if (j == 1)
			cat *= -1;

		    ret =
			Vect_net_ttb_shortest_path(&Map, node1, 0, cat, 1,
						   tucfield, NULL,
						   &cost);
		    if (ret == -1) {
			continue;
		    }		/* node unreachable */

		    /* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but
	             *  only if centre and node are not identical, because at the end node cost is add later */
		    if (ret != 1)
			cost += n1cost;

		    G_debug(5,
			    "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
			    node1, line, cost, Nodes[line * 2 + j].centre,
			    Nodes[line * 2 + j].cost);
		    if (Nodes[line * 2 + j].centre == -1 ||
			cost < Nodes[line * 2 + j].cost) {
			Nodes[line * 2 + j].cost = cost;
			Nodes[line * 2 + j].centre = centre;
		    }
		}
	    }
	else
	    for (node2 = 1; node2 <= nnodes; node2++) {
		G_percent(node2, nnodes, 1);
		G_debug(5, "  node1 = %d node2 = %d", node1, node2);
		Vect_net_get_node_cost(&Map, node2, &n2cost);
		if (n2cost == -1) {
		    continue;
		}		/* closed, left it as not attached */

		ret = Vect_net_shortest_path(&Map, node1, node2, NULL, &cost);
		if (ret == -1) {
		    continue;
		}		/* node unreachable */

		/* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but
		 *  only if centre and node are not identical, because at the end node cost is add later */
		if (node1 != node2)
		    cost += n1cost;
		G_debug(5,
			"Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
			node1, node2, cost, Nodes[node2].centre,
			Nodes[node2].cost);
		if (Nodes[node2].centre == -1 || cost < Nodes[node2].cost) {
		    Nodes[node2].cost = cost;
		    Nodes[node2].centre = centre;
		}
	    }
    }

    /* Write arcs to new map */
    if (Vect_open_new(&Out, output->answer, Vect_is_3d(&Map)) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), output->answer);

    Vect_hist_command(&Out);

    G_message("Generating isolines...");
    nlines = Vect_get_num_lines(&Map);
    for (line = 1; line <= nlines; line++) {
	G_percent(line, nlines, 2);

	ltype = Vect_read_line(&Map, Points, NULL, line);
	if (!(ltype & type)) {
	    continue;
	}

	l = Vect_line_length(Points);
	if (l == 0)
	    continue;

	if (turntable_f->answer) {
	    centre1 = Nodes[line * 2].centre;
	    centre2 = Nodes[line * 2 + 1].centre;
	    s1cost = Nodes[line * 2].cost;
	    s2cost = Nodes[line * 2 + 1].cost;
	    n1cost = n2cost = 0;
	}
	else {
	    Vect_get_line_nodes(&Map, line, &node1, &node2);
	    centre1 = Nodes[node1].centre;
	    centre2 = Nodes[node2].centre;
	    s1cost = Nodes[node1].cost;
	    s2cost = Nodes[node2].cost;

	    Vect_net_get_node_cost(&Map, node1, &n1cost);
	    Vect_net_get_node_cost(&Map, node2, &n2cost);

	}

	Vect_net_get_line_cost(&Map, line, GV_FORWARD, &e1cost);
	Vect_net_get_line_cost(&Map, line, GV_BACKWARD, &e2cost);

	G_debug(3, "Line %d : length = %f", line, l);
	G_debug(3, "Arc centres: %d %d (nodes: %d %d)", centre1, centre2,
		node1, node2);

	G_debug(3, "  s1cost = %f n1cost = %f e1cost = %f", s1cost, n1cost,
		e1cost);
	G_debug(3, "  s2cost = %f n2cost = %f e2cost = %f", s2cost, n2cost,
		e2cost);


	/* First check if arc is reachable from at least one side */
	if ((centre1 != -1 && n1cost != -1 && e1cost != -1) ||
	    (centre2 != -1 && n2cost != -1 && e2cost != -1)) {
	    /* Line is reachable at least from one side */
	    G_debug(3, "  -> arc is reachable");

	    /* Add costs of node to starting costs */
	    s1cost += n1cost;
	    s2cost += n2cost;

	    e1cost /= l;
	    e2cost /= l;

	    /* Find points on isolines along the line in both directions, add them to array,
	     *  first point is placed at the beginning/end of line */
	    /* Forward */
	    npnts1 = 0;		/* in case this direction is closed */
	    if (centre1 != -1 && n1cost != -1 && e1cost != -1) {
		/* Find iso for beginning of the line */
		next_iso = 0;
		for (i = niso - 1; i >= 0; i--) {
		    if (iso[i] <= s1cost) {
			next_iso = i;
			break;
		    }
		}
		/* Add first */
		pnts1[0].iso = next_iso;
		pnts1[0].distance = 0;
		npnts1++;
		next_iso++;

		/* Calculate distances for points along line */
		while (next_iso < niso) {
		    if (e1cost == 0)
			break;	/* Outside line */
		    l1 = (iso[next_iso] - s1cost) / e1cost;
		    if (l1 >= l)
			break;	/* Outside line */

		    if (npnts1 == apnts1) {
			apnts1 += 1;
			pnts1 =
			    (ISOPOINT *) G_realloc(pnts1,
						   apnts1 * sizeof(ISOPOINT));
		    }
		    pnts1[npnts1].iso = next_iso;
		    pnts1[npnts1].distance = l1;
		    G_debug(3,
			    "  forward %d : iso %d : distance %f : cost %f",
			    npnts1, next_iso, l1, iso[next_iso]);
		    npnts1++;
		    next_iso++;
		}
	    }
	    G_debug(3, "  npnts1 = %d", npnts1);

	    /* Backward */
	    npnts2 = 0;
	    if (centre2 != -1 && n2cost != -1 && e2cost != -1) {
		/* Find iso for beginning of the line */
		next_iso = 0;
		for (i = niso - 1; i >= 0; i--) {
		    if (iso[i] <= s2cost) {
			next_iso = i;
			break;
		    }
		}
		/* Add first */
		pnts2[0].iso = next_iso;
		pnts2[0].distance = l;
		npnts2++;
		next_iso++;

		/* Calculate distances for points along line */
		while (next_iso < niso) {
		    if (e2cost == 0)
			break;	/* Outside line */
		    l1 = (iso[next_iso] - s2cost) / e2cost;
		    if (l1 >= l)
			break;	/* Outside line */

		    if (npnts2 == apnts2) {
			apnts2 += 1;
			pnts2 =
			    (ISOPOINT *) G_realloc(pnts2,
						   apnts2 * sizeof(ISOPOINT));
		    }
		    pnts2[npnts2].iso = next_iso;
		    pnts2[npnts2].distance = l - l1;
		    G_debug(3,
			    "  backward %d : iso %d : distance %f : cost %f",
			    npnts2, next_iso, l - l1, iso[next_iso]);
		    npnts2++;
		    next_iso++;
		}
	    }
	    G_debug(3, "  npnts2 = %d", npnts2);

	    /* Limit number of points by maximum costs in reverse direction, this may remove
	     *  also the first point in one direction, but not in both */
	    /* Forward */
	    if (npnts2 > 0) {
		for (i = 0; i < npnts1; i++) {
		    G_debug(3,
			    "  pnt1 = %d dist1 = %f iso1 = %d max iso2 = %d",
			    i, pnts1[i].distance, pnts1[i].iso,
			    pnts2[npnts2 - 1].iso);
		    if (pnts2[npnts2 - 1].iso < pnts1[i].iso) {
			G_debug(3, "    -> cut here");
			npnts1 = i;
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts1 cut = %d", npnts1);

	    /* Backward */
	    if (npnts1 > 0) {
		for (i = 0; i < npnts2; i++) {
		    G_debug(3,
			    "  pnt2 = %d dist2 = %f iso2 = %d max iso1 = %d",
			    i, pnts2[i].distance, pnts2[i].iso,
			    pnts1[npnts1 - 1].iso);
		    if (pnts1[npnts1 - 1].iso < pnts2[i].iso) {
			G_debug(3, "    -> cut here");
			npnts2 = i;
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts2 cut = %d", npnts2);

	    /* Biggest cost shoud be equal if exist (npnts > 0). Cut out overlapping segments,
	     *  this can cut only points on line but not first points */
	    if (npnts1 > 1 && npnts2 > 1) {
		while (npnts1 > 1 && npnts2 > 1) {
		    if (pnts1[npnts1 - 1].distance >= pnts2[npnts2 - 1].distance) {	/* overlap */
			npnts1--;
			npnts2--;
		    }
		    else {
			break;
		    }
		}
	    }
	    G_debug(3, "  npnts1 2. cut = %d", npnts1);
	    G_debug(3, "  npnts2 2. cut = %d", npnts2);

	    /* Now we have points in both directions which may not overlap, npoints in one
	     *  direction may be 0 but not both */

	    /* Join both arrays, iso of point is for next segment (point is at the beginning) */
	    /* In case npnts1 == 0 add point at distance 0 */
	    if (npnts1 == 0) {
		G_debug(3,
			"  npnts1 = 0 -> add first at distance 0, cat = %d",
			pnts2[npnts2 - 1].iso);
		pnts1[0].iso = pnts2[npnts2 - 1].iso;	/* use last point iso in reverse direction */
		pnts1[0].distance = 0;
		npnts1++;
	    }
	    for (i = npnts2 - 1; i >= 0; i--) {
		/* Check if identical */
		if (pnts1[npnts1 - 1].distance == pnts2[i].distance)
		    continue;

		if (npnts1 == apnts1) {
		    apnts1 += 1;
		    pnts1 =
			(ISOPOINT *) G_realloc(pnts1,
					       apnts1 * sizeof(ISOPOINT));
		}
		pnts1[npnts1].iso = pnts2[i].iso - 1;	/* last may be -1, but it is not used */
		pnts1[npnts1].distance = pnts2[i].distance;
		npnts1++;
	    }
	    /* In case npnts2 == 0 add point at the end */
	    if (npnts2 == 0) {
		pnts1[npnts1].iso = 0;	/* not used */
		pnts1[npnts1].distance = l;
		npnts1++;
	    }

	    /* Create line segments. */
	    for (i = 1; i < npnts1; i++) {
		cat = pnts1[i - 1].iso + 1;
		G_debug(3, "  segment %f - %f cat %d", pnts1[i - 1].distance,
			pnts1[i].distance, cat);
		ret =
		    Vect_line_segment(Points, pnts1[i - 1].distance,
				      pnts1[i].distance, SPoints);
		if (ret == 0) {
		    G_warning(_
			      ("Cannot get line segment, segment out of line"));
		}
		else {
		    Vect_reset_cats(Cats);
		    Vect_cat_set(Cats, 1, cat);
		    Vect_write_line(&Out, ltype, SPoints, Cats);
		}
	    }
	}
	else {
	    /* arc is not reachable */
	    G_debug(3, "  -> arc is not reachable");
	    Vect_reset_cats(Cats);
	    Vect_write_line(&Out, ltype, Points, Cats);
	}
    }

    Vect_build(&Out);

    /* Free, ... */
    G_free(Nodes);
    G_free(Centers);
    Vect_close(&Map);
    Vect_close(&Out);

    exit(EXIT_SUCCESS);
}
コード例 #29
0
ファイル: main.c プロジェクト: AsherBond/MondocosmOS
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *map_opt, *type_opt, *field_opt, *col_opt, *where_opt,
	*percentile;
    struct Flag *shell_flag, *extended;
    struct Map_info Map;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray Cvarr;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int otype, ofield;
    int compatible = 1;		/* types are compatible: point+centroid or line+boundary or area */
    int nrec, ctype, nlines, line, nareas, area;
    int nmissing = 0;		/* number of missing atttributes */
    int nnull = 0;		/* number of null values */
    int first = 1;

    /* Statistics */
    int count = 0;		/* number of features with non-null attribute */
    double sum = 0.0;
    double sumsq = 0.0;
    double sumcb = 0.0;
    double sumqt = 0.0;
    double sum_abs = 0.0;
    double min = 0.0 / 0.0;	/* init as nan */
    double max = 0.0 / 0.0;
    double mean, mean_abs, pop_variance, sample_variance, pop_stdev,
	sample_stdev, pop_coeff_variation, kurtosis, skewness;
    double total_size = 0.0;	/* total size: length/area */

    /* Extended statistics */
    int perc;

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    module->label =
	_("Calculates univariate statistics for attribute.");
    module->description = _("Variance and standard "
			    "deviation is calculated only for points if specified.");

    map_opt = G_define_standard_option(G_OPT_V_MAP);

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    type_opt = G_define_standard_option(G_OPT_V_TYPE);
    type_opt->options = "point,line,boundary,centroid,area";

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = YES;

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    percentile = G_define_option();
    percentile->key = "percentile";
    percentile->type = TYPE_INTEGER;
    percentile->required = NO;
    percentile->options = "0-100";
    percentile->answer = "90";
    percentile->description =
	_("Percentile to calculate (requires extended statistics flag)");

    shell_flag = G_define_flag();
    shell_flag->key = 'g';
    shell_flag->description = _("Print the stats in shell script style");

    extended = G_define_flag();
    extended->key = 'e';
    extended->description = _("Calculate extended statistics");

    G_gisinit(argv[0]);

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

    otype = Vect_option_to_types(type_opt);
    perc = atoi(percentile->answer);

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

    /* open input vector */
    Vect_set_open_level(2);
    Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer);
    ofield = Vect_get_field_number(&Map, field_opt->answer);

    /* Check if types are compatible */
    if ((otype & GV_POINTS) && ((otype & GV_LINES) || (otype & GV_AREA)))
	compatible = 0;
    if ((otype & GV_LINES) && (otype & GV_AREA))
	compatible = 0;

    if (!compatible) {
	G_warning(_("Incompatible vector type(s) specified, only number of features, minimum, maximum and range "
		   "can be calculated"));
    }

    if (extended->answer && !(otype & GV_POINTS)) {
	G_warning(_("Extended statistics is currently supported only for points/centroids"));
    }

    /* Read attributes */
    db_CatValArray_init(&Cvarr);
    Fi = Vect_get_field(&Map, ofield);
    if (Fi == NULL) {
	G_fatal_error(_(" Database connection not defined for layer <%s>"), field_opt->answer);
    }

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

    /* Note do not check if the column exists in the table because it may be an expression */

    nrec =
	db_select_CatValArray(Driver, Fi->table, Fi->key, col_opt->answer,
			      where_opt->answer, &Cvarr);
    G_debug(2, "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"));

    db_close_database_shutdown_driver(Driver);

    /* Lines */
    nlines = Vect_get_num_lines(&Map);

    for (line = 1; line <= nlines; line++) {
	int i, type;

	G_debug(3, "line = %d", line);

	type = Vect_read_line(&Map, Points, Cats, line);
	if (!(type & otype))
	    continue;

	for (i = 0; i < Cats->n_cats; i++) {
	    if (Cats->field[i] == ofield) {
		double val;
		dbCatVal *catval;

		G_debug(3, "cat = %d", Cats->cat[i]);

		if (db_CatValArray_get_value(&Cvarr, Cats->cat[i], &catval) !=
		    DB_OK) {
		    G_debug(3, "No record for cat = %d", Cats->cat[i]);
		    nmissing++;
		    continue;
		}

		if (catval->isNull) {
		    G_debug(3, "NULL value for cat = %d", Cats->cat[i]);
		    nnull++;
		    continue;
		}

		if (ctype == DB_C_TYPE_INT) {
		    val = catval->val.i;
		}
		else if (ctype == DB_C_TYPE_DOUBLE) {
		    val = catval->val.d;
		}

		count++;

		if (first) {
		    max = val;
		    min = val;
		    first = 0;
		}
		else {
		    if (val > max)
			max = val;
		    if (val < min)
			min = val;
		}

		if (compatible) {
		    if (type & GV_POINTS) {
			sum += val;
			sumsq += val * val;
			sumcb += val * val * val;
			sumqt += val * val * val * val;
			sum_abs += fabs(val);
		    }
		    else {	/* GV_LINES */
			double l;

			l = Vect_line_length(Points);
			sum += l * val;
			sumsq += l * val * val;
			sumcb += l * val * val * val;
			sumqt += l * val * val * val * val;
			sum_abs += l * fabs(val);
			total_size += l;
		    }
		}
		G_debug(3, "sum = %f total_size = %f", sum, total_size);
	    }
	}
    }

    if (otype & GV_AREA) {
	nareas = Vect_get_num_areas(&Map);
	for (area = 1; area <= nareas; area++) {
	    int i, centr;

	    G_debug(3, "area = %d", area);

	    centr = Vect_get_area_centroid(&Map, area);
	    if (centr < 1)
		continue;

	    G_debug(3, "centr = %d", centr);
	    Vect_read_line(&Map, NULL, Cats, centr);

	    for (i = 0; i < Cats->n_cats; i++) {
		if (Cats->field[i] == ofield) {
		    double val;
		    dbCatVal *catval;

		    G_debug(3, "cat = %d", Cats->cat[i]);

		    if (db_CatValArray_get_value
			(&Cvarr, Cats->cat[i], &catval) != DB_OK) {
			G_debug(3, "No record for cat = %d", Cats->cat[i]);
			nmissing++;
			continue;
		    }

		    if (catval->isNull) {
			G_debug(3, "NULL value for cat = %d", Cats->cat[i]);
			nnull++;
			continue;
		    }

		    if (ctype == DB_C_TYPE_INT) {
			val = catval->val.i;
		    }
		    else if (ctype == DB_C_TYPE_DOUBLE) {
			val = catval->val.d;
		    }

		    count++;

		    if (first) {
			max = val;
			min = val;
			first = 0;
		    }
		    else {
			if (val > max)
			    max = val;
			if (val < min)
			    min = val;
		    }

		    if (compatible) {
			double a;

			a = Vect_get_area_area(&Map, area);
			sum += a * val;
			sumsq += a * val * val;
			sumcb += a * val * val * val;
			sumqt += a * val * val * val * val;
			sum_abs += a * fabs(val);
			total_size += a;
		    }
		    G_debug(4, "sum = %f total_size = %f", sum, total_size);
		}
	    }
	}
    }

    G_debug(2, "sum = %f total_size = %f", sum, total_size);

    if (compatible) {
	if ((otype & GV_LINES) || (otype & GV_AREA)) {
	    mean = sum / total_size;
	    mean_abs = sum_abs / total_size;
	    /* Roger Bivand says it is wrong see GRASS devel list 7/2004 */
	    /*
	       pop_variance = (sumsq - sum*sum/total_size)/total_size;
	       pop_stdev = sqrt(pop_variance);
	     */
	}
	else {
	    double n = count;

	    mean = sum / count;
	    mean_abs = sum_abs / count;
	    pop_variance = (sumsq - sum * sum / count) / count;
	    pop_stdev = sqrt(pop_variance);
	    pop_coeff_variation = pop_stdev / (sqrt(sum * sum) / count);
	    sample_variance = (sumsq - sum * sum / count) / (count - 1);
	    sample_stdev = sqrt(sample_variance);
	    kurtosis =
		(sumqt / count - 4 * sum * sumcb / (n * n) +
		 6 * sum * sum * sumsq / (n * n * n) -
		 3 * sum * sum * sum * sum / (n * n * n * n))
		/ (sample_stdev * sample_stdev * sample_stdev *
		   sample_stdev) - 3;
	    skewness =
		(sumcb / n - 3 * sum * sumsq / (n * n) +
		 2 * sum * sum * sum / (n * n * n))
		/ (sample_stdev * sample_stdev * sample_stdev);
	}
    }

    G_debug(3, "otype %d:", otype);

    if (shell_flag->answer) {
	fprintf(stdout, "n=%d\n", count);
	fprintf(stdout, "nmissing=%d\n", nmissing);
	fprintf(stdout, "nnull=%d\n", nnull);
	if (count > 0) {
	    fprintf(stdout, "min=%g\n", min);
	    fprintf(stdout, "max=%g\n", max);
	    fprintf(stdout, "range=%g\n", max - min);
	    if (compatible && (otype & GV_POINTS)) {
		fprintf(stdout, "mean=%g\n", mean);
		fprintf(stdout, "mean_abs=%g\n", mean_abs);
		fprintf(stdout, "population_stddev=%g\n", pop_stdev);
		fprintf(stdout, "population_variance=%g\n", pop_variance);
		fprintf(stdout, "population_coeff_variation=%g\n",
			pop_coeff_variation);
		if (otype & GV_POINTS) {
		    fprintf(stdout, "sample_stddev=%g\n", sample_stdev);
		    fprintf(stdout, "sample_variance=%g\n", sample_variance);
		    fprintf(stdout, "kurtosis=%g\n", kurtosis);
		    fprintf(stdout, "skewness=%g\n", skewness);
		}
	    }
	}
    }
    else {
	fprintf(stdout, "number of features with non NULL attribute: %d\n",
		count);
	fprintf(stdout, "number of missing attributes: %d\n", nmissing);
	fprintf(stdout, "number of NULL attributes: %d\n", nnull);
	if (count > 0) {
	    fprintf(stdout, "minimum: %g\n", min);
	    fprintf(stdout, "maximum: %g\n", max);
	    fprintf(stdout, "range: %g\n", max - min);
	    if (compatible && (otype & GV_POINTS)) {
		fprintf(stdout, "mean: %g\n", mean);
		fprintf(stdout, "mean of absolute values: %g\n", mean_abs);
		fprintf(stdout, "population standard deviation: %g\n",
			pop_stdev);
		fprintf(stdout, "population variance: %g\n", pop_variance);
		fprintf(stdout, "population coefficient of variation: %g\n",
			pop_coeff_variation);
		if (otype & GV_POINTS) {
		    fprintf(stdout, "sample standard deviation: %g\n",
			    sample_stdev);
		    fprintf(stdout, "sample variance: %g\n", sample_variance);
		    fprintf(stdout, "kurtosis: %g\n", kurtosis);
		    fprintf(stdout, "skewness: %g\n", skewness);
		}
	    }
	}
    }

    /* TODO: mode, skewness, kurtosis */
    if (extended->answer && compatible && (otype & GV_POINTS) && count > 0) {
	double quartile_25 = 0.0, quartile_75 = 0.0, quartile_perc = 0.0;
	double median = 0.0;
	int qpos_25, qpos_75, qpos_perc;

	qpos_25 = (int)(count * 0.25 - 0.5);
	qpos_75 = (int)(count * 0.75 - 0.5);
	qpos_perc = (int)(count * perc / 100. - 0.5);

	if (db_CatValArray_sort_by_value(&Cvarr) != DB_OK)
	    G_fatal_error(_("Cannot sort the key/value array"));

	if (Cvarr.ctype == DB_C_TYPE_INT) {
	    quartile_25 = (Cvarr.value[qpos_25]).val.i;
	    if (count % 2)	/* odd */
		median = (Cvarr.value[(int)(count / 2)]).val.i;
	    else		/* even */
		median =
		    ((Cvarr.value[count / 2 - 1]).val.i +
		     (Cvarr.value[count / 2]).val.i) / 2.0;
	    quartile_75 = (Cvarr.value[qpos_75]).val.i;
	    quartile_perc = (Cvarr.value[qpos_perc]).val.i;
	}
	else {			/* must be DB_C_TYPE_DOUBLE */
	    quartile_25 = (Cvarr.value[qpos_25]).val.d;
	    if (count % 2)	/* odd */
		median = (Cvarr.value[(int)(count / 2)]).val.d;
	    else		/* even */
		median =
		    ((Cvarr.value[count / 2 - 1]).val.d +
		     (Cvarr.value[count / 2]).val.d) / 2.0;
	    quartile_75 = (Cvarr.value[qpos_75]).val.d;
	    quartile_perc = (Cvarr.value[qpos_perc]).val.d;
	}

	if (shell_flag->answer) {
	    fprintf(stdout, "first_quartile=%g\n", quartile_25);
	    fprintf(stdout, "median=%g\n", median);
	    fprintf(stdout, "third_quartile=%g\n", quartile_75);
	    fprintf(stdout, "percentile_%d=%g\n", perc, quartile_perc);
	}
	else {
	    fprintf(stdout, "1st quartile: %g\n", quartile_25);
	    if (count % 2)
		fprintf(stdout, "median (odd number of cells): %g\n", median);
	    else
		fprintf(stdout, "median (even number of cells): %g\n",
			median);
	    fprintf(stdout, "3rd quartile: %g\n", quartile_75);

	    if (perc % 10 == 1 && perc != 11)
		fprintf(stdout, "%dst percentile: %g\n", perc, quartile_perc);
	    else if (perc % 10 == 2 && perc != 12)
		fprintf(stdout, "%dnd percentile: %g\n", perc, quartile_perc);
	    else if (perc % 10 == 3 && perc != 13)
		fprintf(stdout, "%drd percentile: %g\n", perc, quartile_perc);
	    else
		fprintf(stdout, "%dth percentile: %g\n", perc, quartile_perc);
	}
    }

    Vect_close(&Map);

    exit(EXIT_SUCCESS);
}
コード例 #30
0
ファイル: main.c プロジェクト: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    struct Map_info In, Out, cut_map;
    static struct line_pnts *Points;
    struct line_cats *Cats;
    struct GModule *module;	/* GRASS module for parsing arguments */
    struct Option *map_in, *map_out, *cut_out;
    struct Option *afield_opt, *nfield_opt, *abcol, *afcol, *ncol;
    struct Option *catsource_opt, *wheresource_opt;
    struct Option *catsink_opt, *wheresink_opt;
    int with_z;
    int afield, nfield, mask_type;
    struct varray *varray_source, *varray_sink;
    dglGraph_s *graph;
    int i, nlines, *flow, total_flow;
    struct ilist *source_list, *sink_list, *cut;
    int find_cut;

    char buf[2000];

    /* Attribute table */
    dbString sql;
    dbDriver *driver;
    struct field_info *Fi;

    /* initialize GIS environment */
    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */

    /* initialize module */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("network"));
    G_add_keyword(_("flow"));
    module->description =
	_("Computes the maximum flow between two sets of nodes in the network.");

    /* Define the different options as defined in gis.h */
    map_in = G_define_standard_option(G_OPT_V_INPUT);

    afield_opt = G_define_standard_option(G_OPT_V_FIELD);
    afield_opt->key = "arc_layer";
    afield_opt->answer = "1";
    afield_opt->label = _("Arc layer");
    afield_opt->guisection = _("Cost");

    nfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    nfield_opt->key = "node_layer";
    nfield_opt->answer = "2";
    nfield_opt->label = _("Node layer");
    nfield_opt->guisection = _("Cost");

    map_out = G_define_standard_option(G_OPT_V_OUTPUT);

    cut_out = G_define_standard_option(G_OPT_V_OUTPUT);
    cut_out->key = "cut";
    cut_out->description =
	_("Name for output vector map containing a minimum cut");

    afcol = G_define_standard_option(G_OPT_DB_COLUMN);
    afcol->key = "arc_column";
    afcol->required = NO;
    afcol->description =
	_("Arc forward/both direction(s) cost column (number)");
    afcol->guisection = _("Cost");

    abcol = G_define_standard_option(G_OPT_DB_COLUMN);
    abcol->key = "arc_backward_column";
    abcol->required = NO;
    abcol->description = _("Arc backward direction cost column (number)");
    abcol->guisection = _("Cost");

    ncol = G_define_standard_option(G_OPT_DB_COLUMN);
    ncol->key = "node_column";
    ncol->required = NO;
    ncol->description = _("Node cost column (number)");
    ncol->guisection = _("Cost");

    catsource_opt = G_define_standard_option(G_OPT_V_CATS);
    catsource_opt->key = "source_cats";
    catsource_opt->label = _("Source category values");
    catsource_opt->guisection = _("Source");

    wheresource_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheresource_opt->key = "source_where";
    wheresource_opt->label =
	_("Source WHERE conditions of SQL statement without 'where' keyword");
    wheresource_opt->guisection = _("Source");

    catsink_opt = G_define_standard_option(G_OPT_V_CATS);
    catsink_opt->key = "sink_cats";
    catsink_opt->label = _("Sink category values");
    catsink_opt->guisection = _("Sink");

    wheresink_opt = G_define_standard_option(G_OPT_DB_WHERE);
    wheresink_opt->key = "sink_where";
    wheresink_opt->label =
	_("Sink WHERE conditions of SQL statement without 'where' keyword");
    wheresink_opt->guisection = _("Sink");

    /* options and flags parser */
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    find_cut = (cut_out->answer[0]);
    /* TODO: make an option for this */
    mask_type = GV_LINE | GV_BOUNDARY;

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

    Vect_check_input_output_name(map_in->answer, map_out->answer,
				 G_FATAL_EXIT);

    Vect_set_open_level(2);

    if (1 > Vect_open_old(&In, map_in->answer, ""))
	G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer);

    with_z = Vect_is_3d(&In);

    if (0 > Vect_open_new(&Out, map_out->answer, with_z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer);
    }

    if (find_cut && 0 > Vect_open_new(&cut_map, cut_out->answer, with_z)) {
	Vect_close(&In);
	Vect_close(&Out);
	G_fatal_error(_("Unable to create vector map <%s>"), cut_out->answer);
    }

    /* parse filter option and select appropriate lines */
    afield = Vect_get_field_number(&In, afield_opt->answer);
    nfield = Vect_get_field_number(&In, nfield_opt->answer);

    /* Create table */
    Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
    Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
			Fi->driver);
    db_init_string(&sql);
    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);
    db_set_error_handler_driver(driver);

    sprintf(buf, "create table %s (cat integer, flow double precision)",
	    Fi->table);

    db_set_string(&sql, buf);
    G_debug(2, "%s", db_get_string(&sql));

    if (db_execute_immediate(driver, &sql) != DB_OK) {
	db_close_database_shutdown_driver(driver);
	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(_("Cannot create index"));

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

    db_begin_transaction(driver);

    source_list = Vect_new_list();
    sink_list = Vect_new_list();

    if (NetA_initialise_varray
	(&In, nfield, GV_POINT,
	 wheresource_opt->answer, catsource_opt->answer, &varray_source) <= 0) {
	G_fatal_error(_("No source features selected. "
			"Please check options '%s', '%s'."),
			catsource_opt->key, wheresource_opt->key);
    }
    if (NetA_initialise_varray
	(&In, nfield, GV_POINT, wheresink_opt->answer,
	 catsink_opt->answer, &varray_sink) <= 0) {
	G_fatal_error(_("No sink features selected. "
			"Please check options '%s', '%s'."),
			catsink_opt->key, wheresink_opt->key);
    }

    NetA_varray_to_nodes(&In, varray_source, source_list, NULL);
    NetA_varray_to_nodes(&In, varray_sink, sink_list, NULL);

    if (source_list->n_values == 0)
	G_fatal_error(_("No sources"));

    if (sink_list->n_values == 0)
	G_fatal_error(_("No sinks"));

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

    if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, abcol->answer,
                                  ncol->answer, 0, 0))
        G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In));
    
    graph = Vect_net_get_graph(&In);
    nlines = Vect_get_num_lines(&In);
    flow = (int *)G_calloc(nlines + 1, sizeof(int));
    if (!flow)
	G_fatal_error(_("Out of memory"));

    total_flow = NetA_flow(graph, source_list, sink_list, flow);
    G_debug(3, "Max flow: %d", total_flow);
    if (find_cut) {
	cut = Vect_new_list();
	total_flow = NetA_min_cut(graph, source_list, sink_list, flow, cut);
	G_debug(3, "Min cut: %d", total_flow);
    }

    G_message(_("Writing the output..."));
    G_percent_reset();
    for (i = 1; i <= nlines; i++) {
	G_percent(i, nlines, 1);
	int type = Vect_read_line(&In, Points, Cats, i);

	Vect_write_line(&Out, type, Points, Cats);
	if (type == GV_LINE) {
	    int cat;

	    Vect_cat_get(Cats, afield, &cat);
	    if (cat == -1)
		continue;	/*TODO: warning? */
	    sprintf(buf, "insert into %s values (%d, %f)", Fi->table, cat,
		    flow[i] / (double)In.dgraph.cost_multip);
	    db_set_string(&sql, buf);
	    G_debug(3, "%s", db_get_string(&sql));

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

    if (find_cut) {
	for (i = 0; i < cut->n_values; i++) {
	    int type = Vect_read_line(&In, Points, Cats, cut->value[i]);

	    Vect_write_line(&cut_map, type, Points, Cats);
	}
	Vect_destroy_list(cut);

	Vect_build(&cut_map);
	Vect_close(&cut_map);
    }

    db_commit_transaction(driver);
    db_close_database_shutdown_driver(driver);

    G_free(flow);
    Vect_destroy_list(source_list);
    Vect_destroy_list(sink_list);

    Vect_build(&Out);

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

    exit(EXIT_SUCCESS);
}