-
Notifications
You must be signed in to change notification settings - Fork 147
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
r.flowaccumulation: Support FCELL and DCELL outputs (#1027)
* r.flowaccumulation: Support FCELL and DCELL outputs * Consistent labels for -z and -Z
- Loading branch information
Showing
29 changed files
with
674 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,164 +1,114 @@ | ||
#include <stdlib.h> | ||
#include <grass/raster.h> | ||
#include "global.h" | ||
|
||
#define ACCUM(row, col) accum_map->cells[(size_t)(row)*ncols + (col)] | ||
#define FIND_UP(row, col) \ | ||
((row > 0 ? (col > 0 && DIR(row - 1, col - 1) == SE ? NW : 0) | \ | ||
(DIR(row - 1, col) == S ? N : 0) | \ | ||
(col < ncols - 1 && DIR(row - 1, col + 1) == SW ? NE : 0) \ | ||
: 0) | \ | ||
(col > 0 && DIR(row, col - 1) == E ? W : 0) | \ | ||
(col < ncols - 1 && DIR(row, col + 1) == W ? E : 0) | \ | ||
(row < nrows - 1 \ | ||
? (col > 0 && DIR(row + 1, col - 1) == NE ? SW : 0) | \ | ||
(DIR(row + 1, col) == N ? S : 0) | \ | ||
(col < ncols - 1 && DIR(row + 1, col + 1) == NW ? SE : 0) \ | ||
: 0)) | ||
|
||
#ifdef USE_LESS_MEMORY | ||
#define UP(row, col) FIND_UP(row, col) | ||
#else | ||
#define UP(row, col) up_cells[(size_t)(row)*ncols + (col)] | ||
static unsigned char *up_cells; | ||
#endif | ||
|
||
static int nrows, ncols; | ||
|
||
static void trace_down(struct raster_map *, struct raster_map *, int, int, int); | ||
static int sum_up(struct raster_map *, int, int, int); | ||
|
||
void accumulate(struct raster_map *dir_map, struct raster_map *accum_map) | ||
{ | ||
int row, col; | ||
|
||
nrows = dir_map->nrows; | ||
ncols = dir_map->ncols; | ||
|
||
#ifndef USE_LESS_MEMORY | ||
up_cells = calloc((size_t)nrows * ncols, sizeof *up_cells); | ||
|
||
#pragma omp parallel for schedule(dynamic) private(col) | ||
for (row = 0; row < nrows; row++) { | ||
for (col = 0; col < ncols; col++) | ||
if (!Rast_is_c_null_value(&DIR(row, col))) | ||
UP(row, col) = FIND_UP(row, col); | ||
} | ||
#endif | ||
|
||
#pragma omp parallel for schedule(dynamic) private(col) | ||
for (row = 0; row < nrows; row++) { | ||
for (col = 0; col < ncols; col++) | ||
/* if the current cell is not null and has no upstream cells, start | ||
* tracing down */ | ||
if (!Rast_is_c_null_value(&DIR(row, col)) && !UP(row, col)) | ||
trace_down(dir_map, accum_map, row, col, 1); | ||
} | ||
|
||
#ifndef USE_LESS_MEMORY | ||
free(up_cells); | ||
#endif | ||
} | ||
|
||
static void trace_down(struct raster_map *dir_map, struct raster_map *accum_map, | ||
int row, int col, int accum) | ||
void accumulate(struct raster_map *dir_map, struct raster_map *accum_map, | ||
int check_overflow, int use_less_memory, int use_zero) | ||
{ | ||
int up, accum_up = 0; | ||
|
||
/* accumulate the current cell itself */ | ||
ACCUM(row, col) = accum; | ||
|
||
/* find the downstream cell */ | ||
switch (DIR(row, col)) { | ||
case NW: | ||
row--; | ||
col--; | ||
break; | ||
case N: | ||
row--; | ||
break; | ||
case NE: | ||
row--; | ||
col++; | ||
switch (accum_map->type) { | ||
case CELL_TYPE: | ||
if (check_overflow) { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_comz(dir_map, accum_map); | ||
else | ||
accumulate_com(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_coz(dir_map, accum_map); | ||
else | ||
accumulate_co(dir_map, accum_map); | ||
} | ||
} | ||
else { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_cmz(dir_map, accum_map); | ||
else | ||
accumulate_cm(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_cz(dir_map, accum_map); | ||
else | ||
accumulate_c(dir_map, accum_map); | ||
} | ||
} | ||
break; | ||
case W: | ||
col--; | ||
case FCELL_TYPE: | ||
if (check_overflow) { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_fomz(dir_map, accum_map); | ||
else | ||
accumulate_fom(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_foz(dir_map, accum_map); | ||
else | ||
accumulate_fo(dir_map, accum_map); | ||
} | ||
} | ||
else { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_fmz(dir_map, accum_map); | ||
else | ||
accumulate_fm(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_fz(dir_map, accum_map); | ||
else | ||
accumulate_f(dir_map, accum_map); | ||
} | ||
} | ||
break; | ||
case E: | ||
col++; | ||
break; | ||
case SW: | ||
row++; | ||
col--; | ||
break; | ||
case S: | ||
row++; | ||
break; | ||
case SE: | ||
row++; | ||
col++; | ||
default: | ||
if (check_overflow) { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_domz(dir_map, accum_map); | ||
else | ||
accumulate_dom(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_doz(dir_map, accum_map); | ||
else | ||
accumulate_do(dir_map, accum_map); | ||
} | ||
} | ||
else { | ||
if (use_less_memory) { | ||
if (use_zero) | ||
accumulate_dmz(dir_map, accum_map); | ||
else | ||
accumulate_dm(dir_map, accum_map); | ||
} | ||
else { | ||
if (use_zero) | ||
accumulate_dz(dir_map, accum_map); | ||
else | ||
accumulate_d(dir_map, accum_map); | ||
} | ||
} | ||
break; | ||
} | ||
|
||
/* if the downstream cell is null or any upstream cells of the downstream | ||
* cell have never been visited, stop tracing down */ | ||
if (row < 0 || row >= nrows || col < 0 || col >= ncols || | ||
Rast_is_c_null_value(&DIR(row, col)) || !(up = UP(row, col)) || | ||
!(accum_up = sum_up(accum_map, row, col, up))) | ||
return; | ||
|
||
/* use gcc -O2 or -O3 flags for tail-call optimization | ||
* (-foptimize-sibling-calls) */ | ||
trace_down(dir_map, accum_map, row, col, accum_up + 1); | ||
} | ||
|
||
/* if any upstream cells have never been visited, 0 is returned; otherwise, the | ||
* sum of upstream accumulation is returned */ | ||
static int sum_up(struct raster_map *accum_map, int row, int col, int up) | ||
void nullify_zero(struct raster_map *accum_map) | ||
{ | ||
int sum = 0, accum; | ||
|
||
#pragma omp flush(accum_map) | ||
if (up & NW) { | ||
if (!(accum = ACCUM(row - 1, col - 1))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & N) { | ||
if (!(accum = ACCUM(row - 1, col))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & NE) { | ||
if (!(accum = ACCUM(row - 1, col + 1))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & W) { | ||
if (!(accum = ACCUM(row, col - 1))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & E) { | ||
if (!(accum = ACCUM(row, col + 1))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & SW) { | ||
if (!(accum = ACCUM(row + 1, col - 1))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & S) { | ||
if (!(accum = ACCUM(row + 1, col))) | ||
return 0; | ||
sum += accum; | ||
} | ||
if (up & SE) { | ||
if (!(accum = ACCUM(row + 1, col + 1))) | ||
return 0; | ||
sum += accum; | ||
switch (accum_map->type) { | ||
case CELL_TYPE: | ||
nullify_zero_c(accum_map); | ||
break; | ||
case FCELL_TYPE: | ||
nullify_zero_f(accum_map); | ||
break; | ||
default: | ||
nullify_zero_d(accum_map); | ||
break; | ||
} | ||
|
||
return sum; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE CELL_TYPE | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE DCELL_TYPE | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_LESS_MEMORY | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#define ACCUM_RAST_TYPE FCELL_TYPE | ||
#define CHECK_OVERFLOW | ||
#define USE_ZERO | ||
#include "accumulate_funcs.h" |
Oops, something went wrong.