OGRErr OGRGRASSLayer::GetExtent (OGREnvelope *psExtent, int bForce) { BOUND_BOX box; Vect_get_map_box ( poMap, &box ); psExtent->MinX = box.W; psExtent->MinY = box.S; psExtent->MaxX = box.E; psExtent->MaxY = box.N; return OGRERR_NONE; }
double do_limits(struct Map_info *Map) { double textsize; struct bound_box box; Vect_get_map_box(Map, &box); dxf_header(); dxf_limits(box.N, box.S, box.E, box.W); dxf_endsec(); if ((box.E - box.W) >= (box.N - box.S)) textsize = (box.E - box.W) * TEXT_SIZE; else textsize = (box.N - box.S) * TEXT_SIZE; return textsize; }
void print_region(const struct Map_info *Map) { char tmp1[100], tmp2[100]; struct bound_box box; /*Print the spatial extent as double values*/ Vect_get_map_box(Map, &box); G_format_northing(box.N, tmp1, -1); G_format_northing(box.S, tmp2, -1); fprintf(stdout, "north=%s\n", tmp1); fprintf(stdout, "south=%s\n", tmp2); G_format_easting(box.E, tmp1, -1); G_format_easting(box.W, tmp2, -1); fprintf(stdout, "east=%s\n", tmp1); fprintf(stdout, "west=%s\n", tmp2); fprintf(stdout, "top=%f\n", box.T); fprintf(stdout, "bottom=%f\n", box.B); }
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); }
int main(int argc, char *argv[]) { struct file_info Current, Trans, Coord; struct GModule *module; struct Option *vold, *vnew, *pointsfile, *xshift, *yshift, *zshift, *xscale, *yscale, *zscale, *zrot, *columns, *table, *field; struct Flag *quiet_flag, *tozero_flag, *shift_flag, *print_mat_flag; char *mapset, mon[4], date[40], buf[1000]; struct Map_info Old, New; int ifield; int day, yr; BOUND_BOX box; double ztozero; double trans_params[7]; /* xshift, ..., xscale, ..., zrot */ /* columns */ unsigned int i; int idx, out3d; char **tokens; char *columns_name[7]; /* xshift, yshift, zshift, xscale, yscale, zscale, zrot */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, transformation"); module->description = _("Performs an affine transformation (shift, scale and rotate, " "or GPCs) on vector map."); /* remove in GRASS7 */ quiet_flag = G_define_flag(); quiet_flag->key = 'q'; quiet_flag->description = _("Suppress display of residuals or other information"); tozero_flag = G_define_flag(); tozero_flag->key = 't'; tozero_flag->description = _("Shift all z values to bottom=0"); tozero_flag->guisection = _("Custom"); print_mat_flag = G_define_flag(); print_mat_flag->key = 'm'; print_mat_flag->description = _("Print the transformation matrix to stdout"); shift_flag = G_define_flag(); shift_flag->key = 's'; shift_flag->description = _("Instead of points use transformation parameters " "(xshift, yshift, zshift, xscale, yscale, zscale, zrot)"); shift_flag->guisection = _("Custom"); vold = G_define_standard_option(G_OPT_V_INPUT); field = G_define_standard_option(G_OPT_V_FIELD); field->answer = "-1"; vnew = G_define_standard_option(G_OPT_V_OUTPUT); pointsfile = G_define_standard_option(G_OPT_F_INPUT); pointsfile->key = "pointsfile"; pointsfile->required = NO; pointsfile->label = _("ASCII file holding transform coordinates"); pointsfile->description = _("If not given, transformation parameters " "(xshift, yshift, zshift, xscale, yscale, zscale, zrot) are used instead"); pointsfile->gisprompt = "old_file,file,points"; pointsfile->guisection = _("Points"); xshift = G_define_option(); xshift->key = "xshift"; xshift->type = TYPE_DOUBLE; xshift->required = NO; xshift->multiple = NO; xshift->description = _("Shifting value for x coordinates"); xshift->answer = "0.0"; xshift->guisection = _("Custom"); yshift = G_define_option(); yshift->key = "yshift"; yshift->type = TYPE_DOUBLE; yshift->required = NO; yshift->multiple = NO; yshift->description = _("Shifting value for y coordinates"); yshift->answer = "0.0"; yshift->guisection = _("Custom"); zshift = G_define_option(); zshift->key = "zshift"; zshift->type = TYPE_DOUBLE; zshift->required = NO; zshift->multiple = NO; zshift->description = _("Shifting value for z coordinates"); zshift->answer = "0.0"; zshift->guisection = _("Custom"); xscale = G_define_option(); xscale->key = "xscale"; xscale->type = TYPE_DOUBLE; xscale->required = NO; xscale->multiple = NO; xscale->description = _("Scaling factor for x coordinates"); xscale->answer = "1.0"; xscale->guisection = _("Custom"); yscale = G_define_option(); yscale->key = "yscale"; yscale->type = TYPE_DOUBLE; yscale->required = NO; yscale->multiple = NO; yscale->description = _("Scaling factor for y coordinates"); yscale->answer = "1.0"; yscale->guisection = _("Custom"); zscale = G_define_option(); zscale->key = "zscale"; zscale->type = TYPE_DOUBLE; zscale->required = NO; zscale->multiple = NO; zscale->description = _("Scaling factor for z coordinates"); zscale->answer = "1.0"; zscale->guisection = _("Custom"); zrot = G_define_option(); zrot->key = "zrot"; zrot->type = TYPE_DOUBLE; zrot->required = NO; zrot->multiple = NO; zrot->description = _("Rotation around z axis in degrees counterclockwise"); zrot->answer = "0.0"; zrot->guisection = _("Custom"); table = G_define_standard_option(G_OPT_TABLE); table->description = _("Name of table containing transformation parameters"); table->guisection = _("Attributes"); columns = G_define_option(); columns->key = "columns"; columns->type = TYPE_STRING; columns->required = NO; columns->multiple = NO; columns->label = _("Name of attribute column(s) used as transformation parameters"); columns->description = _("Format: parameter:column, e.g. xshift:xs,yshift:ys,zrot:zr"); columns->guisection = _("Attributes"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_strcpy(Current.name, vold->answer); G_strcpy(Trans.name, vnew->answer); Vect_check_input_output_name(vold->answer, vnew->answer, GV_FATAL_EXIT); out3d = WITHOUT_Z; ifield = atoi(field->answer); if (shift_flag->answer) G_warning(_("The '%c' flag is deprecated and will be removed in future. " "Transformation parameters are used automatically when no pointsfile is given."), shift_flag->key); /* please remove in GRASS7 */ if (quiet_flag->answer) { G_warning(_("The '%c' flag is deprecated and will be removed in future. " "Please use '--quiet' instead."), quiet_flag->key); G_putenv("GRASS_VERBOSE", "0"); } /* if a table is specified, require columns and layer */ /* if columns are specified, but no table, require layer > 0 and use * the table attached to that layer */ if (table->answer && !columns->answer) { G_fatal_error(_("Column names are not defined. Please use '%s' parameter."), columns->key); } if ((columns->answer || table->answer) && ifield < 1) { G_fatal_error(_("Please specify a valid layer with '%s' parameter."), field->key); } if (table->answer && strcmp(vnew->answer, table->answer) == 0) { G_fatal_error(_("Name of table and name for output vector map must be different. " "Otherwise the table is overwritten.")); } if (!columns->answer && !table->answer) ifield = -1; if (pointsfile->answer != NULL && !shift_flag->answer) { G_strcpy(Coord.name, pointsfile->answer); } else { Coord.name[0] = '\0'; } /* open coord file */ if (Coord.name[0] != '\0') { if ((Coord.fp = fopen(Coord.name, "r")) == NULL) G_fatal_error(_("Unable to open file with coordinates <%s>"), Coord.name); } /* tokenize columns names */ for (i = 0; i <= IDX_ZROT; i++) { columns_name[i] = NULL; } i = 0; if (columns->answer) { while (columns->answers[i]) { tokens = G_tokenize(columns->answers[i], ":"); if (G_number_of_tokens(tokens) == 2) { if (strcmp(tokens[0], xshift->key) == 0) idx = IDX_XSHIFT; else if (strcmp(tokens[0], yshift->key) == 0) idx = IDX_YSHIFT; else if (strcmp(tokens[0], zshift->key) == 0) idx = IDX_ZSHIFT; else if (strcmp(tokens[0], xscale->key) == 0) idx = IDX_XSCALE; else if (strcmp(tokens[0], yscale->key) == 0) idx = IDX_YSCALE; else if (strcmp(tokens[0], zscale->key) == 0) idx = IDX_ZSCALE; else if (strcmp(tokens[0], zrot->key) == 0) idx = IDX_ZROT; else idx = -1; if (idx != -1) columns_name[idx] = G_store(tokens[1]); G_free_tokens(tokens); } else { G_fatal_error(_("Unable to tokenize column string: [%s]"), columns->answers[i]); } i++; } } /* determine transformation parameters */ trans_params[IDX_XSHIFT] = atof(xshift->answer); trans_params[IDX_YSHIFT] = atof(yshift->answer); trans_params[IDX_ZSHIFT] = atof(zshift->answer); trans_params[IDX_XSCALE] = atof(xscale->answer); trans_params[IDX_YSCALE] = atof(yscale->answer); trans_params[IDX_ZSCALE] = atof(zscale->answer); trans_params[IDX_ZROT] = atof(zrot->answer); /* open vector maps */ if ((mapset = G_find_vector2(vold->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), vold->answer); Vect_open_old(&Old, vold->answer, mapset); /* should output be 3D ? * note that z-scale and ztozero have no effect with input 2D */ if (Vect_is_3d(&Old) || trans_params[IDX_ZSHIFT] != 0. || columns_name[IDX_ZSHIFT]) out3d = WITH_Z; Vect_open_new(&New, vnew->answer, out3d); /* copy and set header */ Vect_copy_head_data(&Old, &New); Vect_hist_copy(&Old, &New); Vect_hist_command(&New); sprintf(date, "%s", G_date()); sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr); sprintf(date, "%s %d %d", mon, day, yr); Vect_set_date(&New, date); Vect_set_person(&New, G_whoami()); sprintf(buf, "transformed from %s", vold->answer); Vect_set_map_name(&New, buf); Vect_set_scale(&New, 1); Vect_set_zone(&New, 0); Vect_set_thresh(&New, 0.0); /* points file */ if (Coord.name[0]) { create_transform_from_file(&Coord, quiet_flag->answer); if (Coord.name[0] != '\0') fclose(Coord.fp); } Vect_get_map_box(&Old, &box); /* z to zero */ if (tozero_flag->answer) ztozero = 0 - box.B; else ztozero = 0; /* do the transformation */ transform_digit_file(&Old, &New, Coord.name[0] ? 1 : 0, ztozero, trans_params, table->answer, columns_name, ifield); if (Vect_copy_tables(&Old, &New, 0)) G_warning(_("Failed to copy attribute table to output map")); Vect_close(&Old); Vect_build(&New); if (!quiet_flag->answer) { Vect_get_map_box(&New, &box); G_message(_("\nNew vector map <%s> boundary coordinates:"), vnew->answer); G_message(_(" N: %-10.3f S: %-10.3f"), box.N, box.S); G_message(_(" E: %-10.3f W: %-10.3f"), box.E, box.W); G_message(_(" B: %6.3f T: %6.3f"), box.B, box.T); /* print the transformation matrix if requested */ if (print_mat_flag->answer) print_transform_matrix(); } Vect_close(&New); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int i; int print_flag = 0; int flat_flag; int set_flag; double x; int ival; int row_flag = 0, col_flag = 0; struct Cell_head window, temp_window; const char *value; const char *name; const char *mapset; char **rast_ptr, **vect_ptr; struct GModule *module; struct { struct Flag *update, *print, *gprint, *flprint, *lprint, *eprint, *nangle, *center, *res_set, *dist_res, *dflt, *z, *savedefault, *bbox, *gmt_style, *wms_style; } flag; struct { struct Option *north, *south, *east, *west, *top, *bottom, *res, *nsres, *ewres, *res3, *tbres, *rows, *cols, *save, *region, *raster, *raster3d, *align, *zoom, *vect; } parm; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("general")); G_add_keyword(_("settings")); module->description = _("Manages the boundary definitions for the " "geographic region."); /* flags */ flag.dflt = G_define_flag(); flag.dflt->key = 'd'; flag.dflt->description = _("Set from default region"); flag.dflt->guisection = _("Existing"); flag.savedefault = G_define_flag(); flag.savedefault->key = 's'; flag.savedefault->label = _("Save as default region"); flag.savedefault->description = _("Only possible from the PERMANENT mapset"); flag.savedefault->guisection = _("Existing"); flag.print = G_define_flag(); flag.print->key = 'p'; flag.print->description = _("Print the current region"); flag.print->guisection = _("Print"); flag.lprint = G_define_flag(); flag.lprint->key = 'l'; flag.lprint->description = _("Print the current region in lat/long " "using the current ellipsoid/datum"); flag.lprint->guisection = _("Print"); flag.eprint = G_define_flag(); flag.eprint->key = 'e'; flag.eprint->description = _("Print the current region extent"); flag.eprint->guisection = _("Print"); flag.center = G_define_flag(); flag.center->key = 'c'; flag.center->description = _("Print the current region map center coordinates"); flag.center->guisection = _("Print"); flag.gmt_style = G_define_flag(); flag.gmt_style->key = 't'; flag.gmt_style->description = _("Print the current region in GMT style"); flag.gmt_style->guisection = _("Print"); flag.wms_style = G_define_flag(); flag.wms_style->key = 'w'; flag.wms_style->description = _("Print the current region in WMS style"); flag.wms_style->guisection = _("Print"); flag.dist_res = G_define_flag(); flag.dist_res->key = 'm'; flag.dist_res->description = _("Print region resolution in meters (geodesic)"); flag.dist_res->guisection = _("Print"); flag.nangle = G_define_flag(); flag.nangle->key = 'n'; flag.nangle->label = _("Print the convergence angle (degrees CCW)"); flag.nangle->description = _("The difference between the projection's grid north and true north, " "measured at the center coordinates of the current region."); flag.nangle->guisection = _("Print"); flag.z = G_define_flag(); flag.z->key = '3'; flag.z->description = _("Print also 3D settings"); flag.z->guisection = _("Print"); flag.bbox = G_define_flag(); flag.bbox->key = 'b'; flag.bbox->description = _("Print the maximum bounding box in lat/long on WGS84"); flag.bbox->guisection = _("Print"); flag.gprint = G_define_flag(); flag.gprint->key = 'g'; flag.gprint->description = _("Print in shell script style"); flag.gprint->guisection = _("Print"); flag.flprint = G_define_flag(); flag.flprint->key = 'f'; flag.flprint->description = _("Print in shell script style, but in one line (flat)"); flag.flprint->guisection = _("Print"); flag.res_set = G_define_flag(); flag.res_set->key = 'a'; flag.res_set->description = _("Align region to resolution (default = align to bounds, " "works only for 2D resolution)"); flag.res_set->guisection = _("Bounds"); flag.update = G_define_flag(); flag.update->key = 'u'; flag.update->description = _("Do not update the current region"); flag.update->guisection = _("Effects"); /* parameters */ parm.region = G_define_standard_option(G_OPT_M_REGION); parm.region->description = _("Set current region from named region"); parm.region->guisection = _("Existing"); parm.raster = G_define_standard_option(G_OPT_R_MAP); parm.raster->key = "raster"; parm.raster->required = NO; parm.raster->multiple = YES; parm.raster->description = _("Set region to match raster map(s)"); parm.raster->guisection = _("Existing"); parm.raster3d = G_define_standard_option(G_OPT_R3_MAP); parm.raster3d->key = "raster_3d"; parm.raster3d->required = NO; parm.raster3d->multiple = NO; parm.raster3d->description = _("Set region to match 3D raster map(s) (both 2D and 3D " "values)"); parm.raster3d->guisection = _("Existing"); parm.vect = G_define_standard_option(G_OPT_V_MAP); parm.vect->key = "vector"; parm.vect->required = NO; parm.vect->multiple = YES; parm.vect->label = _("Set region to match vector map(s)"); parm.vect->description = NULL; parm.vect->guisection = _("Existing"); parm.north = G_define_option(); parm.north->key = "n"; parm.north->key_desc = "value"; parm.north->required = NO; parm.north->multiple = NO; parm.north->type = TYPE_STRING; parm.north->description = _("Value for the northern edge"); parm.north->guisection = _("Bounds"); parm.south = G_define_option(); parm.south->key = "s"; parm.south->key_desc = "value"; parm.south->required = NO; parm.south->multiple = NO; parm.south->type = TYPE_STRING; parm.south->description = _("Value for the southern edge"); parm.south->guisection = _("Bounds"); parm.east = G_define_option(); parm.east->key = "e"; parm.east->key_desc = "value"; parm.east->required = NO; parm.east->multiple = NO; parm.east->type = TYPE_STRING; parm.east->description = _("Value for the eastern edge"); parm.east->guisection = _("Bounds"); parm.west = G_define_option(); parm.west->key = "w"; parm.west->key_desc = "value"; parm.west->required = NO; parm.west->multiple = NO; parm.west->type = TYPE_STRING; parm.west->description = _("Value for the western edge"); parm.west->guisection = _("Bounds"); parm.top = G_define_option(); parm.top->key = "t"; parm.top->key_desc = "value"; parm.top->required = NO; parm.top->multiple = NO; parm.top->type = TYPE_STRING; parm.top->description = _("Value for the top edge"); parm.top->guisection = _("Bounds"); parm.bottom = G_define_option(); parm.bottom->key = "b"; parm.bottom->key_desc = "value"; parm.bottom->required = NO; parm.bottom->multiple = NO; parm.bottom->type = TYPE_STRING; parm.bottom->description = _("Value for the bottom edge"); parm.bottom->guisection = _("Bounds"); parm.rows = G_define_option(); parm.rows->key = "rows"; parm.rows->key_desc = "value"; parm.rows->required = NO; parm.rows->multiple = NO; parm.rows->type = TYPE_INTEGER; parm.rows->description = _("Number of rows in the new region"); parm.rows->guisection = _("Resolution"); parm.cols = G_define_option(); parm.cols->key = "cols"; parm.cols->key_desc = "value"; parm.cols->required = NO; parm.cols->multiple = NO; parm.cols->type = TYPE_INTEGER; parm.cols->description = _("Number of columns in the new region"); parm.cols->guisection = _("Resolution"); parm.res = G_define_option(); parm.res->key = "res"; parm.res->key_desc = "value"; parm.res->required = NO; parm.res->multiple = NO; parm.res->type = TYPE_STRING; parm.res->description = _("2D grid resolution (north-south and east-west)"); parm.res->guisection = _("Resolution"); parm.res3 = G_define_option(); parm.res3->key = "res3"; parm.res3->key_desc = "value"; parm.res3->required = NO; parm.res3->multiple = NO; parm.res3->type = TYPE_STRING; parm.res3->description = _("3D grid resolution (north-south, east-west and top-bottom)"); parm.res3->guisection = _("Resolution"); parm.nsres = G_define_option(); parm.nsres->key = "nsres"; parm.nsres->key_desc = "value"; parm.nsres->required = NO; parm.nsres->multiple = NO; parm.nsres->type = TYPE_STRING; parm.nsres->description = _("North-south 2D grid resolution"); parm.nsres->guisection = _("Resolution"); parm.ewres = G_define_option(); parm.ewres->key = "ewres"; parm.ewres->key_desc = "value"; parm.ewres->required = NO; parm.ewres->multiple = NO; parm.ewres->type = TYPE_STRING; parm.ewres->description = _("East-west 2D grid resolution"); parm.ewres->guisection = _("Resolution"); parm.tbres = G_define_option(); parm.tbres->key = "tbres"; parm.tbres->key_desc = "value"; parm.tbres->required = NO; parm.tbres->multiple = NO; parm.tbres->type = TYPE_STRING; parm.tbres->description = _("Top-bottom 3D grid resolution"); parm.tbres->guisection = _("Resolution"); parm.zoom = G_define_option(); parm.zoom->key = "zoom"; parm.zoom->key_desc = "name"; parm.zoom->required = NO; parm.zoom->multiple = NO; parm.zoom->type = TYPE_STRING; parm.zoom->description = _("Shrink region until it meets non-NULL data from this raster map"); parm.zoom->gisprompt = "old,cell,raster"; parm.zoom->guisection = _("Bounds"); parm.align = G_define_option(); parm.align->key = "align"; parm.align->key_desc = "name"; parm.align->required = NO; parm.align->multiple = NO; parm.align->type = TYPE_STRING; parm.align->description = _("Adjust region cells to cleanly align with this raster map"); parm.align->gisprompt = "old,cell,raster"; parm.align->guisection = _("Bounds"); parm.save = G_define_option(); parm.save->key = "save"; parm.save->key_desc = "name"; parm.save->required = NO; parm.save->multiple = NO; parm.save->type = TYPE_STRING; parm.save->description = _("Save current region settings in named region file"); parm.save->gisprompt = "new,windows,region"; parm.save->guisection = _("Effects"); G_option_required(flag.dflt, flag.savedefault, flag.print, flag.lprint, flag.eprint, flag.center, flag.gmt_style, flag.wms_style, flag.dist_res, flag.nangle, flag. z, flag.bbox, flag.gprint, flag.res_set, flag.update, parm.region, parm.raster, parm.raster3d, parm.vect, parm.north, parm.south, parm.east, parm.west, parm.top, parm.bottom, parm.rows, parm.cols, parm.res, parm.res3, parm.nsres, parm.ewres, parm.tbres, parm.zoom, parm.align, parm.save, NULL); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_get_default_window(&window); set_flag = !flag.update->answer; flat_flag = flag.flprint->answer; if (flag.print->answer) print_flag |= PRINT_REG; if (flag.gprint->answer) print_flag |= PRINT_SH; if (flag.lprint->answer) print_flag |= PRINT_LL; if (flag.eprint->answer) print_flag |= PRINT_EXTENT; if (flag.center->answer) print_flag |= PRINT_CENTER; if (flag.gmt_style->answer) print_flag |= PRINT_GMT; if (flag.wms_style->answer) print_flag |= PRINT_WMS; if (flag.nangle->answer) print_flag |= PRINT_NANGLE; if (flag.dist_res->answer) print_flag |= PRINT_METERS; if (flag.z->answer) print_flag |= PRINT_3D; if (flag.bbox->answer) print_flag |= PRINT_MBBOX; if (print_flag == PRINT_METERS) print_flag |= PRINT_SH; if (print_flag == PRINT_SH || print_flag & PRINT_3D || print_flag == PRINT_METERS + PRINT_SH) { print_flag |= PRINT_REG; } if (!flag.dflt->answer) G_get_window(&window); /* region= */ if ((name = parm.region->answer)) { mapset = G_find_file2("windows", name, ""); if (!mapset) G_fatal_error(_("Region <%s> not found"), name); G_get_element_window(&window, "windows", name, mapset); } /* raster= */ if (parm.raster->answer) { int first = 0; rast_ptr = parm.raster->answers; for (; *rast_ptr != NULL; rast_ptr++) { char rast_name[GNAME_MAX]; strcpy(rast_name, *rast_ptr); mapset = G_find_raster2(rast_name, ""); if (!mapset) G_fatal_error(_("Raster map <%s> not found"), rast_name); Rast_get_cellhd(rast_name, mapset, &temp_window); if (!first) { window = temp_window; first = 1; } else { window.north = (window.north > temp_window.north) ? window.north : temp_window.north; window.south = (window.south < temp_window.south) ? window.south : temp_window.south; window.east = (window.east > temp_window.east) ? window.east : temp_window.east; window.west = (window.west < temp_window.west) ? window.west : temp_window.west; } } G_adjust_Cell_head3(&window, 0, 0, 0); } /* raster3d= */ if ((name = parm.raster3d->answer)) { RASTER3D_Region win; if ((mapset = G_find_raster3d(name, "")) == NULL) G_fatal_error(_("3D raster map <%s> not found"), name); if (Rast3d_read_region_map(name, mapset, &win) < 0) G_fatal_error(_("Unable to read header of 3D raster map <%s@%s>"), name, mapset); Rast3d_region_to_cell_head(&win, &window); } /* vector= */ if (parm.vect->answer) { int first = 0; vect_ptr = parm.vect->answers; for (; *vect_ptr != NULL; vect_ptr++) { struct Map_info Map; struct bound_box box; char vect_name[GNAME_MAX]; struct Cell_head map_window; strcpy(vect_name, *vect_ptr); mapset = G_find_vector2(vect_name, ""); if (!mapset) G_fatal_error(_("Vector map <%s> not found"), vect_name); temp_window = window; Vect_set_open_level(2); if (2 > Vect_open_old_head(&Map, vect_name, mapset)) G_fatal_error(_("Unable to open vector map <%s> on topological level"), vect_name); Vect_get_map_box(&Map, &box); map_window = window; map_window.north = box.N; map_window.south = box.S; map_window.west = box.W; map_window.east = box.E; map_window.top = box.T; map_window.bottom = box.B; if (!first) { window = map_window; first = 1; } else { window.north = (window.north > map_window.north) ? window.north : map_window.north; window.south = (window.south < map_window.south) ? window.south : map_window.south; window.east = (window.east > map_window.east) ? window.east : map_window.east; window.west = (window.west < map_window.west) ? window.west : map_window.west; if (map_window.top > window.top) window.top = map_window.top; if (map_window.bottom < window.bottom) window.bottom = map_window.bottom; } if (window.north == window.south) { window.north = window.north + 0.5 * temp_window.ns_res; window.south = window.south - 0.5 * temp_window.ns_res; } if (window.east == window.west) { window.west = window.west - 0.5 * temp_window.ew_res; window.east = window.east + 0.5 * temp_window.ew_res; } if (window.top == window.bottom) { window.bottom = (window.bottom - 0.5 * temp_window.tb_res); window.top = (window.top + 0.5 * temp_window.tb_res); } if (flag.res_set->answer) Rast_align_window(&window, &temp_window); Vect_close(&Map); } } /* n= */ if ((value = parm.north->answer)) { if ((i = nsew(value, "n+", "n-", "s+"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.north); switch (i) { case 1: window.north += x; break; case 2: window.north -= x; break; case 3: window.north = window.south + x; break; } } else if (G_scan_northing(value, &x, window.proj)) window.north = x; else die(parm.north); } /* s= */ if ((value = parm.south->answer)) { if ((i = nsew(value, "s+", "s-", "n-"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.south); switch (i) { case 1: window.south += x; break; case 2: window.south -= x; break; case 3: window.south = window.north - x; break; } } else if (G_scan_northing(value, &x, window.proj)) window.south = x; else die(parm.south); } /* e= */ if ((value = parm.east->answer)) { if ((i = nsew(value, "e+", "e-", "w+"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.east); switch (i) { case 1: window.east += x; break; case 2: window.east -= x; break; case 3: window.east = window.west + x; break; } } else if (G_scan_easting(value, &x, window.proj)) window.east = x; else die(parm.east); } /* w= */ if ((value = parm.west->answer)) { if ((i = nsew(value, "w+", "w-", "e-"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.west); switch (i) { case 1: window.west += x; break; case 2: window.west -= x; break; case 3: window.west = window.east - x; break; } } else if (G_scan_easting(value, &x, window.proj)) window.west = x; else die(parm.west); } /* t= */ if ((value = parm.top->answer)) { if ((i = nsew(value, "t+", "t-", "b+"))) { if (sscanf(value + 2, "%lf", &x) != 1) die(parm.top); switch (i) { case 1: window.top += x; break; case 2: window.top -= x; break; case 3: window.top = window.bottom + x; break; } } else if (sscanf(value, "%lf", &x) == 1) window.top = x; else die(parm.top); } /* b= */ if ((value = parm.bottom->answer)) { if ((i = nsew(value, "b+", "b-", "t-"))) { if (sscanf(value + 2, "%lf", &x) != 1) die(parm.bottom); switch (i) { case 1: window.bottom += x; break; case 2: window.bottom -= x; break; case 3: window.bottom = window.top - x; break; } } else if (sscanf(value, "%lf", &x) == 1) window.bottom = x; else die(parm.bottom); } /* res= */ if ((value = parm.res->answer)) { if (!G_scan_resolution(value, &x, window.proj)) die(parm.res); window.ns_res = x; window.ew_res = x; if (flag.res_set->answer) { window.north = ceil(window.north / x) * x; window.south = floor(window.south / x) * x; window.east = ceil(window.east / x) * x; window.west = floor(window.west / x) * x; } } /* res3= */ if ((value = parm.res3->answer)) { if (!G_scan_resolution(value, &x, window.proj)) die(parm.res); window.ns_res3 = x; window.ew_res3 = x; window.tb_res = x; } /* nsres= */ if ((value = parm.nsres->answer)) { if (!G_scan_resolution(value, &x, window.proj)) die(parm.nsres); window.ns_res = x; if (flag.res_set->answer) { window.north = ceil(window.north / x) * x; window.south = floor(window.south / x) * x; } } /* ewres= */ if ((value = parm.ewres->answer)) { if (!G_scan_resolution(value, &x, window.proj)) die(parm.ewres); window.ew_res = x; if (flag.res_set->answer) { window.east = ceil(window.east / x) * x; window.west = floor(window.west / x) * x; } } /* tbres= */ if ((value = parm.tbres->answer)) { if (sscanf(value, "%lf", &x) != 1) die(parm.tbres); window.tb_res = x; if (flag.res_set->answer) { window.top = ceil(window.top / x) * x; window.bottom = floor(window.bottom / x) * x; } } /* rows= */ if ((value = parm.rows->answer)) { if (sscanf(value, "%i", &ival) != 1) die(parm.rows); window.rows = ival; row_flag = 1; } /* cols= */ if ((value = parm.cols->answer)) { if (sscanf(value, "%i", &ival) != 1) die(parm.cols); window.cols = ival; col_flag = 1; } /* zoom= */ if ((name = parm.zoom->answer)) { mapset = G_find_raster2(name, ""); if (!mapset) G_fatal_error(_("Raster map <%s> not found"), name); zoom(&window, name, mapset); } /* align= */ if ((name = parm.align->answer)) { mapset = G_find_raster2(name, ""); if (!mapset) G_fatal_error(_("Raster map <%s> not found"), name); Rast_get_cellhd(name, mapset, &temp_window); Rast_align_window(&window, &temp_window); } /* save= */ if ((name = parm.save->answer)) { temp_window = window; G_adjust_Cell_head3(&temp_window, 0, 0, 0); if (G_put_element_window(&temp_window, "windows", name) < 0) G_fatal_error(_("Unable to set region <%s>"), name); } G_adjust_Cell_head3(&window, row_flag, col_flag, 0); if (set_flag) { if (G_put_window(&window) < 0) G_fatal_error(_("Unable to update current region")); } if (flag.savedefault->answer) { if (strcmp(G_mapset(), "PERMANENT") == 0) { G_put_element_window(&window, "", "DEFAULT_WIND"); } else { G_fatal_error(_("Unable to change default region. " "The current mapset is not <PERMANENT>.")); } } /* / flag.savedefault->answer */ if (print_flag) print_window(&window, print_flag, flat_flag); exit(EXIT_SUCCESS); }
int display_shape(struct Map_info *Map, int type, struct cat_list *Clist, const struct Cell_head *window, const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat, const char *icon, double size, const char *size_column, int sqrt_flag, const char *rot_column, /* lines only */ int id_flag, int cats_colors_flag, char *rgb_column, int default_width, char *width_column, double width_scale, char *z_style) { int open_db, field, i, stat; dbCatValArray cvarr_rgb, cvarr_width, cvarr_size, cvarr_rot; struct field_info *fi; dbDriver *driver; int nrec_rgb, nrec_width, nrec_size, nrec_rot, have_colors; struct Colors colors, zcolors; struct bound_box box; stat = 0; nrec_rgb = nrec_width = nrec_size = nrec_rot = 0; open_db = rgb_column || width_column || size_column || rot_column; if (open_db) { field = Clist->field > 0 ? Clist->field : 1; fi = Vect_get_field(Map, field); if (!fi) { G_fatal_error(_("Database connection not defined for layer %d"), field); } 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); } /* fisrt search for color table */ have_colors = Vect_read_colors(Vect_get_name(Map), Vect_get_mapset(Map), &colors); if (have_colors && rgb_column) { G_warning(_("Both color table and <%s> option detected. " "Color table will ignored."), "rgb_column"); have_colors = FALSE; } if (rgb_column) { /* read RRR:GGG:BBB color strings from table */ db_CatValArray_init(&cvarr_rgb); nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key, rgb_column, NULL, &cvarr_rgb); G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb); if (cvarr_rgb.ctype != DB_C_TYPE_STRING) { G_warning(_("Color definition column ('%s') not a string. " "Column must be of form 'RRR:GGG:BBB' where RGB values range 0-255. " "You can use '%s' module to define color rules. " "Unable to colorize features."), rgb_column, "v.colors"); rgb_column = NULL; } else { if (nrec_rgb < 0) G_fatal_error(_("Unable to select data ('%s') from table"), rgb_column); G_debug(2, "\n%d records selected from table", nrec_rgb); } } if (width_column) { if (*width_column == '\0') G_fatal_error(_("Line width column not specified")); db_CatValArray_init(&cvarr_width); nrec_width = db_select_CatValArray(driver, fi->table, fi->key, width_column, NULL, &cvarr_width); G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width); if (cvarr_width.ctype != DB_C_TYPE_INT && cvarr_width.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Line width column ('%s') not a number"), width_column); if (nrec_width < 0) G_fatal_error(_("Unable to select data ('%s') from table"), width_column); G_debug(2, "\n%d records selected from table", nrec_width); for (i = 0; i < cvarr_width.n_values; i++) { G_debug(4, "cat = %d %s = %d", cvarr_width.value[i].cat, width_column, (cvarr_width.ctype == DB_C_TYPE_INT ? cvarr_width.value[i].val. i : (int)cvarr_width.value[i].val.d)); } } if (size_column) { if (*size_column == '\0') G_fatal_error(_("Symbol size column not specified")); db_CatValArray_init(&cvarr_size); nrec_size = db_select_CatValArray(driver, fi->table, fi->key, size_column, NULL, &cvarr_size); G_debug(3, "nrec_size (%s) = %d", size_column, nrec_size); if (cvarr_size.ctype != DB_C_TYPE_INT && cvarr_size.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Symbol size column ('%s') is not numeric"), size_column); if (nrec_size < 0) G_fatal_error(_("Unable to select data ('%s') from table"), size_column); G_debug(2, " %d records selected from table", nrec_size); for (i = 0; i < cvarr_size.n_values; i++) { G_debug(4, "(size) cat = %d %s = %.2f", cvarr_size.value[i].cat, size_column, (cvarr_size.ctype == DB_C_TYPE_INT ? (double)cvarr_size.value[i].val.i : cvarr_size.value[i].val.d)); } } if (rot_column) { if (*rot_column == '\0') G_fatal_error(_("Symbol rotation column not specified")); db_CatValArray_init(&cvarr_rot); nrec_rot = db_select_CatValArray(driver, fi->table, fi->key, rot_column, NULL, &cvarr_rot); G_debug(3, "nrec_rot (%s) = %d", rot_column, nrec_rot); if (cvarr_rot.ctype != DB_C_TYPE_INT && cvarr_rot.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Symbol rotation column ('%s') is not numeric"), rot_column); if (nrec_rot < 0) G_fatal_error(_("Unable to select data ('%s') from table"), rot_column); G_debug(2, " %d records selected from table", nrec_rot); for (i = 0; i < cvarr_rot.n_values; i++) { G_debug(4, "(rot) cat = %d %s = %.2f", cvarr_rot.value[i].cat, rot_column, (cvarr_rot.ctype == DB_C_TYPE_INT ? (double)cvarr_rot.value[i].val.i : cvarr_rot.value[i].val.d)); } } if (open_db) { db_close_database_shutdown_driver(driver); } if (z_style) { if (!Vect_is_3d(Map)) { G_warning(_("Vector map is not 3D. Unable to colorize features based on z-coordinates.")); z_style = NULL; } else if (rgb_column) { G_warning(_("%s= and %s= are mutually exclusive. " "%s= will be ignored."), "zcolor", "rgb_column", "zcolor"); z_style = NULL; } else { Vect_get_map_box(Map, &box); Rast_make_fp_colors(&zcolors, z_style, box.B, box.T); } } stat = 0; if (type & GV_AREA && Vect_get_num_primitives(Map, GV_CENTROID | GV_BOUNDARY) > 0) stat += display_area(Map, Clist, window, bcolor, fcolor, chcat, id_flag, cats_colors_flag, default_width, width_scale, z_style ? &zcolors : NULL, rgb_column ? &cvarr_rgb : NULL, have_colors ? &colors : NULL, &cvarr_width, nrec_width); stat += display_lines(Map, type, Clist, bcolor, fcolor, chcat, icon, size, sqrt_flag, id_flag, cats_colors_flag, default_width, width_scale, z_style ? &zcolors : NULL, rgb_column ? &cvarr_rgb : NULL, have_colors ? &colors : NULL, &cvarr_width, nrec_width, &cvarr_size, nrec_size, &cvarr_rot, nrec_rot); return stat; }
int main(int argc, char **argv) { char *mapset; int ret, level; int i, stat = 0, type, display; int chcat = 0; int r, g, b; int has_color, has_fcolor; struct color_rgb color, fcolor; double size; int default_width; double width_scale; int verbose = FALSE; double minreg, maxreg, reg; char map_name[128]; struct GModule *module; struct Option *map_opt; struct Option *color_opt, *fcolor_opt, *rgbcol_opt, *zcol_opt; struct Option *type_opt, *display_opt; struct Option *icon_opt, *size_opt, *sizecolumn_opt, *rotcolumn_opt; struct Option *where_opt; struct Option *field_opt, *cat_opt, *lfield_opt; struct Option *lcolor_opt, *bgcolor_opt, *bcolor_opt; struct Option *lsize_opt, *font_opt, *xref_opt, *yref_opt; struct Option *attrcol_opt, *maxreg_opt, *minreg_opt; struct Option *width_opt, *wcolumn_opt, *wscale_opt; struct Option *render_opt; struct Flag *verbose_flag; /* please remove before GRASS 7 released */ struct Flag *id_flag, *table_acolors_flag, *cats_acolors_flag, *x_flag, *zcol_flag; struct cat_list *Clist; int *cats, ncat; LATTR lattr; struct Map_info Map; struct field_info *fi; dbDriver *driver; dbHandle handle; struct Cell_head window; BOUND_BOX box; double overlap; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("display, vector"); module->description = _("Displays user-specified vector map " "in the active graphics frame."); map_opt = G_define_standard_option(G_OPT_V_MAP); display_opt = G_define_option(); display_opt->key = "display"; display_opt->type = TYPE_STRING; display_opt->required = YES; display_opt->multiple = YES; display_opt->answer = "shape"; display_opt->options = "shape,cat,topo,dir,attr,zcoor"; display_opt->description = _("Display"); display_opt->descriptions = _("shape;Display geometry of features;" "cat;Display category numbers of features;" "topo;Display topology information (nodes, edges);" "dir;Display direction of linear features;" "attr;Display selected attribute based on 'attrcol';" "zcoor;Display z-coordinate of features (only for 3D vector maps)"); /* Query */ type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->answer = "point,line,boundary,centroid,area,face"; type_opt->options = "point,line,boundary,centroid,area,face"; type_opt->guisection = _("Selection"); field_opt = G_define_standard_option(G_OPT_V_FIELD); field_opt->label = _("Layer number (if -1, all layers are displayed)"); field_opt->gisprompt = "old_layer,layer,layer_all"; field_opt->guisection = _("Selection"); cat_opt = G_define_standard_option(G_OPT_V_CATS); cat_opt->guisection = _("Selection"); where_opt = G_define_standard_option(G_OPT_WHERE); where_opt->guisection = _("Selection"); /* Colors */ color_opt = G_define_option(); color_opt->key = "color"; color_opt->type = TYPE_STRING; color_opt->answer = DEFAULT_FG_COLOR; color_opt->label = _("Feature color"); color_opt->guisection = _("Colors"); color_opt->gisprompt = "old_color,color,color_none"; color_opt->description = _("Either a standard GRASS color, R:G:B triplet, or \"none\""); fcolor_opt = G_define_option(); fcolor_opt->key = "fcolor"; fcolor_opt->type = TYPE_STRING; fcolor_opt->answer = "200:200:200"; fcolor_opt->label = _("Area fill color"); fcolor_opt->guisection = _("Colors"); fcolor_opt->gisprompt = "old_color,color,color_none"; fcolor_opt->description = _("Either a standard GRASS color, R:G:B triplet, or \"none\""); rgbcol_opt = G_define_standard_option(G_OPT_COLUMN); rgbcol_opt->key = "rgb_column"; rgbcol_opt->guisection = _("Colors"); rgbcol_opt->description = _("Name of color definition column (for use with -a flag)"); rgbcol_opt->answer = "GRASSRGB"; zcol_opt = G_define_option(); zcol_opt->key = "zcolor"; zcol_opt->key_desc = "style"; zcol_opt->type = TYPE_STRING; zcol_opt->required = NO; zcol_opt->description = _("Type of color table (for use with -z flag)"); zcol_opt->answer = "terrain"; zcol_opt->guisection = _("Colors"); /* Lines */ width_opt = G_define_option(); width_opt->key = "width"; width_opt->type = TYPE_INTEGER; width_opt->answer = "0"; width_opt->guisection = _("Lines"); width_opt->description = _("Line width"); wcolumn_opt = G_define_standard_option(G_OPT_COLUMN); wcolumn_opt->key = "wcolumn"; wcolumn_opt->guisection = _("Lines"); wcolumn_opt->description = _("Name of column for line widths (these values will be scaled by wscale)"); wscale_opt = G_define_option(); wscale_opt->key = "wscale"; wscale_opt->type = TYPE_DOUBLE; wscale_opt->answer = "1"; wscale_opt->guisection = _("Lines"); wscale_opt->description = _("Scale factor for wcolumn"); /* Symbols */ icon_opt = G_define_option(); icon_opt->key = "icon"; icon_opt->type = TYPE_STRING; icon_opt->required = NO; icon_opt->multiple = NO; icon_opt->guisection = _("Symbols"); icon_opt->answer = "basic/x"; /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */ icon_opt->options = icon_files(); icon_opt->description = _("Point and centroid symbol"); size_opt = G_define_option(); size_opt->key = "size"; size_opt->type = TYPE_DOUBLE; size_opt->answer = "5"; size_opt->guisection = _("Symbols"); size_opt->label = _("Symbol size"); size_opt->description = _("When used with the size_column option this becomes the scale factor"); sizecolumn_opt = G_define_standard_option(G_OPT_COLUMN); sizecolumn_opt->key = "size_column"; sizecolumn_opt->guisection = _("Symbols"); sizecolumn_opt->description = _("Name of numeric column containing symbol size"); rotcolumn_opt = G_define_standard_option(G_OPT_COLUMN); rotcolumn_opt->key = "rot_column"; rotcolumn_opt->guisection = _("Symbols"); rotcolumn_opt->label = _("Name of numeric column containing symbol rotation angle"); rotcolumn_opt->description = _("Measured in degrees CCW from east"); /* Labels */ lfield_opt = G_define_standard_option(G_OPT_V_FIELD); lfield_opt->key = "llayer"; lfield_opt->guisection = _("Labels"); lfield_opt->description = _("Layer number for labels (default: the given layer number)"); attrcol_opt = G_define_standard_option(G_OPT_COLUMN); attrcol_opt->key = "attrcol"; attrcol_opt->multiple = NO; /* or fix attr.c, around line 102 */ attrcol_opt->guisection = _("Labels"); attrcol_opt->description = _("Name of column to be displayed"); lcolor_opt = G_define_option(); lcolor_opt->key = "lcolor"; lcolor_opt->type = TYPE_STRING; lcolor_opt->answer = "red"; lcolor_opt->label = _("Label color"); lcolor_opt->guisection = _("Labels"); lcolor_opt->gisprompt = "old_color,color,color"; lcolor_opt->description = _("Either a standard color name or R:G:B triplet"); bgcolor_opt = G_define_option(); bgcolor_opt->key = "bgcolor"; bgcolor_opt->type = TYPE_STRING; bgcolor_opt->answer = "none"; bgcolor_opt->guisection = _("Labels"); bgcolor_opt->label = _("Label background color"); bgcolor_opt->gisprompt = "old_color,color,color_none"; bgcolor_opt->description = _("Either a standard GRASS color, R:G:B triplet, or \"none\""); bcolor_opt = G_define_option(); bcolor_opt->key = "bcolor"; bcolor_opt->type = TYPE_STRING; bcolor_opt->answer = "none"; bcolor_opt->guisection = _("Labels"); bcolor_opt->label = _("Label border color"); bcolor_opt->gisprompt = "old_color,color,color_none"; bcolor_opt->description = _("Either a standard GRASS color, R:G:B triplet, or \"none\""); lsize_opt = G_define_option(); lsize_opt->key = "lsize"; lsize_opt->type = TYPE_INTEGER; lsize_opt->answer = "8"; lsize_opt->guisection = _("Labels"); lsize_opt->description = _("Label size (pixels)"); font_opt = G_define_option(); font_opt->key = "font"; font_opt->type = TYPE_STRING; font_opt->guisection = _("Labels"); font_opt->description = _("Font name"); xref_opt = G_define_option(); xref_opt->key = "xref"; xref_opt->type = TYPE_STRING; xref_opt->guisection = _("Labels"); xref_opt->answer = "left"; xref_opt->options = "left,center,right"; xref_opt->description = _("Label horizontal justification"); yref_opt = G_define_option(); yref_opt->key = "yref"; yref_opt->type = TYPE_STRING; yref_opt->guisection = _("Labels"); yref_opt->answer = "center"; yref_opt->options = "top,center,bottom"; yref_opt->description = _("Label vertical justification"); minreg_opt = G_define_option(); minreg_opt->key = "minreg"; minreg_opt->type = TYPE_DOUBLE; minreg_opt->required = NO; minreg_opt->description = _("Minimum region size (average from height and width) " "when map is displayed"); maxreg_opt = G_define_option(); maxreg_opt->key = "maxreg"; maxreg_opt->type = TYPE_DOUBLE; maxreg_opt->required = NO; maxreg_opt->description = _("Maximum region size (average from height and width) " "when map is displayed"); render_opt = G_define_option(); render_opt->key = "render"; render_opt->type = TYPE_STRING; render_opt->required = NO; render_opt->multiple = NO; render_opt->answer = "c"; render_opt->options = "g,r,d,c,l"; render_opt->description = _("Rendering method for filled polygons"); render_opt->descriptions = _("g;use the libgis render functions (features: clipping);" "r;use the raster graphics library functions (features: polylines);" "d;use the display library basic functions (features: polylines);" "c;use the display library clipping functions (features: clipping);" "l;use the display library culling functions (features: culling, polylines)"); /* please remove before GRASS 7 released */ verbose_flag = G_define_flag(); verbose_flag->key = 'v'; verbose_flag->description = _("Run verbosely"); /* Colors */ table_acolors_flag = G_define_flag(); table_acolors_flag->key = 'a'; table_acolors_flag->guisection = _("Colors"); table_acolors_flag->description = _("Get colors from map table column (of form RRR:GGG:BBB)"); cats_acolors_flag = G_define_flag(); cats_acolors_flag->key = 'c'; cats_acolors_flag->guisection = _("Colors"); cats_acolors_flag->description = _("Random colors according to category number " "(or layer number if 'layer=-1' is given)"); /* Query */ id_flag = G_define_flag(); id_flag->key = 'i'; id_flag->guisection = _("Selection"); id_flag->description = _("Use values from 'cats' option as feature id"); x_flag = G_define_flag(); x_flag->key = 'x'; x_flag->description = _("Don't add to list of vectors and commands in monitor " "(it won't be drawn if the monitor is refreshed)"); zcol_flag = G_define_flag(); zcol_flag->key = 'z'; zcol_flag->description = _("Colorize polygons according to z height"); zcol_flag->guisection = _("Colors"); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (G_strcasecmp(render_opt->answer, "g") == 0) render = RENDER_GPP; else if (G_strcasecmp(render_opt->answer, "r") == 0) render = RENDER_RPA; else if (G_strcasecmp(render_opt->answer, "d") == 0) render = RENDER_DP; else if (G_strcasecmp(render_opt->answer, "c") == 0) render = RENDER_DPC; else if (G_strcasecmp(render_opt->answer, "l") == 0) render = RENDER_DPL; else render = RENDER_GPP; /* please remove -v flag before GRASS 7 released */ if (verbose_flag->answer) { G_putenv("GRASS_VERBOSE", "3"); G_warning(_("The '-v' flag is superseded and will be removed " "in future. Please use '--verbose' instead.")); } /* but keep this */ if (G_verbose() > G_verbose_std()) verbose = TRUE; G_get_set_window(&window); if (R_open_driver() != 0) G_fatal_error(_("No graphics device selected")); /* Read map options */ /* Check min/max region */ reg = ((window.east - window.west) + (window.north - window.south)) / 2; if (minreg_opt->answer) { minreg = atof(minreg_opt->answer); if (reg < minreg) { G_message(_("Region size is lower than minreg, nothing displayed.")); D_add_to_list(G_recreate_command()); exit(EXIT_SUCCESS); } } if (maxreg_opt->answer) { maxreg = atof(maxreg_opt->answer); if (reg > maxreg) { G_message(_("Region size is greater than maxreg, nothing displayed.")); D_add_to_list(G_recreate_command()); exit(EXIT_SUCCESS); } } G_strcpy(map_name, map_opt->answer); default_width = atoi(width_opt->answer); if (default_width < 0) default_width = 0; width_scale = atof(wscale_opt->answer); if (table_acolors_flag->answer && cats_acolors_flag->answer) { cats_acolors_flag->answer = '\0'; G_warning(_("The '-c' and '-a' flags cannot be used together, " "the '-c' flag will be ignored!")); } color = G_standard_color_rgb(WHITE); ret = G_str_to_color(color_opt->answer, &r, &g, &b); if (ret == 1) { has_color = 1; color.r = r; color.g = g; color.b = b; } else if (ret == 2) { /* none */ has_color = 0; } else if (ret == 0) { /* error */ G_fatal_error(_("Unknown color: [%s]"), color_opt->answer); } fcolor = G_standard_color_rgb(WHITE); ret = G_str_to_color(fcolor_opt->answer, &r, &g, &b); if (ret == 1) { has_fcolor = 1; fcolor.r = r; fcolor.g = g; fcolor.b = b; } else if (ret == 2) { /* none */ has_fcolor = 0; } else if (ret == 0) { /* error */ G_fatal_error(_("Unknown color: '%s'"), fcolor_opt->answer); } size = atof(size_opt->answer); /* Make sure map is available */ mapset = G_find_vector2(map_name, ""); if (mapset == NULL) G_fatal_error(_("Vector map <%s> not found"), map_name); /* if where_opt was specified select categories from db * otherwise parse cat_opt */ Clist = Vect_new_cat_list(); Clist->field = atoi(field_opt->answer); /* open vector */ level = Vect_open_old(&Map, map_name, mapset); if (where_opt->answer) { if (Clist->field < 1) G_fatal_error(_("'layer' must be > 0 for 'where'.")); chcat = 1; if ((fi = Vect_get_field(&Map, Clist->field)) == NULL) G_fatal_error(_("Database connection not defined")); if (fi != NULL) { driver = db_start_driver(fi->driver); if (driver == NULL) G_fatal_error(_("Unable to start driver <%s>"), fi->driver); db_init_handle(&handle); db_set_handle(&handle, fi->database, NULL); if (db_open_database(driver, &handle) != DB_OK) G_fatal_error(_("Unable to open database <%s>"), fi->database); ncat = db_select_int(driver, fi->table, fi->key, where_opt->answer, &cats); db_close_database(driver); db_shutdown_driver(driver); Vect_array_to_cat_list(cats, ncat, Clist); } } else if (cat_opt->answer) { if (Clist->field < 1) G_fatal_error(_("'layer' must be > 0 for 'cats'.")); chcat = 1; ret = Vect_str_to_cat_list(cat_opt->answer, Clist); if (ret > 0) G_warning(_("%d errors in cat option"), ret); } type = Vect_option_to_types(type_opt); i = 0; display = 0; while (display_opt->answers[i]) { switch (display_opt->answers[i][0]) { case 's': display |= DISP_SHAPE; break; case 'c': display |= DISP_CAT; break; case 't': display |= DISP_TOPO; break; case 'd': display |= DISP_DIR; break; case 'a': display |= DISP_ATTR; break; case 'z': display |= DISP_ZCOOR; break; } i++; } /* Read label options */ if (lfield_opt->answer != NULL) lattr.field = atoi(lfield_opt->answer); else lattr.field = Clist->field; lattr.color.R = lattr.color.G = lattr.color.B = 255; if (G_str_to_color(lcolor_opt->answer, &r, &g, &b)) { lattr.color.R = r; lattr.color.G = g; lattr.color.B = b; } lattr.has_bgcolor = 0; if (G_str_to_color(bgcolor_opt->answer, &r, &g, &b) == 1) { lattr.has_bgcolor = 1; lattr.bgcolor.R = r; lattr.bgcolor.G = g; lattr.bgcolor.B = b; } lattr.has_bcolor = 0; if (G_str_to_color(bcolor_opt->answer, &r, &g, &b) == 1) { lattr.has_bcolor = 1; lattr.bcolor.R = r; lattr.bcolor.G = g; lattr.bcolor.B = b; } lattr.size = atoi(lsize_opt->answer); lattr.font = font_opt->answer; switch (xref_opt->answer[0]) { case 'l': lattr.xref = LLEFT; break; case 'c': lattr.xref = LCENTER; break; case 'r': lattr.xref = LRIGHT; break; } switch (yref_opt->answer[0]) { case 't': lattr.yref = LTOP; break; case 'c': lattr.yref = LCENTER; break; case 'b': lattr.yref = LBOTTOM; break; } D_setup(0); G_setup_plot(D_get_d_north(), D_get_d_south(), D_get_d_west(), D_get_d_east(), D_move_abs, D_cont_abs); if (verbose) G_message(_("Plotting ...")); if (level >= 2) Vect_get_map_box(&Map, &box); if (level >= 2 && (window.north < box.S || window.south > box.N || window.east < box.W || window.west > G_adjust_easting(box.E, &window))) { G_message(_("The bounding box of the map is outside the current region, " "nothing drawn.")); stat = 0; } else { overlap = G_window_percentage_overlap(&window, box.N, box.S, box.E, box.W); G_debug(1, "overlap = %f \n", overlap); if (overlap < 1) Vect_set_constraint_region(&Map, window.north, window.south, window.east, window.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX); /* default line width */ if (!wcolumn_opt->answer) D_line_width(default_width); if (type & GV_AREA) { if (level >= 2) { if (display & DISP_SHAPE) { stat = darea(&Map, Clist, has_color ? &color : NULL, has_fcolor ? &fcolor : NULL, chcat, (int)id_flag->answer, table_acolors_flag->answer, cats_acolors_flag->answer, &window, rgbcol_opt->answer, default_width, wcolumn_opt->answer, width_scale, zcol_flag->answer, zcol_opt->answer); } if (wcolumn_opt->answer) D_line_width(default_width); } else G_warning(_("Unable to display areas, topology not available")); } if (display & DISP_SHAPE) { if (id_flag->answer && level < 2) { G_warning(_("Unable to display lines by id, topology not available")); } else { stat = plot1(&Map, type, Clist, has_color ? &color : NULL, has_fcolor ? &fcolor : NULL, chcat, icon_opt->answer, size, sizecolumn_opt->answer, rotcolumn_opt->answer, (int)id_flag->answer, table_acolors_flag->answer, cats_acolors_flag->answer, rgbcol_opt->answer, default_width, wcolumn_opt->answer, width_scale, zcol_flag->answer, zcol_opt->answer); if (wcolumn_opt->answer) D_line_width(default_width); } } if (has_color) { R_RGB_color(color.r, color.g, color.b); if (display & DISP_DIR) stat = dir(&Map, type, Clist, chcat, size); } /* reset line width: Do we need to get line width from display * driver (not implemented)? It will help restore previous line * width (not just 0) determined by another module (e.g., * d.linewidth). */ if (!wcolumn_opt->answer) R_line_width(0); if (display & DISP_CAT) stat = label(&Map, type, Clist, &lattr, chcat); if (display & DISP_ATTR) stat = attr(&Map, type, attrcol_opt->answer, Clist, &lattr, chcat); if (display & DISP_ZCOOR) stat = zcoor(&Map, type, &lattr); if (display & DISP_TOPO) { if (level >= 2) stat = topo(&Map, type, &lattr); else G_warning(_("Unable to display topology, not available")); } } if (!x_flag->answer) { D_add_to_list(G_recreate_command()); D_set_dig_name(G_fully_qualified_name(map_name, mapset)); D_add_to_dig_list(G_fully_qualified_name(map_name, mapset)); } R_close_driver(); if (verbose) G_done_msg(" "); Vect_close(&Map); Vect_destroy_cat_list(Clist); exit(stat); }
void print_info(const struct Map_info *Map) { int i, map_type; char line[1024]; char timebuff[256]; struct TimeStamp ts; int time_ok, first_time_ok, second_time_ok; struct bound_box box; char tmp1[1024], tmp2[1024]; time_ok = first_time_ok = second_time_ok = FALSE; map_type = Vect_maptype(Map); /* Check the Timestamp */ time_ok = G_read_vector_timestamp(Vect_get_name(Map), NULL, "", &ts); /* Check for valid entries, show none if no timestamp available */ if (time_ok == TRUE) { if (ts.count > 0) first_time_ok = TRUE; if (ts.count > 1) second_time_ok = TRUE; } divider('+'); sprintf(line, "%-17s%s", _("Name:"), Vect_get_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Mapset:"), Vect_get_mapset(Map)); printline(line); sprintf(line, "%-17s%s", _("Location:"), G_location()); printline(line); sprintf(line, "%-17s%s", _("Database:"), G_gisdbase()); printline(line); sprintf(line, "%-17s%s", _("Title:"), Vect_get_map_name(Map)); printline(line); sprintf(line, "%-17s1:%d", _("Map scale:"), Vect_get_scale(Map)); printline(line); sprintf(line, "%-17s%s", _("Name of creator:"), Vect_get_person(Map)); printline(line); sprintf(line, "%-17s%s", _("Organization:"), Vect_get_organization(Map)); printline(line); sprintf(line, "%-17s%s", _("Source date:"), Vect_get_map_date(Map)); printline(line); /* This shows the TimeStamp (if present) */ if (time_ok == TRUE && (first_time_ok || second_time_ok)) { G_format_timestamp(&ts, timebuff); sprintf(line, "%-17s%s", _("Timestamp (first layer): "), timebuff); printline(line); } else { strcpy(line, _("Timestamp (first layer): none")); printline(line); } divider('|'); if (map_type == GV_FORMAT_OGR || map_type == GV_FORMAT_OGR_DIRECT) { sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_finfo_format_info(Map)); printline(line); /* for OGR format print also datasource and layer */ sprintf(line, "%-17s%s", _("OGR layer:"), Vect_get_finfo_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("OGR datasource:"), Vect_get_finfo_dsn_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Feature type:"), Vect_get_finfo_geometry_type(Map)); printline(line); } else if (map_type == GV_FORMAT_POSTGIS) { int topo_format; char *toposchema_name, *topogeom_column; int topo_geo_only; const struct Format_info *finfo; finfo = Vect_get_finfo(Map); sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_finfo_format_info(Map)); printline(line); /* for PostGIS format print also datasource and layer */ sprintf(line, "%-17s%s", _("DB table:"), Vect_get_finfo_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("DB name:"), Vect_get_finfo_dsn_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Geometry column:"), finfo->pg.geom_column); printline(line); sprintf(line, "%-17s%s", _("Feature type:"), Vect_get_finfo_geometry_type(Map)); printline(line); topo_format = Vect_get_finfo_topology_info(Map, &toposchema_name, &topogeom_column, &topo_geo_only); if (topo_format == GV_TOPO_POSTGIS) { sprintf(line, "%-17s%s (%s %s%s)", _("Topology:"), "PostGIS", _("schema:"), toposchema_name, topo_geo_only ? ", topo-geo-only: yes" : ""); printline(line); sprintf(line, "%-17s%s", _("Topology column:"), topogeom_column); } else sprintf(line, "%-17s%s", _("Topology:"), "pseudo (simple features)"); printline(line); } else { sprintf(line, "%-17s%s", _("Map format:"), Vect_maptype_info(Map)); printline(line); } divider('|'); sprintf(line, " %s: %s (%s: %i)", _("Type of map"), _("vector"), _("level"), Vect_level(Map)); printline(line); if (Vect_level(Map) > 0) { printline(""); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of points:"), Vect_get_num_primitives(Map, GV_POINT), _("Number of centroids:"), Vect_get_num_primitives(Map, GV_CENTROID)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of lines:"), Vect_get_num_primitives(Map, GV_LINE), _("Number of boundaries:"), Vect_get_num_primitives(Map, GV_BOUNDARY)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of areas:"), Vect_get_num_areas(Map), _("Number of islands:"), Vect_get_num_islands(Map)); printline(line); if (Vect_is_3d(Map)) { sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of faces:"), Vect_get_num_primitives(Map, GV_FACE), _("Number of kernels:"), Vect_get_num_primitives(Map, GV_KERNEL)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of volumes:"), Vect_get_num_volumes(Map), _("Number of holes:"), Vect_get_num_holes(Map)); printline(line); } printline(""); sprintf(line, " %-24s%s", _("Map is 3D:"), Vect_is_3d(Map) ? _("Yes") : _("No")); printline(line); sprintf(line, " %-24s%-9d", _("Number of dblinks:"), Vect_get_num_dblinks(Map)); printline(line); } printline(""); /* this differs from r.info in that proj info IS taken from the map here, not the location settings */ /* Vect_get_proj_name() and _zone() are typically unset?! */ if (G_projection() == PROJECTION_UTM) { int utm_zone; utm_zone = Vect_get_zone(Map); if (utm_zone < 0 || utm_zone > 60) strcpy(tmp1, _("invalid")); else if (utm_zone == 0) strcpy(tmp1, _("unspecified")); else sprintf(tmp1, "%d", utm_zone); sprintf(line, " %s: %s (%s %s)", _("Projection"), Vect_get_proj_name(Map), _("zone"), tmp1); } else sprintf(line, " %s: %s", _("Projection"), Vect_get_proj_name(Map)); printline(line); printline(""); Vect_get_map_box(Map, &box); G_format_northing(box.N, tmp1, G_projection()); G_format_northing(box.S, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'N', tmp1, 'S', tmp2); printline(line); G_format_easting(box.E, tmp1, G_projection()); G_format_easting(box.W, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'E', tmp1, 'W', tmp2); printline(line); if (Vect_is_3d(Map)) { format_double(box.B, tmp1); format_double(box.T, tmp2); sprintf(line, " %c: %17s %c: %17s", 'B', tmp1, 'T', tmp2); printline(line); } printline(""); format_double(Vect_get_thresh(Map), tmp1); sprintf(line, " %s: %s", _("Digitization threshold"), tmp1); printline(line); sprintf(line, " %s:", _("Comment")); printline(line); sprintf(line, " %s", Vect_get_comment(Map)); printline(line); divider('+'); fprintf(stdout, "\n"); }
int main(int argc, char **argv) { struct GModule *module; struct opts opt; struct Map_info In, Out; BOUND_BOX box; int field, type; int ret; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, transformation, 3D"); module->description = _("Performs transformation of 2D vector features to 3D."); parse_args(&opt); if (G_parser(argc, argv)) exit(EXIT_FAILURE); field = atoi(opt.field->answer); type = Vect_option_to_types(opt.type); if (!opt.reverse->answer) { if ((!opt.height->answer && !opt.column->answer) || (opt.height->answer && opt.column->answer)) { G_fatal_error(_("Either '%s' or '%s' parameter have to be used"), opt.height->key, opt.column->key); } } else { if (opt.height->answer) { G_warning(_("Parameters '%s' ignored"), opt.height->key); } } if (opt.reverse->answer && opt.table->answer) { G_fatal_error(_("Attribute table required")); } Vect_check_input_output_name(opt.input->answer, opt.output->answer, GV_FATAL_EXIT); /* open input vector, topology not needed */ Vect_set_open_level(1); if (Vect_open_old(&In, opt.input->answer, "") < 1) G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer); if (opt.reverse->answer && !Vect_is_3d(&In)) { Vect_close(&In); G_fatal_error(_("Vector map <%s> is 2D"), opt.input->answer); } if (!opt.reverse->answer && Vect_is_3d(&In)) { Vect_close(&In); G_fatal_error(_("Vector map <%s> is 3D"), opt.input->answer); } /* create output vector */ Vect_set_open_level(2); if (Vect_open_new(&Out, opt.output->answer, opt.reverse->answer ? WITHOUT_Z : WITH_Z) == -1) G_fatal_error(_("Unable to create vector map <%s>"), opt.output->answer); /* copy history & header */ Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Out); if (opt.reverse->answer && !opt.table->answer) { G_message(_("Copying attributes...")); if (Vect_copy_tables(&In, &Out, 0) == -1) { G_warning(_("Unable to copy attributes")); } } G_message(_("Transforming features...")); ret = 0; if (opt.reverse->answer) { /* 3d -> 2d */ ret = trans3d(&In, &Out, type, field, opt.column->answer); } else { /* 2d -> 3d */ double height = 0.; if (opt.height->answer) { height = atof(opt.height->answer); } ret = trans2d(&In, &Out, type, height, field, opt.column->answer); } if (ret < 0) { Vect_close(&In); Vect_close(&Out); Vect_delete(opt.output->answer); G_fatal_error(_("%s failed"), G_program_name()); } if (!opt.reverse->answer && !opt.table->answer) { G_message(_("Copying attributes...")); if (Vect_copy_tables(&In, &Out, 0) == -1) { G_warning(_("Unable to copy attributes")); } } Vect_close(&In); Vect_build(&Out); if (!opt.reverse->answer) { Vect_get_map_box(&Out, &box); G_message(_("Vertical extent of vector map <%s>: B: %f T: %f"), opt.output->answer, box.B, box.T); } Vect_close(&Out); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { FILE *ascii; struct Option *input, *output, *type_opt, *dp_opt, *layer_opt, *scale; struct Flag *coorcorr, *numatts, *labels; int itype, *types = NULL, typenum = 0, dp, i; struct Map_info Map; struct bound_box box; struct GModule *module; int layer, level; double zscale = 1.0, llscale = 1.0; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("export")); G_add_keyword("VTK"); module->description = _("Converts a vector map to VTK ASCII output."); input = G_define_standard_option(G_OPT_V_INPUT); output = G_define_standard_option(G_OPT_F_OUTPUT); output->required = NO; output->description = _("Name for output VTK file"); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->answer = "point,kernel,centroid,line,boundary,area,face"; type_opt->options = "point,kernel,centroid,line,boundary,area,face"; dp_opt = G_define_option(); dp_opt->key = "dp"; dp_opt->type = TYPE_INTEGER; dp_opt->required = NO; dp_opt->description = _("Number of significant digits (floating point only)"); scale = G_define_option(); scale->key = "scale"; scale->type = TYPE_DOUBLE; scale->required = NO; scale->description = _("Scale factor for elevation"); scale->answer = "1.0"; layer_opt = G_define_option(); layer_opt->key = "layer"; layer_opt->type = TYPE_INTEGER; layer_opt->required = NO; layer_opt->answer = "1"; layer_opt->description = _("Layer number"); coorcorr = G_define_flag(); coorcorr->key = 'c'; coorcorr->description = _("Correct the coordinates to fit the VTK-OpenGL precision"); numatts = G_define_flag(); numatts->key = 'n'; numatts->description = _("Export numeric attribute table fields as VTK scalar variables"); labels = NULL; /* to avoid compiler warning about "unused variable"*/ /* not yet supported labels = G_define_flag(); labels->key = 'l'; labels->description = _("Export text attribute table fields as VTK labels"); */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); for (i = 0; type_opt->answers && type_opt->answers[i]; i++) typenum++; if (typenum > 0) { types = (int *)calloc(typenum, sizeof(int)); } else { G_fatal_error("Usage: Wrong vector type"); } i = 0; while (type_opt->answers[i]) { types[i] = -1; switch (type_opt->answers[i][0]) { case 'p': types[i] = GV_POINT; break; case 'k': types[i] = GV_KERNEL; break; case 'c': types[i] = GV_CENTROID; break; case 'l': types[i] = GV_LINE; break; case 'b': types[i] = GV_BOUNDARY; break; case 'a': types[i] = GV_AREA; break; case 'f': types[i] = GV_FACE; break; } i++; } itype = Vect_option_to_types(type_opt); /* read and compute the scale factor */ sscanf(scale->answer, "%lf", &zscale); /*if LL projection, convert the elevation values to degrees */ if (G_projection() == PROJECTION_LL) { llscale = M_PI / (180) * 6378137; zscale /= llscale; printf("Scale %g\n", zscale); } /*The precision of the output */ if (dp_opt->answer) { if (sscanf(dp_opt->answer, "%d", &dp) != 1) G_fatal_error(_("Failed to interpret 'dp' parameter as an integer")); if (dp > 8 || dp < 0) G_fatal_error(_("dp has to be from 0 to 8")); } else { dp = 8; /*This value is taken from the lib settings in G_feature_easting */ } /*The Layer */ if (layer_opt->answer) { if (sscanf(layer_opt->answer, "%d", &layer) != 1) G_fatal_error(_("Failed to interpret 'layer' parameter as an integer")); } else { layer = 1; } if (output->answer) { ascii = fopen(output->answer, "w"); if (ascii == NULL) { G_fatal_error(_("Unable to open file <%s>"), output->answer); } } else { ascii = stdout; } /* Open input vector */ level = Vect_open_old(&Map, input->answer, ""); if (level < 2 && (itype & GV_AREA)) G_fatal_error(_("Export of areas requires topology. " "Please adjust '%s' option or rebuild topology."), type_opt->key); if (level == 2) Vect_get_map_box(&Map, &box); else { int i, type, first = TRUE; struct line_pnts *Points = Vect_new_line_struct(); Vect_rewind(&Map); while ((type = Vect_read_next_line(&Map, Points, NULL)) > 0) { if (first) { box.E = box.W = Points->x[0]; box.N = box.S = Points->y[0]; box.B = box.T = Points->z[0]; first = FALSE; } for (i = 1; i < Points->n_points; i++) { if (Points->x[i] > box.E) box.E = Points->x[i]; else if (Points->x[i] < box.W) box.W = Points->x[i]; if (Points->y[i] > box.N) box.N = Points->y[i]; else if (Points->y[i] < box.S) box.S = Points->y[i]; if (Points->z[i] > box.T) box.T = Points->z[i]; else if (Points->z[i] < box.B) box.B = Points->z[i]; } } Vect_destroy_line_struct(Points); } /*Correct the coordinates, so the precision of VTK is not hurt :( */ if (coorcorr->answer) { /*Use the center of the vector's bbox as extent */ y_extent = (box.N + box.S) / 2; x_extent = (box.W + box.E) / 2; } else { x_extent = 0; y_extent = 0; } /*Write the header */ write_vtk_head(ascii, &Map); /*Write the geometry and data */ write_vtk(ascii, &Map, layer, types, typenum, dp, zscale, numatts->answer, 0 ); /* change to this, when labels get supported: write_vtk(ascii, &Map, layer, types, typenum, dp, zscale, numatts->answer, labels->answer ); */ if (ascii != NULL) fclose(ascii); Vect_close(&Map); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Option *input, *output, *zshift, *height, *elevation, *hcolumn, *type, *field, *cats, *where, *interp, *scale, *null; } opt; struct { struct Flag *trace; } flag; struct Map_info In, Out; struct line_pnts *Points; struct line_cats *Cats; struct bound_box map_box; struct cat_list *cat_list; struct Cell_head window; int field; int only_type, cat; int fdrast, interp_method, trace; double objheight, objheight_default, voffset; double scale, null_val; struct field_info *Fi; dbDriver *driver = NULL; char *comment; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("geometry")); G_add_keyword(_("sampling")); G_add_keyword(_("3D")); module->label = _("Extrudes flat vector features to 3D vector features with defined height."); module->description = _("Optionally the height can be derived from sampling of elevation raster map."); flag.trace = G_define_flag(); flag.trace->key = 't'; flag.trace->description = _("Trace elevation"); flag.trace->guisection = _("Elevation"); opt.input = G_define_standard_option(G_OPT_V_INPUT); opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL); opt.field->guisection = _("Selection"); opt.cats = G_define_standard_option(G_OPT_V_CATS); opt.cats->guisection = _("Selection"); opt.where = G_define_standard_option(G_OPT_DB_WHERE); opt.where->guisection = _("Selection"); opt.type = G_define_standard_option(G_OPT_V_TYPE); opt.type->answer = "point,line,area"; opt.type->options = "point,line,area"; opt.type->guisection = _("Selection"); opt.output = G_define_standard_option(G_OPT_V_OUTPUT); opt.zshift = G_define_option(); opt.zshift->key = "zshift"; opt.zshift->description = _("Shifting value for z coordinates"); opt.zshift->type = TYPE_DOUBLE; opt.zshift->required = NO; opt.zshift->answer = "0"; opt.zshift->guisection = _("Height"); opt.height = G_define_option(); opt.height->key = "height"; opt.height->type = TYPE_DOUBLE; opt.height->required = NO; opt.height->multiple = NO; opt.height->description = _("Fixed height for 3D vector features"); opt.height->guisection = _("Height"); opt.hcolumn = G_define_standard_option(G_OPT_DB_COLUMN); opt.hcolumn->key = "height_column"; opt.hcolumn->multiple = NO; opt.hcolumn->description = _("Name of attribute column with feature height"); opt.hcolumn->guisection = _("Height"); /* raster sampling */ opt.elevation = G_define_standard_option(G_OPT_R_ELEV); opt.elevation->required = NO; opt.elevation->description = _("Elevation raster map for height extraction"); opt.elevation->guisection = _("Elevation"); opt.interp = G_define_standard_option(G_OPT_R_INTERP_TYPE); opt.interp->answer = "nearest"; opt.interp->guisection = _("Elevation"); opt.scale = G_define_option(); opt.scale->key = "scale"; opt.scale->type = TYPE_DOUBLE; opt.scale->description = _("Scale factor sampled raster values"); opt.scale->answer = "1.0"; opt.scale->guisection = _("Elevation"); opt.null = G_define_option(); opt.null->key = "null_value"; opt.null->type = TYPE_DOUBLE; opt.null->description = _("Height for sampled raster NULL values"); opt.null->guisection = _("Elevation"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (!opt.height->answer && !opt.hcolumn->answer) { G_fatal_error(_("One of '%s' or '%s' parameters must be set"), opt.height->key, opt.hcolumn->key); } sscanf(opt.zshift->answer, "%lf", &voffset); G_debug(1, "voffset = %f", voffset); if (opt.height->answer) sscanf(opt.height->answer, "%lf", &objheight); else objheight = 0.; G_debug(1, "objheight = %f", objheight); objheight_default = objheight; only_type = Vect_option_to_types(opt.type); /* sampling method */ interp_method = Rast_option_to_interp_type(opt.interp); /* used to scale sampled raster values */ scale = atof(opt.scale->answer); /* is null value defined */ if (opt.null->answer) null_val = atof(opt.null->answer); /* trace elevation */ trace = flag.trace->answer ? TRUE : FALSE; /* set input vector map name and mapset */ Vect_check_input_output_name(opt.input->answer, opt.output->answer, G_FATAL_EXIT); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_set_open_level(2); /* topology required for input */ /* opening input vector map */ if (Vect_open_old2(&In, opt.input->answer, "", opt.field->answer) < 0) G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer); Vect_set_error_handler_io(&In, &Out); /* creating output vector map */ if (Vect_open_new(&Out, opt.output->answer, WITH_Z) < 0) G_fatal_error(_("Unable to create vector map <%s>"), opt.output->answer); field = Vect_get_field_number(&In, opt.field->answer); if ((opt.hcolumn->answer || opt.cats->answer || opt.where->answer) && field == -1) { G_warning(_("Invalid layer number (%d). " "Parameter '%s', '%s' or '%s' specified, assuming layer '1'."), field, opt.hcolumn->key, opt.cats->key, opt.where->key); field = 1; } /* set constraint for cats or where */ cat_list = NULL; if (field > 0) cat_list = Vect_cats_set_constraint(&In, field, opt.where->answer, opt.cats->answer); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); /* opening database connection, if required */ if (opt.hcolumn->answer) { int ctype; dbColumn *column; if ((Fi = Vect_get_field(&In, field)) == NULL) G_fatal_error(_("Database connection not defined for layer %d"), field); if ((driver = db_start_driver_open_database(Fi->driver, Fi->database)) == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_set_error_handler_driver(driver); if (db_get_column(driver, Fi->table, opt.hcolumn->answer, &column) != DB_OK) G_fatal_error(_("Column <%s> does not exist"), opt.hcolumn->answer); else db_free_column(column); ctype = db_column_Ctype(driver, Fi->table, opt.hcolumn->answer); if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_STRING && ctype != DB_C_TYPE_DOUBLE) { G_fatal_error(_("Column <%s>: invalid data type"), opt.hcolumn->answer); } } /* do we work with elevation raster? */ fdrast = -1; if (opt.elevation->answer) { /* raster setup */ G_get_window(&window); /* open the elev raster, and check for error condition */ fdrast = Rast_open_old(opt.elevation->answer, ""); } /* if area */ if (only_type & GV_AREA) { int area, nareas, centroid; nareas = Vect_get_num_areas(&In); G_debug(2, "n_areas = %d", nareas); if (nareas > 0) G_message(_("Extruding areas...")); for (area = 1; area <= nareas; area++) { G_debug(3, "area = %d", area); G_percent(area, nareas, 2); if (!Vect_area_alive(&In, area)) continue; centroid = Vect_get_area_centroid(&In, area); if (!centroid) { G_warning(_("Skipping area %d without centroid"), area); continue; } Vect_read_line(&In, NULL, Cats, centroid); if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list)) continue; /* height attribute */ if (opt.hcolumn->answer) { cat = Vect_get_area_cat(&In, area, field); if (cat == -1) { G_warning(_("No category defined for area %d. Using default fixed height %f."), area, objheight_default); objheight = objheight_default; } if (get_height(Fi, opt.hcolumn->answer, driver, cat, &objheight) != 0) { G_warning(_("Unable to fetch height from DB for area %d. Using default fixed height %f."), area, objheight_default); objheight = objheight_default; } } /* if opt.hcolumn->answer */ Vect_get_area_points(&In, area, Points); G_debug(3, "area: %d height: %f", area, objheight); extrude(&In, &Out, Cats, Points, fdrast, trace, interp_method, scale, opt.null->answer ? TRUE : FALSE, null_val, objheight, voffset, &window, GV_AREA, centroid); } /* foreach area */ } if (only_type > 0) { int line, nlines; int type; G_debug(1, "other than areas"); /* loop through each line in the dataset */ nlines = Vect_get_num_lines(&In); G_message(_("Extruding features...")); for (line = 1; line <= nlines; line++) { /* progress feedback */ G_percent(line, nlines, 2); if (!Vect_line_alive(&In, line)) continue; /* read line */ type = Vect_read_line(&In, Points, Cats, line); if (!(type & only_type)) continue; if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list)) continue; /* height attribute */ if (opt.hcolumn->answer) { cat = Vect_get_line_cat(&In, line, field); if (cat == -1) { G_warning(_("No category defined for feature %d. Using default fixed height %f."), line, objheight_default); objheight = objheight_default; } if (get_height(Fi, opt.hcolumn->answer, driver, cat, &objheight) != 0) { G_warning(_("Unable to fetch height from DB for line %d. Using default fixed height %f."), line, objheight_default); objheight = objheight_default; } } /* if opt.hcolumn->answer */ extrude(&In, &Out, Cats, Points, fdrast, trace, interp_method, scale, opt.null->answer ? TRUE : FALSE, null_val, objheight, voffset, &window, type, -1); } /* for each line */ } /* else if area */ if (driver) { db_close_database(driver); db_shutdown_driver(driver); } G_important_message(_("Copying attribute table...")); if (field < 0) Vect_copy_tables(&In, &Out, 0); else Vect_copy_table_by_cat_list(&In, &Out, field, field, NULL, GV_1TABLE, cat_list); Vect_build(&Out); /* header */ G_asprintf(&comment, "Generated by %s from vector map <%s>", G_program_name(), Vect_get_full_name(&In)); Vect_set_comment(&Out, comment); G_free(comment); Vect_get_map_box(&Out, &map_box); Vect_close(&In); Vect_close(&Out); Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats); G_done_msg("T: %f B: %f.", map_box.T, map_box.B); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int i; double x; struct Cell_head cellhd, window; const char *value; const char *name; struct GModule *module; struct { struct Flag *dflt, *cur; } flag; struct { struct Option *map, *north, *south, *east, *west, *raster, *vect, *region, *align; } parm; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("metadata")); module->description = _("Sets the boundary definitions for a raster map."); /* flags */ flag.cur = G_define_flag(); flag.cur->key = 'c'; flag.cur->description = _("Set from current region"); flag.cur->guisection = _("Existing"); flag.dflt = G_define_flag(); flag.dflt->key = 'd'; flag.dflt->description = _("Set from default region"); flag.dflt->guisection = _("Existing"); /* parameters */ parm.map = G_define_standard_option(G_OPT_R_MAP); parm.map->description = _("Name of raster map to change"); parm.region = G_define_option(); parm.region->key = "region"; parm.region->key_desc = "name"; parm.region->required = NO; parm.region->multiple = NO; parm.region->type = TYPE_STRING; parm.region->description = _("Set region from named region"); parm.region->gisprompt = "old,windows,region"; parm.region->guisection = _("Existing"); parm.raster = G_define_standard_option(G_OPT_R_MAP); parm.raster->key = "raster"; parm.raster->required = NO; parm.raster->multiple = NO; parm.raster->description = _("Set region to match this raster map"); parm.raster->guisection = _("Existing"); parm.vect = G_define_standard_option(G_OPT_V_MAP); parm.vect->key = "vector"; parm.vect->required = NO; parm.vect->multiple = NO; parm.vect->description = _("Set region to match this vector map"); parm.vect->guisection = _("Existing"); parm.north = G_define_option(); parm.north->key = "n"; parm.north->key_desc = "value"; parm.north->required = NO; parm.north->multiple = NO; parm.north->type = TYPE_STRING; parm.north->description = _("Value for the northern edge"); parm.north->guisection = _("Bounds"); parm.south = G_define_option(); parm.south->key = "s"; parm.south->key_desc = "value"; parm.south->required = NO; parm.south->multiple = NO; parm.south->type = TYPE_STRING; parm.south->description = _("Value for the southern edge"); parm.south->guisection = _("Bounds"); parm.east = G_define_option(); parm.east->key = "e"; parm.east->key_desc = "value"; parm.east->required = NO; parm.east->multiple = NO; parm.east->type = TYPE_STRING; parm.east->description = _("Value for the eastern edge"); parm.east->guisection = _("Bounds"); parm.west = G_define_option(); parm.west->key = "w"; parm.west->key_desc = "value"; parm.west->required = NO; parm.west->multiple = NO; parm.west->type = TYPE_STRING; parm.west->description = _("Value for the western edge"); parm.west->guisection = _("Bounds"); parm.align = G_define_standard_option(G_OPT_R_MAP); parm.align->key = "align"; parm.align->required = NO; parm.align->multiple = NO; parm.align->description = _("Raster map to align to"); parm.align->guisection = _("Existing"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_get_window(&window); name = parm.map->answer; Rast_get_cellhd(name, G_mapset(), &cellhd); window = cellhd; if (flag.dflt->answer) G_get_default_window(&window); if (flag.cur->answer) G_get_window(&window); if ((name = parm.region->answer)) /* region= */ G__get_window(&window, "windows", name, ""); if ((name = parm.raster->answer)) { /* raster= */ Rast_get_cellhd(name, "", &window); } if ((name = parm.vect->answer)) { /* vect= */ struct Map_info Map; struct bound_box box; Vect_set_open_level(1); if (Vect_open_old(&Map, name, "") != 1) G_fatal_error(_("Unable to open vector map <%s>"), name); Vect_get_map_box(&Map, &box); window.north = box.N; window.south = box.S; window.west = box.W; window.east = box.E; Rast_align_window(&window, &cellhd); Vect_close(&Map); } if ((value = parm.north->answer)) { /* n= */ if ((i = nsew(value, "n+", "n-", "s+"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.north); switch (i) { case 1: window.north += x; break; case 2: window.north -= x; break; case 3: window.north = window.south + x; break; } } else if (G_scan_northing(value, &x, window.proj)) window.north = x; else die(parm.north); } if ((value = parm.south->answer)) { /* s= */ if ((i = nsew(value, "s+", "s-", "n-"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.south); switch (i) { case 1: window.south += x; break; case 2: window.south -= x; break; case 3: window.south = window.north - x; break; } } else if (G_scan_northing(value, &x, window.proj)) window.south = x; else die(parm.south); } if ((value = parm.east->answer)) { /* e= */ if ((i = nsew(value, "e+", "e-", "w+"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.east); switch (i) { case 1: window.east += x; break; case 2: window.east -= x; break; case 3: window.east = window.west + x; break; } } else if (G_scan_easting(value, &x, window.proj)) window.east = x; else die(parm.east); } if ((value = parm.west->answer)) { /* w= */ if ((i = nsew(value, "w+", "w-", "e-"))) { if (!G_scan_resolution(value + 2, &x, window.proj)) die(parm.west); switch (i) { case 1: window.west += x; break; case 2: window.west -= x; break; case 3: window.west = window.east - x; break; } } else if (G_scan_easting(value, &x, window.proj)) window.west = x; else die(parm.west); } if ((name = parm.align->answer)) { /* align= */ struct Cell_head temp_window; Rast_get_cellhd(name, "", &temp_window); Rast_align_window(&window, &temp_window); } window.rows = cellhd.rows; window.cols = cellhd.cols; G_adjust_Cell_head(&window, 1, 1); cellhd.north = window.north; cellhd.south = window.south; cellhd.east = window.east; cellhd.west = window.west; Rast_put_cellhd(parm.map->answer, &cellhd); G_done_msg(" "); return 0; }
int main(int argc, char **argv) { int ret, level; int stat, type, display; int chcat; int has_color, has_fcolor; struct color_rgb color, fcolor; double size; int default_width; double width_scale; double minreg, maxreg, reg; char map_name[GNAME_MAX]; struct GModule *module; struct Option *map_opt; struct Option *color_opt, *fcolor_opt, *rgbcol_opt, *zcol_opt; struct Option *type_opt, *display_opt; struct Option *icon_opt, *size_opt, *sizecolumn_opt, *rotcolumn_opt; struct Option *where_opt; struct Option *field_opt, *cat_opt, *lfield_opt; struct Option *lcolor_opt, *bgcolor_opt, *bcolor_opt; struct Option *lsize_opt, *font_opt, *enc_opt, *xref_opt, *yref_opt; struct Option *attrcol_opt, *maxreg_opt, *minreg_opt; struct Option *width_opt, *wcolumn_opt, *wscale_opt; struct Option *leglab_opt; struct Option *icon_line_opt, *icon_area_opt; struct Flag *id_flag, *cats_acolors_flag, *sqrt_flag, *legend_flag; char *desc; struct cat_list *Clist; LATTR lattr; struct Map_info Map; struct Cell_head window; struct bound_box box; double overlap; stat = 0; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("display")); G_add_keyword(_("graphics")); G_add_keyword(_("vector")); module->description = _("Displays user-specified vector map " "in the active graphics frame."); map_opt = G_define_standard_option(G_OPT_V_MAP); field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL); field_opt->answer = "1"; field_opt->guisection = _("Selection"); display_opt = G_define_option(); display_opt->key = "display"; display_opt->type = TYPE_STRING; display_opt->required = YES; display_opt->multiple = YES; display_opt->answer = "shape"; display_opt->options = "shape,cat,topo,vert,dir,zcoor"; display_opt->description = _("Display"); desc = NULL; G_asprintf(&desc, "shape;%s;cat;%s;topo;%s;vert;%s;dir;%s;zcoor;%s", _("Display geometry of features"), _("Display category numbers of features"), _("Display topology information (nodes, edges)"), _("Display vertices of features"), _("Display direction of linear features"), _("Display z-coordinate of features (only for 3D vector maps)")); display_opt->descriptions = desc; /* Query */ type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->answer = "point,line,area,face"; type_opt->options = "point,line,boundary,centroid,area,face"; type_opt->guisection = _("Selection"); cat_opt = G_define_standard_option(G_OPT_V_CATS); cat_opt->guisection = _("Selection"); where_opt = G_define_standard_option(G_OPT_DB_WHERE); where_opt->guisection = _("Selection"); /* Colors */ color_opt = G_define_standard_option(G_OPT_CN); color_opt->label = _("Feature color"); color_opt->guisection = _("Colors"); fcolor_opt = G_define_standard_option(G_OPT_CN); fcolor_opt->key = "fill_color"; fcolor_opt->answer = "200:200:200"; fcolor_opt->label = _("Area fill color"); fcolor_opt->guisection = _("Colors"); rgbcol_opt = G_define_standard_option(G_OPT_DB_COLUMN); rgbcol_opt->key = "rgb_column"; rgbcol_opt->guisection = _("Colors"); rgbcol_opt->label = _("Colorize features according color definition column"); rgbcol_opt->description = _("Color definition in R:G:B form"); zcol_opt = G_define_standard_option(G_OPT_M_COLR); zcol_opt->key = "zcolor"; zcol_opt->description = _("Colorize point or area features according to z-coordinate"); zcol_opt->guisection = _("Colors"); /* Lines */ width_opt = G_define_option(); width_opt->key = "width"; width_opt->type = TYPE_INTEGER; width_opt->answer = "0"; width_opt->guisection = _("Lines"); width_opt->description = _("Line width"); wcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN); wcolumn_opt->key = "width_column"; wcolumn_opt->guisection = _("Lines"); wcolumn_opt->label = _("Name of numeric column containing line width"); wcolumn_opt->description = _("These values will be scaled by width_scale"); wscale_opt = G_define_option(); wscale_opt->key = "width_scale"; wscale_opt->type = TYPE_DOUBLE; wscale_opt->answer = "1"; wscale_opt->guisection = _("Lines"); wscale_opt->description = _("Scale factor for width_column"); /* Symbols */ icon_opt = G_define_option(); icon_opt->key = "icon"; icon_opt->type = TYPE_STRING; icon_opt->required = NO; icon_opt->multiple = NO; icon_opt->guisection = _("Symbols"); icon_opt->answer = "basic/x"; /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */ icon_opt->options = icon_files(); icon_opt->description = _("Point and centroid symbol"); size_opt = G_define_option(); size_opt->key = "size"; size_opt->type = TYPE_DOUBLE; size_opt->answer = "5"; size_opt->guisection = _("Symbols"); size_opt->label = _("Symbol size"); size_opt->description = _("When used with the size_column option this becomes the scale factor"); sizecolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN); sizecolumn_opt->key = "size_column"; sizecolumn_opt->guisection = _("Symbols"); sizecolumn_opt->description = _("Name of numeric column containing symbol size"); rotcolumn_opt = G_define_standard_option(G_OPT_DB_COLUMN); rotcolumn_opt->key = "rotation_column"; rotcolumn_opt->guisection = _("Symbols"); rotcolumn_opt->label = _("Name of numeric column containing symbol rotation angle"); rotcolumn_opt->description = _("Measured in degrees CCW from east"); icon_area_opt = G_define_option(); icon_area_opt->key = "icon_area"; icon_area_opt->type = TYPE_STRING; icon_area_opt->required = NO; icon_area_opt->multiple = NO; icon_area_opt->guisection = _("Legend"); icon_area_opt->answer = "legend/area"; icon_area_opt->options = icon_files(); icon_area_opt->description = _("Area/boundary symbol for legend"); icon_line_opt = G_define_option(); icon_line_opt->key = "icon_line"; icon_line_opt->type = TYPE_STRING; icon_line_opt->required = NO; icon_line_opt->multiple = NO; icon_line_opt->guisection = _("Legend"); icon_line_opt->answer = "legend/line"; icon_line_opt->options = icon_files(); icon_line_opt->description = _("Line symbol for legend"); leglab_opt = G_define_option(); leglab_opt->key = "legend_label"; leglab_opt->type = TYPE_STRING; leglab_opt->guisection = _("Legend"); leglab_opt->description = _("Label to display after symbol in vector legend"); /* Labels */ lfield_opt = G_define_standard_option(G_OPT_V_FIELD); lfield_opt->key = "label_layer"; lfield_opt->required = NO; lfield_opt->guisection = _("Labels"); lfield_opt->label = _("Layer number for labels (default: the given layer number)"); attrcol_opt = G_define_standard_option(G_OPT_DB_COLUMN); attrcol_opt->key = "attribute_column"; attrcol_opt->multiple = NO; /* or fix attr.c, around line 102 */ attrcol_opt->guisection = _("Labels"); attrcol_opt->description = _("Name of column to be displayed as a label"); lcolor_opt = G_define_standard_option(G_OPT_C); lcolor_opt->key = "label_color"; lcolor_opt->answer = "red"; lcolor_opt->label = _("Label color"); lcolor_opt->guisection = _("Labels"); bgcolor_opt = G_define_standard_option(G_OPT_CN); bgcolor_opt->key = "label_bgcolor"; bgcolor_opt->answer = "none"; bgcolor_opt->guisection = _("Labels"); bgcolor_opt->label = _("Label background color"); bcolor_opt = G_define_standard_option(G_OPT_CN); bcolor_opt->key = "label_bcolor"; bcolor_opt->type = TYPE_STRING; bcolor_opt->answer = "none"; bcolor_opt->guisection = _("Labels"); bcolor_opt->label = _("Label border color"); lsize_opt = G_define_option(); lsize_opt->key = "label_size"; lsize_opt->type = TYPE_INTEGER; lsize_opt->answer = "8"; lsize_opt->guisection = _("Labels"); lsize_opt->description = _("Label size (pixels)"); font_opt = G_define_option(); font_opt->key = "font"; font_opt->type = TYPE_STRING; font_opt->guisection = _("Labels"); font_opt->description = _("Font name"); enc_opt = G_define_option(); enc_opt->key = "encoding"; enc_opt->type = TYPE_STRING; enc_opt->guisection = _("Labels"); enc_opt->description = _("Text encoding"); xref_opt = G_define_option(); xref_opt->key = "xref"; xref_opt->type = TYPE_STRING; xref_opt->guisection = _("Labels"); xref_opt->answer = "left"; xref_opt->options = "left,center,right"; xref_opt->description = _("Label horizontal justification"); yref_opt = G_define_option(); yref_opt->key = "yref"; yref_opt->type = TYPE_STRING; yref_opt->guisection = _("Labels"); yref_opt->answer = "center"; yref_opt->options = "top,center,bottom"; yref_opt->description = _("Label vertical justification"); minreg_opt = G_define_option(); minreg_opt->key = "minreg"; minreg_opt->type = TYPE_DOUBLE; minreg_opt->required = NO; minreg_opt->description = _("Minimum region size (average from height and width) " "when map is displayed"); maxreg_opt = G_define_option(); maxreg_opt->key = "maxreg"; maxreg_opt->type = TYPE_DOUBLE; maxreg_opt->required = NO; maxreg_opt->description = _("Maximum region size (average from height and width) " "when map is displayed"); /* Colors */ cats_acolors_flag = G_define_flag(); cats_acolors_flag->key = 'c'; cats_acolors_flag->guisection = _("Colors"); cats_acolors_flag->description = _("Random colors according to category number " "(or layer number if 'layer=-1' is given)"); /* Query */ id_flag = G_define_flag(); id_flag->key = 'i'; id_flag->guisection = _("Selection"); id_flag->description = _("Use values from 'cats' option as feature id"); sqrt_flag = G_define_flag(); sqrt_flag->key = 'r'; sqrt_flag->label = _("Use square root of the value of size_column"); sqrt_flag->description = _("This makes circle areas proportionate to the size_column values " "instead of circle radius"); sqrt_flag->guisection = _("Symbols"); legend_flag = G_define_flag(); legend_flag->key = 's'; legend_flag->label = _("Do not show this layer in vector legend"); legend_flag->guisection = _("Legend"); /* Check command line */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); D_open_driver(); G_get_set_window(&window); /* Check min/max region */ reg = ((window.east - window.west) + (window.north - window.south)) / 2; if (minreg_opt->answer) { minreg = atof(minreg_opt->answer); if (reg < minreg) { G_important_message(_("Region size is lower than minreg, nothing displayed")); exit(EXIT_SUCCESS); } } if (maxreg_opt->answer) { maxreg = atof(maxreg_opt->answer); if (reg > maxreg) { G_important_message(_("Region size is greater than maxreg, nothing displayed")); exit(EXIT_SUCCESS); } } strcpy(map_name, map_opt->answer); default_width = atoi(width_opt->answer); if (default_width < 0) default_width = 0; width_scale = atof(wscale_opt->answer); if (cats_acolors_flag->answer && rgbcol_opt->answer) { G_warning(_("The -%c flag and <%s> option cannot be used together, " "the -%c flag will be ignored!"), cats_acolors_flag->key, rgbcol_opt->key, cats_acolors_flag->key); cats_acolors_flag->answer = FALSE; } color = G_standard_color_rgb(WHITE); has_color = option_to_color(&color, color_opt->answer); fcolor = G_standard_color_rgb(WHITE); has_fcolor = option_to_color(&fcolor, fcolor_opt->answer); size = atof(size_opt->answer); /* if where_opt was specified select categories from db * otherwise parse cat_opt */ Clist = Vect_new_cat_list(); Clist->field = atoi(field_opt->answer); /* open vector */ level = Vect_open_old2(&Map, map_name, "", field_opt->answer); chcat = 0; if (where_opt->answer) { if (Clist->field < 1) G_fatal_error(_("Option <%s> must be > 0"), field_opt->key); chcat = 1; option_to_where(&Map, Clist, where_opt->answer); } else if (cat_opt->answer) { if (Clist->field < 1 && !id_flag->answer) G_fatal_error(_("Option <%s> must be > 0"), field_opt->key); chcat = 1; ret = Vect_str_to_cat_list(cat_opt->answer, Clist); if (ret > 0) G_warning(n_("%d error in cat option", "%d errors in cat option", ret), ret); } type = Vect_option_to_types(type_opt); display = option_to_display(display_opt); /* labels */ options_to_lattr(&lattr, lfield_opt->answer, lcolor_opt->answer, bgcolor_opt->answer, bcolor_opt->answer, atoi(lsize_opt->answer), font_opt->answer, enc_opt->answer, xref_opt->answer, yref_opt->answer); D_setup(0); D_set_reduction(1.0); G_verbose_message(_("Plotting...")); if (level >= 2) Vect_get_map_box(&Map, &box); if (level >= 2 && (window.north < box.S || window.south > box.N || window.east < box.W || window.west > G_adjust_easting(box.E, &window))) { G_warning(_("The bounding box of the map is outside the current region, " "nothing drawn")); } else { overlap = G_window_percentage_overlap(&window, box.N, box.S, box.E, box.W); G_debug(1, "overlap = %f \n", overlap); if (overlap < 1) Vect_set_constraint_region(&Map, window.north, window.south, window.east, window.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX); /* default line width */ if (!wcolumn_opt->answer) D_line_width(default_width); if (display & DISP_SHAPE) { stat += display_shape(&Map, type, Clist, &window, has_color ? &color : NULL, has_fcolor ? &fcolor : NULL, chcat, icon_opt->answer, size, sizecolumn_opt->answer, sqrt_flag->answer ? TRUE : FALSE, rotcolumn_opt->answer, id_flag->answer ? TRUE : FALSE, cats_acolors_flag->answer ? TRUE : FALSE, rgbcol_opt->answer, default_width, wcolumn_opt->answer, width_scale, zcol_opt->answer); if (wcolumn_opt->answer) D_line_width(default_width); } if (has_color) { D_RGB_color(color.r, color.g, color.b); if (display & DISP_DIR) stat += display_dir(&Map, type, Clist, chcat, size); } if (!legend_flag->answer) { write_into_legfile(&Map, type, leglab_opt->answer, map_name, icon_opt->answer, size_opt->answer, color_opt->answer, fcolor_opt->answer, width_opt->answer, icon_area_opt->answer, icon_line_opt->answer, sizecolumn_opt->answer); } /* reset line width: Do we need to get line width from display * driver (not implemented)? It will help restore previous line * width (not just 0) determined by another module (e.g., * d.linewidth). */ if (!wcolumn_opt->answer) D_line_width(0); if (display & DISP_CAT) stat += display_label(&Map, type, Clist, &lattr, chcat); if (attrcol_opt->answer) stat += display_attr(&Map, type, attrcol_opt->answer, Clist, &lattr, chcat); if (display & DISP_ZCOOR) stat += display_zcoor(&Map, type, &lattr); if (display & DISP_VERT) stat += display_vert(&Map, type, &lattr, size); if (display & DISP_TOPO) stat += display_topo(&Map, type, &lattr, size); } D_save_command(G_recreate_command()); D_close_driver(); Vect_close(&Map); Vect_destroy_cat_list(Clist); if (stat != 0) { G_fatal_error(_("Rendering failed")); } G_done_msg(" "); exit(EXIT_SUCCESS); }
void print_info(const struct Map_info *Map) { int i; char line[100]; char tmp1[100], tmp2[100]; struct bound_box box; divider('+'); if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) { /* for OGR format print also datasource and layer */ sprintf(line, "%-17s%s", _("OGR layer:"), Vect_get_ogr_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("OGR datasource:"), Vect_get_ogr_dsn_name(Map)); printline(line); } else { sprintf(line, "%-17s%s", _("Name:"), Vect_get_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Mapset:"), Vect_get_mapset(Map)); printline(line); } sprintf(line, "%-17s%s", _("Location:"), G_location()); printline(line); sprintf(line, "%-17s%s", _("Database:"), G_gisdbase()); printline(line); sprintf(line, "%-17s%s", _("Title:"), Vect_get_map_name(Map)); printline(line); sprintf(line, "%-17s1:%d", _("Map scale:"), Vect_get_scale(Map)); printline(line); if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) { sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_ogr_format_info(Map)); } else { sprintf(line, "%-17s%s", _("Map format:"), Vect_maptype_info(Map)); } printline(line); sprintf(line, "%-17s%s", _("Name of creator:"), Vect_get_person(Map)); printline(line); sprintf(line, "%-17s%s", _("Organization:"), Vect_get_organization(Map)); printline(line); sprintf(line, "%-17s%s", _("Source date:"), Vect_get_map_date(Map)); printline(line); divider('|'); sprintf(line, " %s: %s (%s: %i)", _("Type of map"), _("vector"), _("level"), Vect_level(Map)); printline(line); if (Vect_level(Map) > 0) { printline(""); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of points:"), Vect_get_num_primitives(Map, GV_POINT), _("Number of centroids:"), Vect_get_num_primitives(Map, GV_CENTROID)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of lines:"), Vect_get_num_primitives(Map, GV_LINE), _("Number of boundaries:"), Vect_get_num_primitives(Map, GV_BOUNDARY)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of areas:"), Vect_get_num_areas(Map), _("Number of islands:"), Vect_get_num_islands(Map)); printline(line); if (Vect_is_3d(Map)) { sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of faces:"), Vect_get_num_primitives(Map, GV_FACE), _("Number of kernels:"), Vect_get_num_primitives(Map, GV_KERNEL)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of volumes:"), Vect_get_num_volumes(Map), _("Number of holes:"), Vect_get_num_holes(Map)); printline(line); } printline(""); sprintf(line, " %-24s%s", _("Map is 3D:"), Vect_is_3d(Map) ? _("Yes") : _("No")); printline(line); sprintf(line, " %-24s%-9d", _("Number of dblinks:"), Vect_get_num_dblinks(Map)); printline(line); } printline(""); /* this differs from r.info in that proj info IS taken from the map here, not the location settings */ /* Vect_get_proj_name() and _zone() are typically unset?! */ if (G_projection() == PROJECTION_UTM) sprintf(line, " %s: %s (%s %d)", _("Projection:"), Vect_get_proj_name(Map), _("zone"), Vect_get_zone(Map)); else sprintf(line, " %s: %s", _("Projection"), Vect_get_proj_name(Map)); printline(line); printline(""); Vect_get_map_box(Map, &box); G_format_northing(box.N, tmp1, G_projection()); G_format_northing(box.S, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'N', tmp1, 'S', tmp2); printline(line); G_format_easting(box.E, tmp1, G_projection()); G_format_easting(box.W, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'E', tmp1, 'W', tmp2); printline(line); if (Vect_is_3d(Map)) { format_double(box.B, tmp1); format_double(box.T, tmp2); sprintf(line, " %c: %17s %c: %17s", 'B', tmp1, 'T', tmp2); printline(line); } printline(""); format_double(Vect_get_thresh(Map), tmp1); sprintf(line, " %s: %s", _("Digitization threshold"), tmp1); printline(line); sprintf(line, " %s:", _("Comment")); printline(line); sprintf(line, " %s", Vect_get_comment(Map)); printline(line); divider('+'); fprintf(stdout, "\n"); }
bool GRASS_EXPORT QgsGrass::mapRegion( int type, QString gisbase, QString location, QString mapset, QString map, struct Cell_head *window ) { QgsDebugMsg( "entered." ); QgsDebugMsg( QString( "map = %1" ).arg( map ) ); QgsDebugMsg( QString( "mapset = %1" ).arg( mapset ) ); QgsGrass::setLocation( gisbase, location ); if ( type == Raster ) { if ( G_get_cellhd( map.toUtf8().data(), mapset.toUtf8().data(), window ) < 0 ) { QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot read raster map region" ) ); return false; } } else if ( type == Vector ) { // Get current projection region( gisbase, location, mapset, window ); struct Map_info Map; int level = Vect_open_old_head( &Map, map.toUtf8().data(), mapset.toUtf8().data() ); if ( level < 2 ) { QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot read vector map region" ) ); return false; } BOUND_BOX box; Vect_get_map_box( &Map, &box ); window->north = box.N; window->south = box.S; window->west = box.W; window->east = box.E; window->top = box.T; window->bottom = box.B; // Is this optimal ? window->ns_res = ( window->north - window->south ) / 1000; window->ew_res = window->ns_res; if ( window->top > window->bottom ) { window->tb_res = ( window->top - window->bottom ) / 10; } else { window->top = window->bottom + 1; window->tb_res = 1; } G_adjust_Cell_head3( window, 0, 0, 0 ); Vect_close( &Map ); } else if ( type == Region ) { if ( G__get_window( window, ( char * ) "windows", map.toUtf8().data(), mapset.toUtf8().data() ) != NULL ) { QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot read region" ) ); return false; } } return true; }
int main(int argc, char *argv[]) { int i, j, k; int print_as_matrix; /* only for all */ int all; /* calculate from each to each within the threshold */ struct GModule *module; struct Option *from_opt, *to_opt, *from_type_opt, *to_type_opt, *from_field_opt, *to_field_opt; struct Option *out_opt, *max_opt, *min_opt, *table_opt; struct Option *upload_opt, *column_opt, *to_column_opt; struct Flag *print_flag, *all_flag; struct Map_info From, To, Out, *Outp; int from_type, to_type, from_field, to_field; double max, min; double *max_step; int n_max_steps, curr_step; struct line_pnts *FPoints, *TPoints; struct line_cats *FCats, *TCats; NEAR *Near, *near; int anear; /* allocated space, used only for all */ UPLOAD *Upload; /* zero terminated */ int ftype, fcat, tcat, count; int nfrom, nto, nfcats, fline, tline, tseg, tarea, area, isle, nisles; double tx, ty, tz, dist, talong, tmp_tx, tmp_ty, tmp_tz, tmp_dist, tmp_talong; struct field_info *Fi, *toFi; dbString stmt, dbstr; dbDriver *driver, *to_driver; int *catexist, ncatexist, *cex; char buf1[2000], buf2[2000]; int update_ok, update_err, update_exist, update_notexist, update_dupl, update_notfound; struct boxlist *List; struct bound_box box; dbCatValArray cvarr; dbColumn *column; all = 0; print_as_matrix = 0; column = NULL; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("database")); G_add_keyword(_("attribute table")); module->description = _("Finds the nearest element in vector map 'to' for elements in vector map 'from'."); from_opt = G_define_standard_option(G_OPT_V_INPUT); from_opt->key = "from"; from_opt->description = _("Name of existing vector map (from)"); from_opt->guisection = _("From"); from_field_opt = G_define_standard_option(G_OPT_V_FIELD); from_field_opt->key = "from_layer"; from_field_opt->label = _("Layer number or name (from)"); from_field_opt->guisection = _("From"); from_type_opt = G_define_standard_option(G_OPT_V_TYPE); from_type_opt->key = "from_type"; from_type_opt->options = "point,centroid"; from_type_opt->answer = "point"; from_type_opt->label = _("Feature type (from)"); from_type_opt->guisection = _("From"); to_opt = G_define_standard_option(G_OPT_V_INPUT); to_opt->key = "to"; to_opt->description = _("Name of existing vector map (to)"); to_opt->guisection = _("To"); to_field_opt = G_define_standard_option(G_OPT_V_FIELD); to_field_opt->key = "to_layer"; to_field_opt->label = _("Layer number or name (to)"); to_field_opt->guisection = _("To"); to_type_opt = G_define_standard_option(G_OPT_V_TYPE); to_type_opt->key = "to_type"; to_type_opt->options = "point,line,boundary,centroid,area"; to_type_opt->answer = "point,line,area"; to_type_opt->label = _("Feature type (to)"); to_type_opt->guisection = _("To"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->key = "output"; out_opt->required = NO; out_opt->description = _("Name for output vector map containing lines " "connecting nearest elements"); max_opt = G_define_option(); max_opt->key = "dmax"; max_opt->type = TYPE_DOUBLE; max_opt->required = NO; max_opt->answer = "-1"; max_opt->description = _("Maximum distance or -1 for no limit"); min_opt = G_define_option(); min_opt->key = "dmin"; min_opt->type = TYPE_DOUBLE; min_opt->required = NO; min_opt->answer = "-1"; min_opt->description = _("Minimum distance or -1 for no limit"); upload_opt = G_define_option(); upload_opt->key = "upload"; upload_opt->type = TYPE_STRING; upload_opt->required = YES; upload_opt->multiple = YES; upload_opt->options = "cat,dist,to_x,to_y,to_along,to_angle,to_attr"; upload_opt->description = _("Values describing the relation between two nearest features"); upload_opt->descriptions = _("cat;category of the nearest feature;" "dist;minimum distance to nearest feature;" "to_x;x coordinate of the nearest point on 'to' feature;" "to_y;y coordinate of the nearest point on 'to' feature;" "to_along;distance between points/centroids in 'from' map and the linear feature's " "start point in 'to' map, along this linear feature;" "to_angle;angle between the linear feature in 'to' map and the positive x axis, at " "the location of point/centroid in 'from' map, counterclockwise, in radians, which " "is between -PI and PI inclusive;" "to_attr;attribute of nearest feature given by to_column option"); /* "from_x - x coordinate of the nearest point on 'from' feature;" */ /* "from_y - y coordinate of the nearest point on 'from' feature;" */ /* "from_along - distance to the nearest point on 'from' feature along linear feature;" */ column_opt = G_define_standard_option(G_OPT_DB_COLUMN); column_opt->required = YES; column_opt->multiple = YES; column_opt->description = _("Column name(s) where values specified by 'upload' option will be uploaded"); column_opt->guisection = _("From_map"); to_column_opt = G_define_standard_option(G_OPT_DB_COLUMN); to_column_opt->key = "to_column"; to_column_opt->description = _("Column name of nearest feature (used with upload=to_attr)"); to_column_opt->guisection = _("To"); table_opt = G_define_standard_option(G_OPT_DB_TABLE); table_opt->gisprompt = "new_dbtable,dbtable,dbtable"; table_opt->description = _("Name of table created for output when the distance to all flag is used"); print_flag = G_define_flag(); print_flag->key = 'p'; print_flag->label = _("Print output to stdout, don't update attribute table"); print_flag->description = _("First column is always category of 'from' feature called from_cat"); all_flag = G_define_flag(); all_flag->key = 'a'; all_flag->label = _("Calculate distances to all features within the threshold"); all_flag->description = _("The output is written to stdout but may be uploaded " "to a new table created by this module. " "From categories are may be multiple."); /* huh? */ /* GUI dependency */ from_opt->guidependency = G_store(from_field_opt->key); sprintf(buf1, "%s,%s", to_field_opt->key, to_column_opt->key); to_opt->guidependency = G_store(buf1); to_field_opt->guidependency = G_store(to_column_opt->key); if (G_parser(argc, argv)) exit(EXIT_FAILURE); from_type = Vect_option_to_types(from_type_opt); to_type = Vect_option_to_types(to_type_opt); from_field = atoi(from_field_opt->answer); max = atof(max_opt->answer); min = atof(min_opt->answer); if (all_flag->answer) all = 1; /* Read upload and column options */ /* count */ i = 0; while (upload_opt->answers[i]) i++; if (strcmp(from_opt->answer, to_opt->answer) == 0 && all && !table_opt->answer && i == 1) print_as_matrix = 1; /* alloc */ Upload = (UPLOAD *) G_calloc(i + 1, sizeof(UPLOAD)); /* read upload */ i = 0; while (upload_opt->answers[i]) { if (strcmp(upload_opt->answers[i], "cat") == 0) Upload[i].upload = CAT; else if (strcmp(upload_opt->answers[i], "from_x") == 0) Upload[i].upload = FROM_X; else if (strcmp(upload_opt->answers[i], "from_y") == 0) Upload[i].upload = FROM_Y; else if (strcmp(upload_opt->answers[i], "to_x") == 0) Upload[i].upload = TO_X; else if (strcmp(upload_opt->answers[i], "to_y") == 0) Upload[i].upload = TO_Y; else if (strcmp(upload_opt->answers[i], "from_along") == 0) Upload[i].upload = FROM_ALONG; else if (strcmp(upload_opt->answers[i], "to_along") == 0) Upload[i].upload = TO_ALONG; else if (strcmp(upload_opt->answers[i], "dist") == 0) Upload[i].upload = DIST; else if (strcmp(upload_opt->answers[i], "to_angle") == 0) Upload[i].upload = TO_ANGLE; else if (strcmp(upload_opt->answers[i], "to_attr") == 0) { if (!(to_column_opt->answer)) { G_fatal_error(_("to_column option missing")); } Upload[i].upload = TO_ATTR; } i++; } Upload[i].upload = END; /* read columns */ i = 0; while (column_opt->answers[i]) { if (Upload[i].upload == END) { G_warning(_("Too many column names")); break; } Upload[i].column = G_store(column_opt->answers[i]); i++; } if (Upload[i].upload != END) G_fatal_error(_("Not enough column names")); /* Open 'from' vector */ Vect_set_open_level(2); Vect_open_old(&From, from_opt->answer, G_mapset()); /* Open 'to' vector */ Vect_set_open_level(2); Vect_open_old2(&To, to_opt->answer, "", to_field_opt->answer); to_field = Vect_get_field_number(&To, to_field_opt->answer); /* Open output vector */ if (out_opt->answer) { Vect_open_new(&Out, out_opt->answer, WITHOUT_Z); Vect_hist_command(&Out); Outp = &Out; } else { Outp = NULL; } /* TODO: add maxdist = -1 to Vect_select_ !!! */ /* Calc maxdist */ n_max_steps = 1; if (max != 0) { struct bound_box fbox, tbox; double dx, dy, dz, tmp_max; int n_features = 0; Vect_get_map_box(&From, &fbox); Vect_get_map_box(&To, &tbox); Vect_box_extend(&fbox, &tbox); dx = fbox.E - fbox.W; dy = fbox.N - fbox.S; if (Vect_is_3d(&From)) dz = fbox.T - fbox.B; else dz = 0.0; tmp_max = sqrt(dx * dx + dy * dy + dz * dz); if (max < 0) max = tmp_max; /* how to determine a reasonable number of steps to increase the search box? */ /* with max > 0 but max <<< tmp_max, 2 steps are sufficient, first 0 then max * a reasonable number of steps also depends on the number of features in To * e.g. only one area in To, no need to step */ nto = Vect_get_num_lines(&To); for (tline = 1; tline <= nto; tline++) { /* TODO: Vect_get_line_type() */ n_features += ((to_type & To.plus.Line[tline]->type) != 0); } if (to_type & GV_AREA) { if (Vect_get_num_areas(&To) > n_features) n_features = Vect_get_num_areas(&To); } if (n_features == 0) G_fatal_error(_("No features of selected type in To vector <%s>"), to_opt->answer); n_max_steps = sqrt(n_features) * max / tmp_max; /* max 9 steps from testing */ if (n_max_steps > 9) n_max_steps = 9; if (n_max_steps < 2) n_max_steps = 2; if (n_max_steps > n_features) n_max_steps = n_features; G_debug(2, "max = %f", max); G_debug(2, "maximum reasonable search distance = %f", tmp_max); G_debug(2, "n_features = %d", n_features); G_debug(2, "n_max_steps = %d", n_max_steps); } if (min > max) G_fatal_error("dmin can not be larger than dmax"); if (n_max_steps > 1) { /* set up steps to increase search box */ max_step = G_malloc(n_max_steps * sizeof(double)); /* first step always 0 */ max_step[0] = 0; for (curr_step = 1; curr_step < n_max_steps - 1; curr_step++) { /* for 9 steps, this would be max / [128, 64, 32, 16, 8, 4, 2] */ max_step[curr_step] = max / (2 << (n_max_steps - 1 - curr_step)); } /* last step always max */ max_step[n_max_steps - 1] = max; } else { max_step = G_malloc(sizeof(double)); max_step[0] = max; } /* Open database driver */ db_init_string(&stmt); db_init_string(&dbstr); driver = NULL; if (!print_flag->answer) { if (!all) { Fi = Vect_get_field(&From, from_field); if (Fi == NULL) G_fatal_error(_("Database connection not defined for layer %d"), from_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); /* check if column exists */ i = 0; while (column_opt->answers[i]) { db_get_column(driver, Fi->table, column_opt->answers[i], &column); if (column) { db_free_column(column); column = NULL; } else { G_fatal_error(_("Column <%s> not found in table <%s>"), column_opt->answers[i], Fi->table); } i++; } } else { driver = db_start_driver_open_database(NULL, NULL); if (driver == NULL) G_fatal_error(_("Unable to open default database")); } } to_driver = NULL; if (to_column_opt->answer) { toFi = Vect_get_field(&To, to_field); if (toFi == NULL) G_fatal_error(_("Database connection not defined for layer %d"), to_field); to_driver = db_start_driver_open_database(toFi->driver, toFi->database); if (to_driver == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), toFi->database, toFi->driver); /* check if to_column exists */ db_get_column(to_driver, toFi->table, to_column_opt->answer, &column); if (column) { db_free_column(column); column = NULL; } else { G_fatal_error(_("Column <%s> not found in table <%s>"), to_column_opt->answer, toFi->table); } /* Check column types */ if (!print_flag->answer && !all) { char *fcname = NULL; int fctype, tctype; i = 0; while (column_opt->answers[i]) { if (Upload[i].upload == TO_ATTR) { fcname = column_opt->answers[i]; break; } i++; } if (fcname) { fctype = db_column_Ctype(driver, Fi->table, fcname); tctype = db_column_Ctype(to_driver, toFi->table, to_column_opt->answer); if (((tctype == DB_C_TYPE_STRING || tctype == DB_C_TYPE_DATETIME) && (fctype == DB_C_TYPE_INT || fctype == DB_C_TYPE_DOUBLE)) || ((tctype == DB_C_TYPE_INT || tctype == DB_C_TYPE_DOUBLE) && (fctype == DB_C_TYPE_STRING || fctype == DB_C_TYPE_DATETIME)) ) { G_fatal_error(_("Incompatible column types")); } } } } FPoints = Vect_new_line_struct(); TPoints = Vect_new_line_struct(); FCats = Vect_new_cats_struct(); TCats = Vect_new_cats_struct(); List = Vect_new_boxlist(1); /* Allocate space ( may be more than needed (duplicate cats and elements without cats) ) */ nfrom = Vect_get_num_lines(&From); nto = Vect_get_num_lines(&To); if (all) { /* Attention with space for all, it can easily run out of memory */ anear = 2 * nfrom; Near = (NEAR *) G_calloc(anear, sizeof(NEAR)); } else { Near = (NEAR *) G_calloc(nfrom, sizeof(NEAR)); } /* Read all cats from 'from' */ if (!all) { nfcats = 0; for (i = 1; i <= nfrom; i++) { ftype = Vect_read_line(&From, NULL, FCats, i); /* This keeps also categories of areas for future (if area s in from_type) */ if (!(ftype & from_type) && (ftype != GV_CENTROID || !(from_type & GV_AREA))) continue; Vect_cat_get(FCats, from_field, &fcat); if (fcat < 0) continue; Near[nfcats].from_cat = fcat; nfcats++; } G_debug(1, "%d cats loaded from vector (including duplicates)", nfcats); /* Sort by cats and remove duplicates */ qsort((void *)Near, nfcats, sizeof(NEAR), cmp_near); /* remove duplicates */ for (i = 1; i < nfcats; i++) { if (Near[i].from_cat == Near[i - 1].from_cat) { for (j = i; j < nfcats - 1; j++) { Near[j].from_cat = Near[j + 1].from_cat; } nfcats--; } } G_debug(1, "%d cats loaded from vector (unique)", nfcats); } /* Go through all lines in 'from' and find nearest in 'to' for each */ /* Note: as from_type is restricted to GV_POINTS (for now) everything is simple */ count = 0; /* count of distances in 'all' mode */ /* Find nearest lines */ if (to_type & (GV_POINTS | GV_LINES)) { struct line_pnts *LLPoints; if (G_projection() == PROJECTION_LL) { LLPoints = Vect_new_line_struct(); } else { LLPoints = NULL; } G_message(_("Finding nearest feature...")); for (fline = 1; fline <= nfrom; fline++) { int tmp_tcat; double tmp_tangle, tangle; double tmp_min = (min < 0 ? 0 : min); double box_edge = 0; int done = 0; curr_step = 0; G_debug(3, "fline = %d", fline); G_percent(fline, nfrom, 2); ftype = Vect_read_line(&From, FPoints, FCats, fline); if (!(ftype & from_type)) continue; Vect_cat_get(FCats, from_field, &fcat); if (fcat < 0 && !all) continue; while (!done) { done = 1; if (!all) { /* enlarge search box until we get a hit */ /* the objective is to enlarge the search box * in the first iterations just a little bit * to keep the number of hits low */ Vect_reset_boxlist(List); while (curr_step < n_max_steps) { box_edge = max_step[curr_step]; if (box_edge < tmp_min) continue; box.E = FPoints->x[0] + box_edge; box.W = FPoints->x[0] - box_edge; box.N = FPoints->y[0] + box_edge; box.S = FPoints->y[0] - box_edge; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; Vect_select_lines_by_box(&To, &box, to_type, List); curr_step++; if (List->n_values > 0) break; } } else { box.E = FPoints->x[0] + max; box.W = FPoints->x[0] - max; box.N = FPoints->y[0] + max; box.S = FPoints->y[0] - max; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; Vect_select_lines_by_box(&To, &box, to_type, List); } G_debug(3, " %d lines in box", List->n_values); tline = 0; dist = PORT_DOUBLE_MAX; for (i = 0; i < List->n_values; i++) { tmp_tcat = -1; Vect_read_line(&To, TPoints, TCats, List->id[i]); tseg = Vect_line_distance(TPoints, FPoints->x[0], FPoints->y[0], FPoints->z[0], (Vect_is_3d(&From) && Vect_is_3d(&To)) ? WITH_Z : WITHOUT_Z, &tmp_tx, &tmp_ty, &tmp_tz, &tmp_dist, NULL, &tmp_talong); Vect_point_on_line(TPoints, tmp_talong, NULL, NULL, NULL, &tmp_tangle, NULL); if (tmp_dist > max || tmp_dist < min) continue; /* not in threshold */ /* TODO: more cats of the same field */ Vect_cat_get(TCats, to_field, &tmp_tcat); if (G_projection() == PROJECTION_LL) { /* calculate distances in meters not degrees (only 2D) */ Vect_reset_line(LLPoints); Vect_append_point(LLPoints, FPoints->x[0], FPoints->y[0], FPoints->z[0]); Vect_append_point(LLPoints, tmp_tx, tmp_ty, tmp_tz); tmp_dist = Vect_line_geodesic_length(LLPoints); Vect_reset_line(LLPoints); for (k = 0; k < tseg; k++) Vect_append_point(LLPoints, TPoints->x[k], TPoints->y[k], TPoints->z[k]); Vect_append_point(LLPoints, tmp_tx, tmp_ty, tmp_tz); tmp_talong = Vect_line_geodesic_length(LLPoints); } G_debug(4, " tmp_dist = %f tmp_tcat = %d", tmp_dist, tmp_tcat); if (all) { if (anear <= count) { anear += 10 + nfrom / 10; Near = (NEAR *) G_realloc(Near, anear * sizeof(NEAR)); } near = &(Near[count]); /* store info about relation */ near->from_cat = fcat; near->to_cat = tmp_tcat; /* -1 is OK */ near->dist = tmp_dist; near->from_x = FPoints->x[0]; near->from_y = FPoints->y[0]; near->from_z = FPoints->z[0]; near->to_x = tmp_tx; near->to_y = tmp_ty; near->to_z = tmp_tz; near->to_along = tmp_talong; /* 0 for points */ near->to_angle = tmp_tangle; near->count++; count++; } else { if (tline == 0 || (tmp_dist < dist)) { tline = List->id[i]; tcat = tmp_tcat; dist = tmp_dist; tx = tmp_tx; ty = tmp_ty; tz = tmp_tz; talong = tmp_talong; tangle = tmp_tangle; } } } G_debug(4, " dist = %f", dist); if (curr_step < n_max_steps) { /* enlarging the search box is possible */ if (tline > 0 && dist > box_edge) { /* line found but distance > search edge: * line bbox overlaps with search box, line itself is outside search box */ done = 0; } else if (tline == 0) { /* no line within max dist, but search box can still be enlarged */ done = 0; } } if (done && !all && tline > 0) { /* find near by cat */ near = (NEAR *) bsearch((void *)&fcat, Near, nfcats, sizeof(NEAR), cmp_near); G_debug(4, " near.from_cat = %d near.count = %d", near->from_cat, near->count); /* store info about relation */ if (near->count == 0 || near->dist > dist) { near->to_cat = tcat; /* -1 is OK */ near->dist = dist; near->from_x = FPoints->x[0]; near->from_y = FPoints->y[0]; near->from_z = FPoints->z[0]; near->to_x = tx; near->to_y = ty; near->to_z = tz; near->to_along = talong; /* 0 for points */ near->to_angle = tangle; } near->count++; } } /* done */ } /* next feature */ if (LLPoints) { Vect_destroy_line_struct(LLPoints); } } /* Find nearest areas */ if (to_type & GV_AREA) { G_message(_("Finding nearest areas...")); for (fline = 1; fline <= nfrom; fline++) { double tmp_min = (min < 0 ? 0 : min); double box_edge = 0; int done = 0; curr_step = 0; G_debug(3, "fline = %d", fline); G_percent(fline, nfrom, 2); ftype = Vect_read_line(&From, FPoints, FCats, fline); if (!(ftype & from_type)) continue; Vect_cat_get(FCats, from_field, &fcat); if (fcat < 0 && !all) continue; while (!done) { done = 1; if (!all) { /* enlarge search box until we get a hit */ /* the objective is to enlarge the search box * in the first iterations just a little bit * to keep the number of hits low */ Vect_reset_boxlist(List); while (curr_step < n_max_steps) { box_edge = max_step[curr_step]; if (box_edge < tmp_min) continue; box.E = FPoints->x[0] + box_edge; box.W = FPoints->x[0] - box_edge; box.N = FPoints->y[0] + box_edge; box.S = FPoints->y[0] - box_edge; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; Vect_select_areas_by_box(&To, &box, List); curr_step++; if (List->n_values > 0) break; } } else { box.E = FPoints->x[0] + max; box.W = FPoints->x[0] - max; box.N = FPoints->y[0] + max; box.S = FPoints->y[0] - max; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX; Vect_select_areas_by_box(&To, &box, List); } G_debug(4, "%d areas selected by box", List->n_values); /* For each area in box check the distance */ tarea = 0; dist = PORT_DOUBLE_MAX; for (i = 0; i < List->n_values; i++) { int tmp_tcat; area = List->id[i]; G_debug(4, "%d: area %d", i, area); Vect_get_area_points(&To, area, TPoints); /* Find the distance to this area */ if (Vect_point_in_area(FPoints->x[0], FPoints->y[0], &To, area, List->box[i])) { /* in area */ tmp_dist = 0; tmp_tx = FPoints->x[0]; tmp_ty = FPoints->y[0]; } else if (Vect_point_in_poly(FPoints->x[0], FPoints->y[0], TPoints) > 0) { /* in isle */ nisles = Vect_get_area_num_isles(&To, area); for (j = 0; j < nisles; j++) { double tmp2_dist, tmp2_tx, tmp2_ty; isle = Vect_get_area_isle(&To, area, j); Vect_get_isle_points(&To, isle, TPoints); Vect_line_distance(TPoints, FPoints->x[0], FPoints->y[0], FPoints->z[0], WITHOUT_Z, &tmp2_tx, &tmp2_ty, NULL, &tmp2_dist, NULL, NULL); if (j == 0 || tmp2_dist < tmp_dist) { tmp_dist = tmp2_dist; tmp_tx = tmp2_tx; tmp_ty = tmp2_ty; } } } else { /* outside area */ Vect_line_distance(TPoints, FPoints->x[0], FPoints->y[0], FPoints->z[0], WITHOUT_Z, &tmp_tx, &tmp_ty, NULL, &tmp_dist, NULL, NULL); } if (tmp_dist > max || tmp_dist < min) continue; /* not in threshold */ Vect_get_area_cats(&To, area, TCats); tmp_tcat = -1; /* TODO: all cats of given field ? */ for (j = 0; j < TCats->n_cats; j++) { if (TCats->field[j] == to_field) { if (tmp_tcat >= 0) G_warning(_("More cats found in to_layer (area=%d)"), area); tmp_tcat = TCats->cat[j]; } } G_debug(4, " tmp_dist = %f tmp_tcat = %d", tmp_dist, tmp_tcat); if (all) { if (anear <= count) { anear += 10 + nfrom / 10; Near = (NEAR *) G_realloc(Near, anear * sizeof(NEAR)); } near = &(Near[count]); /* store info about relation */ near->from_cat = fcat; near->to_cat = tmp_tcat; /* -1 is OK */ near->dist = tmp_dist; near->from_x = FPoints->x[0]; near->from_y = FPoints->y[0]; near->to_x = tmp_tx; near->to_y = tmp_ty; near->to_along = 0; /* nonsense for areas */ near->to_angle = 0; /* not supported for areas */ near->count++; count++; } else if (tarea == 0 || tmp_dist < dist) { tarea = area; tcat = tmp_tcat; dist = tmp_dist; tx = tmp_tx; ty = tmp_ty; } } if (curr_step < n_max_steps) { /* enlarging the search box is possible */ if (tarea > 0 && dist > box_edge) { /* area found but distance > search edge: * area bbox overlaps with search box, area itself is outside search box */ done = 0; } else if (tarea == 0) { /* no area within max dist, but search box can still be enlarged */ done = 0; } } if (done && !all && tarea > 0) { /* find near by cat */ near = (NEAR *) bsearch((void *)&fcat, Near, nfcats, sizeof(NEAR), cmp_near); G_debug(4, "near.from_cat = %d near.count = %d dist = %f", near->from_cat, near->count, near->dist); /* store info about relation */ if (near->count == 0 || near->dist > dist) { near->to_cat = tcat; /* -1 is OK */ near->dist = dist; near->from_x = FPoints->x[0]; near->from_y = FPoints->y[0]; near->to_x = tx; near->to_y = ty; near->to_along = 0; /* nonsense for areas */ near->to_angle = 0; /* not supported for areas */ } near->count++; } } /* done */ } /* next feature */ } G_debug(3, "count = %d", count); /* Update database / print to stdout / create output map */ if (print_flag->answer) { /* print header */ fprintf(stdout, "from_cat"); i = 0; while (Upload[i].upload != END) { fprintf(stdout, "|%s", Upload[i].column); i++; } fprintf(stdout, "\n"); } else if (all && table_opt->answer) { /* create new table */ db_set_string(&stmt, "create table "); db_append_string(&stmt, table_opt->answer); db_append_string(&stmt, " (from_cat integer"); j = 0; while (Upload[j].upload != END) { db_append_string(&stmt, ", "); switch (Upload[j].upload) { case CAT: sprintf(buf2, "%s integer", Upload[j].column); break; case DIST: case FROM_X: case FROM_Y: case TO_X: case TO_Y: case FROM_ALONG: case TO_ALONG: case TO_ANGLE: sprintf(buf2, "%s double precision", Upload[j].column); } db_append_string(&stmt, buf2); j++; } db_append_string(&stmt, " )"); G_debug(3, "SQL: %s", db_get_string(&stmt)); if (db_execute_immediate(driver, &stmt) != DB_OK) G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&stmt)); if (db_grant_on_table(driver, table_opt->answer, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Unable to grant privileges on table <%s>"), table_opt->answer); } else if (!all) { /* read existing cats from table */ ncatexist = db_select_int(driver, Fi->table, Fi->key, NULL, &catexist); G_debug(1, "%d cats selected from the table", ncatexist); } update_ok = update_err = update_exist = update_notexist = update_dupl = update_notfound = 0; if (!all) { count = nfcats; } else if (print_as_matrix) { qsort((void *)Near, count, sizeof(NEAR), cmp_near_to); } if (driver) db_begin_transaction(driver); /* select 'to' attributes */ if (to_column_opt->answer) { int nrec; db_CatValArray_init(&cvarr); nrec = db_select_CatValArray(to_driver, toFi->table, toFi->key, to_column_opt->answer, NULL, &cvarr); G_debug(3, "selected values = %d", nrec); if (cvarr.ctype == DB_C_TYPE_DATETIME) { G_warning(_("DATETIME type not yet supported, no attributes will be uploaded")); } db_close_database_shutdown_driver(to_driver); } if (!(print_flag->answer || (all && !table_opt->answer))) /* no printing */ G_message("Update database..."); for (i = 0; i < count; i++) { dbCatVal *catval = 0; if (!(print_flag->answer || (all && !table_opt->answer))) /* no printing */ G_percent(i, count, 1); /* Write line connecting nearest points */ if (Outp != NULL) { Vect_reset_line(FPoints); Vect_reset_cats(FCats); Vect_append_point(FPoints, Near[i].from_x, Near[i].from_y, 0); if (Near[i].dist == 0) { Vect_write_line(Outp, GV_POINT, FPoints, FCats); } else { Vect_append_point(FPoints, Near[i].to_x, Near[i].to_y, 0); Vect_write_line(Outp, GV_LINE, FPoints, FCats); } } if (Near[i].count > 1) update_dupl++; if (Near[i].count == 0) update_notfound++; if (to_column_opt->answer && Near[i].count > 0) { db_CatValArray_get_value(&cvarr, Near[i].to_cat, &catval); } if (print_flag->answer || (all && !table_opt->answer)) { /* print only */ /* input and output is the same && calculate distances && only one upload option given -> print as a matrix */ if (print_as_matrix) { if (i == 0) { for (j = 0; j < nfrom; j++) { if (j == 0) fprintf(stdout, " "); fprintf(stdout, "|%d", Near[j].to_cat); } fprintf(stdout, "\n"); } if (i % nfrom == 0) { fprintf(stdout, "%d", Near[i].from_cat); for (j = 0; j < nfrom; j++) { print_upload(Near, Upload, i + j, &cvarr, catval); } fprintf(stdout, "\n"); } } else { fprintf(stdout, "%d", Near[i].from_cat); print_upload(Near, Upload, i, &cvarr, catval); fprintf(stdout, "\n"); } } else if (all) { /* insert new record */ sprintf(buf1, "insert into %s values ( %d ", table_opt->answer, Near[i].from_cat); db_set_string(&stmt, buf1); j = 0; while (Upload[j].upload != END) { db_append_string(&stmt, ","); switch (Upload[j].upload) { case CAT: sprintf(buf2, " %d", Near[i].to_cat); break; case DIST: sprintf(buf2, " %f", Near[i].dist); break; case FROM_X: sprintf(buf2, " %f", Near[i].from_x); break; case FROM_Y: sprintf(buf2, " %f", Near[i].from_y); break; case TO_X: sprintf(buf2, " %f", Near[i].to_x); break; case TO_Y: sprintf(buf2, " %f", Near[i].to_y); break; case FROM_ALONG: sprintf(buf2, " %f", Near[i].from_along); break; case TO_ALONG: sprintf(buf2, " %f", Near[i].to_along); break; case TO_ANGLE: sprintf(buf2, " %f", Near[i].to_angle); break; case TO_ATTR: if (catval) { switch (cvarr.ctype) { case DB_C_TYPE_INT: sprintf(buf2, " %d", catval->val.i); break; case DB_C_TYPE_DOUBLE: sprintf(buf2, " %.15e", catval->val.d); break; case DB_C_TYPE_STRING: db_set_string(&dbstr, db_get_string(catval->val.s)); db_double_quote_string(&dbstr); sprintf(buf2, " '%s'", db_get_string(&dbstr)); break; case DB_C_TYPE_DATETIME: /* TODO: formating datetime */ sprintf(buf2, " null"); break; } } else { sprintf(buf2, " null"); } break; } db_append_string(&stmt, buf2); j++; } db_append_string(&stmt, " )"); G_debug(3, "SQL: %s", db_get_string(&stmt)); if (db_execute_immediate(driver, &stmt) == DB_OK) { update_ok++; } else { update_err++; } } else { /* update table */ /* check if exists in table */ cex = (int *)bsearch((void *)&(Near[i].from_cat), catexist, ncatexist, sizeof(int), cmp_exist); if (cex == NULL) { /* cat does not exist in DB */ update_notexist++; continue; } update_exist++; sprintf(buf1, "update %s set", Fi->table); db_set_string(&stmt, buf1); j = 0; while (Upload[j].upload != END) { if (j > 0) db_append_string(&stmt, ","); sprintf(buf2, " %s =", Upload[j].column); db_append_string(&stmt, buf2); if (Near[i].count == 0) { /* no nearest found */ db_append_string(&stmt, " null"); } else { switch (Upload[j].upload) { case CAT: if (Near[i].to_cat > 0) sprintf(buf2, " %d", Near[i].to_cat); else sprintf(buf2, " null"); break; case DIST: sprintf(buf2, " %f", Near[i].dist); break; case FROM_X: sprintf(buf2, " %f", Near[i].from_x); break; case FROM_Y: sprintf(buf2, " %f", Near[i].from_y); break; case TO_X: sprintf(buf2, " %f", Near[i].to_x); break; case TO_Y: sprintf(buf2, " %f", Near[i].to_y); break; case FROM_ALONG: sprintf(buf2, " %f", Near[i].from_along); break; case TO_ALONG: sprintf(buf2, " %f", Near[i].to_along); break; case TO_ANGLE: sprintf(buf2, " %f", Near[i].to_angle); break; case TO_ATTR: if (catval) { switch (cvarr.ctype) { case DB_C_TYPE_INT: sprintf(buf2, " %d", catval->val.i); break; case DB_C_TYPE_DOUBLE: sprintf(buf2, " %.15e", catval->val.d); break; case DB_C_TYPE_STRING: db_set_string(&dbstr, db_get_string(catval->val.s)); db_double_quote_string(&dbstr); sprintf(buf2, " '%s'", db_get_string(&dbstr)); break; case DB_C_TYPE_DATETIME: /* TODO: formating datetime */ sprintf(buf2, " null"); break; } } else { sprintf(buf2, " null"); } break; } db_append_string(&stmt, buf2); } j++; } sprintf(buf2, " where %s = %d", Fi->key, Near[i].from_cat); db_append_string(&stmt, buf2); G_debug(2, "SQL: %s", db_get_string(&stmt)); if (db_execute_immediate(driver, &stmt) == DB_OK) { update_ok++; } else { update_err++; } } } G_percent(count, count, 1); if (driver) db_commit_transaction(driver); /* print stats */ if (update_dupl > 0) G_message(_("%d categories with more than 1 feature in vector map <%s>"), update_dupl, from_opt->answer); if (update_notfound > 0) G_message(_("%d categories - no nearest feature found"), update_notfound); if (!print_flag->answer) { db_close_database_shutdown_driver(driver); db_free_string(&stmt); /* print stats */ if (all && table_opt->answer) { G_message(_("%d distances calculated"), count); G_message(_("%d records inserted"), update_ok); if (update_err > 0) G_message(_("%d insert errors"), update_err); } else if (!all) { if (nfcats > 0) G_message(_("%d categories read from the map"), nfcats); if (ncatexist > 0) G_message(_("%d categories exist in the table"), ncatexist); if (update_exist > 0) G_message(_("%d categories read from the map exist in the table"), update_exist); if (update_notexist > 0) G_message(_("%d categories read from the map don't exist in the table"), update_notexist); G_message(_("%d records updated"), update_ok); if (update_err > 0) G_message(_("%d update errors"), update_err); G_free(catexist); } Vect_set_db_updated(&From); } Vect_close(&From); if (Outp != NULL) { Vect_build(Outp); Vect_close(Outp); } G_done_msg(" "); exit(EXIT_SUCCESS); }