/**************************************************************************** * * MODULE: r.basins.fill * * AUTHOR(S): Dale White - Dept. of Geography, Pennsylvania State U. * Larry Band - Dept. of Geography, University of Toronto * * PURPOSE: Generates a raster map layer showing watershed subbasins. * * COPYRIGHT: (C) 2005, 2010 by the GRASS Development Team * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * ****************************************************************************/ /*====================================================================*/ /* program to propagate the link label into the hillslope areas; */ /* processes CELL files only and works on window derived from link */ /* label map */ /*====================================================================*/ #include #include #include #include #include #include #include "local_proto.h" #define NOMASK 1 int main(int argc, char *argv[]) { int partfd; int nrows, ncols; const char *drain_name; const char *ridge_name; const char *part_name; CELL *drain, *ridge; struct Cell_head window; int row, col, npass, tpass; struct GModule *module; struct Option *num_opt, *drain_opt, *ridge_opt, *part_opt; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("hydrology")); G_add_keyword(_("watershed")); module->description = _("Generates watershed subbasins raster map."); drain_opt = G_define_standard_option(G_OPT_R_INPUT); drain_opt->key = "cnetwork"; drain_opt->description = _("Name of input coded stream network raster map"); ridge_opt = G_define_standard_option(G_OPT_R_INPUT); ridge_opt->key = "tnetwork"; ridge_opt->description = _("Name of input thinned ridge network raster map"); part_opt = G_define_standard_option(G_OPT_R_OUTPUT); num_opt = G_define_option(); num_opt->key = "number"; num_opt->type = TYPE_INTEGER; num_opt->required = YES; num_opt->description = _("Number of passes through the dataset"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); sscanf(num_opt->answer, "%d", &tpass); drain_name = drain_opt->answer; /* this isn't a nice thing to do. Rast_align_window() should be used first */ Rast_get_cellhd(drain_name, "", &window); Rast_set_window(&window); nrows = Rast_window_rows(); ncols = Rast_window_cols(); ridge_name = ridge_opt->answer; part_name = part_opt->answer; drain = read_map(drain_name, NOMASK, nrows, ncols); ridge = read_map(ridge_name, NOMASK, nrows, ncols); partfd = Rast_open_c_new(part_name); /* run through file and set streams to zero at locations where ridges exist */ for (row = 0; row < nrows; row++) { for (col = 0; col < ncols; col++) if (ridge[row * ncols + col] != 0) drain[row * ncols + col] = 0; } for (npass = 1; npass <= tpass; npass++) { for (row = 1; row < nrows - 1; row++) { for (col = 1; col < ncols - 1; col++) { if (drain[row * ncols + col] == 0 && ridge[row * ncols + col] == 0) { if (drain[(row - 1) * ncols + col] != 0 && ridge[(row - 1) * ncols + col] == 0) drain[row * ncols + col] = drain[(row - 1) * ncols + col]; if (drain[row * ncols + (col - 1)] != 0 && ridge[row * ncols + (col - 1)] == 0) drain[row * ncols + col] = drain[row * ncols + (col - 1)]; } } } G_message(_("Forward sweep complete")); for (row = nrows - 3; row > 1; --row) { for (col = ncols - 3; col > 1; --col) { if (drain[row * ncols + col] == 0 && ridge[row * ncols + col] == 0) { if (drain[(row + 1) * ncols + col] != 0 && ridge[(row + 1) * ncols + col] == 0) drain[row * ncols + col] = drain[(row + 1) * ncols + col]; if (drain[row * ncols + (col + 1)] != 0 && ridge[row * ncols + (col + 1)] == 0) drain[row * ncols + col] = drain[row * ncols + (col + 1)]; } } } G_message(_("Reverse sweep complete")); } /* write out partitioned watershed map */ for (row = 0; row < nrows; row++) Rast_put_row(partfd, drain + (row * ncols), CELL_TYPE); G_message(_("Creating support files for <%s>..."), part_name); Rast_close(partfd); exit(EXIT_SUCCESS); }