Пример #1
0
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);
	}
    }
}
Пример #2
0
    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();
        }
    }
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
/* 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;
}