[GRASS-SVN] r72919 - grass-addons/grass7/raster/r.accumulate

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jun 28 15:31:30 PDT 2018


Author: hcho
Date: 2018-06-28 15:31:30 -0700 (Thu, 28 Jun 2018)
New Revision: 72919

Modified:
   grass-addons/grass7/raster/r.accumulate/delineate_streams.c
   grass-addons/grass7/raster/r.accumulate/global.h
   grass-addons/grass7/raster/r.accumulate/main.c
   grass-addons/grass7/raster/r.accumulate/r.accumulate.html
Log:
r.accumulate: Do not delineate streams across confluences by default; Add -c to do that

Modified: grass-addons/grass7/raster/r.accumulate/delineate_streams.c
===================================================================
--- grass-addons/grass7/raster/r.accumulate/delineate_streams.c	2018-06-28 19:10:43 UTC (rev 72918)
+++ grass-addons/grass7/raster/r.accumulate/delineate_streams.c	2018-06-28 22:31:30 UTC (rev 72919)
@@ -2,11 +2,12 @@
 #include <grass/vector.h>
 #include "global.h"
 
-static void trace_down(struct cell_map *, struct Cell_head *, int, int,
+static void trace_down(struct cell_map *, struct raster_map *accum_buf,
+                       double, char, struct Cell_head *, int, int,
                        struct point_list *);
 
-void delineate_streams(struct Map_info *Map, double thresh,
-                       struct cell_map *dir_buf, struct raster_map *accum_buf)
+void delineate_streams(struct Map_info *Map, struct cell_map *dir_buf,
+                       struct raster_map *accum_buf, double thresh, char conf)
 {
     struct Cell_head window;
     int rows = accum_buf->rows, cols = accum_buf->cols;
@@ -27,7 +28,7 @@
     for (row = 0; row < rows; row++) {
         for (col = 0; col < cols; col++) {
             int i, j;
-            char has_thresh_inflow = 0;
+            int nup = 0;
 
             /* if the current cell is less than the threshold, skip */
             if (get(accum_buf, row, col) < thresh)
@@ -34,7 +35,7 @@
                 continue;
 
             /* the current cell is greater than the threshold; check if it is
-             * headwater (no upstream cells greater than the threshold) */
+             * a headwater (no upstream cells greater than the threshold) */
             for (i = -1; i <= 1; i++) {
                 /* skip edge cells */
                 if (row + i < 0 || row + i >= rows)
@@ -47,18 +48,20 @@
 
                     /* if a neighbor cell flows into the current cell and has a
                      * flow higher than the threshold, the current cell is not
-                     * headwater */
+                     * a headwater */
                     if (dir_buf->c[row + i][col + j] ==
                         dir_checks[i + 1][j + 1][0] &&
                         get(accum_buf, row + i, col + j) >= thresh)
-                        has_thresh_inflow = 1;
+                        nup++;
                 }
             }
 
-            /* if headwater is found, trace down flow directions */
-            if (!has_thresh_inflow) {
+            /* if a headwater is found or a confluence is found and requested,
+             * trace down flow directions */
+            if (!nup || (!conf && nup > 1)) {
                 reset_point_list(&pl);
-                trace_down(dir_buf, &window, row, col, &pl);
+                trace_down(dir_buf, accum_buf, thresh, conf, &window, row,
+                           col, &pl);
 
                 /* if tracing is successful, write out the stream */
                 if (pl.n > 0) {
@@ -79,7 +82,8 @@
     Vect_destroy_cats_struct(Cats);
 }
 
-static void trace_down(struct cell_map *dir_buf, struct Cell_head *window,
+static void trace_down(struct cell_map *dir_buf, struct raster_map *accum_buf,
+                       double thresh, char conf, struct Cell_head *window,
                        int row, int col, struct point_list *pl)
 {
     static int next_cells[8][2] = {
@@ -86,6 +90,7 @@
         {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}
     };
     int rows = dir_buf->rows, cols = dir_buf->cols;
+    int i, j;
     int dir;
 
     /* if the current cell is outside the computational region, stop tracing */
@@ -96,10 +101,38 @@
     add_point(pl, Rast_col_to_easting(col + 0.5, window),
               Rast_row_to_northing(row + 0.5, window));
 
+    /* conf = 1 for continuous streams across a confluence;
+     * conf = 0 for split streams at a confluence */
+    if (!conf) {
+        int nup = 0;
+
+        for (i = -1; i <= 1; i++) {
+            /* skip edge cells */
+            if (row + i < 0 || row + i >= rows)
+                continue;
+
+            for (j = -1; j <= 1; j++) {
+                /* skip the current and edge cells */
+                if ((i == 0 && j == 0) || col + j < 0 || col + j >= cols)
+                    continue;
+
+                /* if multiple neighbor cells flow into the current cell and
+                 * have a flow higher than the threshold, the current cell is a
+                 * confluence; stop tracing in this case only if this cell is
+                 * not starting a new stream at this confluence */
+                if (dir_buf->c[row + i][col + j] ==
+                    dir_checks[i + 1][j + 1][0] &&
+                    get(accum_buf, row + i, col + j) >= thresh && pl->n > 1 &&
+                    ++nup > 1)
+                    return;
+            }
+        }
+    }
+
     /* if the current cell doesn't flow out of the computational region
      * (negative direction from r.watershed flows out), keep tracing */
     dir = dir_buf->c[row][col] - 1;
     if (dir >= 0 && dir < 8)
-        trace_down(dir_buf, window, row + next_cells[dir][0],
-                   col + next_cells[dir][1], pl);
+        trace_down(dir_buf, accum_buf, thresh, conf, window,
+                   row + next_cells[dir][0], col + next_cells[dir][1], pl);
 }

Modified: grass-addons/grass7/raster/r.accumulate/global.h
===================================================================
--- grass-addons/grass7/raster/r.accumulate/global.h	2018-06-28 19:10:43 UTC (rev 72918)
+++ grass-addons/grass7/raster/r.accumulate/global.h	2018-06-28 22:31:30 UTC (rev 72919)
@@ -87,8 +87,8 @@
                 char **, char);
 
 /* delineate_streams.c */
-void delineate_streams(struct Map_info *, double, struct cell_map *,
-                       struct raster_map *);
+void delineate_streams(struct Map_info *, struct cell_map *,
+                       struct raster_map *, double, char);
 
 /* calculate_lfp.c */
 void calculate_lfp(struct Map_info *, struct cell_map *, struct raster_map *,

Modified: grass-addons/grass7/raster/r.accumulate/main.c
===================================================================
--- grass-addons/grass7/raster/r.accumulate/main.c	2018-06-28 19:10:43 UTC (rev 72918)
+++ grass-addons/grass7/raster/r.accumulate/main.c	2018-06-28 22:31:30 UTC (rev 72919)
@@ -53,14 +53,16 @@
     struct
     {
         struct Flag *neg;
+        struct Flag *conf;
     } flag;
     char *desc;
-    char *dir_name, *weight_name, *accum_name, *stream_name, *outlet_name, *lfp_name;
+    char *dir_name, *weight_name, *accum_name, *stream_name, *outlet_name,
+        *lfp_name;
     int dir_fd;
     double dir_format, thresh;
     struct Range dir_range;
     CELL dir_min, dir_max;
-    char neg;
+    char neg, conf;
     char **done;
     struct cell_map dir_buf;
     struct raster_map weight_buf, accum_buf;
@@ -158,6 +160,10 @@
     flag.neg->label =
         _("Use negative flow accumulation for likely underestimates");
 
+    flag.conf = G_define_flag();
+    flag.conf->key = 'c';
+    flag.conf->label = _("Delineate streams across confluences");
+
     /* weighting doesn't support negative accumulation because weights
      * themselves can be negative; the longest flow path requires positive
      * non-weighted accumulation */
@@ -168,6 +174,7 @@
     G_option_requires(opt.idcol, opt.id, opt.outlet_idcol, NULL);
     G_option_requires_all(opt.id, opt.idcol, opt.coords, NULL);
     G_option_requires_all(opt.outlet_idcol, opt.idcol, opt.outlet, NULL);
+    G_option_requires(flag.conf, opt.stream, NULL);
 
     if (G_parser(argc, argv))
         exit(EXIT_FAILURE);
@@ -329,6 +336,7 @@
 
     thresh = opt.thresh->answer ? atof(opt.thresh->answer) : 0.0;
     neg = flag.neg->answer;
+    conf = flag.conf->answer;
 
     rows = Rast_window_rows();
     cols = Rast_window_cols();
@@ -417,7 +425,7 @@
         Vect_set_map_name(&Map, "Stream network");
         Vect_hist_command(&Map);
 
-        delineate_streams(&Map, thresh, &dir_buf, &accum_buf);
+        delineate_streams(&Map, &dir_buf, &accum_buf, thresh, conf);
 
         if (!Vect_build(&Map))
             G_warning(_("Unable to build topology for vector map <%s>"),

Modified: grass-addons/grass7/raster/r.accumulate/r.accumulate.html
===================================================================
--- grass-addons/grass7/raster/r.accumulate/r.accumulate.html	2018-06-28 19:10:43 UTC (rev 72918)
+++ grass-addons/grass7/raster/r.accumulate/r.accumulate.html	2018-06-28 22:31:30 UTC (rev 72919)
@@ -38,8 +38,12 @@
 
 With <b>stream</b> and <b>threshold</b> options, the module will delineate
 stream networks with the minimum flow accumulation for stream generation. A
-<b>weight</b> input map may be used with <b>threshold</b>.
+<b>weight</b> input map may be used with <b>threshold</b>. Delineated stream
+lines are split at confluences.
 
+<p>With <b>-c</b> flag, stream lines are delineated across confluences and may
+overlap with other stream lines that share the same downstream outlet.
+
 <h3>Longest flow path calculation</h3>
 
 With <b>longest_flow_path</b> option, the module will create a longest flow



More information about the grass-commit mailing list