[GRASS-SVN] r72928 - grass-addons/grass7/raster/r.accumulate
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jun 28 22:42:55 PDT 2018
Author: hcho
Date: 2018-06-28 22:42:55 -0700 (Thu, 28 Jun 2018)
New Revision: 72928
Modified:
grass-addons/grass7/raster/r.accumulate/calculate_lfp.c
Log:
r.accumulate: Fix longest flow path calculation; it was largest accumulation path
Modified: grass-addons/grass7/raster/r.accumulate/calculate_lfp.c
===================================================================
--- grass-addons/grass7/raster/r.accumulate/calculate_lfp.c 2018-06-29 02:03:58 UTC (rev 72927)
+++ grass-addons/grass7/raster/r.accumulate/calculate_lfp.c 2018-06-29 05:42:55 UTC (rev 72928)
@@ -1,3 +1,4 @@
+#include <math.h>
#include <grass/gis.h>
#include <grass/vector.h>
#include <grass/dbmi.h>
@@ -78,6 +79,7 @@
Vect_reset_cats(Cats);
Vect_cat_set(Cats, 1, cat);
+ Vect_line_reverse(ll.lines[n]->Points);
Vect_write_line(Map, GV_LINE, ll.lines[n]->Points, Cats);
if (driver) {
@@ -155,6 +157,7 @@
struct Cell_head *window, int row, int col,
struct point_list *pl, struct line_list *ll)
{
+ static struct line_pnts *Points = NULL;
int rows = dir_buf->rows, cols = dir_buf->cols;
double x, y;
int i, j, nup;
@@ -202,22 +205,68 @@
qsort(up_accum, nup, sizeof(struct neighbor_accum),
compare_neighbor_accum);
+ if (!Points)
+ Points = Vect_new_line_struct();
+
/* trace up the largest accumulation */
- for (i = 0; i < nup && up_accum[i].accum == up_accum[0].accum; i++) {
+ for (i = 0; i < nup; i++) {
+ static double diag_length;
+
/* store pl->n to come back later */
int split_pl_n = pl->n;
+ /* try to avoid unnecessary tracing */
+ if (ll->n) {
+ double max_length;
+
+ /* theoretically, the longest longest flow path is when all
+ * accumulated upstream cells are diagonally flowing */
+ Vect_reset_line(Points);
+ Vect_copy_xyz_to_pnts(Points, pl->x, pl->y, NULL, pl->n);
+ max_length =
+ Vect_line_length(Points) + up_accum[i].accum * diag_length;
+
+ for (j = 0; j < ll->n && max_length < ll->lines[j]->length; j++) ;
+
+ /* if the theoretical longest lfp < all existing, skip tracing
+ * because it's impossible to obtain a longer lfp */
+ if (j == ll->n)
+ continue;
+ }
+ else
+ diag_length =
+ sqrt(pow(window->ew_res, 2.0) + pow(window->ns_res, 2.0));
+
/* if tracing is successful, store the line and its length */
if (trace_up
(dir_buf, accum_buf, window, up_accum[i].row, up_accum[i].col, pl,
ll) && pl->n > 0) {
- struct line *line = (struct line *)G_malloc(sizeof(struct line));
+ static struct line *line;
+ double length;
- line->Points = Vect_new_line_struct();
- Vect_copy_xyz_to_pnts(line->Points, pl->x, pl->y, NULL, pl->n);
- Vect_line_reverse(line->Points);
- line->length = Vect_line_length(line->Points);
- add_line(ll, line);
+ Vect_reset_line(Points);
+ Vect_copy_xyz_to_pnts(Points, pl->x, pl->y, NULL, pl->n);
+ length = Vect_line_length(Points);
+
+ for (j = 0; j < ll->n && length < ll->lines[j]->length; j++) ;
+
+ /* if first or length >= any existing */
+ if (!ll->n || j < ll->n) {
+ if (!ll->n || length == ll->lines[j]->length) {
+ /* first or length == existing (tie); add new */
+ line = (struct line *)G_malloc(sizeof(struct line));
+ line->Points = Vect_new_line_struct();
+ add_line(ll, line);
+ }
+ else {
+ /* length > existing; replace existing */
+ line = ll->lines[j];
+ Vect_reset_line(line->Points);
+ }
+ Vect_copy_xyz_to_pnts(line->Points, pl->x, pl->y, NULL,
+ pl->n);
+ line->length = length;
+ }
}
/* keep tracing if the next upstream cell has the same largest
More information about the grass-commit
mailing list