[GRASS-SVN] r60824 - sandbox/annakrat/r3.flow
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Jun 13 14:29:09 PDT 2014
Author: annakrat
Date: 2014-06-13 14:29:09 -0700 (Fri, 13 Jun 2014)
New Revision: 60824
Added:
sandbox/annakrat/r3.flow/voxel_traversal.py
Modified:
sandbox/annakrat/r3.flow/r3.flow.py
Log:
r3.flow: implemented voxel traversal algorithm for precise flow accumulation computation
Modified: sandbox/annakrat/r3.flow/r3.flow.py
===================================================================
--- sandbox/annakrat/r3.flow/r3.flow.py 2014-06-13 20:52:10 UTC (rev 60823)
+++ sandbox/annakrat/r3.flow/r3.flow.py 2014-06-13 21:29:09 UTC (rev 60824)
@@ -66,7 +66,7 @@
#% type: double
#% required: no
#% label: Integration step in selected unit
-#% description: Default step is 0.5 cell
+#% description: Default step is 0.25 cell
#% gisprompt: Integration
#%end
#%option
@@ -254,7 +254,5 @@
if options['flowaccumulation']:
flowacc.write(mapname=options['flowaccumulation'])
-
-
if __name__ == '__main__':
main()
Added: sandbox/annakrat/r3.flow/voxel_traversal.py
===================================================================
--- sandbox/annakrat/r3.flow/voxel_traversal.py (rev 0)
+++ sandbox/annakrat/r3.flow/voxel_traversal.py 2014-06-13 21:29:09 UTC (rev 60824)
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+"""
+ at brief voxel traversal algorithm for precise flowaccumulation computing
+ at author: Anna Petrasova
+"""
+
+import numpy as np
+import math
+
+
+def traverse(start, end, region_info):
+ """!Computes which voxel cells are traversed by a line.
+ To each transected cell we add 1.
+
+ :param start: start point (3 coordinates)
+ :param end: end point (3 coordinates)
+ :param dict region_info: information about region
+ :return: coordinates of transected voxel cells
+ """
+ # initialize
+ dx = end[0] - start[0]
+ dy = end[1] - start[1]
+ dz = end[2] - start[2]
+
+ X = int(math.floor((start[0] - region_info['west']) / region_info['ewres']))
+ Y = int(math.floor((start[1] - region_info['south']) / region_info['nsres']))
+ Z = int(math.floor((start[2] - region_info['bottom']) / region_info['tbres']))
+ X_end = int(math.floor((end[0] - region_info['west']) / region_info['ewres']))
+ Y_end = int(math.floor((end[1] - region_info['south']) / region_info['nsres']))
+ Z_end = int(math.floor((end[2] - region_info['bottom']) / region_info['tbres']))
+
+ tDeltaX = region_info['ewres'] / float(dx) if dx != 0 else 1e6
+ tDeltaY = region_info['nsres'] / float(dy) if dy != 0 else 1e6
+ tDeltaZ = region_info['tbres'] / float(dz) if dz != 0 else 1e6
+
+ xtmp = start[0] / region_info['ewres']
+ ytmp = start[1] / region_info['nsres']
+ ztmp = start[2] / region_info['tbres']
+ xtmp = xtmp if xtmp > 0 else -xtmp
+ ytmp = ytmp if ytmp > 0 else -ytmp
+ ztmp = ztmp if ztmp > 0 else -ztmp
+ tMaxX = tDeltaX * (1.0 - (xtmp - int(xtmp)))
+ tMaxY = tDeltaY * (1.0 - (ytmp - int(ytmp)))
+ tMaxZ = tDeltaZ * (1.0 - (ztmp - int(ztmp)))
+
+ stepX = 1 if start[0] < end[0] else -1
+ stepY = 1 if start[1] < end[1] else -1
+ stepZ = 1 if start[2] < end[2] else -1
+
+ coordinates = []
+ while True:
+ if abs(tMaxX) < abs(tMaxY):
+ if abs(tMaxX) < abs(tMaxZ):
+ tMaxX = tMaxX + tDeltaX
+ X = X + stepX
+ if (X - X_end) * stepX > 0:
+ break
+ else:
+ tMaxZ = tMaxZ + tDeltaZ
+ Z = Z + stepZ
+ if (Z - Z_end) * stepZ > 0:
+ break
+ else:
+ if abs(tMaxY) < abs(tMaxZ):
+ tMaxY = tMaxY + tDeltaY
+ Y = Y + stepY
+ if (Y - Y_end) * stepY > 0:
+ break
+ else:
+ tMaxZ = tMaxZ + tDeltaZ
+ Z = Z + stepZ
+ if (Z - Z_end) * stepZ > 0:
+ break
+
+ coordinates.append((X, Y, Z))
+ return coordinates
+
+if __name__ == '__main__':
+ info = {}
+ info['cols'] = 10
+ info['rows'] = 10
+ info['depths'] = 10
+ info['nsres'] = 4
+ info['ewres'] = 8
+ info['tbres'] = 1
+ info['west'] = -80
+ info['south'] = -40
+ info['bottom'] = -10
+ start = [-66.2,-38.9,-9.5]
+ end = [-25,-24.5,-9.5]
+ X = int(math.floor((start[0] - info['west']) / info['ewres']))
+ Y = int(math.floor((start[1] - info['south']) / info['nsres']))
+ Z = int(math.floor((start[2] - info['bottom']) / info['tbres']))
+ X_end = int(math.floor((end[0] - info['west']) / info['ewres']))
+ Y_end = int(math.floor((end[1] - info['south']) / info['nsres']))
+ Z_end = int(math.floor((end[2] - info['bottom']) / info['tbres']))
+# start = [1, 1, 0.5]
+# end = [74, 42, 0.5]
+
+ array = np.zeros((info['depths'], info['rows'], info['cols']), dtype=np.int8)
+ coords = traverse(start, end, info)
+ array[Z, array.shape[1] - Y - 1, X] = 1
+ array[Z_end, array.shape[1] - Y_end - 1, X_end] = 3
+ for coord in coords:
+ array[coord[2], array.shape[1] - coord[1] - 1, coord[0]] = 2
+ q = array[0]
More information about the grass-commit
mailing list