| 1 | #!/usr/bin/env python
|
|---|
| 2 | ################################################################################
|
|---|
| 3 | #
|
|---|
| 4 | # MODULE: r.width.funct
|
|---|
| 5 | #
|
|---|
| 6 | # AUTHOR(S): Massimo Di Stefano, Francesco Di Stefano, Margherita Di Leo
|
|---|
| 7 | #
|
|---|
| 8 | # PURPOSE: The module produces the Width Function of a basin. The Width
|
|---|
| 9 | # Function W(x) gives the number of the cells in a basin at a
|
|---|
| 10 | # flow distance x from the outlet (distance-area function)
|
|---|
| 11 | #
|
|---|
| 12 | # COPYRIGHT: (c) 2010 Massimo Di Stefano, Francesco Di Stefano, Margherita Di Leo
|
|---|
| 13 | #
|
|---|
| 14 | # This program is free software under the GNU General Public
|
|---|
| 15 | # License (>=v2). Read the file COPYING that comes with GRASS
|
|---|
| 16 | # for details.
|
|---|
| 17 | #
|
|---|
| 18 | # REQUIRES: Matplotlib
|
|---|
| 19 | # http://matplotlib.sourceforge.net/
|
|---|
| 20 | #
|
|---|
| 21 | #
|
|---|
| 22 | ################################################################################
|
|---|
| 23 | #%module
|
|---|
| 24 | #% description: Calculates the Width Function of a watershed basin.
|
|---|
| 25 | #% keyword: raster
|
|---|
| 26 | #% keyword: hydrology
|
|---|
| 27 | #%end
|
|---|
| 28 |
|
|---|
| 29 | #%option G_OPT_R_INPUT
|
|---|
| 30 | #% key: map
|
|---|
| 31 | #% description: Distance to outlet map (from r.stream.distance)
|
|---|
| 32 | #% required: yes
|
|---|
| 33 | #%end
|
|---|
| 34 |
|
|---|
| 35 | #%option G_OPT_F_OUTPUT
|
|---|
| 36 | #% key: image
|
|---|
| 37 | #% key_desc: image
|
|---|
| 38 | #% description: Name for output graph file (png)
|
|---|
| 39 | #% required: yes
|
|---|
| 40 | #%END
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 | import sys
|
|---|
| 44 | import os
|
|---|
| 45 | import matplotlib #required by windows
|
|---|
| 46 | matplotlib.use('wx') #required by windows
|
|---|
| 47 | import matplotlib.pyplot as plt
|
|---|
| 48 | import grass.script as grass
|
|---|
| 49 | import numpy as np
|
|---|
| 50 |
|
|---|
| 51 | def main():
|
|---|
| 52 | stats = grass.read_command('r.stats', input = options['map'], \
|
|---|
| 53 | sep = 'space', \
|
|---|
| 54 | nv = '*', \
|
|---|
| 55 | nsteps = '255', \
|
|---|
| 56 | flags = 'Anc').split('\n')[:-1]
|
|---|
| 57 |
|
|---|
| 58 | # res = cellsize
|
|---|
| 59 | res = grass.region()['nsres']
|
|---|
| 60 |
|
|---|
| 61 | zn = np.zeros((len(stats),4),float)
|
|---|
| 62 | kl = np.zeros((len(stats),2),float)
|
|---|
| 63 | prc = np.zeros((9,2),float)
|
|---|
| 64 |
|
|---|
| 65 | for i in range(len(stats)):
|
|---|
| 66 | if i == 0:
|
|---|
| 67 | zn[i,0], zn[i,1] = map(float, stats[i].split(' '))
|
|---|
| 68 | zn[i,1] = zn[i,1]
|
|---|
| 69 | zn[i,2] = zn[i,1] * res
|
|---|
| 70 | if i != 0:
|
|---|
| 71 | zn[i,0], zn[i,1] = map(float, stats[i].split(' '))
|
|---|
| 72 | zn[i,2] = zn[i,1] + zn[i-1,2]
|
|---|
| 73 | zn[i,3] = zn[i,1] * (res**2)
|
|---|
| 74 |
|
|---|
| 75 | totcell = sum(zn[:,1])
|
|---|
| 76 | print("Tot. cells %s" %(totcell))
|
|---|
| 77 | totarea = totcell * (res**2)
|
|---|
| 78 | print("Tot. area %s" %(totarea))
|
|---|
| 79 | maxdist = max(zn[:,0])
|
|---|
| 80 | print("Max distance %s" %(maxdist))
|
|---|
| 81 |
|
|---|
| 82 | for i in range(len(stats)):
|
|---|
| 83 | kl[i,0] = zn[i,0]
|
|---|
| 84 | kl[i,1] = zn[i,2] / totcell
|
|---|
| 85 |
|
|---|
| 86 | # quantiles
|
|---|
| 87 | prc[0,0] , prc[0,1] = findint(kl,0.05) , 0.05
|
|---|
| 88 | prc[1,0] , prc[1,1] = findint(kl,0.15) , 0.15
|
|---|
| 89 | prc[2,0] , prc[2,1] = findint(kl,0.3) , 0.3
|
|---|
| 90 | prc[3,0] , prc[3,1] = findint(kl,0.4) , 0.4
|
|---|
| 91 | prc[4,0] , prc[4,1] = findint(kl,0.5) , 0.5
|
|---|
| 92 | prc[5,0] , prc[5,1] = findint(kl,0.6) , 0.6
|
|---|
| 93 | prc[6,0] , prc[6,1] = findint(kl,0.7) , 0.7
|
|---|
| 94 | prc[7,0] , prc[7,1] = findint(kl,0.85) , 0.85
|
|---|
| 95 | prc[8,0] , prc[8,1] = findint(kl,0.95) , 0.95
|
|---|
| 96 |
|
|---|
| 97 | # plot
|
|---|
| 98 | plotImage(zn[:,0], zn[:,3], options['image']+'_width_function.png','-','x','W(x)','Width Function')
|
|---|
| 99 |
|
|---|
| 100 | print("===========================")
|
|---|
| 101 | print("Width Function | quantiles")
|
|---|
| 102 | print("===========================")
|
|---|
| 103 | print('%.0f | %s') %(findint(kl,0.05), 0.05)
|
|---|
| 104 | print('%.0f | %s') %(findint(kl,0.15), 0.15)
|
|---|
| 105 | print('%.0f | %s') %(findint(kl,0.3), 0.3)
|
|---|
| 106 | print('%.0f | %s') %(findint(kl,0.4), 0.4)
|
|---|
| 107 | print('%.0f | %s') %(findint(kl,0.5), 0.5)
|
|---|
| 108 | print('%.0f | %s') %(findint(kl,0.6), 0.6)
|
|---|
| 109 | print('%.0f | %s') %(findint(kl,0.7), 0.7)
|
|---|
| 110 | print('%.0f | %s') %(findint(kl,0.85), 0.85)
|
|---|
| 111 | print('%.0f | %s') %(findint(kl,0.95), 0.95)
|
|---|
| 112 | print('\n')
|
|---|
| 113 | print('Done!')
|
|---|
| 114 |
|
|---|
| 115 | def plotImage(x,y,image,type,xlabel,ylabel,title):
|
|---|
| 116 | plt.plot(x, y, type)
|
|---|
| 117 | plt.ylabel(ylabel)
|
|---|
| 118 | plt.xlabel(xlabel)
|
|---|
| 119 | plt.xlim( min(x), max(x) )
|
|---|
| 120 | plt.ylim( min(y), max(y) )
|
|---|
| 121 | plt.title(title)
|
|---|
| 122 | plt.grid(True)
|
|---|
| 123 | plt.savefig(image)
|
|---|
| 124 | plt.close('all')
|
|---|
| 125 |
|
|---|
| 126 | def findint(kl,f):
|
|---|
| 127 | Xf = np.abs(kl-f); Xf = np.where(Xf==Xf.min())
|
|---|
| 128 | z1, z2, f1, f2 = kl[int(Xf[0])][0], kl[int(Xf[0]-1)][0], kl[int(Xf[0])][1], kl[int(Xf[0]-1)][1]
|
|---|
| 129 | z = z1 + ((z2 - z1) / (f2 - f1)) * (f - f1)
|
|---|
| 130 | return z
|
|---|
| 131 |
|
|---|
| 132 |
|
|---|
| 133 | if __name__ == "__main__":
|
|---|
| 134 | options, flags = grass.parser()
|
|---|
| 135 | sys.exit(main())
|
|---|