/* * open_new_vect - opens new vector map for writing */ int open_new_vect(struct Map_info *map, char *vect) { Vect_open_new(map, vect, 1); Vect_set_map_name(map, vect); Vect_set_comment(map, G_recreate_command()); Vect_hist_command(map); return 1; }
/*! \brief Read header of GRASS ASCII vector format \param dascii pointer to the ASCII file \param Map pointer to Map_info structure \return 0 on success \return -1 on error */ int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map) { char buff[1024]; char *ptr; for (;;) { if (0 == G_getl2(buff, sizeof(buff) - 1, dascii)) return (0); /* Last line of header */ if (strncmp(buff, "VERTI:", 6) == 0) return (0); if (!(ptr = strchr(buff, ':'))) { G_warning(_("Unexpected data in vector header:\n[%s]"), buff); return -1; } ptr++; /* Search for the start of text */ while (*ptr == ' ') ptr++; if (strncmp(buff, "ORGANIZATION:", 12) == 0) Vect_set_organization(Map, ptr); else if (strncmp(buff, "DIGIT DATE:", 11) == 0) Vect_set_date(Map, ptr); else if (strncmp(buff, "DIGIT NAME:", 11) == 0) Vect_set_person(Map, ptr); else if (strncmp(buff, "MAP NAME:", 9) == 0) Vect_set_map_name(Map, ptr); else if (strncmp(buff, "MAP DATE:", 9) == 0) Vect_set_map_date(Map, ptr); else if (strncmp(buff, "MAP SCALE:", 10) == 0) Vect_set_scale(Map, atoi(ptr)); else if (strncmp(buff, "OTHER INFO:", 11) == 0) Vect_set_comment(Map, ptr); else if (strncmp(buff, "ZONE:", 5) == 0 || strncmp(buff, "UTM ZONE:", 9) == 0) Vect_set_zone(Map, atoi(ptr)); else if (strncmp(buff, "WEST EDGE:", 10) == 0) { } else if (strncmp(buff, "EAST EDGE:", 10) == 0) { } else if (strncmp(buff, "SOUTH EDGE:", 11) == 0) { } else if (strncmp(buff, "NORTH EDGE:", 11) == 0) { } else if (strncmp(buff, "MAP THRESH:", 11) == 0) Vect_set_thresh(Map, atof(ptr)); else { G_warning(_("Unknown keyword <%s> in vector head"), buff); } } /* NOTREACHED */ }
/* * open_new_vect - opens new vector map for writing */ int open_new_vect(struct Map_info *map, char *vect) { if (Vect_open_new(map, vect, 1) < 0) G_fatal_error(_("Unable to create vector map <%s>"), vect); Vect_set_map_name(map, vect); Vect_set_comment(map, G_recreate_command()); Vect_hist_command(map); return 1; }
/*! \brief Copy header data from one to another map \param from target vector map \param[out] to destination vector map \return 0 */ int Vect_copy_head_data(const struct Map_info *from, struct Map_info *to) { Vect_set_organization(to, Vect_get_organization(from)); Vect_set_date(to, Vect_get_date(from)); Vect_set_person(to, Vect_get_person(from)); Vect_set_map_name(to, Vect_get_map_name(from)); Vect_set_map_date(to, Vect_get_map_date(from)); Vect_set_comment(to, Vect_get_comment(from)); Vect_set_scale(to, Vect_get_scale(from)); Vect_set_zone(to, Vect_get_zone(from)); Vect_set_thresh(to, Vect_get_thresh(from)); return 0; }
/*! \brief Initialize Map_info head structure (dig_head) \param[in,out] Map pointer to Map_info structure */ void Vect__init_head(struct Map_info *Map) { char buf[64]; /* organization */ Map->head.organization = NULL; Vect_set_organization(Map, ""); /* date */ Map->head.date = NULL; Vect_set_date(Map, ""); /* user name */ Map->head.user_name = NULL; sprintf(buf, "%s", G_whoami()); Vect_set_person(Map, buf); /* map name */ Map->head.map_name = NULL; Vect_set_map_name(Map, ""); /* source date */ Map->head.source_date = NULL; sprintf(buf, "%s", G_date()); Vect_set_map_date(Map, buf); /* comments */ Map->head.comment = NULL; Vect_set_comment(Map, ""); /* scale, threshold */ Vect_set_scale(Map, 1); Vect_set_thresh(Map, 0.0); /* proj, zone */ Vect_set_proj(Map, -1); Vect_set_zone(Map, -1); /* support variables */ Map->plus.Spidx_built = 0; Map->plus.release_support = 0; Map->plus.update_cidx = 0; }
int main(int argc, char *argv[]) { /* variables */ DCELL *data_buf; CELL *clump_buf; CELL i, max; int row, col, rows, cols; int out_mode, use_MASK, *n, *e; long int *count; int fd_data, fd_clump; const char *datamap, *clumpmap, *centroidsmap; double avg, vol, total_vol, east, north, *sum; struct Cell_head window; struct Map_info *fd_centroids; struct line_pnts *Points; struct line_cats *Cats; struct field_info *Fi; char buf[DB_SQL_MAX]; dbString sql; dbDriver *driver; struct GModule *module; struct { struct Option *input, *clump, *centroids, *output; } opt; struct { struct Flag *report; } flag; /* define parameters and flags */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("volume")); G_add_keyword(_("clumps")); module->label = _("Calculates the volume of data \"clumps\"."); module->description = _("Optionally produces a GRASS vector points map " "containing the calculated centroids of these clumps."); opt.input = G_define_standard_option(G_OPT_R_INPUT); opt.input->description = _("Name of input raster map representing data that will be summed within clumps"); opt.clump = G_define_standard_option(G_OPT_R_INPUT); opt.clump->key = "clump"; opt.clump->required = NO; opt.clump->label = _("Name of input clump raster map"); opt.clump->description = _("Preferably the output of r.clump. " "If no clump map is given than MASK is used."); opt.centroids = G_define_standard_option(G_OPT_V_OUTPUT); opt.centroids->key = "centroids"; opt.centroids->required = NO; opt.centroids->description = _("Name for output vector points map to contain clump centroids"); opt.output = G_define_standard_option(G_OPT_F_OUTPUT); opt.output->required = NO; opt.output->label = _("Name for output file to hold the report"); opt.output->description = _("If no output file given report is printed to standard output"); flag.report = G_define_flag(); flag.report->key = 'f'; flag.report->description = _("Generate unformatted report (items separated by colon)"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* get arguments */ datamap = opt.input->answer; clumpmap = NULL; if (opt.clump->answer) clumpmap = opt.clump->answer; centroidsmap = NULL; fd_centroids = NULL; Points = NULL; Cats = NULL; driver = NULL; if (opt.centroids->answer) { centroidsmap = opt.centroids->answer; fd_centroids = G_malloc(sizeof(struct Map_info)); } out_mode = (!flag.report->answer); /* * see if MASK or a separate "clumpmap" raster map is to be used * -- it must(!) be one of those two choices. */ use_MASK = 0; if (!clumpmap) { clumpmap = "MASK"; use_MASK = 1; if (!G_find_raster2(clumpmap, G_mapset())) G_fatal_error(_("No MASK found. If no clump map is given than the MASK is required. " "You need to define a clump raster map or create a MASK by r.mask command.")); G_important_message(_("No clump map given, using MASK")); } /* open input and clump raster maps */ fd_data = Rast_open_old(datamap, ""); fd_clump = Rast_open_old(clumpmap, use_MASK ? G_mapset() : ""); /* initialize vector map (for centroids) if needed */ if (centroidsmap) { if (Vect_open_new(fd_centroids, centroidsmap, WITHOUT_Z) < 0) G_fatal_error(_("Unable to create vector map <%s>"), centroidsmap); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* initialize data structures */ Vect_append_point(Points, 0., 0., 0.); Vect_cat_set(Cats, 1, 1); } /* initialize output file */ if (opt.output->answer && strcmp(opt.output->answer, "-") != 0) { if (freopen(opt.output->answer, "w", stdout) == NULL) { perror(opt.output->answer); exit(EXIT_FAILURE); } } /* initialize data accumulation arrays */ max = Rast_get_max_c_cat(clumpmap, use_MASK ? G_mapset() : ""); sum = (double *)G_malloc((max + 1) * sizeof(double)); count = (long int *)G_malloc((max + 1) * sizeof(long int)); G_zero(sum, (max + 1) * sizeof(double)); G_zero(count, (max + 1) * sizeof(long int)); data_buf = Rast_allocate_d_buf(); clump_buf = Rast_allocate_c_buf(); /* get window size */ G_get_window(&window); rows = window.rows; cols = window.cols; /* now get the data -- first pass */ for (row = 0; row < rows; row++) { G_percent(row, rows, 2); Rast_get_d_row(fd_data, data_buf, row); Rast_get_c_row(fd_clump, clump_buf, row); for (col = 0; col < cols; col++) { i = clump_buf[col]; if (i > max) G_fatal_error(_("Invalid category value %d (max=%d): row=%d col=%d"), i, max, row, col); if (i < 1) { G_debug(3, "row=%d col=%d: zero or negs ignored", row, col); continue; /* ignore zeros and negs */ } if (Rast_is_d_null_value(&data_buf[col])) { G_debug(3, "row=%d col=%d: NULL ignored", row, col); continue; } sum[i] += data_buf[col]; count[i]++; } } G_percent(1, 1, 1); /* free some buffer space */ G_free(data_buf); G_free(clump_buf); /* data lists for centroids of clumps */ e = (int *)G_malloc((max + 1) * sizeof(int)); n = (int *)G_malloc((max + 1) * sizeof(int)); i = centroids(fd_clump, e, n, 1, max); /* close raster maps */ Rast_close(fd_data); Rast_close(fd_clump); /* got everything, now do output */ if (centroidsmap) { G_message(_("Creating vector point map <%s>..."), centroidsmap); /* set comment */ sprintf(buf, _("From '%s' on raster map <%s> using clumps from <%s>"), argv[0], datamap, clumpmap); Vect_set_comment(fd_centroids, buf); /* create attribute table */ Fi = Vect_default_field_info(fd_centroids, 1, NULL, GV_1TABLE); driver = db_start_driver_open_database(Fi->driver, Vect_subst_var(Fi->database, fd_centroids)); if (driver == NULL) { G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, fd_centroids), Fi->driver); } db_set_error_handler_driver(driver); db_begin_transaction(driver); db_init_string(&sql); sprintf(buf, "create table %s (cat integer, volume double precision, " "average double precision, sum double precision, count integer)", Fi->table); db_set_string(&sql, buf); Vect_map_add_dblink(fd_centroids, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database, Fi->driver); G_debug(3, "%s", db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) { G_fatal_error(_("Unable to create table: %s"), db_get_string(&sql)); } } /* print header */ if (out_mode) { fprintf(stdout, _("\nVolume report on data from <%s> using clumps on <%s> raster map"), datamap, clumpmap); fprintf(stdout, "\n\n"); fprintf(stdout, _("Category Average Data # Cells Centroid Total\n")); fprintf(stdout, _("Number in clump Total in clump Easting Northing Volume")); fprintf(stdout, "\n%s\n", SEP); } total_vol = 0.0; /* print output, write centroids */ for (i = 1; i <= max; i++) { if (count[i]) { avg = sum[i] / (double)count[i]; vol = sum[i] * window.ew_res * window.ns_res; total_vol += vol; east = window.west + (e[i] + 0.5) * window.ew_res; north = window.north - (n[i] + 0.5) * window.ns_res; if (fd_centroids) { /* write centroids if requested */ Points->x[0] = east; Points->y[0] = north; Cats->cat[0] = i; Vect_write_line(fd_centroids, GV_POINT, Points, Cats); sprintf(buf, "insert into %s values (%d, %f, %f, %f, %ld)", Fi->table, i, vol, avg, sum[i], count[i]); db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) G_fatal_error(_("Cannot insert new row: %s"), db_get_string(&sql)); } if (out_mode) fprintf(stdout, "%8d%10.2f%10.0f %7ld %10.2f %10.2f %16.2f\n", i, avg, sum[i], count[i], east, north, vol); else fprintf(stdout, "%d:%.2f:%.0f:%ld:%.2f:%.2f:%.2f\n", i, avg, sum[i], count[i], east, north, vol); } } /* write centroid attributes and close the map*/ if (fd_centroids) { db_commit_transaction(driver); Vect_close(fd_centroids); } /* print total value */ if (total_vol > 0.0 && out_mode) { fprintf(stdout, "%s\n", SEP); fprintf(stdout, "%60s = %14.2f", _("Total Volume"), total_vol); fprintf(stdout, "\n"); } exit(EXIT_SUCCESS); }
/* Create GRASS vector output map. Create attribute table. Calculate geometries and write them into the output map. Calculate attributes and write them into the output map's attribute table. */ void writeMap() { int i, j; double xlength, ylength, zlength; double length, flatLength, bailLength; double xoffset, yoffset, zoffset; double xys[12]; int ratio; double zRatio; /* attributes to be written to output map */ int boneID; int skelID; int unitID; int oldID; int cat; char *organization; char buf[MAXSTR]; if ( numPoints < 2 ) { G_fatal_error ("Less than two valid measurement points in input file"); } G_message (_("Constructing geometries for %i valid points:"), numPoints ); /* CREATE OUTPUT VECTOR MAP */ if (Vect_legal_filename(output->answer) < 0) { G_fatal_error(_("Use '%s' option to change vector map name"), output->key); } Map = (struct Map_info *) G_malloc (sizeof ( struct Map_info ) ); if (Vect_open_new(Map, output->answer, WITH_Z) < 0) { G_fatal_error(_("Unable to create vector map <%s>"), output->answer); } Vect_set_map_name(Map, output->answer); Vect_hist_command(Map); if ((organization = getenv("GRASS_ORGANIZATION"))) { Vect_set_organization(Map, organization); } else { Vect_set_organization(Map, "UNKNOWN ORGANIZATION"); } Vect_set_date(Map, G_date()); Vect_set_person(Map, G_whoami()); Vect_set_map_date(Map, ""); Vect_set_scale(Map, 2400); Vect_set_comment(Map, ""); Vect_set_zone(Map, 0); Vect_set_thresh(Map, 0.0); /* START DBMS INTERFACE */ /* prepare strings for use in db_* calls */ db_init_string(&sql); /* start default database driver */ Fi = Vect_default_field_info(Map, 1, NULL, GV_1TABLE); driver = db_start_driver_open_database(Fi->driver,Vect_subst_var(Fi->database, Map)); if (driver == NULL) { Vect_delete(output->answer); G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, Map), Fi->driver); } /* create attribute table */ db_begin_transaction ( driver ); sprintf(buf, "create table %s (cat integer, skel_id integer, bone_id integer, unit_id integer, GRASSRGB varchar(11),BONERGB varchar(11));", Fi->table); if ( DEBUG ) { fprintf ( stderr, "Creating attribute table: %s\n", buf ); } db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to create attribute table: %s"), db_get_string(&sql)); } if (db_grant_on_table (driver, output->answer, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to grant privileges on table <%s>"), output->answer); } if (db_create_index2(driver, output->answer, "cat") != DB_OK) { G_warning(_("Unable to create index for table <%s>, key <%s>"), output->answer, "cat"); } /* link vector map to attribute table */ if (Vect_map_add_dblink(Map, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver) ) { Vect_delete(output->answer); G_fatal_error(_("Unable to add database link for vector map <%s>"), Vect_get_full_name(Map)); } /* PROCESS POINTS AND WRITE GEOMETRIES */ /* Now process point measurements and write geometries into output vector map. */ /* At this stage, the global points array has an even number of valid points. */ oldID = pointTable[0].SKEL_ID; unitID = 1; cat = 0; for ( i = 0; i < numPoints; i = i + 2 ) { /* This boneID is a generalized ID that does not differentiate between start and end measurement. */ boneID = (int) pointTable[i+1].BONE_ID / 2; skelID = pointTable[i+1].SKEL_ID; /* get coordinates for top and bottom of bone */ ax = pointTable[i].X; ay = pointTable[i].Y; az = pointTable[i].Z; bx = pointTable[i+1].X; by = pointTable[i+1].Y; bz = pointTable[i+1].Z; /* get vector lengths */ xlength = fabs (ax - bx); ylength = fabs (ay - by); zlength = fabs (az - bz); /* get real length */ length = sqrt ( (xlength*xlength) + (ylength*ylength) + (zlength*zlength) ); /* get length in x/y plane */ flatLength = sqrt ( (xlength*xlength) + (ylength*ylength) ); /* determine ratio for triangles, depending on bone type */ ratio = 12; /* default */ for ( j = 0; j < NUM_RATIOS; j ++ ) { if ( boneID == RATIO_ID[j] ) { ratio = RATIO_VAL[j]; } } /* get bail length */ bailLength = (double) ( length / (double) ratio); /* calculate bail offsets from top point (one bail is mirror of the other) */ xoffset = (bailLength * ylength) / flatLength; yoffset = ( (bailLength * xlength) / flatLength ) * (-1); zoffset = 0; xys[0]= ax + xoffset; xys[1]= ay + yoffset; xys[2]= az + zoffset; xys[6]= ax - xoffset; xys[7]= ay - yoffset; xys[8]= az - zoffset; /* get 3rd axis offsets */ zRatio = (zlength/ratio) / flatLength; xoffset = xlength * zRatio; yoffset = ylength * zRatio; zoffset = (flatLength/ratio) * (-1); xys[3]= ax + xoffset; xys[4]= ay + yoffset; xys[5]= az + zoffset; xys[9]= ax - xoffset; xys[10]= ay - yoffset; xys[11]= az - zoffset; /* Increase unit ID by "1", if we have another skeleton ID */ if ( oldID != pointTable[i+1].SKEL_ID ) { unitID ++; oldID = pointTable[i+1].SKEL_ID; /* switch to next colour for next geometry */ RGBNUM ++; if ( RGBNUM == RGBMAX ) { RGBNUM = 0; } } /* write geometries */ if ( MODE == MODE_DARTS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_LINES ) { writeLine ( cat, skelID, boneID, unitID ); cat ++; } if ( MODE == MODE_PLANES_H ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; } if ( MODE == MODE_PLANES_V ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_POINTS ) { writePoints ( cat, skelID, boneID, unitID ); cat = cat + 2; } if ( MODE == MODE_PYRAMIDS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 3 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 6, 9 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 9, 0 ); cat ++; writeSquare ( cat, skelID, boneID, unitID, xys ); cat ++; } /* switch to next colour for bone colouring */ RGBNUM_BONE ++; if ( RGBNUM_BONE == RGBMAX ) { RGBNUM_BONE = 0; } G_percent ( i, numPoints - 2, 1 ); } fprintf ( stdout, "\n" ); /* commit DBMS actions */ db_commit_transaction(driver); db_close_database_shutdown_driver(driver); if (!Vect_build(Map)) { G_warning("Building topology failed"); } Vect_close(Map); db_free_string(&sql); }
/*! \brief Reads head information from text file (GV_HEAD_ELEMENT) - for internal use only \param Map pointer to Map_info structure \return 0 on success \return -1 on error */ int Vect__read_head(struct Map_info *Map) { FILE *head_fp; char buff[2000]; char *path, *ptr; /* Reset / init */ Vect__init_head(Map); G_debug(1, "Vect__read_head(): vector = %s@%s", Map->name, Map->mapset); path = Vect__get_path(Map); head_fp = G_fopen_old(path, GV_HEAD_ELEMENT, Map->mapset); G_free(path); if (head_fp == NULL) { G_warning(_("Unable to open header file of vector <%s>"), Vect_get_full_name(Map)); return -1; } while (G_getl2(buff, 2000, head_fp)) { if (!(ptr = strchr(buff, ':'))) { G_warning(_("Corrupted row in head: %s"), buff); continue; } ptr++; /* Search for the start of text */ while (*ptr == ' ') ptr++; if (strncmp(buff, "ORGANIZATION:", sizeof(char) * 12) == 0) Vect_set_organization(Map, ptr); else if (strncmp(buff, "DIGIT DATE:", sizeof(char) * 11) == 0) Vect_set_date(Map, ptr); else if (strncmp(buff, "DIGIT NAME:", sizeof(char) * 11) == 0) Vect_set_person(Map, ptr); else if (strncmp(buff, "MAP NAME:", sizeof(char) * 9) == 0) Vect_set_map_name(Map, ptr); else if (strncmp(buff, "MAP DATE:", sizeof(char) * 9) == 0) Vect_set_map_date(Map, ptr); else if (strncmp(buff, "MAP SCALE:", sizeof(char) * 10) == 0) Vect_set_scale(Map, atoi(ptr)); else if (strncmp(buff, "OTHER INFO:", sizeof(char) * 11) == 0) Vect_set_comment(Map, ptr); else if (strncmp(buff, "PROJ:", sizeof(char) * 5) == 0) Vect_set_proj(Map, atoi(ptr)); else if (strncmp(buff, "ZONE:", sizeof(char) * 5) == 0 || strncmp(buff, "UTM ZONE:", sizeof(char) * 9) == 0) Vect_set_zone(Map, atoi(ptr)); else if (strncmp(buff, "WEST EDGE:", sizeof(char) * 10) == 0) { } else if (strncmp(buff, "EAST EDGE:", sizeof(char) * 10) == 0) { } else if (strncmp(buff, "SOUTH EDGE:", sizeof(char) * 11) == 0) { } else if (strncmp(buff, "NORTH EDGE:", sizeof(char) * 11) == 0) { } else if (strncmp(buff, "MAP THRESH:", sizeof(char) * 11) == 0) Vect_set_thresh(Map, atof(ptr)); else G_warning(_("Unknown keyword '%s' in vector head"), buff); } fclose(head_fp); return 0; }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Option *input, *output, *zshift, *height, *elevation, *hcolumn, *type, *field, *cats, *where, *interp, *scale, *null; } opt; struct { struct Flag *trace; } flag; struct Map_info In, Out; struct line_pnts *Points; struct line_cats *Cats; struct bound_box map_box; struct cat_list *cat_list; struct Cell_head window; int field; int only_type, cat; int fdrast, interp_method, trace; double objheight, objheight_default, voffset; double scale, null_val; struct field_info *Fi; dbDriver *driver = NULL; char *comment; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("geometry")); G_add_keyword(_("sampling")); G_add_keyword(_("3D")); module->label = _("Extrudes flat vector features to 3D vector features with defined height."); module->description = _("Optionally the height can be derived from sampling of elevation raster map."); flag.trace = G_define_flag(); flag.trace->key = 't'; flag.trace->description = _("Trace elevation"); flag.trace->guisection = _("Elevation"); opt.input = G_define_standard_option(G_OPT_V_INPUT); opt.field = G_define_standard_option(G_OPT_V_FIELD_ALL); opt.field->guisection = _("Selection"); opt.cats = G_define_standard_option(G_OPT_V_CATS); opt.cats->guisection = _("Selection"); opt.where = G_define_standard_option(G_OPT_DB_WHERE); opt.where->guisection = _("Selection"); opt.type = G_define_standard_option(G_OPT_V_TYPE); opt.type->answer = "point,line,area"; opt.type->options = "point,line,area"; opt.type->guisection = _("Selection"); opt.output = G_define_standard_option(G_OPT_V_OUTPUT); opt.zshift = G_define_option(); opt.zshift->key = "zshift"; opt.zshift->description = _("Shifting value for z coordinates"); opt.zshift->type = TYPE_DOUBLE; opt.zshift->required = NO; opt.zshift->answer = "0"; opt.zshift->guisection = _("Height"); opt.height = G_define_option(); opt.height->key = "height"; opt.height->type = TYPE_DOUBLE; opt.height->required = NO; opt.height->multiple = NO; opt.height->description = _("Fixed height for 3D vector features"); opt.height->guisection = _("Height"); opt.hcolumn = G_define_standard_option(G_OPT_DB_COLUMN); opt.hcolumn->key = "height_column"; opt.hcolumn->multiple = NO; opt.hcolumn->description = _("Name of attribute column with feature height"); opt.hcolumn->guisection = _("Height"); /* raster sampling */ opt.elevation = G_define_standard_option(G_OPT_R_ELEV); opt.elevation->required = NO; opt.elevation->description = _("Elevation raster map for height extraction"); opt.elevation->guisection = _("Elevation"); opt.interp = G_define_standard_option(G_OPT_R_INTERP_TYPE); opt.interp->answer = "nearest"; opt.interp->guisection = _("Elevation"); opt.scale = G_define_option(); opt.scale->key = "scale"; opt.scale->type = TYPE_DOUBLE; opt.scale->description = _("Scale factor sampled raster values"); opt.scale->answer = "1.0"; opt.scale->guisection = _("Elevation"); opt.null = G_define_option(); opt.null->key = "null_value"; opt.null->type = TYPE_DOUBLE; opt.null->description = _("Height for sampled raster NULL values"); opt.null->guisection = _("Elevation"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (!opt.height->answer && !opt.hcolumn->answer) { G_fatal_error(_("One of '%s' or '%s' parameters must be set"), opt.height->key, opt.hcolumn->key); } sscanf(opt.zshift->answer, "%lf", &voffset); G_debug(1, "voffset = %f", voffset); if (opt.height->answer) sscanf(opt.height->answer, "%lf", &objheight); else objheight = 0.; G_debug(1, "objheight = %f", objheight); objheight_default = objheight; only_type = Vect_option_to_types(opt.type); /* sampling method */ interp_method = Rast_option_to_interp_type(opt.interp); /* used to scale sampled raster values */ scale = atof(opt.scale->answer); /* is null value defined */ if (opt.null->answer) null_val = atof(opt.null->answer); /* trace elevation */ trace = flag.trace->answer ? TRUE : FALSE; /* set input vector map name and mapset */ Vect_check_input_output_name(opt.input->answer, opt.output->answer, G_FATAL_EXIT); Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_set_open_level(2); /* topology required for input */ /* opening input vector map */ if (Vect_open_old2(&In, opt.input->answer, "", opt.field->answer) < 0) G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer); Vect_set_error_handler_io(&In, &Out); /* creating output vector map */ if (Vect_open_new(&Out, opt.output->answer, WITH_Z) < 0) G_fatal_error(_("Unable to create vector map <%s>"), opt.output->answer); field = Vect_get_field_number(&In, opt.field->answer); if ((opt.hcolumn->answer || opt.cats->answer || opt.where->answer) && field == -1) { G_warning(_("Invalid layer number (%d). " "Parameter '%s', '%s' or '%s' specified, assuming layer '1'."), field, opt.hcolumn->key, opt.cats->key, opt.where->key); field = 1; } /* set constraint for cats or where */ cat_list = NULL; if (field > 0) cat_list = Vect_cats_set_constraint(&In, field, opt.where->answer, opt.cats->answer); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); /* opening database connection, if required */ if (opt.hcolumn->answer) { int ctype; dbColumn *column; if ((Fi = Vect_get_field(&In, field)) == NULL) G_fatal_error(_("Database connection not defined for layer %d"), field); if ((driver = db_start_driver_open_database(Fi->driver, Fi->database)) == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_set_error_handler_driver(driver); if (db_get_column(driver, Fi->table, opt.hcolumn->answer, &column) != DB_OK) G_fatal_error(_("Column <%s> does not exist"), opt.hcolumn->answer); else db_free_column(column); ctype = db_column_Ctype(driver, Fi->table, opt.hcolumn->answer); if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_STRING && ctype != DB_C_TYPE_DOUBLE) { G_fatal_error(_("Column <%s>: invalid data type"), opt.hcolumn->answer); } } /* do we work with elevation raster? */ fdrast = -1; if (opt.elevation->answer) { /* raster setup */ G_get_window(&window); /* open the elev raster, and check for error condition */ fdrast = Rast_open_old(opt.elevation->answer, ""); } /* if area */ if (only_type & GV_AREA) { int area, nareas, centroid; nareas = Vect_get_num_areas(&In); G_debug(2, "n_areas = %d", nareas); if (nareas > 0) G_message(_("Extruding areas...")); for (area = 1; area <= nareas; area++) { G_debug(3, "area = %d", area); G_percent(area, nareas, 2); if (!Vect_area_alive(&In, area)) continue; centroid = Vect_get_area_centroid(&In, area); if (!centroid) { G_warning(_("Skipping area %d without centroid"), area); continue; } Vect_read_line(&In, NULL, Cats, centroid); if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list)) continue; /* height attribute */ if (opt.hcolumn->answer) { cat = Vect_get_area_cat(&In, area, field); if (cat == -1) { G_warning(_("No category defined for area %d. Using default fixed height %f."), area, objheight_default); objheight = objheight_default; } if (get_height(Fi, opt.hcolumn->answer, driver, cat, &objheight) != 0) { G_warning(_("Unable to fetch height from DB for area %d. Using default fixed height %f."), area, objheight_default); objheight = objheight_default; } } /* if opt.hcolumn->answer */ Vect_get_area_points(&In, area, Points); G_debug(3, "area: %d height: %f", area, objheight); extrude(&In, &Out, Cats, Points, fdrast, trace, interp_method, scale, opt.null->answer ? TRUE : FALSE, null_val, objheight, voffset, &window, GV_AREA, centroid); } /* foreach area */ } if (only_type > 0) { int line, nlines; int type; G_debug(1, "other than areas"); /* loop through each line in the dataset */ nlines = Vect_get_num_lines(&In); G_message(_("Extruding features...")); for (line = 1; line <= nlines; line++) { /* progress feedback */ G_percent(line, nlines, 2); if (!Vect_line_alive(&In, line)) continue; /* read line */ type = Vect_read_line(&In, Points, Cats, line); if (!(type & only_type)) continue; if (field > 0 && !Vect_cats_in_constraint(Cats, field, cat_list)) continue; /* height attribute */ if (opt.hcolumn->answer) { cat = Vect_get_line_cat(&In, line, field); if (cat == -1) { G_warning(_("No category defined for feature %d. Using default fixed height %f."), line, objheight_default); objheight = objheight_default; } if (get_height(Fi, opt.hcolumn->answer, driver, cat, &objheight) != 0) { G_warning(_("Unable to fetch height from DB for line %d. Using default fixed height %f."), line, objheight_default); objheight = objheight_default; } } /* if opt.hcolumn->answer */ extrude(&In, &Out, Cats, Points, fdrast, trace, interp_method, scale, opt.null->answer ? TRUE : FALSE, null_val, objheight, voffset, &window, type, -1); } /* for each line */ } /* else if area */ if (driver) { db_close_database(driver); db_shutdown_driver(driver); } G_important_message(_("Copying attribute table...")); if (field < 0) Vect_copy_tables(&In, &Out, 0); else Vect_copy_table_by_cat_list(&In, &Out, field, field, NULL, GV_1TABLE, cat_list); Vect_build(&Out); /* header */ G_asprintf(&comment, "Generated by %s from vector map <%s>", G_program_name(), Vect_get_full_name(&In)); Vect_set_comment(&Out, comment); G_free(comment); Vect_get_map_box(&Out, &map_box); Vect_close(&In); Vect_close(&Out); Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats); G_done_msg("T: %f B: %f.", map_box.T, map_box.B); exit(EXIT_SUCCESS); }
/* read old 3.0 or 4.0 dig file into array returns number of elements read into array or -1 on error */ int read_dig(FILE * Digin, struct Map_info *Mapout, struct Line **plines, int endian, int att) { char buf[100]; struct dig_head In_head; int lalloc, line = 0, type, portable = 1; int npoints = 0, nlines = 0, nbounds = 0; int ndpoints = 0, ndlines = 0, ndbounds = 0, nunknown = 0; struct Line *lines; struct line_pnts *nline; struct line_cats *cat_out; double dbuf; int ibuf; long lbuf; struct gvfile gvf; dig_file_init(&gvf); gvf.file = Digin; Vect__init_head(Mapout); /* set conversion matrices */ dig_init_portable(&(In_head.port), endian); /* Version 3 dig files were not portable and some version 4 * files may be also non portable */ G_message(_("Reading dig file...")); /* read and copy head */ dig_fseek(&gvf, 0L, SEEK_SET); /* set to beginning */ if (0 >= dig__fread_port_C(buf, DIG4_ORGAN_LEN, &gvf)) return -1; buf[DIG4_ORGAN_LEN - 1] = '\0'; Vect_set_organization(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_DATE_LEN, &gvf)) return -1; buf[DIG4_DATE_LEN - 1] = '\0'; Vect_set_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_YOUR_NAME_LEN, &gvf)) return -1; buf[DIG4_YOUR_NAME_LEN - 1] = '\0'; Vect_set_person(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_MAP_NAME_LEN, &gvf)) return -1; buf[DIG4_MAP_NAME_LEN - 1] = '\0'; Vect_set_map_name(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_SOURCE_DATE_LEN, &gvf)) return -1; buf[DIG4_SOURCE_DATE_LEN - 1] = '\0'; Vect_set_map_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_LINE_3_LEN, &gvf)) return -1; buf[DIG4_LINE_3_LEN - 1] = '\0'; Vect_set_comment(Mapout, buf); if (0 >= dig__fread_port_C(buf, VERS_4_DATA_SIZE, &gvf)) return -1; if (buf[0] != '%' || buf[1] != '%') { /* Version3.0 */ In_head.Version_Major = 3; portable = 0; /* input vector is not portable format */ G_message(_("Input file is version 3.")); } else { In_head.Version_Major = 4; G_message(_("Input file is version 4.")); /* determine if in portable format or not */ if (buf[6] == 1 && (~buf[6] & 0xff) == (buf[7] & 0xff)) { /* portable ? */ portable = 1; /* input vector is portable format */ } else { portable = 0; /* input vector is not portable format */ } } if (portable == 1) { G_message(_("Input file is portable.")); } else { G_warning(_("Input file is not portable. " "We will attempt to convert anyway but conversion may fail. " "Please read manual for detail information.")); } /* set Cur_Head because it is used by dig__*_convert() called by dig__fread_port_*() */ dig_set_cur_port(&(In_head.port)); if (0 >= dig__fread_port_L(&lbuf, 1, &gvf)) return -1; Vect_set_scale(Mapout, (int)lbuf); if (0 >= dig__fread_port_I(&ibuf, 1, &gvf)) return -1; Vect_set_zone(Mapout, ibuf); if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* W */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* E */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* S */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* N */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; Vect_set_thresh(Mapout, dbuf); /* reading dig file body (elements) */ nline = Vect_new_line_struct(); cat_out = Vect_new_cats_struct(); lalloc = 0; lines = NULL; line = 0; while (1) { type = read_line(&gvf, nline); G_debug(3, "read line = %d, type = %d", line, type); if (type == -2) break; /* EOF */ switch (type) { case GV_POINT: npoints++; break; case GV_LINE: nlines++; break; case GV_BOUNDARY: nbounds++; break; case 0: /* dead */ break; default: nunknown++; break; } if (!(type & (GV_POINT | GV_LINE | GV_BOUNDARY))) continue; if ((type & GV_BOUNDARY) || !att) { Vect_write_line(Mapout, type, nline, cat_out); /* reset In_head */ dig_set_cur_port(&(In_head.port)); } else { /* GV_POINT or GV_LINE */ if (line >= lalloc) { lalloc += 10000; lines = (struct Line *)G_realloc(lines, lalloc * sizeof(struct Line)); } lines[line].type = type; lines[line].n_points = nline->n_points; lines[line].cat = -1; lines[line].x = (double *)G_malloc(nline->n_points * sizeof(double)); lines[line].y = (double *)G_malloc(nline->n_points * sizeof(double)); memcpy((void *)lines[line].x, (void *)nline->x, nline->n_points * sizeof(double)); memcpy((void *)lines[line].y, (void *)nline->y, nline->n_points * sizeof(double)); line++; } } if (att) { G_message(_("[%d] points read to memory"), npoints); G_message(_("[%d] lines read to memory"), nlines); } else { G_message(_("[%d] points read and written to output"), npoints); G_message(_("[%d] lines read and written to output"), nlines); } G_message(_("[%d] area boundaries read and written to output"), nbounds); G_message(_("[%d] dead points skipped"), ndpoints); G_message(_("[%d] dead lines skipped"), ndlines); G_message(_("[%d] dead area boundaries skipped"), ndbounds); G_message(_("[%d] elements of unknown type skipped"), nunknown); G_message(_("[%d] elements read to memory"), line); *plines = lines; return (line); }