-
Notifications
You must be signed in to change notification settings - Fork 0
/
r.lfp.py
executable file
·150 lines (128 loc) · 4.86 KB
/
r.lfp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
############################################################################
#
# MODULE: r.lfp
# AUTHOR(S): Huidae Cho
# PURPOSE: Calculates the longest flow path for a given outlet point.
#
# COPYRIGHT: (C) 2014, 2017 by the GRASS Development Team
#
# This program is free software under the GNU General Public
# License (>=v2). Read the file COPYING that comes with GRASS
# for details.
#
#############################################################################
#%module
#% description: Calculates the longest flow path for a given outlet point using the r.stream.distance addon.
#% keyword: hydrology
#% keyword: watershed
#%end
#%option G_OPT_R_INPUT
#% description: Name of input drainage direction raster map
#%end
#%option G_OPT_R_OUTPUT
#% description: Name for output longest flow path raster map
#%end
#%option G_OPT_M_COORDS
#% description: Coordinates of outlet point
#% required: yes
#%end
import sys
import os
import grass.script as grass
from grass.exceptions import CalledModuleError
# check requirements
def check_progs():
found_missing = False
prog = 'r.stream.distance'
if not grass.find_program(prog, '--help'):
found_missing = True
grass.warning(_("'%s' required. Please install '%s' first using 'g.extension %s'") % (prog, prog, prog))
if found_missing:
grass.fatal(_("An ERROR occurred running r.lfp"))
def main():
# check dependencies
check_progs()
input = options["input"]
output = options["output"]
coords = options["coordinates"]
calculate_lfp(input, output, coords)
def calculate_lfp(input, output, coords):
prefix = "r_lfp_%d_" % os.getpid()
# create the outlet vector map
outlet = prefix + "outlet"
p = grass.feed_command("v.in.ascii", overwrite=True,
input="-", output=outlet, separator=",")
p.stdin.write(coords)
p.stdin.close()
p.wait()
if p.returncode != 0:
grass.fatal(_("Cannot create the outlet vector map"))
# convert the outlet vector map to raster
try:
grass.run_command("v.to.rast", overwrite=True,
input=outlet, output=outlet, use="cat", type="point")
except CalledModuleError:
grass.fatal(_("Cannot convert the outlet vector to raster"))
# calculate the downstream flow length
flds = prefix + "flds"
try:
grass.run_command("r.stream.distance", overwrite=True, flags="om",
stream_rast=outlet, direction=input,
method="downstream", distance=flds)
except CalledModuleError:
grass.fatal(_("Cannot calculate the downstream flow length"))
# calculate the upstream flow length
flus = prefix + "flus"
try:
grass.run_command("r.stream.distance", overwrite=True, flags="o",
stream_rast=outlet, direction=input,
method="upstream", distance=flus)
except CalledModuleError:
grass.fatal(_("Cannot calculate the upstream flow length"))
# calculate the sum of downstream and upstream flow lengths
fldsus = prefix + "fldsus"
try:
grass.run_command("r.mapcalc", overwrite=True,
expression="%s=%s+%s" % (fldsus, flds, flus))
except CalledModuleError:
grass.fatal(_("Cannot calculate the sum of downstream and upstream flow lengths"))
# find the longest flow length
p = grass.pipe_command("r.info", flags="r", map=fldsus)
max = ""
for line in p.stdout:
line = line.rstrip("\n")
if line.startswith("max="):
max = line.split("=")[1]
break
p.wait()
if p.returncode != 0 or max == "":
grass.fatal(_("Cannot find the longest flow length"))
min = float(max) - 0.0005
# extract the longest flow path
lfp = prefix + "lfp"
try:
grass.run_command("r.mapcalc", overwrite=True,
expression="%s=if(%s>=%f, 1, null())" %
(lfp, fldsus, min))
except CalledModuleError:
grass.fatal(_("Cannot create the longest flow path raster map"))
# thin the longest flow path raster map
try:
grass.run_command("r.thin", input=lfp, output=output)
except CalledModuleError:
grass.fatal(_("Cannot thin the longest flow path raster map"))
# remove intermediate outputs
grass.run_command("g.remove", flags="f", type="raster,vector",
pattern="%s*" % prefix)
# write metadata
tmphist = grass.tempfile()
f = open(tmphist, "w+")
f.write(os.environ["CMDLINE"])
f.close()
grass.run_command("r.support", map=output, title="Longest flow path",
loadhistory=tmphist, description="generated by r.lfp")
grass.try_remove(tmphist)
if __name__ == "__main__":
options, flags = grass.parser()
sys.exit(main())