/*! \brief Lowest level open routine. Opens the file <i>name</i> in <i>element</i> ("cell", etc.) in mapset <i>mapset</i> according to the i/o <i>mode</i>. - mode = 0 (read) will look for <i>name</i> in <i>mapset</i> and open the file for read only the file must exist - mode = 1 (write) will create an empty file <i>name</i> in the current mapset and open the file for write only <i>mapset</i> ignored - mode = 2 (read and write) will open a file in the current mapset for reading and writing creating a new file if necessary <i>mapset</i> ignored \param element database element name \param name map file name \param mapset mapset containing map <i>name</i> \param mode r/w mode 0=read, 1=write, 2=read/write \return open file descriptor (int) \return -1 could not open */ static int G__open(const char *element, const char *name, const char *mapset, int mode) { char path[GPATH_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; G__check_gisinit(); /* READ */ if (mode == 0) { if (G_name_is_fully_qualified(name, xname, xmapset)) { if (*mapset && strcmp(xmapset, mapset) != 0) { G_warning(_("G__open(read): mapset <%s> doesn't match xmapset <%s>"), mapset, xmapset); return -1; } name = xname; mapset = xmapset; } else if (!mapset || !*mapset) mapset = G_find_file2(element, name, mapset); if (!mapset) return -1; G_file_name(path, element, name, mapset); return open(path, 0); } /* WRITE */ if (mode == 1 || mode == 2) { mapset = G_mapset(); if (G_name_is_fully_qualified(name, xname, xmapset)) { if (strcmp(xmapset, mapset) != 0) { G_warning(_("G__open(write): xmapset <%s> != G_mapset() <%s>"), xmapset, mapset); return -1; } name = xname; } if (*name && G_legal_filename(name) == -1) return -1; G_file_name(path, element, name, mapset); if (mode == 1 || access(path, 0) != 0) { G__make_mapset_element(element); close(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666)); } return open(path, mode); } return -1; }
static const char *find_file1( int misc, const char *dir, const char *element, char *name, const char *mapset) { char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; const char *pname, *pmapset; const char *mp; if (G_name_is_fully_qualified(name, xname, xmapset)) { pname = xname; pmapset = xmapset; } else { pname = name; pmapset = mapset; } mp = find_file(misc, dir, element, pname, pmapset); if (mp && name != pname) strcpy(name, pname); return mp; }
/*! * \brief Write map layer color table * * The color table is written for the raster map <i>name</i> in the * specified <i>mapset</i> from the <i>colors</i> structure. * * If there is an error, -1 is returned. No diagnostic is * printed. Otherwise, 1 is returned. * * The <i>colors</i> structure must be created properly, i.e., * Rast_init_colors() to initialize the structure and Rast_add_c_color_rule() * to set the category colors. These routines are called by * higher level routines which read or create entire color tables, * such as Rast_read_colors() or Rast_make_ramp_colors(). * * <b>Note:</b> The calling sequence for this function deserves * special attention. The <i>mapset</i> parameter seems to imply that * it is possible to overwrite the color table for a raster map which * is in another mapset. However, this is not what actually * happens. It is very useful for users to create their own color * tables for raster maps in other mapsets, but without overwriting * other users' color tables for the same raster map. If <i>mapset</i> * is the current mapset, then the color file for <i>name</i> will be * overwritten by the new color table. But if <i>mapset</i> is not the * current mapset, then the color table is actually written in the * current mapset under the <tt>colr2</tt> element as: * <tt>colr2/mapset/name</tt>. * * The rules are written out using floating-point format, removing * trailing zeros (possibly producing integers). The flag marking the * colors as floating-point is <b>not</b> written. * * If the environment variable FORCE_GRASS3_COLORS is set (to anything at all) * then the output format is 3.0, even if the structure contains 4.0 rules. * This allows users to create 3.0 color files for export to sites which * don't yet have 4.0 * * \param name map name * \param mapset mapset name * \param colors pointer to structure Colors which holds color info * * \return void */ void Rast_write_colors(const char *name, const char *mapset, struct Colors *colors) { char element[512]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; FILE *fd; if (G_name_is_fully_qualified(name, xname, xmapset)) { if (strcmp(xmapset, mapset) != 0) G_fatal_error(_("Qualified name <%s> doesn't match mapset <%s>"), name, mapset); name = xname; } /* * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass) * and then write original color table * else write secondary color table */ sprintf(element, "colr2/%s", mapset); if (strcmp(mapset, G_mapset()) == 0) { G_remove(element, name); /* get rid of existing colr2, if any */ strcpy(element, "colr"); } if (!(fd = G_fopen_new(element, name))) G_fatal_error(_("Unable to create <%s> file for map <%s>"), element, name); Rast__write_colors(fd, colors); fclose(fd); }
/*! \brief Returns unqualified map name (without @ mapset) Returns an unqualified name for the file <i>name</i> in <i>mapset</i>. Note: - <i>name, xname</i> are char array of size GNAME_MAX - <i>mapset, xmapset</i> are char array of size GMAPSET_MAX \param fullname map name \param fullname map mapset \param[out] name map name \param[out] mapset mapset name \return 1 if input map name is fully qualified \return 0 if ... \return -1 if input mapset invalid */ int G_unqualified_name(const char *name, const char *mapset, char *xname, char *xmapset) { if (G_name_is_fully_qualified(name, xname, xmapset)) { if (mapset && *mapset && strcmp(mapset, xmapset) != 0) return -1; return 1; } strcpy(xname, name); strcpy(xmapset, mapset); return 0; }
char *construct_pattern(char **names) { char *pattern, *p; int i, len, found_illegal_names; const char *mapset; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; len = 0; for (i = 0; names[i]; i++) { if ((p = strchr(names[i], '@'))) len += p - names[i]; else len += strlen(names[i]); } len += i; /* # names - 1 commas + \0 */ pattern = p = (char *)G_malloc(len); mapset = G_mapset(); found_illegal_names = 0; for (i = 0; names[i]; i++) { char *name; name = names[i]; if (G_name_is_fully_qualified(name, xname, xmapset)) { if (strcmp(xmapset, mapset) != 0) G_fatal_error(_("%s: Cannot remove or exclude files not in " "the current mapset."), name); name = xname; } if (G_legal_filename(name) == -1) found_illegal_names = 1; if (i) *p++ = ','; strcpy(p, name); p += strlen(name); } if (found_illegal_names) G_fatal_error(_("Illegal filenames not allowed in the names or ignore " "option.")); return pattern; }
/*! \brief Remove color table of raster map \param name name of raster map \param mapset name of mapset \return -1 on error \return 0 color table not found \return 1 on success */ int Vect_remove_colors(const char *name, const char *mapset) { char element[GPATH_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int stat; if (G_name_is_fully_qualified(name, xname, xmapset)) { if (strcmp(xmapset, mapset) != 0) return -1; name = xname; } /* get rid of existing colr2, if any */ sprintf(element, "%s/%s", GV_COLR2_DIRECTORY, mapset); stat = G_remove(element, name); if (strcmp(mapset, G_mapset()) == 0) { sprintf(element, "%s/%s", GV_DIRECTORY, name); stat = G_remove(element, GV_COLR_ELEMENT); } return stat; }
/* * If windowName == NULL -> RASTER3D_WINDOW_ELEMENT ("$MAPSET/WIND3") * otherwise RASTER3D_WINDOW_DATABASE ("$MAPSET/windows3d/$NAME") */ static void Rast3d_getFullWindowPath(char *path, const char *windowName) { char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; if (windowName == NULL) { G_file_name(path, "", RASTER3D_WINDOW_ELEMENT, G_mapset()); return; } while (*windowName == ' ') windowName++; if (strchr(windowName, GRASS_DIRSEP) || strchr(windowName, HOST_DIRSEP)) { sprintf(path, "%s", windowName); return; } if (G_name_is_fully_qualified(windowName, xname, xmapset)) { G_file_name(path, RASTER3D_WINDOW_DATABASE, xname, xmapset); return; } G_file_name(path, RASTER3D_WINDOW_DATABASE, windowName, G_mapset()); }
/*----------------------------------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Declarations */ int dim_vect, nparameters, BW, npoints; int nsply, nsplx, nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; const char *dvr, *db, *mapset; char table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; double lambda, mean, stepN, stepE, HighThresh, LowThresh; double N_extension, E_extension, edgeE, edgeN; int i, nterrain, count_terrain; int last_row, last_column, flag_auxiliar = FALSE; int *lineVect; double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect, **obsVect_all; /* Interpolation and least-square matrix */ struct Map_info In, Out, Terrain; struct Option *in_opt, *out_opt, *out_terrain_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *Thresh_A_opt, *Thresh_B_opt; struct Flag *spline_step_flag; struct GModule *module; struct Cell_head elaboration_reg, original_reg; struct Reg_dimens dims; struct bound_box general_box, overlap_box; struct Point *observ; struct lidar_cat *lcat; dbDriver *driver; /*----------------------------------------------------------------------------------------------------------*/ /* Options' declaration */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("LIDAR")); module->description = _("Corrects the v.lidar.growing output. It is the last of the three algorithms for LIDAR filtering."); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->description = _("Input observation vector map name (v.lidar.growing output)"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->description = _("Output classified vector map name"); out_terrain_opt = G_define_option(); out_terrain_opt->key = "terrain"; out_terrain_opt->type = TYPE_STRING; out_terrain_opt->key_desc = "name"; out_terrain_opt->required = YES; out_terrain_opt->gisprompt = "new,vector,vector"; out_terrain_opt->description = _("Only 'terrain' points output vector map"); stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "25"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "25"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda_c"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Regularization weight in reclassification evaluation"); lambda_f_opt->answer = "1"; Thresh_A_opt = G_define_option(); Thresh_A_opt->key = "tch"; Thresh_A_opt->type = TYPE_DOUBLE; Thresh_A_opt->required = NO; Thresh_A_opt->description = _("High threshold for object to terrain reclassification"); Thresh_A_opt->answer = "2"; Thresh_B_opt = G_define_option(); Thresh_B_opt->key = "tcl"; Thresh_B_opt->type = TYPE_DOUBLE; Thresh_B_opt->required = NO; Thresh_B_opt->description = _("Low threshold for terrain to object reclassification"); Thresh_B_opt->answer = "1"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); HighThresh = atof(Thresh_A_opt->answer); LowThresh = atof(Thresh_B_opt->answer); if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of database")); if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of driver")); /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); /* Something went wrong in a previous v.lidar.correction execution */ if (db_table_exists(dvr, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Checking vector names */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); /* Open input vector */ if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); Vect_set_open_level(1); /* without topology */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); /* Input vector must be 3D */ if (!Vect_is_3d(&In)) G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer); /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { G_message("Estimated point density: %.4g", dens); G_message("Estimated mean distance between points: %.4g", dist); } else G_warning(_("No points in current region!")); Vect_close(&In); exit(EXIT_SUCCESS); } /* Open output vector */ if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } if (0 > Vect_open_new(&Terrain, out_terrain_opt->answer, WITH_Z)) { Vect_close(&In); Vect_close(&Out); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Terrain); Vect_hist_copy(&In, &Terrain); Vect_hist_command(&Terrain); /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); /* Create auxiliar table */ if ((flag_auxiliar = P_Create_Aux2_Table(driver, table_name)) == FALSE) { Vect_close(&In); Vect_close(&Out); Vect_close(&Terrain); exit(EXIT_FAILURE); } db_create_index2(driver, table_name, "ID"); /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(dvr, db); /* Setting regions and boxes */ G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(P_BILINEAR, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(n_("adjusted EW spline %d", "adjusted EW splines %d", nsplx_adj), nsplx_adj); G_verbose_message(n_("adjusted NS spline %d", "adjusted NS splines %d", nsply_adj), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; /* if (nsply > NSPLY_MAX) { nsply = NSPLY_MAX; } */ G_debug(1, _("nsply = %d"), nsply); elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each column */ subregion++; if (nsubregions > 1) G_message(_("subregion %d of %d"), subregion, nsubregions); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; /* if (nsplx > NSPLX_MAX) { nsplx = NSPLX_MAX; } */ G_debug(1, _("nsplx = %d"), nsplx); dim_vect = nsplx * nsply; G_debug(1, _("read vector region map")); observ = P_Read_Vector_Correction(&In, &elaboration_reg, &npoints, &nterrain, dim_vect, &lcat); G_debug(5, _("npoints = %d, nterrain = %d"), npoints, nterrain); if (npoints > 0) { /* If there is any point falling into elaboration_reg. */ count_terrain = 0; nparameters = nsplx * nsply; /* Mean calculation */ G_debug(3, _("Mean calculation")); mean = P_Mean_Calc(&elaboration_reg, observ, npoints); /*Least Squares system */ BW = P_get_BandWidth(P_BILINEAR, nsply); /* Bilinear interpolation */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Bilinear parameters vector */ obsVect = G_alloc_matrix(nterrain + 1, 3); /* Observation vector with terrain points */ obsVect_all = G_alloc_matrix(npoints + 1, 3); /* Observation vector with all points */ Q = G_alloc_vector(nterrain + 1); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints + 1); /* Setting obsVect vector & Q matrix */ G_debug(3, _("Only TERRAIN points")); for (i = 0; i < npoints; i++) { if (observ[i].cat == TERRAIN_SINGLE) { obsVect[count_terrain][0] = observ[i].coordX; obsVect[count_terrain][1] = observ[i].coordY; obsVect[count_terrain][2] = observ[i].coordZ - mean; Q[count_terrain] = 1; /* Q=I */ count_terrain++; } lineVect[i] = observ[i].lineID; obsVect_all[i][0] = observ[i].coordX; obsVect_all[i][1] = observ[i].coordY; obsVect_all[i][2] = observ[i].coordZ - mean; } G_free(observ); G_verbose_message(_("Bilinear interpolation")); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, nterrain, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); G_free_matrix(obsVect); G_verbose_message( _("Correction and creation of terrain vector")); P_Sparse_Correction(&In, &Out, &Terrain, &elaboration_reg, general_box, overlap_box, obsVect_all, lcat, parVect, lineVect, stepN, stepE, dims.overlap, HighThresh, LowThresh, nsplx, nsply, npoints, driver, mean, table_name); G_free_vector(parVect); G_free_matrix(obsVect_all); G_free_ivector(lineVect); } else { G_free(observ); G_warning(_("No data within this subregion. " "Consider changing the spline step.")); } G_free(lcat); } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ /* Dropping auxiliar table */ if (npoints > 0) { G_debug(1, _("Dropping <%s>"), table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliar table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_close(&Out); Vect_close(&Terrain); G_done_msg(" "); exit(EXIT_SUCCESS); } /*! END MAIN */
/*--------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variable declarations */ int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row, subregion_row, subregion_col; int subregion = 0, nsubregions = 0; int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross; /* booleans */ double stepN, stepE, lambda, mean; double N_extension, E_extension, edgeE, edgeN; const char *mapset, *drv, *db, *vector, *map; char table_name[GNAME_MAX], title[64]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int dim_vect, nparameters, BW; int *lineVect; /* Vector restoring primitive's ID */ double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect; /* Interpolation and least-square matrix */ SEGMENT out_seg, mask_seg; const char *out_file, *mask_file; int out_fd, mask_fd; double seg_size; int seg_mb, segments_in_memory; int have_mask; /* Structs declarations */ int raster; struct Map_info In, In_ext, Out; struct History history; struct GModule *module; struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt, *memory_opt, *solver, *error, *iter; struct Flag *cross_corr_flag, *spline_step_flag; struct Reg_dimens dims; struct Cell_head elaboration_reg, original_reg; struct bound_box general_box, overlap_box, original_box; struct Point *observ; struct line_cats *Cats; dbCatValArray cvarr; int with_z; int nrec, ctype = 0; struct field_info *Fi; dbDriver *driver, *driver_cats; /*----------------------------------------------------------------*/ /* Options declarations */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("LIDAR")); module->description = _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization."); cross_corr_flag = G_define_flag(); cross_corr_flag->key = 'c'; cross_corr_flag->description = _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method"); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->label = _("Name of input vector point map"); dfield_opt = G_define_standard_option(G_OPT_V_FIELD); dfield_opt->guisection = _("Settings"); col_opt = G_define_standard_option(G_OPT_DB_COLUMN); col_opt->required = NO; col_opt->label = _("Name of the attribute column with values to be used for approximation"); col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used."); col_opt->guisection = _("Settings"); in_ext_opt = G_define_standard_option(G_OPT_V_INPUT); in_ext_opt->key = "sparse_input"; in_ext_opt->required = NO; in_ext_opt->label = _("Name of input vector map with sparse points"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->required = NO; out_opt->guisection = _("Outputs"); out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_map_opt->key = "raster_output"; out_map_opt->required = NO; out_map_opt->guisection = _("Outputs"); mask_opt = G_define_standard_option(G_OPT_R_INPUT); mask_opt->key = "mask"; mask_opt->label = _("Raster map to use for masking (applies to raster output only)"); mask_opt->description = _("Only cells that are not NULL and not zero are interpolated"); mask_opt->required = NO; stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "4"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "4"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); type_opt = G_define_option(); type_opt->key = "method"; type_opt->description = _("Spline interpolation algorithm"); type_opt->type = TYPE_STRING; type_opt->options = "bilinear,bicubic"; type_opt->answer = "bilinear"; type_opt->guisection = _("Settings"); G_asprintf((char **) &(type_opt->descriptions), "bilinear;%s;bicubic;%s", _("Bilinear interpolation"), _("Bicubic interpolation")); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda_i"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)"); lambda_f_opt->answer = "0.01"; lambda_f_opt->guisection = _("Settings"); solver = N_define_standard_option(N_OPT_SOLVER_SYMM); solver->options = "cholesky,cg"; solver->answer = "cholesky"; iter = N_define_standard_option(N_OPT_MAX_ITERATIONS); error = N_define_standard_option(N_OPT_ITERATION_ERROR); memory_opt = G_define_option(); memory_opt->key = "memory"; memory_opt->type = TYPE_INTEGER; memory_opt->required = NO; memory_opt->answer = "300"; memory_opt->label = _("Maximum memory to be used (in MB)"); memory_opt->description = _("Cache size for raster rows"); /*----------------------------------------------------------------*/ /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); vector = out_opt->answer; map = out_map_opt->answer; if (vector && map) G_fatal_error(_("Choose either vector or raster output, not both")); if (!vector && !map && !cross_corr_flag->answer) G_fatal_error(_("No raster or vector or cross-validation output")); if (!strcmp(type_opt->answer, "linear")) bilin = P_BILINEAR; else bilin = P_BICUBIC; stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); flag_auxiliar = FALSE; drv = db_get_default_driver_name(); if (!drv) { if (db_set_default_connection() != DB_OK) G_fatal_error(_("Unable to set default DB connection")); drv = db_get_default_driver_name(); } db = db_get_default_database_name(); if (!db) G_fatal_error(_("No default DB defined")); /* Set auxiliary table's name */ if (vector) { if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); } /* Something went wrong in a previous v.surf.bspline execution */ if (db_table_exists(drv, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(drv, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), drv); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliary table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Open input vector */ if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); bspline_field = 0; /* assume 3D input */ bspline_column = col_opt->answer; with_z = !bspline_column && Vect_is_3d(&In); if (Vect_is_3d(&In)) { if (!with_z) G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation")); else G_verbose_message(_("Input is 3D: using z-coordinates for approximation")); } else { /* 2D */ if (!bspline_column) G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key); } if (!with_z) { bspline_field = Vect_get_field_number(&In, dfield_opt->answer); } /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { fprintf(stdout, _("Estimated point density: %.4g"), dens); fprintf(stdout, _("Estimated mean distance between points: %.4g"), dist); } else { fprintf(stdout, _("No points in current region")); } Vect_close(&In); exit(EXIT_SUCCESS); } /*----------------------------------------------------------------*/ /* Cross-correlation begins */ if (cross_corr_flag->answer) { G_debug(1, "CrossCorrelation()"); cross = cross_correlation(&In, stepE, stepN); if (cross != TRUE) G_fatal_error(_("Cross validation didn't finish correctly")); else { G_debug(1, "Cross validation finished correctly"); Vect_close(&In); G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN); exit(EXIT_SUCCESS); } } /* Open input ext vector */ ext = FALSE; if (in_ext_opt->answer) { ext = TRUE; G_message(_("Vector map <%s> of sparse points will be interpolated"), in_ext_opt->answer); if ((mapset = G_find_vector2(in_ext_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_ext_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In_ext, in_ext_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); } /* Open output map */ /* vector output */ if (vector && !map) { if (strcmp(drv, "dbf") == 0) G_fatal_error(_("Sorry, the <%s> driver is not compatible with " "the vector output of this module. " "Try with raster output or another driver."), drv); Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); grid = FALSE; if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); /* Copy vector Head File */ if (ext == FALSE) { Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); } else { Vect_copy_head_data(&In_ext, &Out); Vect_hist_copy(&In_ext, &Out); } Vect_hist_command(&Out); G_verbose_message(_("Points in input vector map <%s> will be interpolated"), vector); } /* read z values from attribute table */ if (bspline_field > 0) { G_message(_("Reading values from attribute table...")); db_CatValArray_init(&cvarr); Fi = Vect_get_field(&In, bspline_field); if (Fi == NULL) G_fatal_error(_("Cannot read layer info")); driver_cats = db_start_driver_open_database(Fi->driver, Fi->database); /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */ if (driver_cats == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_set_error_handler_driver(driver_cats); nrec = db_select_CatValArray(driver_cats, Fi->table, Fi->key, col_opt->answer, NULL, &cvarr); G_debug(3, "nrec = %d", nrec); ctype = cvarr.ctype; if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (nrec < 0) G_fatal_error(_("Unable to select data from table")); G_verbose_message(_("%d records selected from table"), nrec); db_close_database_shutdown_driver(driver_cats); } /*----------------------------------------------------------------*/ /* Interpolation begins */ G_debug(1, "Interpolation()"); /* Open driver and database */ driver = db_start_driver_open_database(drv, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. " "Run db.connect."), drv); db_set_error_handler_driver(driver); /* Create auxiliary table */ if (vector) { if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) { P_Drop_Aux_Table(driver, table_name); G_fatal_error(_("Interpolation: Creating table: " "It was impossible to create table <%s>."), table_name); } /* db_create_index2(driver, table_name, "ID"); */ /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(drv, db); } /* raster output */ raster = -1; Rast_set_fp_type(DCELL_TYPE); if (!vector && map) { grid = TRUE; raster = Rast_open_fp_new(out_map_opt->answer); G_verbose_message(_("Cells for raster map <%s> will be interpolated"), map); } /* Setting regions and boxes */ G_debug(1, "Interpolation: Setting regions and boxes"); G_get_window(&original_reg); G_get_window(&elaboration_reg); Vect_region_box(&original_reg, &original_box); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* Alloc raster matrix */ have_mask = 0; out_file = mask_file = NULL; out_fd = mask_fd = -1; if (grid == TRUE) { int row; DCELL *drastbuf; seg_mb = atoi(memory_opt->answer); if (seg_mb < 3) G_fatal_error(_("Memory in MB must be >= 3")); if (mask_opt->answer) seg_size = sizeof(double) + sizeof(char); else seg_size = sizeof(double); seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20); segments_in_memory = seg_mb / seg_size + 0.5; G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE); out_file = G_tempfile(); out_fd = creat(out_file, 0666); if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1) G_fatal_error(_("Can not create temporary file")); close(out_fd); out_fd = open(out_file, 2); if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1) G_fatal_error(_("Can not initialize temporary file")); /* initialize output */ G_message(_("Initializing output...")); drastbuf = Rast_allocate_buf(DCELL_TYPE); Rast_set_d_null_value(drastbuf, ncols); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Segment_put_row(&out_seg, drastbuf, row); } G_percent(row, nrows, 2); if (mask_opt->answer) { int row, col, maskfd; DCELL dval, *drastbuf; char mask_val; G_message(_("Load masking map")); mask_file = G_tempfile(); mask_fd = creat(mask_file, 0666); if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1) G_fatal_error(_("Can not create temporary file")); close(mask_fd); mask_fd = open(mask_file, 2); if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1) G_fatal_error(_("Can not initialize temporary file")); maskfd = Rast_open_old(mask_opt->answer, ""); drastbuf = Rast_allocate_buf(DCELL_TYPE); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_d_row(maskfd, drastbuf, row); for (col = 0; col < ncols; col++) { dval = drastbuf[col]; if (Rast_is_d_null_value(&dval) || dval == 0) mask_val = 0; else mask_val = 1; Segment_put(&mask_seg, &mask_val, row, col); } } G_percent(row, nrows, 2); G_free(drastbuf); Rast_close(maskfd); have_mask = 1; } } /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); /* Set dim struct to zero */ nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(bilin, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj); G_verbose_message(_("Adjusted NS splines %d"), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; /* Creating line and categories structs */ Cats = Vect_new_cats_struct(); Vect_cat_set(Cats, 1, 0); subregion_row = 0; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each subregion row */ subregion_row++; P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; G_debug(1, "Interpolation: nsply = %d", nsply); /* if (nsply > NSPLY_MAX) nsply = NSPLY_MAX; */ elaboration_reg.east = original_reg.west; last_column = FALSE; subregion_col = 0; /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */ /* I'm not sure about pthreads, but you can tell OpenMP to start all at the same time and it will keep num_workers supplied with the next job as free cpus become available */ while (last_column == FALSE) { /* For each subregion column */ int npoints = 0; /* needed for sparse points interpolation */ int npoints_ext, *lineVect_ext = NULL; double **obsVect_ext; /*, mean_ext = .0; */ struct Point *observ_ext; subregion_col++; subregion++; if (nsubregions > 1) G_message(_("Processing subregion %d of %d..."), subregion, nsubregions); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; G_debug(1, "Interpolation: nsplx = %d", nsplx); /* if (nsplx > NSPLX_MAX) nsplx = NSPLX_MAX; */ G_debug(1, "Interpolation: (%d,%d): subregion bounds", subregion_row, subregion_col); G_debug(1, "Interpolation: \t\tNORTH:%.2f\t", elaboration_reg.north); G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f", elaboration_reg.west, elaboration_reg.east); G_debug(1, "Interpolation: \t\tSOUTH:%.2f", elaboration_reg.south); #ifdef DEBUG_SUBREGIONS fprintf(stdout, "B 5\n"); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north); fprintf(stdout, "C 1 1\n"); fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2, (elaboration_reg.south + elaboration_reg.north) / 2); fprintf(stdout, " 1 %d\n", subregion); #endif /* reading points in interpolation region */ dim_vect = nsplx * nsply; observ_ext = NULL; if (grid == FALSE && ext == TRUE) { observ_ext = P_Read_Vector_Region_Map(&In_ext, &elaboration_reg, &npoints_ext, dim_vect, 1); } else npoints_ext = 1; if (grid == TRUE && have_mask) { /* any unmasked cells in general region ? */ mean = 0; observ_ext = P_Read_Raster_Region_masked(&mask_seg, &original_reg, original_box, general_box, &npoints_ext, dim_vect, mean); } observ = NULL; if (npoints_ext > 0) { observ = P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints, dim_vect, bspline_field); } else npoints = 1; G_debug(1, "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d", subregion_row, subregion_col, npoints); if (npoints > 0) G_verbose_message(_("%d points found in this subregion"), npoints); /* only interpolate if there are any points in current subregion */ if (npoints > 0 && npoints_ext > 0) { int i; nparameters = nsplx * nsply; BW = P_get_BandWidth(bilin, nsply); /* Least Squares system */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Parameters vector */ obsVect = G_alloc_matrix(npoints, 3); /* Observation vector */ Q = G_alloc_vector(npoints); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints); /* */ for (i = 0; i < npoints; i++) { /* Setting obsVect vector & Q matrix */ double dval; Q[i] = 1; /* Q=I */ lineVect[i] = observ[i].lineID; obsVect[i][0] = observ[i].coordX; obsVect[i][1] = observ[i].coordY; /* read z coordinates from attribute table */ if (bspline_field > 0) { int cat, ival, ret; cat = observ[i].cat; if (cat < 0) continue; if (ctype == DB_C_TYPE_INT) { ret = db_CatValArray_get_value_int(&cvarr, cat, &ival); obsVect[i][2] = ival; observ[i].coordZ = ival; } else { /* DB_C_TYPE_DOUBLE */ ret = db_CatValArray_get_value_double(&cvarr, cat, &dval); obsVect[i][2] = dval; observ[i].coordZ = dval; } if (ret != DB_OK) { G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"), subregion_row, subregion_col, cat); continue; } } /* use z coordinates of 3D vector */ else { obsVect[i][2] = observ[i].coordZ; } } /* Mean calculation for every point */ mean = P_Mean_Calc(&elaboration_reg, observ, npoints); G_debug(1, "Interpolation: (%d,%d): mean=%lf", subregion_row, subregion_col, mean); G_free(observ); for (i = 0; i < npoints; i++) obsVect[i][2] -= mean; /* Bilinear interpolation */ if (bilin) { G_debug(1, "Interpolation: (%d,%d): Bilinear interpolation...", subregion_row, subregion_col); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); } /* Bicubic interpolation */ else { G_debug(1, "Interpolation: (%d,%d): Bicubic interpolation...", subregion_row, subregion_col); normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); } if(G_strncasecmp(solver->answer, "cg", 2) == 0) G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer)); else G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); if (grid == TRUE) { /* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */ G_debug(1, "Interpolation: (%d,%d): Regular_Points...", subregion_row, subregion_col); if (!have_mask) { P_Regular_Points(&elaboration_reg, &original_reg, general_box, overlap_box, &out_seg, parVect, stepN, stepE, dims.overlap, mean, nsplx, nsply, nrows, ncols, bilin); } else { P_Sparse_Raster_Points(&out_seg, &elaboration_reg, &original_reg, general_box, overlap_box, observ_ext, parVect, stepE, stepN, dims.overlap, nsplx, nsply, npoints_ext, bilin, mean); } } else { /* OBSERVATION POINTS INTERPOLATION */ if (ext == FALSE) { G_debug(1, "Interpolation: (%d,%d): Sparse_Points...", subregion_row, subregion_col); P_Sparse_Points(&Out, &elaboration_reg, general_box, overlap_box, obsVect, parVect, lineVect, stepE, stepN, dims.overlap, nsplx, nsply, npoints, bilin, Cats, driver, mean, table_name); } else { /* FLAG_EXT == TRUE */ /* done that earlier */ /* int npoints_ext, *lineVect_ext = NULL; double **obsVect_ext; struct Point *observ_ext; observ_ext = P_Read_Vector_Region_Map(&In_ext, &elaboration_reg, &npoints_ext, dim_vect, 1); */ obsVect_ext = G_alloc_matrix(npoints_ext, 3); /* Observation vector_ext */ lineVect_ext = G_alloc_ivector(npoints_ext); for (i = 0; i < npoints_ext; i++) { /* Setting obsVect_ext vector & Q matrix */ obsVect_ext[i][0] = observ_ext[i].coordX; obsVect_ext[i][1] = observ_ext[i].coordY; obsVect_ext[i][2] = observ_ext[i].coordZ - mean; lineVect_ext[i] = observ_ext[i].lineID; } G_free(observ_ext); G_debug(1, "Interpolation: (%d,%d): Sparse_Points...", subregion_row, subregion_col); P_Sparse_Points(&Out, &elaboration_reg, general_box, overlap_box, obsVect_ext, parVect, lineVect_ext, stepE, stepN, dims.overlap, nsplx, nsply, npoints_ext, bilin, Cats, driver, mean, table_name); G_free_matrix(obsVect_ext); G_free_ivector(lineVect_ext); } /* END FLAG_EXT == TRUE */ } /* END GRID == FALSE */ G_free_vector(parVect); G_free_matrix(obsVect); G_free_ivector(lineVect); } else { if (observ) G_free(observ); if (observ_ext) G_free(observ_ext); if (npoints == 0) G_warning(_("No data within this subregion. " "Consider increasing spline step values.")); } } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ G_verbose_message(_("Writing output...")); /* Writing the output raster map */ if (grid == TRUE) { int row, col; DCELL *drastbuf, dval; if (have_mask) { Segment_release(&mask_seg); /* release memory */ close(mask_fd); unlink(mask_file); } drastbuf = Rast_allocate_buf(DCELL_TYPE); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col < ncols; col++) { Segment_get(&out_seg, &dval, row, col); drastbuf[col] = dval; } Rast_put_d_row(raster, drastbuf); } Rast_close(raster); Segment_release(&out_seg); /* release memory */ close(out_fd); unlink(out_file); /* set map title */ sprintf(title, "%s interpolation with Tykhonov regularization", type_opt->answer); Rast_put_cell_title(out_map_opt->answer, title); /* write map history */ Rast_short_history(out_map_opt->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(out_map_opt->answer, &history); } /* Writing to the output vector map the points from the overlapping zones */ else if (flag_auxiliar == TRUE) { if (ext == FALSE) P_Aux_to_Vector(&In, &Out, driver, table_name); else P_Aux_to_Vector(&In_ext, &Out, driver, table_name); /* Drop auxiliary table */ G_debug(1, "%s: Dropping <%s>", argv[0], table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliary table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); if (ext != FALSE) Vect_close(&In_ext); if (vector) Vect_close(&Out); G_done_msg(" "); exit(EXIT_SUCCESS); } /*END MAIN */
/*! * \brief Check input and output file names. * * Check: * 1) output is legal map name, * 2) if can find input map, and * 3) if input was found in current mapset, check if input != output. * * \param input input map name * \param output output map name * \param error error type: G_FATAL_EXIT, G_FATAL_PRINT, G_FATAL_RETURN * * \return 0 OK * \return 1 error */ int G_check_input_output_name(const char *input, const char *output, int error) { const char *mapset; if (output == NULL) return 0; /* don't die on undefined parameters */ if (G_legal_filename(output) == -1) { if (error == G_FATAL_EXIT) { G_fatal_error(_("Output raster map name <%s> is not valid map name"), output); } else if (error == G_FATAL_PRINT) { G_warning(_("Output raster map name <%s> is not valid map name"), output); return 1; } else { /* G_FATAL_RETURN */ return 1; } } mapset = G_find_raster2(input, ""); if (mapset == NULL) { if (error == G_FATAL_EXIT) { G_fatal_error(_("Raster map <%s> not found"), input); } else if (error == G_FATAL_PRINT) { G_warning(_("Raster map <%s> not found"), input); return 1; } else { /* G_FATAL_RETURN */ return 1; } } if (strcmp(mapset, G_mapset()) == 0) { char nm[1000], ms[1000]; const char *in; if (G_name_is_fully_qualified(input, nm, ms)) { in = nm; } else { in = input; } if (strcmp(in, output) == 0) { if (error == G_FATAL_EXIT) { G_fatal_error(_("Output raster map <%s> is used as input"), output); } else if (error == G_FATAL_PRINT) { G_warning(_("Output raster map <%s> is used as input"), output); return 1; } else { /* G_FATAL_RETURN */ return 1; } } } return 0; }
/*--------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variables declarations */ int nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; double N_extension, E_extension, edgeE, edgeN; int dim_vect, nparameters, BW, npoints; double mean, lambda; const char *dvr, *db, *mapset; char table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int last_row, last_column, flag_auxiliar = FALSE; int filter_mode; int *lineVect; double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect; /* Interpolation and least-square matrix */ /* Structs declarations */ struct Map_info In, Out, Outlier, Qgis; struct Option *in_opt, *out_opt, *outlier_opt, *qgis_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *Thres_O_opt, *filter_opt; struct Flag *spline_step_flag; struct GModule *module; struct Reg_dimens dims; struct Cell_head elaboration_reg, original_reg; struct bound_box general_box, overlap_box; struct Point *observ; dbDriver *driver; /*----------------------------------------------------------------*/ /* Options declaration */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("statistics")); G_add_keyword(_("extract")); G_add_keyword(_("select")); G_add_keyword(_("filter")); module->description = _("Removes outliers from vector point data."); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); outlier_opt = G_define_option(); outlier_opt->key = "outlier"; outlier_opt->type = TYPE_STRING; outlier_opt->key_desc = "name"; outlier_opt->required = YES; outlier_opt->gisprompt = "new,vector,vector"; outlier_opt->description = _("Name of output outlier vector map"); qgis_opt = G_define_option(); qgis_opt->key = "qgis"; qgis_opt->type = TYPE_STRING; qgis_opt->key_desc = "name"; qgis_opt->required = NO; qgis_opt->gisprompt = "new,vector,vector"; qgis_opt->description = _("Name of vector map for visualization in QGIS"); stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "10"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "10"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Tykhonov regularization weight"); lambda_f_opt->answer = "0.1"; lambda_f_opt->guisection = _("Settings"); Thres_O_opt = G_define_option(); Thres_O_opt->key = "threshold"; Thres_O_opt->type = TYPE_DOUBLE; Thres_O_opt->required = NO; Thres_O_opt->description = _("Threshold for the outliers"); Thres_O_opt->answer = "50"; filter_opt = G_define_option(); filter_opt->key = "filter"; filter_opt->type = TYPE_STRING; filter_opt->required = NO; filter_opt->description = _("Filtering option"); filter_opt->options = "both,positive,negative"; filter_opt->answer = "both"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of database")); if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of driver")); stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); Thres_Outlier = atof(Thres_O_opt->answer); filter_mode = 0; if (strcmp(filter_opt->answer, "positive") == 0) filter_mode = 1; else if (strcmp(filter_opt->answer, "negative") == 0) filter_mode = -1; P_set_outlier_fn(filter_mode); flag_auxiliar = FALSE; /* Checking vector names */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) { G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); } /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); /* Something went wrong in a previous v.outlier execution */ if (db_table_exists(dvr, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Open input vector */ Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); /* Input vector must be 3D */ if (!Vect_is_3d(&In)) G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer); /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { G_message("Estimated point density: %.4g", dens); G_message("Estimated mean distance between points: %.4g", dist); } else G_warning(_("No points in current region!")); Vect_close(&In); exit(EXIT_SUCCESS); } /* Open output vector */ if (qgis_opt->answer) if (0 > Vect_open_new(&Qgis, qgis_opt->answer, WITHOUT_Z)) G_fatal_error(_("Unable to create vector map <%s>"), qgis_opt->answer); if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&Qgis); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } if (0 > Vect_open_new(&Outlier, outlier_opt->answer, WITH_Z)) { Vect_close(&Out); Vect_close(&Qgis); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Outlier); Vect_hist_copy(&In, &Outlier); Vect_hist_command(&Outlier); if (qgis_opt->answer) { Vect_copy_head_data(&In, &Qgis); Vect_hist_copy(&In, &Qgis); Vect_hist_command(&Qgis); } /* Open driver and database */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); /* Create auxiliar table */ if ((flag_auxiliar = P_Create_Aux2_Table(driver, table_name)) == FALSE) G_fatal_error(_("It was impossible to create <%s> table."), table_name); db_create_index2(driver, table_name, "ID"); /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(dvr, db); /* Setting regions and boxes */ G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); /* Set dim struct to zero */ nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(P_BILINEAR, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj); G_verbose_message(_("Adjusted NS splines %d"), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; /* if (nsply > NSPLY_MAX) nsply = NSPLY_MAX; */ G_debug(1, "nsply = %d", nsply); elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each column */ subregion++; if (nsubregions > 1) G_message(_("Processing subregion %d of %d..."), subregion, nsubregions); else /* v.outlier -e will report mean point distance: */ G_warning(_("No subregions found! Check values for 'ew_step' and 'ns_step' parameters")); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; /* if (nsplx > NSPLX_MAX) nsplx = NSPLX_MAX; */ G_debug(1, "nsplx = %d", nsplx); /*Setting the active region */ dim_vect = nsplx * nsply; observ = P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints, dim_vect, 1); if (npoints > 0) { /* If there is any point falling into elaboration_reg... */ int i; nparameters = nsplx * nsply; /* Mean calculation */ mean = P_Mean_Calc(&elaboration_reg, observ, npoints); /* Least Squares system */ G_debug(1, "Allocation memory for bilinear interpolation"); BW = P_get_BandWidth(P_BILINEAR, nsply); /* Bilinear interpolation */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Bicubic parameters vector */ obsVect = G_alloc_matrix(npoints, 3); /* Observation vector */ Q = G_alloc_vector(npoints); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints); /* Setting obsVect vector & Q matrix */ for (i = 0; i < npoints; i++) { obsVect[i][0] = observ[i].coordX; obsVect[i][1] = observ[i].coordY; obsVect[i][2] = observ[i].coordZ - mean; lineVect[i] = observ[i].lineID; Q[i] = 1; /* Q=I */ } G_free(observ); G_verbose_message(_("Bilinear interpolation")); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); G_verbose_message(_("Outlier detection")); if (qgis_opt->answer) P_Outlier(&Out, &Outlier, &Qgis, elaboration_reg, general_box, overlap_box, obsVect, parVect, mean, dims.overlap, lineVect, npoints, driver, table_name); else P_Outlier(&Out, &Outlier, NULL, elaboration_reg, general_box, overlap_box, obsVect, parVect, mean, dims.overlap, lineVect, npoints, driver, table_name); G_free_vector(parVect); G_free_matrix(obsVect); G_free_ivector(lineVect); } /*! END IF; npoints > 0 */ else { G_free(observ); G_warning(_("No data within this subregion. " "Consider increasing spline step values.")); } } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ /* Drop auxiliar table */ if (npoints > 0) { G_debug(1, "%s: Dropping <%s>", argv[0], table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliary table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_close(&Out); Vect_close(&Outlier); if (qgis_opt->answer) { Vect_build(&Qgis); Vect_close(&Qgis); } G_done_msg(" "); exit(EXIT_SUCCESS); } /*END MAIN */
int main(int argc, char *argv[]) { /* Variables' declarations */ int nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row, subregion = 0, nsubregions = 0; double N_extension, E_extension, edgeE, edgeN; int dim_vect, nparameters, BW, npoints; double lambda_B, lambda_F, grad_H, grad_L, alpha, mean; const char *dvr, *db, *mapset; char table_interpolation[GNAME_MAX], table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int last_row, last_column, flag_auxiliar = FALSE; int *lineVect; double *TN, *Q, *parVect_bilin, *parVect_bicub; /* Interpolating and least-square vectors */ double **N, **obsVect; /* Interpolation and least-square matrix */ /* Structs' declarations */ struct Map_info In, Out; struct Option *in_opt, *out_opt, *stepE_opt, *stepN_opt, *lambdaF_opt, *lambdaB_opt, *gradH_opt, *gradL_opt, *alfa_opt; struct Flag *spline_step_flag; struct GModule *module; struct Cell_head elaboration_reg, original_reg; struct Reg_dimens dims; struct bound_box general_box, overlap_box; struct Point *observ; dbDriver *driver; /*------------------------------------------------------------------------------------------*/ /* Options' declaration */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("LIDAR")); G_add_keyword(_("edges")); module->description = _("Detects the object's edges from a LIDAR data set."); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); stepE_opt = G_define_option(); stepE_opt->key = "see"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "4"; stepE_opt->description = _("Interpolation spline step value in east direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "sen"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "4"; stepN_opt->description = _("Interpolation spline step value in north direction"); stepN_opt->guisection = _("Settings"); lambdaB_opt = G_define_option(); lambdaB_opt->key = "lambda_g"; lambdaB_opt->type = TYPE_DOUBLE; lambdaB_opt->required = NO; lambdaB_opt->description = _("Regularization weight in gradient evaluation"); lambdaB_opt->answer = "0.01"; lambdaB_opt->guisection = _("Settings"); gradH_opt = G_define_option(); gradH_opt->key = "tgh"; gradH_opt->type = TYPE_DOUBLE; gradH_opt->required = NO; gradH_opt->description = _("High gradient threshold for edge classification"); gradH_opt->answer = "6"; gradH_opt->guisection = _("Settings"); gradL_opt = G_define_option(); gradL_opt->key = "tgl"; gradL_opt->type = TYPE_DOUBLE; gradL_opt->required = NO; gradL_opt->description = _("Low gradient threshold for edge classification"); gradL_opt->answer = "3"; gradL_opt->guisection = _("Settings"); alfa_opt = G_define_option(); alfa_opt->key = "theta_g"; alfa_opt->type = TYPE_DOUBLE; alfa_opt->required = NO; alfa_opt->description = _("Angle range for same direction detection"); alfa_opt->answer = "0.26"; alfa_opt->guisection = _("Settings"); lambdaF_opt = G_define_option(); lambdaF_opt->key = "lambda_r"; lambdaF_opt->type = TYPE_DOUBLE; lambdaF_opt->required = NO; lambdaF_opt->description = _("Regularization weight in residual evaluation"); lambdaF_opt->answer = "2"; lambdaF_opt->guisection = _("Settings"); /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); line_out_counter = 1; stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda_F = atof(lambdaF_opt->answer); lambda_B = atof(lambdaB_opt->answer); grad_H = atof(gradH_opt->answer); grad_L = atof(gradL_opt->answer); alpha = atof(alfa_opt->answer); grad_L = grad_L * grad_L; grad_H = grad_H * grad_H; if (!(db = G__getenv2("DB_DATABASE", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of database")); if (!(dvr = G__getenv2("DB_DRIVER", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of driver")); /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); sprintf(table_interpolation, "%s_edge_Interpolation", xname); } else { sprintf(table_name, "%s_aux", out_opt->answer); sprintf(table_interpolation, "%s_edge_Interpolation", out_opt->answer); } /* Something went wrong in a previous v.lidar.edgedetection execution */ if (db_table_exists(dvr, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Something went wrong in a previous v.lidar.edgedetection execution */ if (db_table_exists(dvr, db, table_interpolation)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); if (P_Drop_Aux_Table(driver, table_interpolation) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Checking vector names */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) { G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); } Vect_set_open_level(1); /* Open input vector */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); /* Input vector must be 3D */ if (!Vect_is_3d(&In)) G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer); /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { G_message("Estimated point density: %.4g", dens); G_message("Estimated mean distance between points: %.4g", dist); } else G_warning(_("No points in current region!")); Vect_close(&In); exit(EXIT_SUCCESS); } /* Open output vector */ if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); /* Create auxiliar and interpolation table */ if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) G_fatal_error(_("It was impossible to create <%s>."), table_name); if (P_Create_Aux2_Table(driver, table_interpolation) == FALSE) G_fatal_error(_("It was impossible to create <%s> interpolation table in database."), out_opt->answer); db_create_index2(driver, table_name, "ID"); db_create_index2(driver, table_interpolation, "ID"); /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(dvr, db); /* Setting regions and boxes */ G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(P_BICUBIC, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(_("adjusted EW splines %d"), nsplx_adj); G_verbose_message(_("adjusted NS splines %d"), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; /* if (nsply > NSPLY_MAX) { nsply = NSPLY_MAX; } */ G_debug(1, "nsply = %d", nsply); elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each column */ subregion++; if (nsubregions > 1) G_message(_("subregion %d of %d"), subregion, nsubregions); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; /* if (nsplx > NSPLX_MAX) { nsplx = NSPLX_MAX; } */ G_debug(1, "nsplx = %d", nsplx); /*Setting the active region */ dim_vect = nsplx * nsply; G_debug(1, "read vector region map"); observ = P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints, dim_vect, 1); if (npoints > 0) { /* If there is any point falling into elaboration_reg... */ int i, tn; nparameters = nsplx * nsply; /* Mean's calculation */ mean = P_Mean_Calc(&elaboration_reg, observ, npoints); /* Least Squares system */ G_debug(1, _("Allocating memory for bilinear interpolation")); BW = P_get_BandWidth(P_BILINEAR, nsply); /* Bilinear interpolation */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect_bilin = G_alloc_vector(nparameters); /* Bilinear parameters vector */ obsVect = G_alloc_matrix(npoints + 1, 3); /* Observation vector */ Q = G_alloc_vector(npoints + 1); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints + 1); /* Setting obsVect vector & Q matrix */ for (i = 0; i < npoints; i++) { obsVect[i][0] = observ[i].coordX; obsVect[i][1] = observ[i].coordY; obsVect[i][2] = observ[i].coordZ - mean; lineVect[i] = observ[i].lineID; Q[i] = 1; /* Q=I */ } G_free(observ); G_verbose_message(_("Bilinear interpolation")); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda_B, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect_bilin, TN, nparameters, BW); G_free_matrix(N); for (tn = 0; tn < nparameters; tn++) TN[tn] = 0; G_debug(1, _("Allocating memory for bicubic interpolation")); BW = P_get_BandWidth(P_BICUBIC, nsply); N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ parVect_bicub = G_alloc_vector(nparameters); /* Bicubic parameters vector */ G_verbose_message(_("Bicubic interpolation")); normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectLapl(N, lambda_F, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect_bicub, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); G_verbose_message(_("Point classification")); classification(&Out, elaboration_reg, general_box, overlap_box, obsVect, parVect_bilin, parVect_bicub, mean, alpha, grad_H, grad_L, dims.overlap, lineVect, npoints, driver, table_interpolation, table_name); G_free_vector(parVect_bilin); G_free_vector(parVect_bicub); G_free_matrix(obsVect); G_free_ivector(lineVect); } /* IF */ else { G_free(observ); G_warning(_("No data within this subregion. " "Consider changing the spline step.")); } } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ /* Dropping auxiliar table */ if (npoints > 0) { G_debug(1, _("Dropping <%s>"), table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_warning(_("Auxiliar table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_map_add_dblink(&Out, F_INTERPOLATION, NULL, table_interpolation, "id", db, dvr); Vect_close(&Out); G_done_msg(" "); exit(EXIT_SUCCESS); } /*!END MAIN */
int main(int argc, char *argv[]) { char group[INAME_LEN], extension[INAME_LEN]; int order; /* ADDED WITH CRS MODIFICATIONS */ char *ipolname; /* name of interpolation method */ int method; int n, i, m, k = 0; int got_file = 0, target_overwrite = 0; char *overstr; struct Cell_head cellhd; struct Option *grp, /* imagery group */ *val, /* transformation order */ *ifile, /* input files */ *ext, /* extension */ *tres, /* target resolution */ *mem, /* amount of memory for cache */ *interpol; /* interpolation method: nearest neighbor, bilinear, cubic */ struct Flag *c, *a; struct GModule *module; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("rectify")); module->description = _("Rectifies an image by computing a coordinate " "transformation for each pixel in the image based on the " "control points."); grp = G_define_standard_option(G_OPT_I_GROUP); ifile = G_define_standard_option(G_OPT_R_INPUTS); ifile->required = NO; ext = G_define_option(); ext->key = "extension"; ext->type = TYPE_STRING; ext->required = YES; ext->multiple = NO; ext->description = _("Output raster map(s) suffix"); val = G_define_option(); val->key = "order"; val->type = TYPE_INTEGER; val->required = YES; val->description = _("Rectification polynom order (1-3)"); tres = G_define_option(); tres->key = "res"; tres->type = TYPE_DOUBLE; tres->required = NO; tres->description = _("Target resolution (ignored if -c flag used)"); mem = G_define_option(); mem->key = "memory"; mem->type = TYPE_DOUBLE; mem->key_desc = "memory in MB"; mem->required = NO; mem->answer = "300"; mem->description = _("Amount of memory to use in MB"); ipolname = make_ipol_list(); interpol = G_define_option(); interpol->key = "method"; interpol->type = TYPE_STRING; interpol->required = NO; interpol->answer = "nearest"; interpol->options = ipolname; interpol->description = _("Interpolation method to use"); c = G_define_flag(); c->key = 'c'; c->description = _("Use current region settings in target location (def.=calculate smallest area)"); a = G_define_flag(); a->key = 'a'; a->description = _("Rectify all raster maps in group"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* get the method */ for (method = 0; (ipolname = menu[method].name); method++) if (strcmp(ipolname, interpol->answer) == 0) break; if (!ipolname) G_fatal_error(_("<%s=%s> unknown %s"), interpol->key, interpol->answer, interpol->key); interpolate = menu[method].method; G_strip(grp->answer); strcpy(group, grp->answer); strcpy(extension, ext->answer); order = atoi(val->answer); seg_mb = NULL; if (mem->answer) { if (atoi(mem->answer) > 0) seg_mb = mem->answer; } if (!ifile->answers) a->answer = 1; /* force all */ /* Find out how many files on command line */ if (!a->answer) { for (m = 0; ifile->answers[m]; m++) { k = m; } k++; } if (order < 1 || order > MAXORDER) G_fatal_error(_("Invalid order (%d); please enter 1 to %d"), order, MAXORDER); /* determine the number of files in this group */ if (I_get_group_ref(group, &ref) <= 0) { G_warning(_("Location: %s"), G_location()); G_warning(_("Mapset: %s"), G_mapset()); G_fatal_error(_("Group <%s> does not exist"), grp->answer); } if (ref.nfiles <= 0) { G_important_message(_("Group <%s> contains no raster maps; run i.group"), grp->answer); exit(EXIT_SUCCESS); } ref_list = (int *)G_malloc(ref.nfiles * sizeof(int)); if (a->answer) { for (n = 0; n < ref.nfiles; n++) { ref_list[n] = 1; } } else { char xname[GNAME_MAX], xmapset[GMAPSET_MAX], *name, *mapset; for (n = 0; n < ref.nfiles; n++) ref_list[n] = 0; for (m = 0; m < k; m++) { got_file = 0; if (G_name_is_fully_qualified(ifile->answers[m], xname, xmapset)) { name = xname; mapset = xmapset; } else { name = ifile->answers[m]; mapset = NULL; } got_file = 0; for (n = 0; n < ref.nfiles; n++) { if (mapset) { if (strcmp(name, ref.file[n].name) == 0 && strcmp(mapset, ref.file[n].mapset) == 0) { got_file = 1; ref_list[n] = 1; break; } } else { if (strcmp(name, ref.file[n].name) == 0) { got_file = 1; ref_list[n] = 1; break; } } } if (got_file == 0) err_exit(ifile->answers[m], group); } } /* read the control points for the group */ get_control_points(group, order); /* get the target */ get_target(group); /* Check the GRASS_OVERWRITE environment variable */ if ((overstr = getenv("GRASS_OVERWRITE"))) /* OK ? */ target_overwrite = atoi(overstr); if (!target_overwrite) { /* check if output exists in target location/mapset */ char result[GNAME_MAX]; select_target_env(); for (i = 0; i < ref.nfiles; i++) { if (!ref_list[i]) continue; strcpy(result, ref.file[i].name); strcat(result, extension); if (G_legal_filename(result) < 0) G_fatal_error(_("Extension <%s> is illegal"), extension); if (G_find_raster2(result, G_mapset())) { G_warning(_("The following raster map already exists in")); G_warning(_("target LOCATION %s, MAPSET %s:"), G_location(), G_mapset()); G_warning("<%s>", result); G_fatal_error(_("Orthorectification cancelled.")); } } select_current_env(); } else G_debug(1, "Overwriting OK"); /* do not use current region in target location */ if (!c->answer) { double res = -1; if (tres->answer) { if (!((res = atof(tres->answer)) > 0)) G_warning(_("Target resolution must be > 0, ignored")); } /* Calculate smallest region */ if (a->answer) Rast_get_cellhd(ref.file[0].name, ref.file[0].mapset, &cellhd); else Rast_get_cellhd(ifile->answers[0], ref.file[0].mapset, &cellhd); georef_window(&cellhd, &target_window, order, res); } G_verbose_message(_("Using region: N=%f S=%f, E=%f W=%f"), target_window.north, target_window.south, target_window.east, target_window.west); exec_rectify(order, extension, interpol->answer); G_done_msg(" "); exit(EXIT_SUCCESS); }
/*! \brief Delete vector map including attribute tables \param map vector map name \return -1 error \return 0 success */ int Vect_delete(const char *map) { int i, n, ret; struct Map_info Map; struct field_info *Fi; char buf[GPATH_MAX]; DIR *dir; struct dirent *ent; const char *tmp; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; G_debug(3, "Delete vector '%s'", map); /* remove mapset from fully qualified name */ if (G_name_is_fully_qualified(map, xname, xmapset)) { map = xname; } if (map == NULL || strlen(map) == 0) { G_warning(_("Invalid vector map name <%s>"), map ? map : "null"); return -1; } sprintf(buf, "%s/%s/%s/%s/%s/%s", G_gisdbase(), G_location(), G_mapset(), GV_DIRECTORY, map, GV_DBLN_ELEMENT); G_debug(1, "dbln file: %s", buf); if (access(buf, F_OK) == 0) { /* Open input */ Vect_set_open_level(1); /* Topo not needed */ ret = Vect_open_old_head(&Map, map, G_mapset()); if (ret < 1) { G_warning(_("Unable to open header file for vector map <%s>"), map); return -1; } /* Delete all tables, NOT external (OGR) */ if (Map.format == GV_FORMAT_NATIVE) { n = Vect_get_num_dblinks(&Map); for (i = 0; i < n; i++) { Fi = Vect_get_dblink(&Map, i); if (Fi == NULL) { G_warning(_("Database connection not defined for layer %d"), Map.dblnk->field[i].number); Vect_close(&Map); return -1; } G_debug(3, "Delete drv:db:table '%s:%s:%s'", Fi->driver, Fi->database, Fi->table); ret = db_table_exists(Fi->driver, Fi->database, Fi->table); if (ret == -1) { G_warning(_("Unable to find table <%s> linked to vector map <%s>"), Fi->table, map); Vect_close(&Map); return -1; } if (ret == 1) { ret = db_delete_table(Fi->driver, Fi->database, Fi->table); if (ret == DB_FAILED) { G_warning(_("Unable to delete table <%s>"), Fi->table); Vect_close(&Map); return -1; } } else { G_warning(_("Table <%s> linked to vector map <%s> does not exist"), Fi->table, map); } } } Vect_close(&Map); } /* Delete all files from vector/name directory */ sprintf(buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map); G_debug(3, "opendir '%s'", buf); dir = opendir(buf); if (dir == NULL) { G_warning(_("Unable to open directory '%s'"), buf); return -1; } while ((ent = readdir(dir))) { G_debug(3, "file = '%s'", ent->d_name); if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..") == 0)) continue; sprintf(buf, "%s/%s/vector/%s/%s", G_location_path(), G_mapset(), map, ent->d_name); G_debug(3, "delete file '%s'", buf); ret = unlink(buf); if (ret == -1) { G_warning(_("Unable to delete file '%s'"), buf); closedir(dir); return -1; } } closedir(dir); /* NFS can create .nfsxxxxxxxx files for those deleted * -> we have to move the directory to ./tmp before it is deleted */ sprintf(buf, "%s/%s/vector/%s", G_location_path(), G_mapset(), map); tmp = G_tempfile(); G_debug(3, "rename '%s' to '%s'", buf, tmp); ret = rename(buf, tmp); if (ret == -1) { G_warning(_("Unable to rename directory '%s' to '%s'"), buf, tmp); return -1; } G_debug(3, "remove directory '%s'", tmp); /* Warning: remove() fails on Windows */ ret = rmdir(tmp); if (ret == -1) { G_warning(_("Unable to remove directory '%s'"), tmp); return -1; } return 0; }
/*! \brief Rename a map. Attribute tables are created in the same database where input tables were stored. The original format (native/OGR) is used. Old map ('out') is deleted!!! \param in input vector map name \param out output vector map name \return -1 error \return 0 success */ int Vect_rename(const char *in, const char *out) { int i, n, ret, type; struct Map_info Map; struct field_info *Fin, *Fout; int *fields; dbDriver *driver; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; G_debug(2, "Rename vector '%s' to '%s'", in, out); /* check for [A-Za-z][A-Za-z0-9_]* in name */ if (Vect_legal_filename(out) < 0) G_fatal_error(_("Vector map name is not SQL compliant")); /* Delete old vector if it exists */ if (G_find_vector2(out, G_mapset())) { G_warning(_("Vector map <%s> already exists and will be overwritten"), out); Vect_delete(out); } /* remove mapset from fully qualified name */ if (G_name_is_fully_qualified(in, xname, xmapset)) { in = xname; } /* Move the directory */ ret = G_rename(GV_DIRECTORY, in, out); if (ret == 0) { G_warning(_("Vector map <%s> not found"), in); return -1; } else if (ret == -1) { G_warning(_("Unable to copy vector map <%s> to <%s>"), in, out); return -1; } /* Rename all tables if the format is native */ Vect_set_open_level(1); Vect_open_update_head(&Map, out, G_mapset()); if (Map.format != GV_FORMAT_NATIVE) { /* Done */ Vect_close(&Map); return 0; } /* Copy tables */ n = Vect_get_num_dblinks(&Map); type = GV_1TABLE; if (n > 1) type = GV_MTABLE; /* Make the list of fields */ fields = (int *)G_malloc(n * sizeof(int)); for (i = 0; i < n; i++) { Fin = Vect_get_dblink(&Map, i); fields[i] = Fin->number; } for (i = 0; i < n; i++) { G_debug(3, "field[%d] = %d", i, fields[i]); Fin = Vect_get_field(&Map, fields[i]); if (Fin == NULL) { G_warning(_("Database connection not defined for layer %d"), fields[i]); Vect_close(&Map); return -1; } Fout = Vect_default_field_info(&Map, Fin->number, Fin->name, type); G_debug(3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'", Fin->driver, Fin->database, Fin->table, Fout->driver, Fout->database, Fout->table); /* TODO: db_rename_table instead of db_copy_table */ ret = db_copy_table(Fin->driver, Fin->database, Fin->table, Fout->driver, Vect_subst_var(Fout->database, &Map), Fout->table); if (ret == DB_FAILED) { G_warning(_("Unable to copy table <%s>"), Fin->table); Vect_close(&Map); return -1; } /* Change the link */ Vect_map_del_dblink(&Map, Fin->number); Vect_map_add_dblink(&Map, Fout->number, Fout->name, Fout->table, Fin->key, Fout->database, Fout->driver); /* Delete old table */ ret = db_delete_table(Fin->driver, Fin->database, Fin->table); if (ret == DB_FAILED) { G_warning(_("Unable to delete table <%s>"), Fin->table); Vect_close(&Map); return -1; } driver = db_start_driver_open_database(Fout->driver, Vect_subst_var(Fout->database, &Map)); if (driver == NULL) { G_warning(_("Unable to open database <%s> by driver <%s>"), Fout->database, Fout->driver); } else { if (db_create_index2(driver, Fout->table, Fin->key) != DB_OK) G_warning(_("Unable to create index for table <%s>, key <%s>"), Fout->table, Fout->key); db_close_database_shutdown_driver(driver); } } Vect_close(&Map); free(fields); return 0; }
/*--------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variables' declarations */ int row, nrows, col, ncols, MaxPoints; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; int last_row, last_column; int nlines, nlines_first, line_num; int more; int clas, region = TRUE; double Z_interp; double Thres_j, Thres_d, ew_resol, ns_resol; double minNS, minEW, maxNS, maxEW; const char *mapset; char buf[1024], table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int colorBordo, ripieno, conta, lungPunti, lungHull, xi, c1, c2; double altPiano; extern double **P, **cvxHull, **punti_bordo; /* Struct declarations */ struct Cell_head elaboration_reg, original_reg; struct element_grow **raster_matrix; struct Map_info In, Out, First; struct Option *in_opt, *out_opt, *first_opt, *Thres_j_opt, *Thres_d_opt; struct GModule *module; struct line_pnts *points, *points_first; struct line_cats *Cats, *Cats_first; struct field_info *field; dbDriver *driver; dbString sql; dbTable *table; dbCursor cursor; /*------------------------------------------------------------------------------------------*/ /* Options' declaration */ ; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("LIDAR")); module->description = _("Building contour determination and Region Growing " "algorithm for determining the building inside"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->description = _("Input vector (v.lidar.edgedetection output"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); first_opt = G_define_option(); first_opt->key = "first"; first_opt->type = TYPE_STRING; first_opt->key_desc = "name"; first_opt->required = YES; first_opt->gisprompt = "old,vector,vector"; first_opt->description = _("Name of the first pulse vector map"); Thres_j_opt = G_define_option(); Thres_j_opt->key = "tj"; Thres_j_opt->type = TYPE_DOUBLE; Thres_j_opt->required = NO; Thres_j_opt->description = _("Threshold for cell object frequency in region growing"); Thres_j_opt->answer = "0.2"; Thres_d_opt = G_define_option(); Thres_d_opt->key = "td"; Thres_d_opt->type = TYPE_DOUBLE; Thres_d_opt->required = NO; Thres_d_opt->description = _("Threshold for double pulse in region growing"); Thres_d_opt->answer = "0.6"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); Thres_j = atof(Thres_j_opt->answer); Thres_d = atof(Thres_d_opt->answer); Thres_j += 1; /* Open input vector */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, GV_FATAL_EXIT); if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) { G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); } /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(in_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_edge_Interpolation", xname); } else sprintf(table_name, "%s_edge_Interpolation", in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (Vect_open_old(&In, in_opt->answer, mapset) < 1) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (Vect_open_old(&First, first_opt->answer, mapset) < 1) G_fatal_error(_("Unable to open vector map <%s>"), first_opt->answer); /* Open output vector */ if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&In); Vect_close(&First); exit(EXIT_FAILURE); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); /* Starting driver and open db for edgedetection interpolation table */ field = Vect_get_field(&In, F_INTERPOLATION); /*if (field == NULL) G_fatal_error (_("Cannot read field info")); */ driver = db_start_driver_open_database(field->driver, field->database); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), field->driver); /* is this the right place to open the cursor ??? */ db_init_string(&sql); db_zero_string(&sql); sprintf(buf, "SELECT Interp,ID FROM %s", table_name); G_debug(1, "buf: %s", buf); db_append_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) G_fatal_error(_("Unable to open table <%s>"), table_name); count_obj = 1; /* no topology, get number of lines in input vector */ nlines = 0; points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { nlines++; } Vect_rewind(&In); /* no topology, get number of lines in first pulse input vector */ nlines_first = 0; points_first = Vect_new_line_struct(); Cats_first = Vect_new_cats_struct(); Vect_rewind(&First); while (Vect_read_next_line(&First, points_first, Cats_first) > 0) { nlines_first++; } Vect_rewind(&First); /* Setting regions and boxes */ G_debug(1, _("Setting regions and boxes")); G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); /* Fixing parameters of the elaboration region */ /*! The original_region will be divided into subregions */ ew_resol = original_reg.ew_res; ns_resol = original_reg.ns_res; /* calculate number of subregions */ nsubregion_col = ceil((original_reg.east - original_reg.west) / (LATO * ew_resol)) + 0.5; nsubregion_row = ceil((original_reg.north - original_reg.south) / (LATO * ns_resol)) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; /* Subdividing and working with tiles */ elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each strip of LATO rows */ elaboration_reg.north = elaboration_reg.south; if (elaboration_reg.north > original_reg.north) /* First row */ elaboration_reg.north = original_reg.north; elaboration_reg.south = elaboration_reg.north - LATO * ns_resol; if (elaboration_reg.south <= original_reg.south) { /* Last row */ elaboration_reg.south = original_reg.south; last_row = TRUE; } elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each strip of LATO columns */ struct bound_box elaboration_box; subregion++; if (nsubregions > 1) G_message(_("subregion %d of %d"), subregion, nsubregions); elaboration_reg.west = elaboration_reg.east; if (elaboration_reg.west < original_reg.west) /* First column */ elaboration_reg.west = original_reg.west; elaboration_reg.east = elaboration_reg.west + LATO * ew_resol; if (elaboration_reg.east >= original_reg.east) { /* Last column */ elaboration_reg.east = original_reg.east; last_column = TRUE; } /* Setting the active region */ elaboration_reg.ns_res = ns_resol; elaboration_reg.ew_res = ew_resol; nrows = (elaboration_reg.north - elaboration_reg.south) / ns_resol + 0.1; ncols = (elaboration_reg.east - elaboration_reg.west) / ew_resol + 0.1; elaboration_reg.rows = nrows; elaboration_reg.cols = ncols; G_debug(1, _("Rows = %d"), nrows); G_debug(1, _("Columns = %d"), ncols); raster_matrix = structMatrix(0, nrows, 0, ncols); MaxPoints = nrows * ncols; /* Initializing matrix */ for (row = 0; row <= nrows; row++) { for (col = 0; col <= ncols; col++) { raster_matrix[row][col].interp = 0; raster_matrix[row][col].fi = 0; raster_matrix[row][col].bordo = 0; raster_matrix[row][col].dueImp = SINGLE_PULSE; raster_matrix[row][col].orig = 0; raster_matrix[row][col].fo = 0; raster_matrix[row][col].clas = PRE_TERRAIN; raster_matrix[row][col].fc = 0; raster_matrix[row][col].obj = 0; } } G_verbose_message(_("read points in input vector")); Vect_region_box(&elaboration_reg, &elaboration_box); line_num = 0; Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { line_num++; if ((Vect_point_in_box (points->x[0], points->y[0], points->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points->x[0], &elaboration_reg)); Z_interp = 0; /* TODO: make sure the current db_fetch() usage works */ /* why not: */ /* db_init_string(&sql); sprintf(buf, "SELECT Interp,ID FROM %s WHERE ID=%d", table_name, line_num); db_append_string(&sql, buf); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) G_fatal_error(_("Unable to open table <%s>"), table_name); while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) { dbColumn *Z_Interp_col; dbValue *Z_Interp_value; table = db_get_cursor_table(&cursor); Z_Interp_col = db_get_table_column(table, 1); if (db_sqltype_to_Ctype(db_get_column_sqltype(Z_Interp_col)) == DB_C_TYPE_DOUBLE) Z_Interp_value = db_get_column_value(Z_Interp_col); else continue; Z_interp = db_get_value_double(Z_Interp_value); break; } db_close_cursor(&cursor); db_free_string(&sql); */ /* instead of */ while (1) { if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK || !more) break; dbColumn *Z_Interp_col, *ID_col; dbValue *Z_Interp_value, *ID_value; table = db_get_cursor_table(&cursor); ID_col = db_get_table_column(table, 1); if (db_sqltype_to_Ctype(db_get_column_sqltype(ID_col)) == DB_C_TYPE_INT) ID_value = db_get_column_value(ID_col); else continue; if (db_get_value_int(ID_value) == line_num) { Z_Interp_col = db_get_table_column(table, 0); if (db_sqltype_to_Ctype (db_get_column_sqltype(Z_Interp_col)) == DB_C_TYPE_DOUBLE) Z_Interp_value = db_get_column_value(Z_Interp_col); else continue; Z_interp = db_get_value_double(Z_Interp_value); break; } } raster_matrix[row][col].interp += Z_interp; raster_matrix[row][col].fi++; /*if (( clas = Vect_get_line_cat (&In, line_num, F_EDGE_DETECTION_CLASS) ) != UNKNOWN_EDGE) { */ if (Vect_cat_get(Cats, F_EDGE_DETECTION_CLASS, &clas)) { raster_matrix[row][col].clas += clas; raster_matrix[row][col].fc++; } raster_matrix[row][col].orig += points->z[0]; raster_matrix[row][col].fo++; } Vect_reset_cats(Cats); Vect_reset_line(points); } for (row = 0; row <= nrows; row++) { for (col = 0; col <= ncols; col++) { if (raster_matrix[row][col].fc != 0) { raster_matrix[row][col].clas--; raster_matrix[row][col]. clas /= raster_matrix[row][col].fc; } if (raster_matrix[row][col].fi != 0) raster_matrix[row][col]. interp /= raster_matrix[row][col].fi; if (raster_matrix[row][col].fo != 0) raster_matrix[row][col]. orig /= raster_matrix[row][col].fo; } } /* DOUBLE IMPULSE */ Vect_rewind(&First); while (Vect_read_next_line(&First, points_first, Cats_first) > 0) { if ((Vect_point_in_box (points_first->x[0], points_first->y[0], points_first->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points_first->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points_first->x[0], &elaboration_reg)); if (fabs (points_first->z[0] - raster_matrix[row][col].orig) >= Thres_d) raster_matrix[row][col].dueImp = DOUBLE_PULSE; } Vect_reset_cats(Cats_first); Vect_reset_line(points_first); } /* REGION GROWING */ if (region == TRUE) { G_verbose_message(_("Region Growing")); punti_bordo = G_alloc_matrix(MaxPoints, 3); P = Pvector(0, MaxPoints); colorBordo = 5; ripieno = 6; for (row = 0; row <= nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col <= ncols; col++) { if ((raster_matrix[row][col].clas >= Thres_j) && (raster_matrix[row][col].clas < colorBordo) && (raster_matrix[row][col].fi != 0) && (raster_matrix[row][col].dueImp == SINGLE_PULSE)) { /* Selecting a connected Object zone */ ripieno++; if (ripieno > 10) ripieno = 6; /* Selecting points on a connected edge */ for (conta = 0; conta < MaxPoints; conta++) { punti_bordo[conta][0] = 0; punti_bordo[conta][1] = 0; punti_bordo[conta][2] = 0; P[conta] = punti_bordo[conta]; /* It only makes indexes to be equal, not coord values!! */ } lungPunti = 0; lungHull = 0; regGrow8(elaboration_reg, raster_matrix, punti_bordo, &lungPunti, row, col, colorBordo, Thres_j, MaxPoints); /* CONVEX-HULL COMPUTATION */ lungHull = ch2d(P, lungPunti); cvxHull = G_alloc_matrix(lungHull, 3); for (xi = 0; xi < lungHull; xi++) { cvxHull[xi][0] = P[xi][0]; cvxHull[xi][1] = P[xi][1]; cvxHull[xi][2] = P[xi][2]; } /* Computes the interpoling plane based only on Object points */ altPiano = pianOriz(punti_bordo, lungPunti, &minNS, &minEW, &maxNS, &maxEW, raster_matrix, colorBordo); for (c1 = minNS; c1 <= maxNS; c1++) { for (c2 = minEW; c2 <= maxEW; c2++) { if (checkHull(c1, c2, cvxHull, lungHull) == 1) { raster_matrix[c1][c2].obj = count_obj; if ((raster_matrix[c1][c2].clas == PRE_TERRAIN) && (raster_matrix[c1][c2].orig >= altPiano) && (lungHull > 3)) raster_matrix[c1][c2].clas = ripieno; } } } G_free_matrix(cvxHull); count_obj++; } } } G_free_matrix(punti_bordo); free_Pvector(P, 0, MaxPoints); } /* WRITING THE OUTPUT VECTOR CATEGORIES */ Vect_rewind(&In); while (Vect_read_next_line(&In, points, Cats) > 0) { /* Read every line for buffering points */ if ((Vect_point_in_box (points->x[0], points->y[0], points->z[0], &elaboration_box)) && ((points->x[0] != elaboration_reg.west) || (points->x[0] == original_reg.west)) && ((points->y[0] != elaboration_reg.north) || (points->y[0] == original_reg.north))) { row = (int)(Rast_northing_to_row (points->y[0], &elaboration_reg)); col = (int)(Rast_easting_to_col (points->x[0], &elaboration_reg)); if (raster_matrix[row][col].clas == PRE_TERRAIN) { if (raster_matrix[row][col].dueImp == SINGLE_PULSE) Vect_cat_set(Cats, F_CLASSIFICATION, TERRAIN_SINGLE); else Vect_cat_set(Cats, F_CLASSIFICATION, TERRAIN_DOUBLE); } else { if (raster_matrix[row][col].dueImp == SINGLE_PULSE) Vect_cat_set(Cats, F_CLASSIFICATION, OBJECT_SINGLE); else Vect_cat_set(Cats, F_CLASSIFICATION, OBJECT_DOUBLE); } Vect_cat_set(Cats, F_COUNTER_OBJ, raster_matrix[row][col].obj); Vect_write_line(&Out, GV_POINT, points, Cats); } Vect_reset_cats(Cats); Vect_reset_line(points); } free_structmatrix(raster_matrix, 0, nrows - 1, 0, ncols - 1); } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ Vect_close(&In); Vect_close(&First); Vect_close(&Out); db_close_database_shutdown_driver(driver); G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Option *group, *mapset, *loc; struct GModule *module; struct Flag *c; char t_mapset[GMAPSET_MAX], t_location[GMAPSET_MAX]; char group_name[GNAME_MAX], mapset_name[GMAPSET_MAX]; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("map management")); module->description = _("Targets an imagery group to a GRASS location and mapset."); group = G_define_standard_option(G_OPT_I_GROUP); group->gisprompt = "any,group,group"; loc = G_define_option(); loc->key = "location"; loc->type = TYPE_STRING; loc->required = NO; loc->description = _("Name of imagery target location"); mapset = G_define_option(); mapset->key = "mapset"; mapset->type = TYPE_STRING; mapset->required = NO; mapset->description = _("Name of target mapset"); c = G_define_flag(); c->key = 'c'; c->description = _("Set current location and mapset as target for imagery group"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* check if current mapset: (imagery libs are very lacking in this dept) - abort if not, - remove @mapset part if it is */ if (G_name_is_fully_qualified(group->answer, group_name, mapset_name)) { if (strcmp(mapset_name, G_mapset())) G_fatal_error(_("Group must exist in the current mapset")); } else { strcpy(group_name, group->answer); /* FIXME for buffer overflow (have the parser check that?) */ } /* if no setting options are given, print the current target info */ if (!c->answer && !mapset->answer && !loc->answer) { if (I_get_target(group_name, t_location, t_mapset)) G_message(_("Group <%s> targeted for location [%s], mapset [%s]"), group_name, t_location, t_mapset); else G_message(_("Group <%s> has no target"), group_name); exit(EXIT_SUCCESS); } /* error if -c is specified with other options, or options are incomplete */ if ((c->answer && (mapset->answer || loc->answer)) || (!c->answer && (!mapset->answer || !loc->answer))) G_fatal_error(_("Use either the Current Mapset and " "Location Flag (-c)\n OR\n manually enter the variables")); if (c->answer) { /* point group target to current mapset and location */ I_put_target(group_name, G_location(), G_mapset()); G_message(_("Group <%s> targeted for location [%s], mapset [%s]"), group_name, G_location(), G_mapset()); } else { /* point group target to specified mapset and location */ /* TODO: check if it is in current mapset and strip off @mapset part, if present */ I_put_target(group_name, loc->answer, mapset->answer); G_message(_("Group <%s> targeted for location [%s], mapset [%s]"), group_name, loc->answer, mapset->answer); } G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { char name[GNAME_MAX], mapset[GMAPSET_MAX], xmapset[GMAPSET_MAX]; struct Cell_head cellhd; struct GModule *module; struct Option *grp; /* must run in a term window */ G_putenv("GRASS_UI_TERM", "1"); G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("imagery")); G_add_keyword(_("geometry")); module->description = _("Mark ground control points on image to be rectified."); grp = G_define_option(); grp->key = "group"; grp->type = TYPE_STRING; grp->required = YES; grp->gisprompt = "old,group,group"; grp->description = _("Name of imagery group to be registered"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); Rast_suppress_masking(); /* need to do this for target location */ interrupt_char = G_intr_char(); tempfile1 = G_tempfile(); tempfile2 = G_tempfile(); cell_list = G_tempfile(); vect_list = G_tempfile(); group_list = G_tempfile(); digit_points = G_tempfile(); digit_results = G_tempfile(); if (R_open_driver() != 0) G_fatal_error(_("No graphics device selected")); /* parse group name */ /* only enforce local-mapset-only due to I_get_group_ref() not liking "@mapset" */ if (G_name_is_fully_qualified(grp->answer, group.name, xmapset)) { if (0 != strcmp(G_mapset(), xmapset)) G_fatal_error(_("[%s] Only local groups may be used"), grp->answer); } else { strncpy(group.name, grp->answer, GNAME_MAX - 1); group.name[GNAME_MAX - 1] = '\0'; /* strncpy() doesn't null terminate on overflow */ } if (!I_get_group_ref(group.name, &group.ref)) G_fatal_error(_("Group [%s] contains no maps, run i.group"), group.name); if (group.ref.nfiles <= 0) G_fatal_error(_("Group [%s] contains no maps, run i.group"), group.name); /* write group files to group list file */ prepare_group_list(); /* get target info and environment */ get_target(); find_target_files(); /* read group control points, if any */ G_suppress_warnings(1); if (!I_get_control_points(group.name, &group.points)) group.points.count = 0; G_suppress_warnings(0); /* determine transformation equation */ Compute_equation(); signal(SIGINT, SIG_IGN); /* signal (SIGQUIT, SIG_IGN); */ Init_graphics(); display_title(VIEW_MAP1); select_target_env(); display_title(VIEW_MAP2); select_current_env(); Begin_curses(); G_set_error_routine(error); /* #ifdef SIGTSTP signal (SIGTSTP, SIG_IGN); #endif */ /* ask user for group file to be displayed */ do { if (!choose_groupfile(name, mapset)) quit(0); /* display this file in "map1" */ } while (!G_find_raster2(name, mapset)); Rast_get_cellhd(name, mapset, &cellhd); G_adjust_window_to_box(&cellhd, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows, VIEW_MAP1->ncols); Configure_view(VIEW_MAP1, name, mapset, cellhd.ns_res, cellhd.ew_res); drawcell(VIEW_MAP1); display_points(1); Curses_clear_window(PROMPT_WINDOW); /* determine initial input method. */ setup_digitizer(); if (use_digitizer) { from_digitizer = 1; from_keyboard = 0; from_flag = 1; } /* go do the work */ driver(); quit(0); }
static const char *find_file( int misc, const char *dir, const char *element, const char *name, const char *mapset) { char path[GPATH_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; const char *pname, *pmapset; int n; if (*name == 0) return NULL; *path = 0; /* * if name is in the fully qualified format, split it into * name, mapset (overrides what was in mapset) */ if (G_name_is_fully_qualified(name, xname, xmapset)) { pname = xname; pmapset = xmapset; } else { pname = name; pmapset = mapset; } if (strcmp(element, "vector") == 0 && strcasecmp(pmapset, "ogr") == 0) { /* don't check for virtual OGR mapset */ return G_store(pmapset); } /* * reject illegal names and mapsets */ if (G_legal_filename(pname) == -1) return NULL; if (pmapset && *pmapset && G_legal_filename(pmapset) == -1) return NULL; /* * if no specific mapset is to be searched * then search all mapsets in the mapset search list */ if (pmapset == NULL || *pmapset == 0) { int cnt = 0; const char *pselmapset = NULL; for (n = 0; (pmapset = G__mapset_name(n)); n++) { if (misc) G_file_name_misc(path, dir, element, pname, pmapset); else G_file_name(path, element, pname, pmapset); if (access(path, 0) == 0) { if (!pselmapset) pselmapset = pmapset; else G_warning(_("'%s/%s' was found in more mapsets (also found in <%s>)"), element, pname, pmapset); cnt++; } } if (cnt > 0) { /* If the same name exists in more mapsets and print a warning */ if (cnt > 1) G_warning(_("Using <%s@%s>"), pname, pselmapset); return G_store(pselmapset); } } /* * otherwise just look for the file in the specified mapset. * since the name may have been qualified, mapset may point * to the xmapset, so we must should it to * permanent storage via G_store(). */ else { if (misc) G_file_name_misc(path, dir, element, pname, pmapset); else G_file_name(path, element, pname, pmapset); if (access(path, 0) == 0) return G_store(pmapset); } return NULL; }
int main(int argc, char *argv[]) { int i, cat, with_z, more, ctype, nrows; char buf[DB_SQL_MAX]; int count; double coor[3]; int ncoor; struct Option *driver_opt, *database_opt, *table_opt; struct Option *xcol_opt, *ycol_opt, *zcol_opt, *keycol_opt, *where_opt, *outvect; struct Flag *same_table_flag; struct GModule *module; struct Map_info Map; struct line_pnts *Points; struct line_cats *Cats; dbString sql; dbDriver *driver; dbCursor cursor; dbTable *table; dbColumn *column; dbValue *value; struct field_info *fi; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("import")); G_add_keyword(_("database")); G_add_keyword(_("points")); module->description = _("Creates new vector (points) map from database table containing coordinates."); table_opt = G_define_standard_option(G_OPT_DB_TABLE); table_opt->required = YES; table_opt->description = _("Input table name"); driver_opt = G_define_standard_option(G_OPT_DB_DRIVER); driver_opt->options = db_list_drivers(); driver_opt->answer = (char *)db_get_default_driver_name(); driver_opt->guisection = _("Input DB"); database_opt = G_define_standard_option(G_OPT_DB_DATABASE); database_opt->answer = (char *)db_get_default_database_name(); database_opt->guisection = _("Input DB"); xcol_opt = G_define_standard_option(G_OPT_DB_COLUMN); xcol_opt->key = "x"; xcol_opt->required = YES; xcol_opt->description = _("Name of column containing x coordinate"); ycol_opt = G_define_standard_option(G_OPT_DB_COLUMN); ycol_opt->key = "y"; ycol_opt->required = YES; ycol_opt->description = _("Name of column containing y coordinate"); zcol_opt = G_define_standard_option(G_OPT_DB_COLUMN); zcol_opt->key = "z"; zcol_opt->description = _("Name of column containing z coordinate"); zcol_opt->guisection = _("3D output"); keycol_opt = G_define_standard_option(G_OPT_DB_COLUMN); keycol_opt->key = "key"; keycol_opt->required = NO; keycol_opt->label = _("Name of column containing category number"); keycol_opt->description = _("Must refer to an integer column"); where_opt = G_define_standard_option(G_OPT_DB_WHERE); where_opt->guisection = _("Selection"); outvect = G_define_standard_option(G_OPT_V_OUTPUT); same_table_flag = G_define_flag(); same_table_flag->key = 't'; same_table_flag->description = _("Use imported table as attribute table for new map"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (zcol_opt->answer) { with_z = WITH_Z; ncoor = 3; } else { with_z = WITHOUT_Z; ncoor = 2; } Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); db_init_string(&sql); if (G_get_overwrite()) { /* We don't want to delete the input table when overwriting the output * vector. */ char name[GNAME_MAX], mapset[GMAPSET_MAX]; if (!G_name_is_fully_qualified(outvect->answer, name, mapset)) { strcpy(name, outvect->answer); strcpy(mapset, G_mapset()); } Vect_set_open_level(1); /* no topo needed */ if (strcmp(mapset, G_mapset()) == 0 && G_find_vector2(name, mapset) && Vect_open_old(&Map, name, mapset) >= 0) { int num_dblinks; num_dblinks = Vect_get_num_dblinks(&Map); for (i = 0; i < num_dblinks; i++) { if ((fi = Vect_get_dblink(&Map, i)) != NULL && strcmp(fi->driver, driver_opt->answer) == 0 && strcmp(fi->database, database_opt->answer) == 0 && strcmp(fi->table, table_opt->answer) == 0) G_fatal_error(_("Vector map <%s> cannot be overwritten " "because input table <%s> is linked to " "this map."), outvect->answer, table_opt->answer); } Vect_close(&Map); } } if (Vect_open_new(&Map, outvect->answer, with_z) < 0) G_fatal_error(_("Unable to create vector map <%s>"), outvect->answer); Vect_set_error_handler_io(NULL, &Map); Vect_hist_command(&Map); fi = Vect_default_field_info(&Map, 1, NULL, GV_1TABLE); /* Open driver */ driver = db_start_driver_open_database(driver_opt->answer, database_opt->answer); if (driver == NULL) { G_fatal_error(_("Unable to open database <%s> by driver <%s>"), fi->database, fi->driver); } db_set_error_handler_driver(driver); /* check if target table already exists */ G_debug(3, "Output vector table <%s>, driver: <%s>, database: <%s>", outvect->answer, db_get_default_driver_name(), db_get_default_database_name()); if (!same_table_flag->answer && db_table_exists(db_get_default_driver_name(), db_get_default_database_name(), outvect->answer) == 1) G_fatal_error(_("Output vector map, table <%s> (driver: <%s>, database: <%s>) " "already exists"), outvect->answer, db_get_default_driver_name(), db_get_default_database_name()); if (keycol_opt->answer) { int coltype; coltype = db_column_Ctype(driver, table_opt->answer, keycol_opt->answer); if (coltype == -1) G_fatal_error(_("Column <%s> not found in table <%s>"), keycol_opt->answer, table_opt->answer); if (coltype != DB_C_TYPE_INT) G_fatal_error(_("Data type of key column must be integer")); } else { if (same_table_flag->answer) { G_fatal_error(_("Option <%s> must be specified when -%c flag is given"), keycol_opt->key, same_table_flag->key); } if (strcmp(db_get_default_driver_name(), "sqlite") != 0) G_fatal_error(_("Unable to define key column. This operation is not supported " "by <%s> driver. You need to define <%s> option."), fi->driver, keycol_opt->key); } /* Open select cursor */ sprintf(buf, "SELECT %s, %s", xcol_opt->answer, ycol_opt->answer); db_set_string(&sql, buf); if (with_z) { sprintf(buf, ", %s", zcol_opt->answer); db_append_string(&sql, buf); } if (keycol_opt->answer) { sprintf(buf, ", %s", keycol_opt->answer); db_append_string(&sql, buf); } sprintf(buf, " FROM %s", table_opt->answer); db_append_string(&sql, buf); if (where_opt->answer) { sprintf(buf, " WHERE %s", where_opt->answer); db_append_string(&sql, buf); } G_debug(2, "SQL: %s", db_get_string(&sql)); if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) { G_fatal_error(_("Unable to open select cursor: '%s'"), db_get_string(&sql)); } table = db_get_cursor_table(&cursor); nrows = db_get_num_rows(&cursor); G_debug(2, "%d points selected", nrows); count = cat = 0; G_message(_("Writing features...")); while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) { G_percent(count, nrows, 2); /* key column */ if (keycol_opt->answer) { column = db_get_table_column(table, with_z ? 3 : 2); ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column)); if (ctype != DB_C_TYPE_INT) G_fatal_error(_("Key column must be integer")); value = db_get_column_value(column); cat = db_get_value_int(value); } else { cat++; } /* coordinates */ for (i = 0; i < ncoor; i++) { column = db_get_table_column(table, i); ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column)); if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("x/y/z column must be integer or double")); value = db_get_column_value(column); if (ctype == DB_C_TYPE_INT) coor[i] = (double)db_get_value_int(value); else coor[i] = db_get_value_double(value); } Vect_reset_line(Points); Vect_reset_cats(Cats); Vect_append_point(Points, coor[0], coor[1], coor[2]); Vect_cat_set(Cats, 1, cat); Vect_write_line(&Map, GV_POINT, Points, Cats); count++; } G_percent(1, 1, 1); /* close connection to input DB before copying attributes */ db_close_database_shutdown_driver(driver); /* Copy table */ if (!same_table_flag->answer) { G_message(_("Copying attributes...")); if (DB_FAILED == db_copy_table_where(driver_opt->answer, database_opt->answer, table_opt->answer, fi->driver, fi->database, fi->table, where_opt->answer)) { /* where can be NULL */ G_warning(_("Unable to copy table")); } else { Vect_map_add_dblink(&Map, 1, NULL, fi->table, keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN, fi->database, fi->driver); } if (!keycol_opt->answer) { /* TODO: implement for all DB drivers in generic way if * possible */ driver = db_start_driver_open_database(fi->driver, fi->database); if (driver == NULL) { G_fatal_error(_("Unable to open database <%s> by driver <%s>"), fi->database, fi->driver); } db_set_error_handler_driver(driver); /* add key column */ sprintf(buf, "ALTER TABLE %s ADD COLUMN %s INTEGER", fi->table, GV_KEY_COLUMN); db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) { G_fatal_error(_("Unable to add key column <%s>: " "SERIAL type is not supported by <%s>"), GV_KEY_COLUMN, fi->driver); } /* update key column */ sprintf(buf, "UPDATE %s SET %s = _ROWID_", fi->table, GV_KEY_COLUMN); db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) { G_fatal_error(_("Failed to update key column <%s>"), GV_KEY_COLUMN); } } } else { /* do not copy attributes, link original table */ Vect_map_add_dblink(&Map, 1, NULL, table_opt->answer, keycol_opt->answer ? keycol_opt->answer : GV_KEY_COLUMN, database_opt->answer, driver_opt->answer); } Vect_build(&Map); Vect_close(&Map); G_done_msg(_n("%d point written to vector map.", "%d points written to vector map.", count), count); return (EXIT_SUCCESS); }
/*! \brief Copy a map including attribute tables Old vector is deleted \param in input vector map name \param mapset mapset name \param out output vector map name \return -1 error \return 0 success */ int Vect_copy(const char *in, const char *mapset, const char *out) { int i, n, ret, type; struct Map_info In, Out; struct field_info *Fi, *Fin; char old_path[GPATH_MAX], new_path[GPATH_MAX], buf[GPATH_MAX]; const char *files[] = { GV_FRMT_ELEMENT, GV_COOR_ELEMENT, GV_HEAD_ELEMENT, GV_HIST_ELEMENT, GV_TOPO_ELEMENT, GV_SIDX_ELEMENT, GV_CIDX_ELEMENT, NULL }; const char *inmapset; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; dbDriver *driver; G_debug(2, "Copy vector '%s' in '%s' to '%s'", in, mapset, out); /* check for [A-Za-z][A-Za-z0-9_]* in name */ if (Vect_legal_filename(out) < 0) G_fatal_error(_("Vector map name is not SQL compliant")); inmapset = G_find_vector2(in, mapset); if (!inmapset) { G_warning(_("Unable to find vector map <%s> in <%s>"), in, mapset); return -1; } mapset = inmapset; /* remove mapset from fully qualified name, confuses G_file_name() */ if (G_name_is_fully_qualified(in, xname, xmapset)) { in = xname; } /* Delete old vector if it exists */ if (G_find_vector2(out, G_mapset())) { G_warning(_("Vector map <%s> already exists and will be overwritten"), out); ret = Vect_delete(out); if (ret != 0) { G_warning(_("Unable to delete vector map <%s>"), out); return -1; } } /* Copy the directory */ G__make_mapset_element(GV_DIRECTORY); sprintf(buf, "%s/%s", GV_DIRECTORY, out); G__make_mapset_element(buf); i = 0; while (files[i]) { sprintf(buf, "%s/%s", in, files[i]); G_file_name(old_path, GV_DIRECTORY, buf, mapset); sprintf(buf, "%s/%s", out, files[i]); G_file_name(new_path, GV_DIRECTORY, buf, G_mapset()); if (access(old_path, F_OK) == 0) { /* file exists? */ G_debug(2, "copy %s to %s", old_path, new_path); if (copy_file(old_path, new_path)) { G_warning(_("Unable to copy vector map <%s> to <%s>"), old_path, new_path); } } i++; } G_file_name(old_path, GV_DIRECTORY, in, mapset); G_file_name(new_path, GV_DIRECTORY, out, G_mapset()); /* Open input */ Vect_set_open_level(1); Vect_open_old_head(&In, in, mapset); if (In.format != GV_FORMAT_NATIVE) { /* Done */ Vect_close(&In); return 0; } /* Open output */ Vect_set_open_level(1); Vect_open_update_head(&Out, out, G_mapset()); /* Copy tables */ n = Vect_get_num_dblinks(&In); type = GV_1TABLE; if (n > 1) type = GV_MTABLE; for (i = 0; i < n; i++) { Fi = Vect_get_dblink(&In, i); if (Fi == NULL) { G_warning(_("Database connection not defined for layer %d"), In.dblnk->field[i].number); Vect_close(&In); Vect_close(&Out); return -1; } Fin = Vect_default_field_info(&Out, Fi->number, Fi->name, type); G_debug(3, "Copy drv:db:table '%s:%s:%s' to '%s:%s:%s'", Fi->driver, Fi->database, Fi->table, Fin->driver, Fin->database, Fin->table); Vect_map_add_dblink(&Out, Fi->number, Fi->name, Fin->table, Fi->key, Fin->database, Fin->driver); ret = db_copy_table(Fi->driver, Fi->database, Fi->table, Fin->driver, Vect_subst_var(Fin->database, &Out), Fin->table); if (ret == DB_FAILED) { G_warning(_("Unable to copy table <%s>"), Fin->table); Vect_close(&In); Vect_close(&Out); return -1; } driver = db_start_driver_open_database(Fin->driver, Vect_subst_var(Fin->database, &Out)); if (driver == NULL) { G_warning(_("Unable to open database <%s> by driver <%s>"), Fin->database, Fin->driver); } else { if (db_create_index2(driver, Fin->table, Fi->key) != DB_OK) G_warning(_("Unable to create index for table <%s>, key <%s>"), Fi->table, Fi->key); db_close_database_shutdown_driver(driver); } } Vect_close(&In); Vect_close(&Out); return 0; }