int main(int argc, char *argv[]) { struct dxf_file *dxf; struct Map_info *Map; char *output = NULL; struct GModule *module; struct { struct Flag *list; struct Flag *extent; struct Flag *table; struct Flag *topo; struct Flag *invert; struct Flag *one_layer; struct Flag *frame; } flag; struct { struct Option *input; struct Option *output; struct Option *layers; } opt; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, import"); module->description = _("Converts files in DXF format to GRASS vector map format."); flag.extent = G_define_flag(); flag.extent->key = 'e'; flag.extent->description = _("Ignore the map extent of DXF file"); flag.table = G_define_flag(); flag.table->key = 't'; flag.table->description = _("Do not create attribute tables"); flag.topo = G_define_flag(); flag.topo->key = 'b'; flag.topo->description = _("Do not build topology"); flag.frame = G_define_flag(); flag.frame->key = 'f'; flag.frame->description = _("Import polyface meshes as 3D wire frame"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List available layers and exit"); flag.list->guisection = _("DXF layers"); flag.invert = G_define_flag(); flag.invert->key = 'i'; flag.invert->description = _("Invert selection by layers (don't import layers in list)"); flag.invert->guisection = _("DXF layers"); flag.one_layer = G_define_flag(); flag.one_layer->key = '1'; flag.one_layer->description = _("Import all objects into one layer"); flag.one_layer->guisection = _("DXF layers"); opt.input = G_define_standard_option(G_OPT_F_INPUT); opt.input->description = _("Name of input DXF file"); opt.output = G_define_standard_option(G_OPT_V_OUTPUT); opt.output->required = NO; opt.layers = G_define_option(); opt.layers->key = "layers"; opt.layers->type = TYPE_STRING; opt.layers->required = NO; opt.layers->multiple = YES; opt.layers->description = _("List of layers to import"); opt.layers->guisection = _("DXF layers"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); flag_list = flag.list->answer; flag_extent = flag.extent->answer; flag_table = flag.table->answer; flag_invert = flag.invert->answer; flag_one_layer = flag.one_layer->answer; flag_frame = flag.frame->answer; /* open DXF file */ if (!(dxf = dxf_open(opt.input->answer))) G_fatal_error(_("Unable to open DXF file <%s>"), opt.input->answer); if (flag_list) { num_layers = 0; layers = NULL; Map = NULL; } else { /* make vector map name SQL compliant */ if (opt.output->answer) { output = G_store(opt.output->answer); } else { char *p, *p2; if ((p = G_rindex(dxf->name, '/'))) p++; else p = dxf->name; output = G_store(p); if ((p2 = G_rindex(p, '.'))) output[p2 - p] = 0; } { char *p; for (p = output; *p; p++) if (*p == '.') *p = '_'; } layers = opt.layers->answers; if (!G_check_overwrite(argc, argv) && G_find_vector2(output, G_mapset())) { G_fatal_error(_("Option <%s>: <%s> exists."), opt.output->key, output); } if (Vect_legal_filename(output) < 0) G_fatal_error(_("Use '%s' option to change vector map name"), opt.output->key); /* create vector map */ Map = (struct Map_info *)G_malloc(sizeof(struct Map_info)); if (Vect_open_new(Map, output, 1) < 0) G_fatal_error(_("Unable to create vector map <%s>"), output); Vect_set_map_name(Map, output); Vect_hist_command(Map); } /* import */ dxf_to_vect(dxf, Map); dxf_close(dxf); if (flag_list) init_list(); else { Vect_close(Map); if (found_layers) { if (Vect_open_old(Map, output, G_mapset())) { if (!flag_topo) if (!Vect_build(Map)) G_warning(_("Building topology failed")); Vect_close(Map); } } else { Vect_delete(output); G_fatal_error(_("Failed to import DXF file!")); } G_free(output); G_free(Map); } G_done_msg(" "); exit(EXIT_SUCCESS); }
/* Create GRASS vector output map. Create attribute table. Calculate geometries and write them into the output map. Calculate attributes and write them into the output map's attribute table. */ void writeMap() { int i, j; double xlength, ylength, zlength; double length, flatLength, bailLength; double xoffset, yoffset, zoffset; double xys[12]; int ratio; double zRatio; /* attributes to be written to output map */ int boneID; int skelID; int unitID; int oldID; int cat; char *organization; char buf[MAXSTR]; if ( numPoints < 2 ) { G_fatal_error ("Less than two valid measurement points in input file"); } G_message (_("Constructing geometries for %i valid points:"), numPoints ); /* CREATE OUTPUT VECTOR MAP */ if (Vect_legal_filename(output->answer) < 0) { G_fatal_error(_("Use '%s' option to change vector map name"), output->key); } Map = (struct Map_info *) G_malloc (sizeof ( struct Map_info ) ); if (Vect_open_new(Map, output->answer, WITH_Z) < 0) { G_fatal_error(_("Unable to create vector map <%s>"), output->answer); } Vect_set_map_name(Map, output->answer); Vect_hist_command(Map); if ((organization = getenv("GRASS_ORGANIZATION"))) { Vect_set_organization(Map, organization); } else { Vect_set_organization(Map, "UNKNOWN ORGANIZATION"); } Vect_set_date(Map, G_date()); Vect_set_person(Map, G_whoami()); Vect_set_map_date(Map, ""); Vect_set_scale(Map, 2400); Vect_set_comment(Map, ""); Vect_set_zone(Map, 0); Vect_set_thresh(Map, 0.0); /* START DBMS INTERFACE */ /* prepare strings for use in db_* calls */ db_init_string(&sql); /* start default database driver */ Fi = Vect_default_field_info(Map, 1, NULL, GV_1TABLE); driver = db_start_driver_open_database(Fi->driver,Vect_subst_var(Fi->database, Map)); if (driver == NULL) { Vect_delete(output->answer); G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, Map), Fi->driver); } /* create attribute table */ db_begin_transaction ( driver ); sprintf(buf, "create table %s (cat integer, skel_id integer, bone_id integer, unit_id integer, GRASSRGB varchar(11),BONERGB varchar(11));", Fi->table); if ( DEBUG ) { fprintf ( stderr, "Creating attribute table: %s\n", buf ); } db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to create attribute table: %s"), db_get_string(&sql)); } if (db_grant_on_table (driver, output->answer, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to grant privileges on table <%s>"), output->answer); } if (db_create_index2(driver, output->answer, "cat") != DB_OK) { G_warning(_("Unable to create index for table <%s>, key <%s>"), output->answer, "cat"); } /* link vector map to attribute table */ if (Vect_map_add_dblink(Map, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver) ) { Vect_delete(output->answer); G_fatal_error(_("Unable to add database link for vector map <%s>"), Vect_get_full_name(Map)); } /* PROCESS POINTS AND WRITE GEOMETRIES */ /* Now process point measurements and write geometries into output vector map. */ /* At this stage, the global points array has an even number of valid points. */ oldID = pointTable[0].SKEL_ID; unitID = 1; cat = 0; for ( i = 0; i < numPoints; i = i + 2 ) { /* This boneID is a generalized ID that does not differentiate between start and end measurement. */ boneID = (int) pointTable[i+1].BONE_ID / 2; skelID = pointTable[i+1].SKEL_ID; /* get coordinates for top and bottom of bone */ ax = pointTable[i].X; ay = pointTable[i].Y; az = pointTable[i].Z; bx = pointTable[i+1].X; by = pointTable[i+1].Y; bz = pointTable[i+1].Z; /* get vector lengths */ xlength = fabs (ax - bx); ylength = fabs (ay - by); zlength = fabs (az - bz); /* get real length */ length = sqrt ( (xlength*xlength) + (ylength*ylength) + (zlength*zlength) ); /* get length in x/y plane */ flatLength = sqrt ( (xlength*xlength) + (ylength*ylength) ); /* determine ratio for triangles, depending on bone type */ ratio = 12; /* default */ for ( j = 0; j < NUM_RATIOS; j ++ ) { if ( boneID == RATIO_ID[j] ) { ratio = RATIO_VAL[j]; } } /* get bail length */ bailLength = (double) ( length / (double) ratio); /* calculate bail offsets from top point (one bail is mirror of the other) */ xoffset = (bailLength * ylength) / flatLength; yoffset = ( (bailLength * xlength) / flatLength ) * (-1); zoffset = 0; xys[0]= ax + xoffset; xys[1]= ay + yoffset; xys[2]= az + zoffset; xys[6]= ax - xoffset; xys[7]= ay - yoffset; xys[8]= az - zoffset; /* get 3rd axis offsets */ zRatio = (zlength/ratio) / flatLength; xoffset = xlength * zRatio; yoffset = ylength * zRatio; zoffset = (flatLength/ratio) * (-1); xys[3]= ax + xoffset; xys[4]= ay + yoffset; xys[5]= az + zoffset; xys[9]= ax - xoffset; xys[10]= ay - yoffset; xys[11]= az - zoffset; /* Increase unit ID by "1", if we have another skeleton ID */ if ( oldID != pointTable[i+1].SKEL_ID ) { unitID ++; oldID = pointTable[i+1].SKEL_ID; /* switch to next colour for next geometry */ RGBNUM ++; if ( RGBNUM == RGBMAX ) { RGBNUM = 0; } } /* write geometries */ if ( MODE == MODE_DARTS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_LINES ) { writeLine ( cat, skelID, boneID, unitID ); cat ++; } if ( MODE == MODE_PLANES_H ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; } if ( MODE == MODE_PLANES_V ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_POINTS ) { writePoints ( cat, skelID, boneID, unitID ); cat = cat + 2; } if ( MODE == MODE_PYRAMIDS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 3 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 6, 9 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 9, 0 ); cat ++; writeSquare ( cat, skelID, boneID, unitID, xys ); cat ++; } /* switch to next colour for bone colouring */ RGBNUM_BONE ++; if ( RGBNUM_BONE == RGBMAX ) { RGBNUM_BONE = 0; } G_percent ( i, numPoints - 2, 1 ); } fprintf ( stdout, "\n" ); /* commit DBMS actions */ db_commit_transaction(driver); db_close_database_shutdown_driver(driver); if (!Vect_build(Map)) { G_warning("Building topology failed"); } Vect_close(Map); db_free_string(&sql); }
/*! \brief 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; }
/*! \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[]) { int npmin; int ii; double x_orig, y_orig, dnorm, deltx, delty, xm, ym; char dmaxchar[200]; char dminchar[200]; struct quaddata *data; struct multfunc *functions; struct multtree *tree; int open_check, with_z; char buf[1024]; struct GModule *module; struct { struct Option *input, *field, *zcol, *wheresql, *scol, *elev, *slope, *aspect, *pcurv, *tcurv, *mcurv, *treefile, *overfile, *maskmap, *dmin, *dmax, *zmult, *fi, *rsm, *segmax, *npmin, *cvdev, *devi, *theta, *scalex; } parm; struct { struct Flag *deriv, *cprght, *cv; } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("3D")); module->label = _("Performs surface interpolation from vector points map by splines."); module->description = _("Spatial approximation and topographic analysis from given " "point or isoline data in vector format to floating point " "raster format using regularized spline with tension."); flag.cv = G_define_flag(); flag.cv->key = 'c'; flag.cv->description = _("Perform cross-validation procedure without raster approximation"); flag.cv->guisection = _("Parameters"); flag.cprght = G_define_flag(); flag.cprght->key = 't'; flag.cprght->description = _("Use scale dependent tension"); flag.cprght->guisection = _("Parameters"); flag.deriv = G_define_flag(); flag.deriv->key = 'd'; flag.deriv->description = _("Output partial derivatives instead of topographic parameters"); flag.deriv->guisection = _("Outputs"); parm.input = G_define_standard_option(G_OPT_V_INPUT); parm.field = G_define_standard_option(G_OPT_V_FIELD); parm.field->answer = "1"; parm.field->guisection = _("Selection"); parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN); parm.zcol->key = "zcolumn"; parm.zcol->required = NO; parm.zcol->label = _("Name of the attribute column with values to be used for approximation"); parm.zcol->description = _("If not given and input is 2D vector map then category values are used. " "If input is 3D vector map then z-coordinates are used."); parm.zcol->guisection = _("Parameters"); parm.wheresql = G_define_standard_option(G_OPT_DB_WHERE); parm.wheresql->guisection = _("Selection"); parm.elev = G_define_standard_option(G_OPT_R_OUTPUT); parm.elev->key = "elevation"; parm.elev->required = NO; parm.elev->description = _("Name for output surface elevation raster map"); parm.elev->guisection = _("Outputs"); parm.slope = G_define_standard_option(G_OPT_R_OUTPUT); parm.slope->key = "slope"; parm.slope->required = NO; parm.slope->description = _("Name for output slope raster map"); parm.slope->guisection = _("Outputs"); parm.aspect = G_define_standard_option(G_OPT_R_OUTPUT); parm.aspect->key = "aspect"; parm.aspect->required = NO; parm.aspect->description = _("Name for output aspect raster map"); parm.aspect->guisection = _("Outputs"); parm.pcurv = G_define_standard_option(G_OPT_R_OUTPUT); parm.pcurv->key = "pcurvature"; parm.pcurv->required = NO; parm.pcurv->description = _("Name for output profile curvature raster map"); parm.pcurv->guisection = _("Outputs"); parm.tcurv = G_define_standard_option(G_OPT_R_OUTPUT); parm.tcurv->key = "tcurvature"; parm.tcurv->required = NO; parm.tcurv->description = _("Name for output tangential curvature raster map"); parm.tcurv->guisection = _("Outputs"); parm.mcurv = G_define_standard_option(G_OPT_R_OUTPUT); parm.mcurv->key = "mcurvature"; parm.mcurv->required = NO; parm.mcurv->description = _("Name for output mean curvature raster map"); parm.mcurv->guisection = _("Outputs"); parm.devi = G_define_standard_option(G_OPT_V_OUTPUT); parm.devi->key = "deviations"; parm.devi->required = NO; parm.devi->description = _("Name for output deviations vector point map"); parm.devi->guisection = _("Outputs"); parm.cvdev = G_define_standard_option(G_OPT_V_OUTPUT); parm.cvdev->key = "cvdev"; parm.cvdev->required = NO; parm.cvdev->description = _("Name for output cross-validation errors vector point map"); parm.cvdev->guisection = _("Outputs"); parm.treefile = G_define_standard_option(G_OPT_V_OUTPUT); parm.treefile->key = "treeseg"; parm.treefile->required = NO; parm.treefile->description = _("Name for output vector map showing quadtree segmentation"); parm.treefile->guisection = _("Outputs"); parm.overfile = G_define_standard_option(G_OPT_V_OUTPUT); parm.overfile->key = "overwin"; parm.overfile->required = NO; parm.overfile->description = _("Name for output vector map showing overlapping windows"); parm.overfile->guisection = _("Outputs"); parm.maskmap = G_define_standard_option(G_OPT_R_INPUT); parm.maskmap->key = "mask"; parm.maskmap->required = NO; parm.maskmap->description = _("Name of raster map used as mask"); parm.maskmap->guisection = _("Parameters"); parm.fi = G_define_option(); parm.fi->key = "tension"; parm.fi->type = TYPE_DOUBLE; parm.fi->answer = TENSION; parm.fi->required = NO; parm.fi->description = _("Tension parameter"); parm.fi->guisection = _("Parameters"); parm.rsm = G_define_option(); parm.rsm->key = "smooth"; parm.rsm->type = TYPE_DOUBLE; parm.rsm->required = NO; parm.rsm->description = _("Smoothing parameter"); parm.rsm->guisection = _("Parameters"); parm.scol = G_define_option(); parm.scol->key = "smooth_column"; parm.scol->type = TYPE_STRING; parm.scol->required = NO; parm.scol->description = _("Name of the attribute column with smoothing parameters"); parm.scol->guisection = _("Parameters"); parm.segmax = G_define_option(); parm.segmax->key = "segmax"; parm.segmax->type = TYPE_INTEGER; parm.segmax->answer = MAXSEGM; parm.segmax->required = NO; parm.segmax->description = _("Maximum number of points in a segment"); parm.segmax->guisection = _("Parameters"); parm.npmin = G_define_option(); parm.npmin->key = "npmin"; parm.npmin->type = TYPE_INTEGER; parm.npmin->answer = MINPOINTS; parm.npmin->required = NO; parm.npmin->description = _("Minimum number of points for approximation in a segment (>segmax)"); parm.npmin->guisection = _("Parameters"); parm.dmin = G_define_option(); parm.dmin->key = "dmin"; parm.dmin->type = TYPE_DOUBLE; parm.dmin->required = NO; parm.dmin->description = _("Minimum distance between points (to remove almost identical points)"); parm.dmin->guisection = _("Parameters"); parm.dmax = G_define_option(); parm.dmax->key = "dmax"; parm.dmax->type = TYPE_DOUBLE; parm.dmax->required = NO; parm.dmax->description = _("Maximum distance between points on isoline (to insert additional points)"); parm.dmax->guisection = _("Parameters"); parm.zmult = G_define_option(); parm.zmult->key = "zscale"; parm.zmult->type = TYPE_DOUBLE; parm.zmult->answer = ZMULT; parm.zmult->required = NO; parm.zmult->description = _("Conversion factor for values used for approximation"); parm.zmult->guisection = _("Parameters"); parm.theta = G_define_option(); parm.theta->key = "theta"; parm.theta->type = TYPE_DOUBLE; parm.theta->required = NO; parm.theta->description = _("Anisotropy angle (in degrees counterclockwise from East)"); parm.theta->guisection = _("Parameters"); parm.scalex = G_define_option(); parm.scalex->key = "scalex"; parm.scalex->type = TYPE_DOUBLE; parm.scalex->required = NO; parm.scalex->description = _("Anisotropy scaling factor"); parm.scalex->guisection = _("Parameters"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_get_set_window(&cellhd); ew_res = cellhd.ew_res; ns_res = cellhd.ns_res; n_cols = cellhd.cols; n_rows = cellhd.rows; x_orig = cellhd.west; y_orig = cellhd.south; xm = cellhd.east; ym = cellhd.north; if (ew_res < ns_res) dmin = ew_res / 2; else dmin = ns_res / 2; disk = n_rows * n_cols * sizeof(int); sdisk = n_rows * n_cols * sizeof(short int); sprintf(dmaxchar, "%f", dmin * 5); sprintf(dminchar, "%f", dmin); if (!parm.dmin->answer) { parm.dmin->answer = G_store(dminchar); parm.dmin->answers = (char **) G_malloc(2 * sizeof(char *)); parm.dmin->answers[0] = G_store(dminchar); parm.dmin->answers[1] = NULL; } if (!parm.dmax->answer) { parm.dmax->answer = G_store(dmaxchar); parm.dmax->answers = (char **) G_malloc(2 * sizeof(char *)); parm.dmax->answers[0] = G_store(dmaxchar); parm.dmax->answers[1] = NULL; } input = parm.input->answer; zcol = parm.zcol->answer; scol = parm.scol->answer; wheresql = parm.wheresql->answer; maskmap = parm.maskmap->answer; elev = parm.elev->answer; devi = parm.devi->answer; cvdev = parm.cvdev->answer; slope = parm.slope->answer; aspect = parm.aspect->answer; pcurv = parm.pcurv->answer; tcurv = parm.tcurv->answer; mcurv = parm.mcurv->answer; treefile = parm.treefile->answer; overfile = parm.overfile->answer; if (devi) { if (Vect_legal_filename(devi) == -1) G_fatal_error(_("Output vector map name <%s> is not valid map name"), devi); } if (cvdev) { if (Vect_legal_filename(cvdev) == -1) G_fatal_error(_("Output vector map name <%s> is not valid map name"), cvdev); } if (treefile) { if (Vect_legal_filename(treefile) == -1) G_fatal_error(_("Output vector map name <%s> is not valid map name"), treefile); } if (overfile) { if (Vect_legal_filename(overfile) == -1) G_fatal_error(_("Output vector map name <%s> is not valid map name"), overfile); } /* if (treefile) Vect_check_input_output_name(input, treefile, G_FATAL_EXIT); if (overfile) Vect_check_input_output_name(input, overfile, G_FATAL_EXIT); */ if ((elev == NULL) && (pcurv == NULL) && (tcurv == NULL) && (mcurv == NULL) && (slope == NULL) && (aspect == NULL) && (devi == NULL) && (cvdev == NULL)) G_warning(_("You are not outputting any raster or vector maps")); cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL)); cond1 = ((slope != NULL) || (aspect != NULL) || cond2); deriv = flag.deriv->answer; dtens = flag.cprght->answer; cv = flag.cv->answer; if ((cv && cvdev == NULL) || (!(cv) && cvdev != NULL)) G_fatal_error(_("Both cross-validation options (-c flag and cvdev vector output) must be specified")); if ((elev != NULL || cond1 || cond2 || devi != NULL) && cv) G_fatal_error(_("The cross-validation cannot be computed simultaneously with output raster or devi file")); ertre = 0.1; sscanf(parm.dmax->answer, "%lf", &dmax); sscanf(parm.dmin->answer, "%lf", &dmin); sscanf(parm.fi->answer, "%lf", &fi); sscanf(parm.segmax->answer, "%d", &KMAX); sscanf(parm.npmin->answer, "%d", &npmin); sscanf(parm.zmult->answer, "%lf", &zmult); /* if (fi=0.000000) G_fatal_error("Tension must be > 0.000000") */ if (parm.theta->answer) sscanf(parm.theta->answer, "%lf", &theta); if (parm.scalex->answer) { sscanf(parm.scalex->answer, "%lf", &scalex); if (!parm.theta->answer) G_fatal_error(_("Using anisotropy - both theta and scalex have to be specified")); } if (parm.rsm->answer) { sscanf(parm.rsm->answer, "%lf", &rsm); if (rsm < 0.0) G_fatal_error("Smoothing must be a positive value"); if (scol != NULL) G_warning(_("Both smatt and smooth options specified - using constant")); } else { sscanf(SMOOTH, "%lf", &rsm); if (scol != NULL) rsm = -1; /* used in InterpLib to indicate variable smoothing */ } if (npmin > MAXPOINTS - 50) { G_warning(_("The computation will last too long - lower npmin is suggested")); KMAX2 = 2 * npmin; /* was: KMAX2 = npmin + 50; */ } else KMAX2 = 2 * npmin; /* was: KMAX2 = MAXPOINTS; fixed by JH in 12/01 */ /* handling of KMAX2 in GRASS4 v.surf.rst if (npmin > MAXPOINTS - 50) KMAX2 = npmin + 50; else KMAX2 = MAXPOINTS; */ dmin = dmin * dmin; KMIN = npmin; az = G_alloc_vector(n_cols + 1); if (!az) { G_fatal_error(_("Not enough memory for %s"), "az"); } if (cond1) { adx = G_alloc_vector(n_cols + 1); if (!adx) { G_fatal_error(_("Not enough memory for %s"), "adx"); } ady = G_alloc_vector(n_cols + 1); if (!ady) { G_fatal_error(_("Not enough memory for %s"), "ady"); } if (cond2) { adxx = G_alloc_vector(n_cols + 1); if (!adxx) { G_fatal_error(_("Not enough memory for %s"), "adxx"); } adyy = G_alloc_vector(n_cols + 1); if (!adyy) { G_fatal_error(_("Not enough memory for %s"), "adyy"); } adxy = G_alloc_vector(n_cols + 1); if (!adxy) { G_fatal_error(_("Not enough memory for %s"), "adxy"); } } } if ((data = quad_data_new(x_orig, y_orig, xm, ym, n_rows, n_cols, 0, KMAX)) == NULL) G_fatal_error(_("Unable to create %s"), "quaddata"); if ((functions = MT_functions_new(quad_compare, quad_divide_data, quad_add_data, quad_intersect, quad_division_check, quad_get_points)) == NULL) G_fatal_error(_("Unable to create %s"), "quadfunc"); if ((tree = MT_tree_new(data, NULL, NULL, 0)) == NULL) G_fatal_error(_("Unable to create %s"), "tree"); root = tree; if ((info = MT_tree_info_new(root, functions, dmin, KMAX)) == NULL) G_fatal_error(_("Unable to create %s"), "tree info"); open_check = Vect_open_old2(&Map, input, "", parm.field->answer); if (open_check < 1) G_fatal_error(_("Unable to open vector map <%s>"), input); /* if (open_check < 2) G_fatal_error(_("You first need to run v.build on vector map <%s>"), input); */ /* get value used for approximation */ with_z = !parm.zcol->answer && Vect_is_3d(&Map); field = Vect_get_field_number(&Map, parm.field->answer); if (!with_z && field < 1) G_fatal_error(_("Layer <%s> not found"), parm.field->answer); if (Vect_is_3d(&Map)) { if (!with_z) G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation")); else G_verbose_message(_("Input is 3D: using z-coordinates for approximation")); } else { /* 2D */ if (parm.zcol->answer) G_verbose_message(_("Input is 2D: using attribute values for approximation")); else G_verbose_message(_("Input is 2D: using category values for approximation")); } /* we can't read the input file's timestamp as they don't exist in */ /* the new vector format. Even so, a TimeStamp structure is needed */ /* for IL_init_params_2d(), so we set it to NULL. */ /* If anyone is ever motivated to add it, the Plus_head struct has */ /* 'long coor_mtime' and dig_head has 'char *date; char *source_date;' */ /* which could be read in. */ if (devi != NULL || cvdev != NULL) { Pnts = Vect_new_line_struct(); Cats2 = Vect_new_cats_struct(); db_init_string(&sql2); if (devi != NULL) { if (Vect_open_new(&Map2, devi, 1) < 0) G_fatal_error(_("Unable to create vector map <%s>"), devi); } else { if (Vect_open_new(&Map2, cvdev, 1) < 0) G_fatal_error(_("Unable to create vector map <%s>"), cvdev); } Vect_hist_command(&Map2); ff = Vect_default_field_info(&Map2, 1, NULL, GV_1TABLE); Vect_map_add_dblink(&Map2, 1, NULL, ff->table, GV_KEY_COLUMN, ff->database, ff->driver); /* Create new table */ db_zero_string(&sql2); sprintf(buf, "create table %s ( ", ff->table); db_append_string(&sql2, buf); db_append_string(&sql2, "cat integer"); db_append_string(&sql2, ", flt1 double precision"); db_append_string(&sql2, ")"); G_debug(1, "%s", db_get_string(&sql2)); driver2 = db_start_driver_open_database(ff->driver, ff->database); if (driver2 == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), ff->database, ff->driver); db_set_error_handler_driver(driver2); if (db_execute_immediate(driver2, &sql2) != DB_OK) { G_fatal_error(_("Unable to create table '%s'"), db_get_string(&sql2)); } db_begin_transaction(driver2); count = 1; } ertot = 0.; create_temp_files(); IL_init_params_2d(¶ms, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, n_rows, n_cols, az, adx, ady, adxx, adyy, adxy, fi, KMAX2, SCIK1, SCIK2, SCIK3, rsm, elev, slope, aspect, pcurv, tcurv, mcurv, dmin, x_orig, y_orig, deriv, theta, scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx, Tmp_fd_yy, Tmp_fd_xy, devi, NULL, cv, parm.wheresql->answer); IL_init_func_2d(¶ms, IL_grid_calc_2d, IL_matrix_create, IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst, IL_crstg, IL_write_temp_2d); totsegm = IL_vector_input_data_2d(¶ms, &Map, with_z ? 0 : field, zcol, scol, info, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax, &NPOINT, &dmax); if (totsegm <= 0) { clean(); G_fatal_error(_("Input failed")); } /*Vect_set_release_support(&Map); */ Vect_close(&Map); if (treefile != NULL) { if (0 > Vect_open_new(&TreeMap, treefile, 0)) { clean(); G_fatal_error(_("Unable to open vector map <%s>"), treefile); } Vect_hist_command(&TreeMap); /* sprintf (TreeMap.head.your_name, "grass"); sprintf (TreeMap.head.map_name, "Quad tree for %s", input); TreeMap.head.orig_scale = 100000; TreeMap.head.plani_zone = G_zone (); */ print_tree(root, x_orig, y_orig, &TreeMap); Vect_build(&TreeMap); Vect_close(&TreeMap); } disk = disk + totsegm * sizeof(int) * 4; sdisk = sdisk + totsegm * sizeof(int) * 4; if (elev != NULL) ddisk += disk; if (slope != NULL) sddisk += sdisk; if (aspect != NULL) sddisk += sdisk; if (pcurv != NULL) ddisk += disk; if (tcurv != NULL) ddisk += disk; if (mcurv != NULL) ddisk += disk; ddisk += sddisk; G_verbose_message(_("Processing all selected output files " "will require %d bytes of disk space for temp files"), ddisk); deltx = xmax - xmin; delty = ymax - ymin; dnorm = sqrt((deltx * delty * KMIN) / NPOINT); if (dtens) { params.fi = params.fi * dnorm / 1000.; G_verbose_message("dnorm = %f, rescaled tension = %f", dnorm, params.fi); } bitmask = IL_create_bitmask(¶ms); if (totsegm <= 0) { clean(); G_fatal_error(_("Input failed")); } ertot = 0.; G_message(_("Processing segments...")); if (IL_interp_segments_2d(¶ms, info, info->root, bitmask, zmin, zmax, &zminac, &zmaxac, &gmin, &gmax, &c1min, &c1max, &c2min, &c2max, &ertot, totsegm, n_cols, dnorm) < 0) { clean(); G_fatal_error(_("Interp_segmets failed")); } G_free_vector(az); if (cond1) { G_free_vector(adx); G_free_vector(ady); if (cond2) { G_free_vector(adxx); G_free_vector(adyy); G_free_vector(adxy); } } ii = IL_output_2d(¶ms, &cellhd, zmin, zmax, zminac, zmaxac, c1min, c1max, c2min, c2max, gmin, gmax, ertot, input, dnorm, dtens, 1, NPOINT); if (ii < 0) { clean(); G_fatal_error(_("Unable to write raster maps - try to increase resolution")); } G_free(zero_array_cell); if (elev != NULL) fclose(Tmp_fd_z); if (slope != NULL) fclose(Tmp_fd_dx); if (aspect != NULL) fclose(Tmp_fd_dy); if (pcurv != NULL) fclose(Tmp_fd_xx); if (tcurv != NULL) fclose(Tmp_fd_yy); if (mcurv != NULL) fclose(Tmp_fd_xy); if (overfile != NULL) { if (0 > Vect_open_new(&OverMap, overfile, 0)) { clean(); G_fatal_error(_("Unable to create vector map <%s>"), overfile); } Vect_hist_command(&OverMap); /* sprintf (OverMap.head.your_name, "grass"); sprintf (OverMap.head.map_name, "Overlap segments for %s", input); OverMap.head.orig_scale = 100000; OverMap.head.plani_zone = G_zone (); */ print_tree(root, x_orig, y_orig, &OverMap); Vect_build(&OverMap); Vect_close(&OverMap); } if (elev != NULL) unlink(Tmp_file_z); if (slope != NULL) unlink(Tmp_file_dx); if (aspect != NULL) unlink(Tmp_file_dy); if (pcurv != NULL) unlink(Tmp_file_xx); if (tcurv != NULL) unlink(Tmp_file_yy); if (mcurv != NULL) unlink(Tmp_file_xy); if (cvdev != NULL || devi != NULL) { db_commit_transaction(driver2); db_close_database_shutdown_driver(driver2); Vect_build(&Map2); Vect_close(&Map2); } G_done_msg(" "); exit(EXIT_SUCCESS); }