void backtrace(int start, int nbasins, struct links list[]) { int i; for (i = 1; i <= nbasins; i += 1) { if (list[i].next == start && list[i].trace == 0) { list[i].trace = start; if (get_max(list[start].pp, list[i].pp) == list[start].pp) memcpy(list[i].pp, list[start].pp, bpe()); backtrace(i, nbasins, list); } } }
static void thrd_func(E32Rofs* rofs){ CBytePair bpe(gFastCompress); bool deferred = false; TPlacingSection* p = rofs->GetFileNode(deferred); while(p) { if(!deferred) p->len = p->node->PlaceFile(p->buf, (TUint32)-1, 0, &bpe); p = rofs->GetFileNode(deferred); } rofs->ArriveDeferPoint(); p = rofs->GetDeferredJob(); while(p) { p->len = p->node->PlaceFile(p->buf, (TUint32)-1, 0, &bpe); p = rofs->GetDeferredJob(); } }
int main(int argc, char **argv) { int fe, fd, fm; int i, j, type; int new_id; int nrows, ncols, nbasins; int map_id, dir_id, bas_id; char map_name[GNAME_MAX], new_map_name[GNAME_MAX]; const char *tempfile1, *tempfile2, *tempfile3; char dir_name[GNAME_MAX]; char bas_name[GNAME_MAX]; struct Cell_head window; struct GModule *module; struct Option *opt1, *opt2, *opt3, *opt4, *opt5; struct Flag *flag1; int in_type, bufsz; void *in_buf; CELL *out_buf; struct band3 bnd, bndC; /* Initialize the GRASS environment variables */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster")); G_add_keyword(_("hydrology")); module->description = _("Filters and generates a depressionless elevation map and a " "flow direction map from a given elevation raster map."); opt1 = G_define_standard_option(G_OPT_R_ELEV); opt2 = G_define_standard_option(G_OPT_R_OUTPUT); opt2->key = "depressionless"; opt2->description = _("Name for output depressionless elevation raster map"); opt4 = G_define_standard_option(G_OPT_R_OUTPUT); opt4->key = "direction"; opt4->description = _("Name for output flow direction map for depressionless elevation raster map"); opt5 = G_define_standard_option(G_OPT_R_OUTPUT); opt5->key = "areas"; opt5->required = NO; opt5->description = _("Name for output raster map of problem areas"); opt3 = G_define_option(); opt3->key = "type"; opt3->type = TYPE_STRING; opt3->required = NO; opt3->description = _("Aspect direction format"); opt3->options = "agnps,answers,grass"; opt3->answer = "grass"; flag1 = G_define_flag(); flag1->key = 'f'; flag1->description = _("Find unresolved areas only"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (flag1->answer && opt5->answer == NULL) { G_fatal_error(_("The '%c' flag requires '%s'to be specified"), flag1->key, opt5->key); } type = 0; strcpy(map_name, opt1->answer); strcpy(new_map_name, opt2->answer); strcpy(dir_name, opt4->answer); if (opt5->answer != NULL) strcpy(bas_name, opt5->answer); if (strcmp(opt3->answer, "agnps") == 0) type = 1; else if (strcmp(opt3->answer, "answers") == 0) type = 2; else if (strcmp(opt3->answer, "grass") == 0) type = 3; G_debug(1, "output type (1=AGNPS, 2=ANSWERS, 3=GRASS): %d", type); if (type == 3) G_verbose_message(_("Direction map is D8 resolution, i.e. 45 degrees")); /* open the maps and get their file id */ map_id = Rast_open_old(map_name, ""); /* allocate cell buf for the map layer */ in_type = Rast_get_map_type(map_id); /* set the pointers for multi-typed functions */ set_func_pointers(in_type); /* get the window information */ G_get_window(&window); nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* buffers for internal use */ bndC.ns = ncols; bndC.sz = sizeof(CELL) * ncols; bndC.b[0] = G_calloc(ncols, sizeof(CELL)); bndC.b[1] = G_calloc(ncols, sizeof(CELL)); bndC.b[2] = G_calloc(ncols, sizeof(CELL)); /* buffers for external use */ bnd.ns = ncols; bnd.sz = ncols * bpe(); bnd.b[0] = G_calloc(ncols, bpe()); bnd.b[1] = G_calloc(ncols, bpe()); bnd.b[2] = G_calloc(ncols, bpe()); in_buf = get_buf(); tempfile1 = G_tempfile(); tempfile2 = G_tempfile(); tempfile3 = G_tempfile(); fe = open(tempfile1, O_RDWR | O_CREAT, 0666); /* elev */ fd = open(tempfile2, O_RDWR | O_CREAT, 0666); /* dirn */ fm = open(tempfile3, O_RDWR | O_CREAT, 0666); /* problems */ G_message(_("Reading elevation map...")); for (i = 0; i < nrows; i++) { G_percent(i, nrows, 2); get_row(map_id, in_buf, i); write(fe, in_buf, bnd.sz); } G_percent(1, 1, 1); Rast_close(map_id); /* fill single-cell holes and take a first stab at flow directions */ G_message(_("Filling sinks...")); filldir(fe, fd, nrows, &bnd); /* determine flow directions for ambiguous cases */ G_message(_("Determining flow directions for ambiguous cases...")); resolve(fd, nrows, &bndC); /* mark and count the sinks in each internally drained basin */ nbasins = dopolys(fd, fm, nrows, ncols); if (flag1->answer) { /* determine the watershed for each sink */ wtrshed(fm, fd, nrows, ncols, 4); /* fill all of the watersheds up to the elevation necessary for drainage */ ppupdate(fe, fm, nrows, nbasins, &bnd, &bndC); /* repeat the first three steps to get the final directions */ G_message(_("Repeat to get the final directions...")); filldir(fe, fd, nrows, &bnd); resolve(fd, nrows, &bndC); nbasins = dopolys(fd, fm, nrows, ncols); } G_free(bndC.b[0]); G_free(bndC.b[1]); G_free(bndC.b[2]); G_free(bnd.b[0]); G_free(bnd.b[1]); G_free(bnd.b[2]); out_buf = Rast_allocate_c_buf(); bufsz = ncols * sizeof(CELL); lseek(fe, 0, SEEK_SET); new_id = Rast_open_new(new_map_name, in_type); lseek(fd, 0, SEEK_SET); dir_id = Rast_open_new(dir_name, CELL_TYPE); if (opt5->answer != NULL) { lseek(fm, 0, SEEK_SET); bas_id = Rast_open_new(bas_name, CELL_TYPE); for (i = 0; i < nrows; i++) { read(fm, out_buf, bufsz); Rast_put_row(bas_id, out_buf, CELL_TYPE); } Rast_close(bas_id); close(fm); } for (i = 0; i < nrows; i++) { read(fe, in_buf, bnd.sz); put_row(new_id, in_buf); read(fd, out_buf, bufsz); for (j = 0; j < ncols; j += 1) out_buf[j] = dir_type(type, out_buf[j]); Rast_put_row(dir_id, out_buf, CELL_TYPE); } Rast_close(new_id); close(fe); Rast_close(dir_id); close(fd); G_free(in_buf); G_free(out_buf); exit(EXIT_SUCCESS); }
void ppupdate(int fe, int fb, int nl, int nbasins, struct band3 *elev, struct band3 *basins) { int i, j, ii, n; CELL *here; CELL that_basin; void *barrier_height; void *this_elev; void *that_elev; struct links *list; list = G_malloc((nbasins + 1) * sizeof(struct links)); for (i = 1; i <= nbasins; i += 1) { list[i].next = -1; list[i].pp = G_malloc(bpe()); set_max(list[i].pp); list[i].next_alt = -1; list[i].pp_alt = G_malloc(bpe()); set_max(list[i].pp_alt); list[i].trace = 0; } lseek(fe, 0, SEEK_SET); lseek(fb, 0, SEEK_SET); advance_band3(fb, basins); advance_band3(fb, basins); advance_band3(fe, elev); advance_band3(fe, elev); for (i = 1; i < nl - 1; i += 1) { advance_band3(fb, basins); advance_band3(fe, elev); for (j = 1; j < basins->ns - 1; j += 1) { /* check to see if the cell is non-null and in a basin */ here = (CELL *) basins->b[1] + j; if (G_is_c_null_value(here) || *here < 0) continue; ii = *here; this_elev = elev->b[1] + j * bpe(); /* check each adjoining cell; see if we're on a boundary. */ for (n = 0; n < 8; n += 1) { switch (n) { case 0: that_basin = *((CELL *) basins->b[0] + j + 1); that_elev = elev->b[0] + (j + 1) * bpe(); break; case 1: that_basin = *((CELL *) basins->b[1] + j + 1); that_elev = elev->b[1] + (j + 1) * bpe(); break; case 2: that_basin = *((CELL *) basins->b[2] + j + 1); that_elev = elev->b[2] + (j + 1) * bpe(); break; case 3: that_basin = *((CELL *) basins->b[2] + j); that_elev = elev->b[2] + j * bpe(); break; case 4: that_basin = *((CELL *) basins->b[2] + j - 1); that_elev = elev->b[2] + (j - 1) * bpe(); break; case 5: that_basin = *((CELL *) basins->b[1] + j - 1); that_elev = elev->b[1] + (j - 1) * bpe(); break; case 6: that_basin = *((CELL *) basins->b[0] + j - 1); that_elev = elev->b[0] + (j - 1) * bpe(); break; case 7: that_basin = *((CELL *) basins->b[0] + j); that_elev = elev->b[0] + j * bpe(); } /* end switch */ /* see if we're on a boundary */ if (that_basin != ii) { /* what is that_basin if that_elev is null ? */ if (is_null(that_elev)) { barrier_height = this_elev; } else { barrier_height = get_max(that_elev, this_elev); } if (get_min(barrier_height, list[ii].pp) == barrier_height) { /* save the old list entry in case we need it to fix a loop */ if (list[ii].next != that_basin) { memcpy(list[ii].pp_alt, list[ii].pp, bpe()); list[ii].next_alt = list[ii].next; } /* create the new list entry */ memcpy(list[ii].pp, barrier_height, bpe()); list[ii].next = that_basin; } else if (get_min(barrier_height, list[ii].pp_alt) == barrier_height) { if (list[ii].next == that_basin) continue; memcpy(list[ii].pp_alt, barrier_height, bpe()); list[ii].next_alt = that_basin; } } /* end if */ } /* end neighbor cells */ } /* end cell */ } /* end row */ /* Look for pairs of basins that drain to each other */ for (i = 1; i <= nbasins; i += 1) { if (list[i].next <= 0) continue; n = list[i].next; if (list[n].next == i) { /* we have a pair */ /* find out how large the elevation difference would be for a change in * each basin */ memcpy(that_elev, list[n].pp_alt, bpe()); diff(that_elev, list[n].pp); memcpy(this_elev, list[i].pp_alt, bpe()); diff(this_elev, list[i].pp); /* switch pour points in the basin where it makes the smallest change */ if (get_min(this_elev, that_elev) == this_elev) { list[i].next = list[i].next_alt; list[i].next_alt = n; this_elev = list[i].pp; list[i].pp = list[i].pp_alt; list[i].pp_alt = this_elev; } else { ii = list[n].next; list[n].next = list[n].next_alt; list[n].next_alt = ii; this_elev = list[n].pp; list[n].pp = list[n].pp_alt; list[n].pp_alt = this_elev; } /* end fix */ } /* end problem */ } /* end loop */ /* backtrace drainages from the bottom and adjust pour points */ for (i = 1; i <= nbasins; i += 1) { if (list[i].next == -1) { list[i].trace = i; backtrace(i, nbasins, list); } } /* fill all basins up to the elevation of their lowest bounding elevation */ lseek(fe, 0, SEEK_SET); lseek(fb, 0, SEEK_SET); for (i = 0; i < nl; i += 1) { read(fe, elev->b[1], elev->sz); read(fb, basins->b[1], basins->sz); for (j = 0; j < basins->ns; j += 1) { ii = *((CELL *) basins->b[1] + j); if (ii <= 0) continue; this_elev = elev->b[1] + j * bpe(); memcpy(this_elev, get_max(this_elev, list[ii].pp), bpe()); } lseek(fe, -elev->sz, SEEK_CUR); write(fe, elev->b[1], elev->sz); } G_free(list); }
/* determine the flow direction at each cell on one row */ void build_one_row(int i, int nl, int ns, struct band3 *bnd, CELL * dir, struct metrics m) { int j, offset, inc; CELL sdir; double slope; char *center; char *edge; inc = bpe(); for (j = 0; j < ns; j += 1) { offset = j * bpe(); center = bnd->b[1] + offset; if (is_null(center)) { G_set_c_null_value(dir + j, 1); continue; } sdir = 0; /* slope=HUGE; */ slope = HUGE_VAL; if (i == 0) { sdir = 128; } else if (i == nl - 1) { sdir = 8; } else if (j == 0) { sdir = 32; } else if (j == ns - 1) { sdir = 2; } else { /* slope=-HUGE; */ slope = -HUGE_VAL; /* check one row back */ edge = bnd->b[0] + offset; check(64, &sdir, center, edge - inc, m.diag_res, &slope); check(128, &sdir, center, edge, m.ns_res, &slope); check(1, &sdir, center, edge + inc, m.diag_res, &slope); /* check this row */ check(32, &sdir, center, center - inc, m.ew_res, &slope); check(2, &sdir, center, center + inc, m.ew_res, &slope); /* check one row forward */ edge = bnd->b[2] + offset; check(16, &sdir, center, edge - inc, m.diag_res, &slope); check(8, &sdir, center, edge, m.ns_res, &slope); check(4, &sdir, center, edge + inc, m.diag_res, &slope); } if (slope == 0.) sdir = -sdir; else if (slope < 0.) sdir = -256; dir[j] = sdir; } return; }