static void load_input_raster3d_maps(struct Option *scalar_opt, struct Option *vector_opt, struct Gradient_info *gradient_info, RASTER3D_Region * region) { int i; if (scalar_opt->answer) { gradient_info->scalar_map = Rast3d_open_cell_old(scalar_opt->answer, G_find_raster3d(scalar_opt->answer, ""), region, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (!gradient_info->scalar_map) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), scalar_opt->answer); gradient_info->compute_gradient = TRUE; } else { for (i = 0; i < 3; i++) { gradient_info->velocity_maps[i] = Rast3d_open_cell_old(vector_opt->answers[i], G_find_raster3d(vector_opt->answers[i], ""), region, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (!gradient_info->velocity_maps[i]) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), vector_opt->answers[i]); } gradient_info->compute_gradient = FALSE; } }
static void check_vector_input_maps(struct Option *vector_opt, struct Option *seed_opt) { int i; /* Check for velocity components maps. */ if (vector_opt->answers != NULL) { for (i = 0; i < 3; i++) { if (vector_opt->answers[i] != NULL) { if (NULL == G_find_raster3d(vector_opt->answers[i], "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), vector_opt->answers[i]); } else { Rast3d_fatal_error(_("Please provide three 3D raster maps")); } } } if (seed_opt->answer != NULL) { if (NULL == G_find_vector2(seed_opt->answer, "")) G_fatal_error(_("Vector seed map <%s> not found"), seed_opt->answer); } }
void Rast3d_change_precision(void *map, int precision, const char *nameOut) { void *map2; int x, y, z, savePrecision, saveCompression; char *data; RASTER3D_Region region; int typeIntern; int nx, ny, nz; int tileXsave, tileYsave, tileZsave, tileX, tileY, tileZ, saveType; saveType = Rast3d_get_file_type(); /* Rast3d_set_file_type (Rast3d_file_type_map (map)); */ Rast3d_get_compression_mode(&saveCompression, &savePrecision); Rast3d_set_compression_mode(RASTER3D_COMPRESSION, precision); Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave); Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ); Rast3d_set_tile_dimension(tileX, tileY, tileZ); typeIntern = Rast3d_tile_type_map(map); Rast3d_get_region_struct_map(map, ®ion); map2 = Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_USE_CACHE_DEFAULT, ®ion); if (map2 == NULL) Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_open_cell_new"); Rast3d_set_file_type(saveType); Rast3d_set_compression_mode(saveCompression, savePrecision); Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave); data = Rast3d_alloc_tiles(map, 1); if (data == NULL) Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_alloc_tiles"); Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz); for (z = 0; z < nz; z++) for (y = 0; y < ny; y++) for (x = 0; x < nx; x++) { if (!Rast3d_read_tile(map, Rast3d_tile2tile_index(map, x, y, z), data, typeIntern)) Rast3d_fatal_error ("Rast3d_change_precision: error in Rast3d_read_tile"); if (!Rast3d_write_tile (map2, Rast3d_tile2tile_index(map2, x, y, z), data, typeIntern)) Rast3d_fatal_error ("Rast3d_change_precision: error in Rast3d_write_tile"); } Rast3d_free_tiles(data); if (!Rast3d_close(map2)) Rast3d_fatal_error("Rast3d_change_precision: error in Rast3d_close"); }
void Rast3d_set_tile_dimension(int tileX, int tileY, int tileZ) { if ((g3d_tile_dimension[0] = tileX) <= 0) Rast3d_fatal_error ("Rast3d_set_tile_dimension: value for tile x environment variable out of range"); if ((g3d_tile_dimension[1] = tileY) <= 0) Rast3d_fatal_error ("Rast3d_set_tile_dimension: value for tile y environment variable out of range"); if ((g3d_tile_dimension[2] = tileZ) <= 0) Rast3d_fatal_error ("Rast3d_set_tile_dimension: value for tile z environment variable out of range"); }
static void retileNocache(void *map, const char *nameOut, int tileX, int tileY, int tileZ) { void *map2; int x, y, z, saveType, nx, ny, nz; int typeIntern; void *data; int tileXsave, tileYsave, tileZsave; RASTER3D_Region region; saveType = Rast3d_get_file_type(); Rast3d_set_file_type(Rast3d_file_type_map(map)); Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave); Rast3d_set_tile_dimension(tileX, tileY, tileZ); typeIntern = Rast3d_tile_type_map(map); Rast3d_get_region_struct_map(map, ®ion); map2 = Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_NO_CACHE, ®ion); if (map2 == NULL) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_open_cell_new"); Rast3d_set_file_type(saveType); Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave); data = Rast3d_alloc_tiles(map2, 1); if (data == NULL) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_alloc_tiles"); Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz); for (z = 0; z < nz; z++) { G_percent(z, nz, 1); for (y = 0; y < ny; y++) for (x = 0; x < nx; x++) { Rast3d_get_block(map, x * tileX, y * tileY, z * tileZ, tileX, tileY, tileZ, data, typeIntern); if (!Rast3d_write_tile (map2, Rast3d_tile2tile_index(map2, x, y, z), data, typeIntern)) Rast3d_fatal_error ("Rast3d_retileNocache: error in Rast3d_write_tile"); } } G_percent(1, 1, 1); Rast3d_free_tiles(data); Rast3d_close(map2); }
void Rast3d_set_cache_size(int nTiles) { if (nTiles < 0) Rast3d_fatal_error("Rast3d_set_cache_size: size out of range."); g3d_cache_default = nTiles; }
void Rast3d_set_cache_limit(int nBytes) { if (nBytes <= 0) Rast3d_fatal_error("Rast3d_set_cache_limit: size out of range."); g3d_cache_max = nBytes; }
void Rast3d_set_file_type(int type) { if ((type != FCELL_TYPE) && (type != DCELL_TYPE)) Rast3d_fatal_error("Rast3d_setFileTypeDefault: invalid type"); g3d_file_type = type; }
/*---------------------------------------------------------------------------*/ void fatalError(char *errorMsg) { if (map != NULL) { /* should unopen map here! */ Rast3d_close(map); } Rast3d_fatal_error("%s", errorMsg); }
static void init_flowaccum(RASTER3D_Region * region, RASTER3D_Map * flowacc) { int c, r, d; for (d = 0; d < region->depths; d++) for (r = 0; r < region->rows; r++) for (c = 0; c < region->cols; c++) if (Rast3d_put_float(flowacc, c, r, d, 0) != 1) Rast3d_fatal_error(_("init_flowaccum: error in Rast3d_put_float")); }
/* ************************************************************************* */ void fatal_error(void *map, int *fd, int depths, char *errorMsg) { int i; /* Close files and exit */ if (map != NULL) { if (!Rast3d_close(map)) Rast3d_fatal_error(_("Unable to close 3D raster map")); } if (fd != NULL) { for (i = 0; i < depths; i++) Rast_unopen(fd[i]); } Rast3d_fatal_error("%s", errorMsg); exit(EXIT_FAILURE); }
int Rast3d_length(int t) { if (!RASTER3D_IS_CORRECT_TYPE(t)) Rast3d_fatal_error("Rast3d_length: invalid type"); if (t == FCELL_TYPE) return sizeof(FCELL); if (t == DCELL_TYPE) return sizeof(DCELL); return 0; }
int Rast3d_extern_length(int t) { if (!RASTER3D_IS_CORRECT_TYPE(t)) Rast3d_fatal_error("Rast3d_extern_length: invalid type"); if (t == FCELL_TYPE) return RASTER3D_XDR_FLOAT_LENGTH; if (t == DCELL_TYPE) return RASTER3D_XDR_DOUBLE_LENGTH; return 0; }
/* ************************************************************************* */ void fatal_error(void *map, int elevfd, int outfd, char *errorMsg) { /* Close files and exit */ if (map != NULL) { if (!Rast3d_close(map)) Rast3d_fatal_error(_("Unable to close 3D raster map")); } /*unopen the output map */ if (outfd != -1) Rast_unopen(outfd); if (elevfd != -1) close_output_map(elevfd); Rast3d_fatal_error("%s", errorMsg); exit(EXIT_FAILURE); }
static void getParams(char **name, d_Mask ** maskRules, int *changeNull, double *newNullVal) { *name = params.map->answer; Rast3d_parse_vallist(params.setNull->answers, maskRules); *changeNull = (params.null->answer != NULL); if (*changeNull) if (sscanf(params.null->answer, "%lf", newNullVal) != 1) Rast3d_fatal_error(_("Illegal value for null")); }
int Rast3d_write_tile(RASTER3D_Map * map, int tileIndex, const void *tile, int type) { int rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum; /* valid tileIndex ? */ if ((tileIndex >= map->nTiles) || (tileIndex < 0)) Rast3d_fatal_error("Rast3d_write_tile: tileIndex out of range"); /* already written ? */ if (map->index[tileIndex] != -1) return 2; /* save the file position */ map->index[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END); if (map->index[tileIndex] == -1) { Rast3d_error("Rast3d_write_tile: can't position file"); return 0; } nofNum = Rast3d_compute_clipped_tile_dimensions(map, tileIndex, &rows, &cols, &depths, &xRedundant, &yRedundant, &zRedundant); Rast3d_range_update_from_tile(map, tile, rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum, type); if (!Rast3d_tile2xdrTile(map, tile, rows, cols, depths, xRedundant, yRedundant, zRedundant, nofNum, type)) { Rast3d_error("Rast3d_writeTileCompressed: error in Rast3d_tile2xdrTile"); return 0; } if (map->compression == RASTER3D_NO_COMPRESSION) { if (!Rast3d_writeTileUncompressed(map, nofNum)) { Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileUncompressed"); return 0; } } else if (!Rast3d_writeTileCompressed(map, nofNum)) { Rast3d_error("Rast3d_write_tile: error in Rast3d_writeTileCompressed"); return 0; } /* compute the length */ map->tileLength[tileIndex] = lseek(map->data_fd, (long)0, SEEK_END) - map->index[tileIndex]; return 1; }
static void cache_queue_enqueue(RASTER3D_cache * c, int left, int index) { if (IS_IN_QUEUE_ELT(index)) Rast3d_fatal_error("cache_queue_enqueue: index already in queue"); if (c->first == -1) { if (left != c->last) Rast3d_fatal_error("cache_queue_enqueue: position out of range"); c->first = c->last = index; return; } if (left >= 0 && IS_NOT_IN_QUEUE_ELT(left)) Rast3d_fatal_error("cache_queue_enqueue: position not in queue"); if (left == -1) { c->next[index] = c->first; c->prev[c->first] = index; c->first = index; return; } c->prev[index] = left; if (c->next[left] == -1) { c->next[left] = index; c->last = index; return; } c->prev[c->next[left]] = index; c->next[index] = c->next[left]; c->next[left] = index; }
void Rast3d_set_compression_mode(int doCompress, int doLzw, int doRle, int precision) { if ((doCompress != RASTER3D_NO_COMPRESSION) && (doCompress != RASTER3D_COMPRESSION)) Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doCompress."); g3d_do_compression = doCompress; if (doCompress == RASTER3D_NO_COMPRESSION) return; if ((doLzw != RASTER3D_NO_LZW) && (doLzw != RASTER3D_USE_LZW)) Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doLzw."); if ((doRle != RASTER3D_NO_RLE) && (doRle != RASTER3D_USE_RLE)) Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for doRle."); if (precision < -1) Rast3d_fatal_error("Rast3d_set_compression_mode: wrong value for precision."); g3d_do_lzw_compression = doLzw; g3d_do_rle_compression = doRle; g3d_precision = precision; }
static void cache_queue_dequeue(RASTER3D_cache * c, int index) { if (IS_NOT_IN_QUEUE_ELT(index)) Rast3d_fatal_error("cache_queue_dequeue: index not in queue"); if (index == c->first) c->first = c->next[index]; if (index == c->last) c->last = c->prev[index]; if (c->next[index] != -1) c->prev[c->next[index]] = c->prev[index]; if (c->prev[index] != -1) c->next[c->prev[index]] = c->next[index]; c->next[index] = c->prev[index] = -1; }
int Rast3d_flush_tile_cube(RASTER3D_Map * map, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax) { int x, y, z; if (!map->useCache) Rast3d_fatal_error ("Rast3d_flush_tile_cube: function invalid in non-cache mode"); for (x = xMin; x <= xMax; x++) for (y = yMin; y <= yMax; y++) for (z = zMin; z <= zMax; z++) if (!Rast3d_flush_tile(map, Rast3d_tile2tile_index(map, x, y, z))) { Rast3d_error("Rast3d_flush_tile_cube: error in Rast3d_flush_tile"); return 0; } return 1; }
int Rast3d_read_ints(int fd, int useXdr, int *i, int nofNum) { char xdrIntBuf[RASTER3D_XDR_INT_LENGTH * 1024]; unsigned int n; if (nofNum <= 0) Rast3d_fatal_error("Rast3d_read_ints: nofNum out of range"); if (useXdr == RASTER3D_NO_XDR) { if (read(fd, i, sizeof(int) * nofNum) != sizeof(int) * nofNum) { Rast3d_error("Rast3d_read_ints: reading from file failed"); return 0; } else { return 1; } } do { int j; n = nofNum % 1024; if (n == 0) n = 1024; if (read(fd, xdrIntBuf, RASTER3D_XDR_INT_LENGTH * n) != RASTER3D_XDR_INT_LENGTH * n) { Rast3d_error("Rast3d_read_ints: reading xdr from file failed"); return 0; } for (j = 0; j < n; j++) G_xdr_get_int(i, &xdrIntBuf[RASTER3D_XDR_INT_LENGTH * j]); nofNum -= n; i += n; } while (nofNum); return 1; }
int Rast3d_write_ints(int fd, int useXdr, const int *i, int nofNum) { char xdrIntBuf[RASTER3D_XDR_INT_LENGTH * 1024]; unsigned int n; if (nofNum <= 0) Rast3d_fatal_error("Rast3d_write_ints: nofNum out of range"); if (useXdr == RASTER3D_NO_XDR) { if (write(fd, i, sizeof(int) * nofNum) != sizeof(int) * nofNum) { Rast3d_error("Rast3d_write_ints: writing to file failed"); return 0; } else { return 1; } } do { int j; n = nofNum % 1024; if (n == 0) n = 1024; for (j = 0; j < n; j++) G_xdr_put_int(&xdrIntBuf[RASTER3D_XDR_INT_LENGTH * j], i); if (write(fd, xdrIntBuf, RASTER3D_XDR_INT_LENGTH * n) != RASTER3D_XDR_INT_LENGTH * n) { Rast3d_error("Rast3d_write_ints: writing xdr to file failed"); return 0; } nofNum -= n; i += n; } while (nofNum); return 1; }
static void makeMask(char *name, d_Mask * maskRules) { void *map, *mask; RASTER3D_Region region; int tileX, tileY, tileZ, x, y, z, cacheSize; double value; float floatNull; cacheSize = Rast3d_cache_size_encode(RASTER3D_USE_CACHE_XY, 1); if (NULL == G_find_raster3d(name, "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), name); map = Rast3d_open_cell_old(name, G_mapset(), RASTER3D_DEFAULT_WINDOW, DCELL_TYPE, cacheSize); if (map == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), name); Rast3d_get_region_struct_map(map, ®ion); Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ); mask = Rast3d_open_new_param(Rast3d_mask_file(), FCELL_TYPE, cacheSize, ®ion, FCELL_TYPE, RASTER3D_COMPRESSION, 0, tileX, tileY, tileZ); if (mask == NULL) Rast3d_fatal_error(_("Unable to open 3D raster mask file")); Rast3d_min_unlocked(map, RASTER3D_USE_CACHE_X); Rast3d_autolock_on(map); Rast3d_unlock_all(map); Rast3d_min_unlocked(mask, RASTER3D_USE_CACHE_X); Rast3d_autolock_on(mask); Rast3d_unlock_all(mask); Rast3d_set_null_value(&floatNull, 1, FCELL_TYPE); for (z = 0; z < region.depths; z++) { if ((z % tileZ) == 0) { Rast3d_unlock_all(map); Rast3d_unlock_all(mask); } for (y = 0; y < region.rows; y++) /* We count from north to south in the cube coordinate system */ for (x = 0; x < region.cols; x++) { value = Rast3d_get_double_region(map, x, y, z); if (Rast3d_mask_d_select((DCELL *) & value, maskRules)) Rast3d_put_float(mask, x, y, z, (float)floatNull); /* mask-out value */ else Rast3d_put_float(mask, x, y, z, (float)0.0); /* not mask-out value */ } if ((z % tileZ) == 0) { if (!Rast3d_flush_tiles_in_cube (mask, 0, 0, MAX(0, z - tileZ), region.rows - 1, region.cols - 1, z)) Rast3d_fatal_error(_("makeMask: error flushing tiles in cube")); } } if (!Rast3d_flush_all_tiles(mask)) Rast3d_fatal_error(_("makeMask: error flushing all tiles")); Rast3d_autolock_off(map); Rast3d_unlock_all(map); Rast3d_autolock_off(mask); Rast3d_unlock_all(mask); if (!Rast3d_close(mask)) Rast3d_fatal_error(_("Unable to close 3D raster mask file")); if (!Rast3d_close(map)) Rast3d_fatal_error(_("Unable to close raster map <%s>"), name); }
/* ************************************************************************* */ int main(int argc, char *argv[]) { RASTER3D_Region region, inputmap_bounds; struct Cell_head region2d; struct GModule *module; struct History history; void *map = NULL; /*The 3D Rastermap */ int i = 0, changemask = 0; int *fd = NULL, output_type, cols, rows; char *RasterFileName; int overwrite = 0; /* Initialize GRASS */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("conversion")); G_add_keyword(_("raster")); G_add_keyword(_("voxel")); module->description = _("Converts 3D raster maps to 2D raster maps"); /* Get parameters from user */ set_params(); /* Have GRASS get inputs */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_debug(3, "Open 3D raster map <%s>", param.input->answer); if (NULL == G_find_raster3d(param.input->answer, "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), param.input->answer); /*Set the defaults */ Rast3d_init_defaults(); /*Set the resolution of the output maps */ if (param.res->answer) { /*Open the map with current region */ map = Rast3d_open_cell_old(param.input->answer, G_find_raster3d(param.input->answer, ""), RASTER3D_DEFAULT_WINDOW, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (map == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), param.input->answer); /*Get the region of the map */ Rast3d_get_region_struct_map(map, ®ion); /*set this region as current 3D window for map */ Rast3d_set_window_map(map, ®ion); /*Set the 2d region appropriate */ Rast3d_extract2d_region(®ion, ®ion2d); /*Make the new 2d region the default */ Rast_set_window(®ion2d); } else { /* Figure out the region from the map */ Rast3d_get_window(®ion); /*Open the 3d raster map */ map = Rast3d_open_cell_old(param.input->answer, G_find_raster3d(param.input->answer, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (map == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), param.input->answer); } /*Check if the g3d-region is equal to the 2D rows and cols */ rows = Rast_window_rows(); cols = Rast_window_cols(); /*If not equal, set the 3D window correct */ if (rows != region.rows || cols != region.cols) { G_message(_("The 2D and 3D region settings are different. " "Using the 2D window settings to adjust the 2D part of the 3D region.")); G_get_set_window(®ion2d); region.ns_res = region2d.ns_res; region.ew_res = region2d.ew_res; region.rows = region2d.rows; region.cols = region2d.cols; Rast3d_adjust_region(®ion); Rast3d_set_window_map(map, ®ion); } /* save the input map region for later use (history meta-data) */ Rast3d_get_region_struct_map(map, &inputmap_bounds); /*Get the output type */ output_type = Rast3d_file_type_map(map); /*prepare the filehandler */ fd = (int *) G_malloc(region.depths * sizeof (int)); if (fd == NULL) fatal_error(map, NULL, 0, _("Out of memory")); G_message(_("Creating %i raster maps"), region.depths); /*Loop over all output maps! open */ for (i = 0; i < region.depths; i++) { /*Create the outputmaps */ G_asprintf(&RasterFileName, "%s_%05d", param.output->answer, i + 1); G_message(_("Raster map %i Filename: %s"), i + 1, RasterFileName); overwrite = G_check_overwrite(argc, argv); if (G_find_raster2(RasterFileName, "") && !overwrite) G_fatal_error(_("Raster map %d Filename: %s already exists. Use the flag --o to overwrite."), i + 1, RasterFileName); if (output_type == FCELL_TYPE) fd[i] = open_output_map(RasterFileName, FCELL_TYPE); else if (output_type == DCELL_TYPE) fd[i] = open_output_map(RasterFileName, DCELL_TYPE); } /*if requested set the Mask on */ if (param.mask->answer) { if (Rast3d_mask_file_exists()) { changemask = 0; if (Rast3d_mask_is_off(map)) { Rast3d_mask_on(map); changemask = 1; } } } /*Create the Rastermaps */ g3d_to_raster(map, region, fd); /*Loop over all output maps! close */ for (i = 0; i < region.depths; i++) { close_output_map(fd[i]); /* write history */ G_asprintf(&RasterFileName, "%s_%i", param.output->answer, i + 1); G_debug(4, "Raster map %d Filename: %s", i + 1, RasterFileName); Rast_short_history(RasterFileName, "raster", &history); Rast_set_history(&history, HIST_DATSRC_1, "3D Raster map:"); Rast_set_history(&history, HIST_DATSRC_2, param.input->answer); Rast_append_format_history(&history, "Level %d of %d", i + 1, region.depths); Rast_append_format_history(&history, "Level z-range: %f to %f", region.bottom + (i * region.tb_res), region.bottom + (i + 1 * region.tb_res)); Rast_append_format_history(&history, "Input map full z-range: %f to %f", inputmap_bounds.bottom, inputmap_bounds.top); Rast_append_format_history(&history, "Input map z-resolution: %f", inputmap_bounds.tb_res); if (!param.res->answer) { Rast_append_format_history(&history, "GIS region full z-range: %f to %f", region.bottom, region.top); Rast_append_format_history(&history, "GIS region z-resolution: %f", region.tb_res); } Rast_command_history(&history); Rast_write_history(RasterFileName, &history); } /*We set the Mask off, if it was off before */ if (param.mask->answer) { if (Rast3d_mask_file_exists()) if (Rast3d_mask_is_on(map) && changemask) Rast3d_mask_off(map); } /*Cleaning */ if (RasterFileName) G_free(RasterFileName); if (fd) G_free(fd); /* Close files and exit */ if (!Rast3d_close(map)) fatal_error(map, NULL, 0, _("Unable to close 3D raster map")); map = NULL; return (EXIT_SUCCESS); }
/* ************************************************************************* */ void check_input_maps(void) { int i = 0; const char *mapset, *name; /*Check top and bottom if surface is requested */ if (param.structgrid->answer) { if (!param.top->answer || !param.bottom->answer) Rast3d_fatal_error(_("Specify top and bottom map")); mapset = NULL; name = NULL; name = param.top->answer; mapset = G_find_raster2(name, ""); if (mapset == NULL) { Rast3d_fatal_error(_("Top cell map <%s> not found"), param.top->answer); } mapset = NULL; name = NULL; name = param.bottom->answer; mapset = G_find_raster2(name, ""); if (mapset == NULL) { Rast3d_fatal_error(_("Bottom cell map <%s> not found"), param.bottom->answer); } } /*If input maps are provided, check them */ if (param.input->answers != NULL) { for (i = 0; param.input->answers[i] != NULL; i++) { if (NULL == G_find_raster3d(param.input->answers[i], "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), param.input->answers[i]); } } /*Check for rgb maps. */ if (param.rgbmaps->answers != NULL) { for (i = 0; i < 3; i++) { if (param.rgbmaps->answers[i] != NULL) { if (NULL == G_find_raster3d(param.rgbmaps->answers[i], "")) Rast3d_fatal_error(_("3D raster map RGB map <%s> not found"), param.rgbmaps->answers[i]); } else { Rast3d_fatal_error(_("Please provide three RGB 3D raster maps")); } } } /*Check for vector maps. */ if (param.vectormaps->answers != NULL) { for (i = 0; i < 3; i++) { if (param.vectormaps->answers[i] != NULL) { if (NULL == G_find_raster3d(param.vectormaps->answers[i], "")) Rast3d_fatal_error(_("3D vector map <%s> not found"), param.vectormaps->answers[i]); } else { Rast3d_fatal_error(_("Please provide three 3D raster maps for the xyz-vector maps [x,y,z]")); } } } if (param.input->answers == NULL && param.rgbmaps->answers == NULL && param.vectormaps->answers == NULL) { G_warning(_("No 3D raster data, RGB or xyz-vector maps are provided! Will only write the geometry.")); } return; }
int main(int argc, char **argv) { RASTER3D_Map *input; RASTER3D_Map *output; RASTER3D_Region region; struct GModule *module; stat_func *method_fn; double quantile; int x, y, z; /* Initialize GRASS */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("neighbor")); G_add_keyword(_("aggregation")); G_add_keyword(_("statistics")); G_add_keyword(_("filter")); module->description = _("Makes each voxel value a " "function of the values assigned to the voxels " "around it, and stores new voxel values in an output 3D raster map"); /* Get parameters from user */ set_params(); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (NULL == G_find_raster3d(param.input->answer, "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), param.input->answer); Rast3d_init_defaults(); Rast3d_get_window(®ion); nx = region.cols; ny = region.rows; nz = region.depths; /* Size fo the moving window */ x_size = atoi(param.window->answers[0]); y_size = atoi(param.window->answers[1]); z_size = atoi(param.window->answers[2]); /* Distances in all directions */ x_dist = x_size / 2; y_dist = y_size / 2; z_dist = z_size / 2; /* Maximum size of the buffer */ size = x_size * y_size * z_size; /* Set the computation method */ method_fn = menu[find_method(param.method->answer)].method; if (param.quantile->answer) quantile = atof(param.quantile->answer); else quantile = 0.0; input = Rast3d_open_cell_old(param.input->answer, G_find_raster3d(param.input->answer, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (input == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), param.input->answer); output = Rast3d_open_new_opt_tile_size(param.output->answer, RASTER3D_USE_CACHE_X, ®ion, DCELL_TYPE, 32); if (output == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), param.output->answer); Rast3d_min_unlocked(output, RASTER3D_USE_CACHE_X); Rast3d_autolock_on(output); Rast3d_unlock_all(output); DCELL *buff = NULL, value; buff = (DCELL *) calloc(size, sizeof(DCELL)); if (buff == NULL) Rast3d_fatal_error(_("Unable to allocate buffer")); for (z = 0; z < nz; z++) { for (y = 0; y < ny; y++) { for (x = 0; x < nx; x++) { /* Gather values in moving window */ int num = gather_values(input, buff, x, y, z); /* Compute the resulting value */ if (num > 0) (*method_fn) (&value, buff, num, &quantile); else Rast_set_d_null_value(&value, 1); /* Write the value */ Rast3d_put_double(output, x, y, z, value); } } } free(buff); if (!Rast3d_flush_all_tiles(output)) G_fatal_error(_("Error flushing tiles")); Rast3d_autolock_off(output); Rast3d_unlock_all(output); Rast3d_close(input); Rast3d_close(output); return 0; }
void Rast3d_retile(void *map, const char *nameOut, int tileX, int tileY, int tileZ) { void *map2; double value; int x, y, z, saveType; int rows, cols, depths, typeIntern; int xTile, yTile, zTile; int xOffs, yOffs, zOffs, prev; int tileXsave, tileYsave, tileZsave; RASTER3D_Region region; if (!Rast3d_tile_use_cache_map(map)) { retileNocache(map, nameOut, tileX, tileY, tileZ); return; } saveType = Rast3d_get_file_type(); Rast3d_set_file_type(Rast3d_file_type_map(map)); Rast3d_get_tile_dimension(&tileXsave, &tileYsave, &tileZsave); Rast3d_set_tile_dimension(tileX, tileY, tileZ); typeIntern = Rast3d_tile_type_map(map); Rast3d_get_region_struct_map(map, ®ion); map2 = Rast3d_open_cell_new(nameOut, typeIntern, RASTER3D_USE_CACHE_DEFAULT, ®ion); if (map2 == NULL) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_open_cell_new"); Rast3d_set_file_type(saveType); Rast3d_set_tile_dimension(tileXsave, tileYsave, tileZsave); Rast3d_coord2tile_coord(map2, 0, 0, 0, &xTile, &yTile, &zTile, &xOffs, &yOffs, &zOffs); prev = zTile; x = 0; y = 0; Rast3d_get_coords_map(map, &rows, &cols, &depths); for (z = 0; z < depths; z++) { G_percent(z, depths, 1); Rast3d_coord2tile_coord(map2, x, y, z, &xTile, &yTile, &zTile, &xOffs, &yOffs, &zOffs); if (zTile > prev) { if (!Rast3d_flush_all_tiles(map2)) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_flush_all_tiles"); prev++; } for (y = 0; y < rows; y++) for (x = 0; x < cols; x++) { Rast3d_get_value_region(map, x, y, z, &value, typeIntern); if (!Rast3d_put_value(map2, x, y, z, &value, typeIntern)) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_put_value"); } } G_percent(1, 1, 1); if (!Rast3d_flush_all_tiles(map2)) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_flush_all_tiles"); if (!Rast3d_close(map2)) Rast3d_fatal_error("Rast3d_retile: error in Rast3d_close"); }
/* ************************************************************************* */ int main(int argc, char *argv[]) { RASTER3D_Region region; struct Cell_head window2d; struct GModule *module; void *map = NULL; /*The 3D Rastermap */ int changemask = 0; int elevfd = -1, outfd = -1; /*file descriptors */ int output_type, cols, rows; /* Initialize GRASS */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("profile")); G_add_keyword(_("raster")); G_add_keyword(_("voxel")); module->description = _("Creates cross section 2D raster map from 3D raster map based on 2D elevation map"); /* Get parameters from user */ set_params(); /* Have GRASS get inputs */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_debug(3, "Open 3D raster map %s", param.input->answer); if (NULL == G_find_raster3d(param.input->answer, "")) Rast3d_fatal_error(_("3D raster map <%s> not found"), param.input->answer); /* Figure out the region from the map */ Rast3d_init_defaults(); Rast3d_get_window(®ion); /*Check if the g3d-region is equal to the 2d rows and cols */ rows = Rast_window_rows(); cols = Rast_window_cols(); /*If not equal, set the 2D windows correct */ if (rows != region.rows || cols != region.cols) { G_message (_("The 2D and 3D region settings are different. Using the 3D raster map settings to adjust the 2D region.")); G_get_set_window(&window2d); window2d.ns_res = region.ns_res; window2d.ew_res = region.ew_res; window2d.rows = region.rows; window2d.cols = region.cols; Rast_set_window(&window2d); } /*******************/ /*Open the 3d raster map */ /*******************/ map = Rast3d_open_cell_old(param.input->answer, G_find_raster3d(param.input->answer, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (map == NULL) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), param.input->answer); /*Get the output type */ output_type = Rast3d_file_type_map(map); if (output_type == FCELL_TYPE || output_type == DCELL_TYPE) { /********************************/ /*Open the elevation raster map */ /********************************/ elevfd = Rast_open_old(param.elevation->answer, ""); globalElevMapType = Rast_get_map_type(elevfd); /**********************/ /*Open the Outputmap */ /**********************/ if (G_find_raster2(param.output->answer, "")) G_message(_("Output map already exists. Will be overwritten!")); if (output_type == FCELL_TYPE) outfd = Rast_open_new(param.output->answer, FCELL_TYPE); else if (output_type == DCELL_TYPE) outfd = Rast_open_new(param.output->answer, DCELL_TYPE); /*if requested set the Mask on */ if (param.mask->answer) { if (Rast3d_mask_file_exists()) { changemask = 0; if (Rast3d_mask_is_off(map)) { Rast3d_mask_on(map); changemask = 1; } } } /************************/ /*Create the Rastermaps */ /************************/ rast3d_cross_section(map, region, elevfd, outfd); /*We set the Mask off, if it was off before */ if (param.mask->answer) { if (Rast3d_mask_file_exists()) if (Rast3d_mask_is_on(map) && changemask) Rast3d_mask_off(map); } Rast_close(outfd); Rast_close(elevfd); } else { fatal_error(map, -1, -1, _("Wrong 3D raster datatype! Cannot create raster map")); } /* Close files and exit */ if (!Rast3d_close(map)) Rast3d_fatal_error(_("Unable to close 3D raster map <%s>"), param.input->answer); return (EXIT_SUCCESS); }
void *Rast3d_open_cell_old(const char *name, const char *mapset, RASTER3D_Region * window, int typeIntern, int cache) { RASTER3D_Map *map; int proj, zone; int compression, useRle, useLzw, type, tileX, tileY, tileZ; int rows, cols, depths, precision; double ew_res, ns_res, tb_res; int nofHeaderBytes, dataOffset, useXdr, hasIndex; char *ltmp, *unit; double north, south, east, west, top, bottom; map = Rast3d_open_cell_old_no_header(name, mapset); if (map == NULL) { Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_open_cell_old_no_header")); return (void *)NULL; } if (lseek(map->data_fd, (long)0, SEEK_SET) == -1) { Rast3d_error(_("Rast3d_open_cell_old: can't rewind file")); return (void *)NULL; } if (!Rast3d_read_header(map, &proj, &zone, &north, &south, &east, &west, &top, &bottom, &rows, &cols, &depths, &ew_res, &ns_res, &tb_res, &tileX, &tileY, &tileZ, &type, &compression, &useRle, &useLzw, &precision, &dataOffset, &useXdr, &hasIndex, &unit)) { Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_read_header")); return 0; } if (window == RASTER3D_DEFAULT_WINDOW) window = Rast3d_window_ptr(); if (proj != window->proj) { Rast3d_error(_("Rast3d_open_cell_old: projection does not match window projection")); return (void *)NULL; } if (zone != window->zone) { Rast3d_error(_("Rast3d_open_cell_old: zone does not match window zone")); return (void *)NULL; } map->useXdr = useXdr; if (hasIndex) { /* see RASTER3D_openCell_new () for format of header */ if ((!Rast3d_read_ints(map->data_fd, map->useXdr, &(map->indexLongNbytes), 1)) || (!Rast3d_read_ints(map->data_fd, map->useXdr, &(map->indexNbytesUsed), 1))) { Rast3d_error(_("Rast3d_open_cell_old: can't read header")); return (void *)NULL; } /* if our long is to short to store offsets we can't read the file */ if (map->indexNbytesUsed > sizeof(long)) Rast3d_fatal_error(_("Rast3d_open_cell_old: index does not fit into long")); ltmp = Rast3d_malloc(map->indexLongNbytes); if (ltmp == NULL) { Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_malloc")); return (void *)NULL; } /* convert file long to long */ if (read(map->data_fd, ltmp, map->indexLongNbytes) != map->indexLongNbytes) { Rast3d_error(_("Rast3d_open_cell_old: can't read header")); return (void *)NULL; } Rast3d_long_decode(ltmp, &(map->indexOffset), 1, map->indexLongNbytes); Rast3d_free(ltmp); } nofHeaderBytes = dataOffset; if (typeIntern == RASTER3D_TILE_SAME_AS_FILE) typeIntern = type; if (!Rast3d_fill_header(map, RASTER3D_READ_DATA, compression, useRle, useLzw, type, precision, cache, hasIndex, map->useXdr, typeIntern, nofHeaderBytes, tileX, tileY, tileZ, proj, zone, north, south, east, west, top, bottom, rows, cols, depths, ew_res, ns_res, tb_res, unit)) { Rast3d_error(_("Rast3d_open_cell_old: error in Rast3d_fill_header")); return (void *)NULL; } Rast3d_region_copy(&(map->window), window); Rast3d_adjust_region(&(map->window)); Rast3d_get_nearest_neighbor_fun_ptr(&(map->resampleFun)); return map; }
int main(int argc, char *argv[]) { struct Option *vector_opt, *seed_opt, *flowlines_opt, *flowacc_opt, *sampled_opt, *scalar_opt, *unit_opt, *step_opt, *limit_opt, *skip_opt, *dir_opt, *error_opt; struct Flag *table_fl; struct GModule *module; RASTER3D_Region region; RASTER3D_Map *flowacc, *sampled; struct Integration integration; struct Seed seed; struct Gradient_info gradient_info; struct Map_info seed_Map; struct line_pnts *seed_points; struct line_cats *seed_cats; struct Map_info fl_map; struct line_cats *fl_cats; /* for flowlines */ struct line_pnts *fl_points; /* for flowlines */ struct field_info *finfo; dbDriver *driver; int cat; /* cat of flowlines */ int if_table; int i, r, c, d; char *desc; int n_seeds, seed_count, ltype; int skip[3]; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("hydrology")); G_add_keyword(_("voxel")); module->description = _("Computes 3D flow lines and 3D flow accumulation."); scalar_opt = G_define_standard_option(G_OPT_R3_INPUT); scalar_opt->required = NO; scalar_opt->guisection = _("Input"); vector_opt = G_define_standard_option(G_OPT_R3_INPUTS); vector_opt->key = "vector_field"; vector_opt->required = NO; vector_opt->description = _("Names of three 3D raster maps describing " "x, y, z components of vector field"); vector_opt->guisection = _("Input"); seed_opt = G_define_standard_option(G_OPT_V_INPUT); seed_opt->required = NO; seed_opt->key = "seed_points"; seed_opt->description = _("If no map is provided, " "flow lines are generated " "from each cell of the input 3D raster"); seed_opt->label = _("Name of vector map with points " "from which flow lines are generated"); seed_opt->guisection = _("Input"); flowlines_opt = G_define_standard_option(G_OPT_V_OUTPUT); flowlines_opt->key = "flowline"; flowlines_opt->required = NO; flowlines_opt->description = _("Name for vector map of flow lines"); flowlines_opt->guisection = _("Output"); flowacc_opt = G_define_standard_option(G_OPT_R3_OUTPUT); flowacc_opt->key = "flowaccumulation"; flowacc_opt->required = NO; flowacc_opt->description = _("Name for output flowaccumulation 3D raster"); flowacc_opt->guisection = _("Output"); sampled_opt = G_define_standard_option(G_OPT_R3_INPUT); sampled_opt->key = "sampled"; sampled_opt->required = NO; sampled_opt->label = _("Name for 3D raster sampled by flowlines"); sampled_opt->description = _("Values of this 3D raster will be stored " "as attributes of flowlines segments"); unit_opt = G_define_option(); unit_opt->key = "unit"; unit_opt->type = TYPE_STRING; unit_opt->required = NO; unit_opt->answer = "cell"; unit_opt->options = "time,length,cell"; desc = NULL; G_asprintf(&desc, "time;%s;" "length;%s;" "cell;%s", _("elapsed time"), _("length in map units"), _("length in cells (voxels)")); unit_opt->descriptions = desc; unit_opt->label = _("Unit of integration step"); unit_opt->description = _("Default unit is cell"); unit_opt->guisection = _("Integration"); step_opt = G_define_option(); step_opt->key = "step"; step_opt->type = TYPE_DOUBLE; step_opt->required = NO; step_opt->answer = "0.25"; step_opt->label = _("Integration step in selected unit"); step_opt->description = _("Default step is 0.25 cell"); step_opt->guisection = _("Integration"); limit_opt = G_define_option(); limit_opt->key = "limit"; limit_opt->type = TYPE_INTEGER; limit_opt->required = NO; limit_opt->answer = "2000"; limit_opt->description = _("Maximum number of steps"); limit_opt->guisection = _("Integration"); error_opt = G_define_option(); error_opt->key = "max_error"; error_opt->type = TYPE_DOUBLE; error_opt->required = NO; error_opt->answer = "1e-5"; error_opt->label = _("Maximum error of integration"); error_opt->description = _("Influences step, increase maximum error " "to allow bigger steps"); error_opt->guisection = _("Integration"); skip_opt = G_define_option(); skip_opt->key = "skip"; skip_opt->type = TYPE_INTEGER; skip_opt->required = NO; skip_opt->multiple = YES; skip_opt->description = _("Number of cells between flow lines in x, y and z direction"); dir_opt = G_define_option(); dir_opt->key = "direction"; dir_opt->type = TYPE_STRING; dir_opt->required = NO; dir_opt->multiple = NO; dir_opt->options = "up,down,both"; dir_opt->answer = "down"; dir_opt->description = _("Compute flowlines upstream, " "downstream or in both direction."); table_fl = G_define_flag(); table_fl->key = 'a'; table_fl->description = _("Create and fill attribute table"); G_option_required(scalar_opt, vector_opt, NULL); G_option_exclusive(scalar_opt, vector_opt, NULL); G_option_required(flowlines_opt, flowacc_opt, NULL); G_option_requires(seed_opt, flowlines_opt, NULL); G_option_requires(table_fl, flowlines_opt, NULL); G_option_requires(sampled_opt, table_fl, NULL); if (G_parser(argc, argv)) exit(EXIT_FAILURE); driver = NULL; finfo = NULL; if_table = table_fl->answer ? TRUE : FALSE; check_vector_input_maps(vector_opt, seed_opt); Rast3d_init_defaults(); Rast3d_get_window(®ion); /* set up integration variables */ if (step_opt->answer) { integration.step = atof(step_opt->answer); integration.unit = unit_opt->answer; } else { integration.unit = "cell"; integration.step = 0.25; } integration.max_error = atof(error_opt->answer); integration.max_step = 5 * integration.step; integration.min_step = integration.step / 5; integration.limit = atof(limit_opt->answer); if (strcmp(dir_opt->answer, "up") == 0) integration.direction_type = FLOWDIR_UP; else if (strcmp(dir_opt->answer, "down") == 0) integration.direction_type = FLOWDIR_DOWN; else integration.direction_type = FLOWDIR_BOTH; /* cell size is the diagonal */ integration.cell_size = sqrt(region.ns_res * region.ns_res + region.ew_res * region.ew_res + region.tb_res * region.tb_res); /* set default skip if needed */ if (skip_opt->answers) { for (i = 0; i < 3; i++) { if (skip_opt->answers[i] != NULL) { skip[i] = atoi(skip_opt->answers[i]); } else { G_fatal_error(_("Please provide 3 integer values for skip option.")); } } } else { skip[0] = fmax(1, region.cols / 10); skip[1] = fmax(1, region.rows / 10); skip[2] = fmax(1, region.depths / 10); } /* open raster 3D maps of velocity components */ gradient_info.initialized = FALSE; load_input_raster3d_maps(scalar_opt, vector_opt, &gradient_info, ®ion); /* open new 3D raster map of flowacumulation */ if (flowacc_opt->answer) { flowacc = Rast3d_open_new_opt_tile_size(flowacc_opt->answer, RASTER3D_USE_CACHE_DEFAULT, ®ion, FCELL_TYPE, 32); if (!flowacc) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), flowacc_opt->answer); init_flowaccum(®ion, flowacc); } /* open 3D raster map used for sampling */ if (sampled_opt->answer) { sampled = Rast3d_open_cell_old(sampled_opt->answer, G_find_raster3d(sampled_opt->answer, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (!sampled) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), sampled_opt->answer); } else sampled = NULL; /* open new vector map of flowlines */ if (flowlines_opt->answer) { fl_cats = Vect_new_cats_struct(); fl_points = Vect_new_line_struct(); if (Vect_open_new(&fl_map, flowlines_opt->answer, TRUE) < 0) G_fatal_error(_("Unable to create vector map <%s>"), flowlines_opt->answer); Vect_hist_command(&fl_map); if (if_table) { create_table(&fl_map, &finfo, &driver, gradient_info.compute_gradient, sampled ? 1 : 0); } } n_seeds = 0; /* open vector map of seeds */ if (seed_opt->answer) { if (Vect_open_old2(&seed_Map, seed_opt->answer, "", "1") < 0) G_fatal_error(_("Unable to open vector map <%s>"), seed_opt->answer); if (!Vect_is_3d(&seed_Map)) G_fatal_error(_("Vector map <%s> is not 3D"), seed_opt->answer); n_seeds = Vect_get_num_primitives(&seed_Map, GV_POINT); } if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) { if (flowacc_opt->answer) n_seeds += region.cols * region.rows * region.depths; else { n_seeds += ceil(region.cols / (double)skip[0]) * ceil(region.rows / (double)skip[1]) * ceil(region.depths / (double)skip[2]); } } G_debug(1, "Number of seeds is %d", n_seeds); seed_count = 0; cat = 1; if (seed_opt->answer) { seed_points = Vect_new_line_struct(); seed_cats = Vect_new_cats_struct(); /* compute flowlines from vector seed map */ while (TRUE) { ltype = Vect_read_next_line(&seed_Map, seed_points, seed_cats); if (ltype == -1) { Vect_close(&seed_Map); G_fatal_error(_("Error during reading seed vector map")); } else if (ltype == -2) { break; } else if (ltype == GV_POINT) { seed.x = seed_points->x[0]; seed.y = seed_points->y[0]; seed.z = seed_points->z[0]; seed.flowline = TRUE; seed.flowaccum = FALSE; } G_percent(seed_count, n_seeds, 1); if (integration.direction_type == FLOWDIR_UP || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_UP; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } if (integration.direction_type == FLOWDIR_DOWN || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_DOWN; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } seed_count++; } Vect_destroy_line_struct(seed_points); Vect_destroy_cats_struct(seed_cats); Vect_close(&seed_Map); } if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) { /* compute flowlines from points on grid */ for (r = region.rows; r > 0; r--) { for (c = 0; c < region.cols; c++) { for (d = 0; d < region.depths; d++) { seed.x = region.west + c * region.ew_res + region.ew_res / 2; seed.y = region.south + r * region.ns_res - region.ns_res / 2; seed.z = region.bottom + d * region.tb_res + region.tb_res / 2; seed.flowline = FALSE; seed.flowaccum = FALSE; if (flowacc_opt->answer) seed.flowaccum = TRUE; if (flowlines_opt->answer && !seed_opt->answer && (c % skip[0] == 0) && (r % skip[1] == 0) && (d % skip[2] == 0)) seed.flowline = TRUE; if (seed.flowaccum || seed.flowline) { G_percent(seed_count, n_seeds, 1); if (integration.direction_type == FLOWDIR_UP || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_UP; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } if (integration.direction_type == FLOWDIR_DOWN || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_DOWN; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } seed_count++; } } } } } G_percent(1, 1, 1); if (flowlines_opt->answer) { if (if_table) { db_commit_transaction(driver); db_close_database_shutdown_driver(driver); } Vect_destroy_line_struct(fl_points); Vect_destroy_cats_struct(fl_cats); Vect_build(&fl_map); Vect_close(&fl_map); } if (flowacc_opt->answer) Rast3d_close(flowacc); return EXIT_SUCCESS; }