-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpygeonet_grass_py3.py
213 lines (192 loc) · 8.51 KB
/
pygeonet_grass_py3.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
from __future__ import division
import os
import sys
import shutil
import subprocess
from time import perf_counter
from pygeonet_rasterio import *
def grass(filteredDemArray):
# Software
if sys.platform.startswith('win'):
# MS Windows
grass7bin = r'C:\OSGeo4W64\bin\grass78.bat'
# uncomment when using standalone WinGRASS installer
# grass7bin = r'C:\Program Files (x86)\GRASS GIS 7.2.0\grass72.bat'
# this can be avoided if GRASS executable is added to PATH
elif sys.platform.startswith('darwin'):
# Mac OS X
# TODO: this have to be checked, maybe unix way is good enough
grass7bin = '/Applications/GRASS/GRASS-7.8.app/'
elif sys.platform.startswith('linux'):
grass7bin = r'grass78'
else:
raise OSError('Platform not configured')
# Query GRASS 7 itself for its GISBASE
startcmd = [grass7bin, '--config', 'path']
p = subprocess.Popen(startcmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
print('ERROR: %s' % err, file=sys.stderr)
print("ERROR: Cannot find GRASS GIS 7 " \
"start script (%s)" % startcmd, file=sys.stderr)
sys.exit(-1)
if sys.platform.startswith('linux'):
gisbase = out.decode("utf-8").strip('\n')
elif sys.platform.startswith('win'):
if out.decode("utf-8").find("OSGEO4W home is") != -1:
gisbase = out.decode("utf-8").strip().split('\r\n')[1]
else:
gisbase = out.decode("utf-8").strip('\r\n')
os.environ['GRASS_SH'] = os.path.join(gisbase, 'mysys', 'bin', 'sh.exe')
else:
gisbase = out.decode("utf-8").strip('\n\r')
# Set environment variables
os.environ['GISBASE'] = gisbase
os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'extrabin')
# add path to GRASS addons
home = os.path.expanduser("~")
os.environ['PATH'] += os.pathsep + os.path.join(home, '.grass7', 'addons', 'scripts')
# Define GRASS-Python environment
gpydir = os.path.join(gisbase, "etc", "python")
sys.path.append(gpydir)
# Set GISDBASE environment variable
if sys.platform.startswith('win'):
gisdb = os.path.join(home, "Documents", "grassdata")
else:
gisdb = os.path.join(home, "grassdata")
os.environ['GISDBASE'] = gisdb
# Make GRASS GIS Database if doesn't already exist
if not os.path.exists(gisdb):
try:
os.makedirs(gisdb)
except OSError as e:
if e.errno != errno.EEXIST:
raise
# Linux: Set path to GRASS libs
path = os.getenv('LD_LIBRARY_PATH')
directory = os.path.join(gisbase, 'lib')
if path:
path = directory + os.pathsep + path
else:
path = directory
os.environ['LD_LIBRARY_PATH'] = path
# Language
os.environ['LANG'] = 'en_US'
os.environ['LOCALE'] = 'C'
# Location
location = 'geonet'
os.environ['LOCATION_NAME'] = location
grassGISlocation = os.path.join(gisdb, location)
if os.path.exists(grassGISlocation):
print("Cleaning existing Grass location")
shutil.rmtree(grassGISlocation)
mapset = 'PERMANENT'
os.environ['MAPSET'] = mapset
# import GRASS Python bindings
import grass.script as g
import grass.script.setup as gsetup
# Launch session
gsetup.init(gisbase, gisdb, location, mapset)
#originalGeotiff = os.path.join(Parameters.demDataFilePath, Parameters.demFileName)
geotiff = Parameters.pmGrassGISfileName
print('Making the geonet location')
g.run_command('g.proj', georef=geotiff, location = location)
print('Existing Mapsets after making locations:')
g.read_command('g.mapsets', flags = 'l')
print('Setting GRASSGIS environ')
gsetup.init(gisbase, gisdb, location, mapset)
## g.gisenv()
# Mapset
mapset = 'geonetuser'
os.environ['MAPSET'] = mapset
print('Making mapset now')
g.run_command('g.mapset', flags = 'c', mapset = mapset,\
location = location, dbase = gisdb)
# gsetup initialization
gsetup.init(gisbase, gisdb, location, mapset)
# Manage extensions
extensions = ['r.stream.basins', 'r.stream.watersheds']
extensions_installed = g.read_command('g.extension', 'a').splitlines()
for extension in extensions:
if extension in extensions_installed:
g.run_command('g.extension', extension=extension, operation="remove")
g.run_command('g.extension', extension=extension)
else:
g.run_command('g.extension', extension=extension)
# Read the filtered DEM
print('Import filtered DEM into GRASSGIS and '\
'name the new layer with the DEM name')
demFileName = Parameters.demFileName # this reads something like skunk.tif
geotiffmapraster = demFileName.split('.')[0]
print('GRASSGIS layer name: ',geotiffmapraster)
g.run_command('r.in.gdal', input=geotiff, \
output=geotiffmapraster,overwrite=True)
gtf = Parameters.geotransform
#Flow computation for massive grids (float version)
print("Calling the r.watershed command from GRASS GIS")
subbasinThreshold = defaults.thresholdAreaSubBasinIndexing
if (not hasattr(Parameters, 'xDemSize')) or (not hasattr(Parameters, 'yDemSize')):
Parameters.yDemSize=np.size(filteredDemArray,0)
Parameters.xDemSize=np.size(filteredDemArray,1)
if Parameters.xDemSize > 4000 or Parameters.yDemSize > 4000:
print ('using swap memory option for large size DEM')
g.run_command('r.watershed',flags ='am',overwrite=True,\
elevation=geotiffmapraster, \
threshold=subbasinThreshold, \
drainage = 'dra1v23')
g.run_command('r.watershed',flags ='am',overwrite=True,\
elevation=geotiffmapraster, \
threshold=subbasinThreshold, \
accumulation='acc1v23')
else :
g.run_command('r.watershed',flags ='a',overwrite=True,\
elevation=geotiffmapraster, \
threshold=subbasinThreshold, \
accumulation='acc1v23',\
drainage = 'dra1v23')
print('Identify outlets by negative flow direction')
g.run_command('r.mapcalc',overwrite=True,\
expression='outletmap = if(dra1v23 >= 0,null(),1)')
print('Convert outlet raster to vector')
g.run_command('r.to.vect',overwrite=True,\
input = 'outletmap', output = 'outletsmapvec',\
type='point')
print('Delineate basins according to outlets')
g.run_command('r.stream.basins',overwrite=True,\
direction='dra1v23',points='outletsmapvec',\
basins = 'outletbasins')
# Save the outputs as TIFs
outlet_filename = geotiffmapraster + '_outlets.tif'
g.run_command('r.out.gdal',overwrite=True,\
input='outletmap', type='Float32',\
output=os.path.join(Parameters.geonetResultsDir,
outlet_filename),\
format='GTiff')
outputFAC_filename = geotiffmapraster + '_fac.tif'
g.run_command('r.out.gdal',overwrite=True,\
input='acc1v23', type='Float64',\
output=os.path.join(Parameters.geonetResultsDir,
outputFAC_filename),\
format='GTiff')
outputFDR_filename = geotiffmapraster + '_fdr.tif'
g.run_command('r.out.gdal',overwrite=True,\
input = "dra1v23", type='Int32',\
output=os.path.join(Parameters.geonetResultsDir,
outputFDR_filename),\
format='GTiff')
outputBAS_filename = geotiffmapraster + '_basins.tif'
g.run_command('r.out.gdal',overwrite=True,\
input = "outletbasins", type='Int16',\
output=os.path.join(Parameters.geonetResultsDir,
outputBAS_filename),\
format='GTiff')
def main():
filteredDemArray = read_geotif_filteredDEM()
grass(filteredDemArray)
if __name__ == '__main__':
t0 = perf_counter()
main()
t1 = perf_counter()
print(("time taken to complete flow accumulation:", t1-t0, " seconds"))
sys.exit(0)