[GRASS-SVN] r39730 - grass-addons/raster/r.stream.extract
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Nov 14 07:03:38 EST 2009
Author: mmetz
Date: 2009-11-14 07:03:37 -0500 (Sat, 14 Nov 2009)
New Revision: 39730
Modified:
grass-addons/raster/r.stream.extract/do_astar.c
Log:
fixed A* Search
Modified: grass-addons/raster/r.stream.extract/do_astar.c
===================================================================
--- grass-addons/raster/r.stream.extract/do_astar.c 2009-11-14 11:48:38 UTC (rev 39729)
+++ grass-addons/raster/r.stream.extract/do_astar.c 2009-11-14 12:03:37 UTC (rev 39730)
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <math.h>
#include <grass/gis.h>
#include <grass/glocale.h>
#include "local_proto.h"
@@ -15,16 +16,28 @@
unsigned int heap_drop(void);
+double get_slope2(CELL, CELL, double);
+
int do_astar(void)
{
int r, c, r_nbr, c_nbr, ct_dir;
struct ast_point astp;
- int count, is_in_list;
+ int count, is_in_list, is_worked;
int nextdr[8] = { 1, -1, 0, 0, -1, 1, 1, -1 };
int nextdc[8] = { 0, 0, -1, 1, 1, -1, 1, -1 };
- CELL ele_val, ele_up;
+ CELL ele_val, ele_up, ele_nbr[8];
char asp_val;
unsigned int thisindex, nindex;
+ /* sides
+ * |7|1|4|
+ * |2| |3|
+ * |5|0|6|
+ */
+ int nbr_ew[8] = { 0, 1, 2, 3, 1, 0, 0, 1 };
+ int nbr_ns[8] = { 0, 1, 2, 3, 3, 2, 3, 2 };
+ double dx, dy, dist_to_nbr[8], ew_res, ns_res;
+ double slope[8];
+ struct Cell_head window;
count = 0;
@@ -32,6 +45,23 @@
G_message(_("A* Search..."));
+ G_get_set_window(&window);
+
+ for (ct_dir = 0; ct_dir < sides; ct_dir++) {
+ /* get r, c (r_nbr, c_nbr) for neighbours */
+ r_nbr = nextdr[ct_dir];
+ c_nbr = nextdc[ct_dir];
+ /* account for rare cases when ns_res != ew_res */
+ dy = abs(r_nbr) * window.ns_res;
+ dx = abs(c_nbr) * window.ew_res;
+ if (ct_dir < 4)
+ dist_to_nbr[ct_dir] = dx + dy;
+ else
+ dist_to_nbr[ct_dir] = sqrt(dx * dx + dy * dy);
+ }
+ ew_res = window.ew_res;
+ ns_res = window.ns_res;
+
while (heap_size > 0) {
G_percent(count++, n_points, 1);
if (count > n_points)
@@ -60,10 +90,36 @@
/* get r, c (r_nbr, c_nbr) for neighbours */
r_nbr = r + nextdr[ct_dir];
c_nbr = c + nextdc[ct_dir];
+ slope[ct_dir] = ele_nbr[ct_dir] = 0;
/* check that neighbour is within region */
if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols) {
is_in_list = FLAG_GET(in_list, r_nbr, c_nbr);
+ is_worked = FLAG_GET(worked, r_nbr, c_nbr);
+ if (!is_worked) {
+ nindex = INDEX(r_nbr, c_nbr);
+ ele_nbr[ct_dir] = ele[nindex];
+ slope[ct_dir] =
+ get_slope2(ele_val, ele_nbr[ct_dir],
+ dist_to_nbr[ct_dir]);
+ /* avoid diagonal flow direction bias */
+ if (ct_dir > 3) {
+ if (slope[nbr_ew[ct_dir]]) {
+ /* slope to ew nbr > slope to center */
+ if (slope[ct_dir] <
+ get_slope2(ele_nbr[nbr_ew[ct_dir]],
+ ele_nbr[ct_dir], ew_res))
+ is_in_list = 1;
+ }
+ if (!is_in_list && slope[nbr_ns[ct_dir]]) {
+ /* slope to ns nbr > slope to center */
+ if (slope[ct_dir] <
+ get_slope2(ele_nbr[nbr_ns[ct_dir]],
+ ele_nbr[ct_dir], ns_res))
+ is_in_list = 1;
+ }
+ }
+ }
if (is_in_list == 0) {
nindex = INDEX(r_nbr, c_nbr);
@@ -73,9 +129,9 @@
FLAG_SET(in_list, r_nbr, c_nbr);
}
}
- } /* end neighbours */
+ } /* end neighbours */
FLAG_SET(worked, r, c);
- } /* end A* search */
+ } /* end A* search */
G_percent(n_points, n_points, 1); /* finish it */
@@ -160,7 +216,6 @@
nxt_avail_pt++;
/* sift up: move new point towards top of heap */
-
sift_up(heap_size, ele);
return heap_size;
@@ -224,3 +279,11 @@
return heap_size;
}
+
+double get_slope2(CELL ele, CELL up_ele, double dist)
+{
+ if (ele == up_ele)
+ return 0.5 / dist;
+ else
+ return (double)(up_ele - ele) / dist;
+}
More information about the grass-commit
mailing list