wolfhece 1.8.8__py3-none-any.whl → 1.8.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/GraphNotebook.py +5 -3
- wolfhece/PyDraw.py +13 -6
- wolfhece/PyVertex.py +61 -15
- wolfhece/eva/hydrogramme_mono.py +8 -3
- wolfhece/eva/pyseries.py +210 -25
- wolfhece/ftp/__init__.py +0 -0
- wolfhece/ftp/downloader.py +141 -0
- wolfhece/hydrology/Catchment.py +81 -4
- wolfhece/hydrology/Comparison.py +110 -3
- wolfhece/hydrology/Optimisation.py +32 -8
- wolfhece/hydrology/Outlet.py +4 -4
- wolfhece/hydrology/PyWatershed.py +1951 -0
- wolfhece/hydrology/RetentionBasin.py +6 -6
- wolfhece/hydrology/SubBasin.py +70 -25
- wolfhece/hydrology/data_treatment.py +5 -3
- wolfhece/hydrology/plot_hydrology.py +64 -3
- wolfhece/hydrology/read.py +4 -4
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/libs/WolfDll_debug.dll +0 -0
- wolfhece/mesh2d/wolf2dprev.py +104 -100
- wolfhece/radar/wolfradar.py +204 -13
- wolfhece/wolf_array.py +199 -87
- {wolfhece-1.8.8.dist-info → wolfhece-1.8.9.dist-info}/METADATA +4 -1
- {wolfhece-1.8.8.dist-info → wolfhece-1.8.9.dist-info}/RECORD +27 -24
- wolfhece/PyWatershed.py +0 -1686
- {wolfhece-1.8.8.dist-info → wolfhece-1.8.9.dist-info}/LICENCE +0 -0
- {wolfhece-1.8.8.dist-info → wolfhece-1.8.9.dist-info}/WHEEL +0 -0
- {wolfhece-1.8.8.dist-info → wolfhece-1.8.9.dist-info}/top_level.txt +0 -0
wolfhece/radar/wolfradar.py
CHANGED
@@ -1,41 +1,199 @@
|
|
1
|
-
import wradlib
|
1
|
+
import wradlib as wrl
|
2
|
+
import wx
|
3
|
+
from math import floor
|
4
|
+
from ..PyVertexvectors import *
|
5
|
+
from ..hydrology.read import *
|
2
6
|
from datetime import datetime as date
|
7
|
+
from datetime import timedelta as tdelta
|
8
|
+
from datetime import timezone
|
3
9
|
from os import path
|
4
|
-
from osgeo import gdal
|
5
|
-
from drawing_obj import Element_To_Draw
|
10
|
+
from osgeo import gdal, osr
|
11
|
+
from ..drawing_obj import Element_To_Draw
|
6
12
|
|
7
13
|
|
8
14
|
class L08L72:
|
15
|
+
epsgL08:osr.SpatialReference
|
16
|
+
epsgL72:osr.SpatialReference
|
17
|
+
_conv_L08_2_L72:osr.CoordinateTransformation
|
18
|
+
_conv_L72_2_L08:osr.CoordinateTransformation
|
9
19
|
|
10
20
|
def __init__(self) -> None:
|
11
|
-
|
21
|
+
self.epsgL08 = osr.SpatialReference()
|
22
|
+
self.epsgL72 = osr.SpatialReference()
|
23
|
+
self.epsgL08.ImportFromEPSG(3812)
|
24
|
+
self.epsgL72.ImportFromEPSG(31370)
|
12
25
|
|
13
|
-
|
14
|
-
|
26
|
+
self._conv_L08_2_L72 = osr.CoordinateTransformation(self.epsgL08,self.epsgL72)
|
27
|
+
self._conv_L72_2_L08 = osr.CoordinateTransformation(self.epsgL72,self.epsgL08)
|
15
28
|
|
16
|
-
def
|
17
|
-
|
29
|
+
def L08_2_72(self, x:float, y:float):
|
30
|
+
return self._conv_L08_2_L72.TransformPoint(x, y)[0:2]
|
31
|
+
|
32
|
+
def L72_2_08(self, x:float, y:float):
|
33
|
+
return self._conv_L72_2_L08.TransformPoint(x, y)[0:2]
|
18
34
|
|
19
35
|
|
20
36
|
|
21
37
|
class RadarIRM(Element_To_Draw):
|
22
38
|
def __init__(self, idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
|
23
|
-
super().__init__(idx, plotted, mapviewer, need_for_wx)
|
39
|
+
super().__init__(idx=idx, plotted=plotted, mapviewer=mapviewer, need_for_wx=need_for_wx)
|
24
40
|
pass
|
25
41
|
|
26
42
|
|
27
|
-
def convert2rain(self,
|
43
|
+
def convert2rain(self, coordMin:tuple, coordMax:tuple, dateBegin:date, dateEnd:date, deltaT:tdelta,
|
44
|
+
dirIn:str="", dirOut:str="",
|
45
|
+
check_all_polygons:bool=False):
|
46
|
+
|
47
|
+
from datetime import datetime as date
|
48
|
+
# =================
|
49
|
+
# ALL VERIFICATIONS :
|
50
|
+
|
51
|
+
# Checking the validity of the repository to read and write :
|
52
|
+
isOk, dirIn = check_path(dirIn, applyCWD=True)
|
53
|
+
if not isOk:
|
54
|
+
logging.error("The directory chosen for IRM data does not exist. Please check your path! ")
|
55
|
+
return
|
56
|
+
|
57
|
+
isOk, dirOut = check_path(dirOut, applyCWD=True)
|
58
|
+
if not isOk:
|
59
|
+
logging.error("The directory chosen for IRM data does not exist. Please check your path! ")
|
60
|
+
return
|
61
|
+
|
62
|
+
|
63
|
+
# Checking the validity of the dates :
|
64
|
+
dt = deltaT.total_seconds()
|
65
|
+
nb_intervals = floor((dateEnd - dateBegin).total_seconds() / dt)
|
66
|
+
time = [dateBegin + tdelta(seconds=dt*i) for i in range(nb_intervals + 1)]
|
67
|
+
# Prefix for dates
|
68
|
+
dt_str = "{:.0f}d".format(deltaT.days)*(deltaT.days>0) \
|
69
|
+
+ "{:.0f}h".format(floor(deltaT.seconds)/3600)*(floor(deltaT.seconds/3600)>0) \
|
70
|
+
+ "{:.0f}m".format(floor(deltaT.seconds%3600)/60)*(floor(deltaT.seconds%3600)/60>0)
|
71
|
+
suffix = "".join([".radclim.accum", dt_str, ".hdf"])
|
72
|
+
all_files = [os.path.join(dirIn,"".join([t.strftime("%Y%m%d%H%M%S"),suffix])) for t in time]
|
73
|
+
# are_present = np.all(np.array( \
|
74
|
+
# [os.path.exists(os.path.join(dirIn,"".join([t.strftime("%Y%m%d%H%M%S"),suffix]))) for t in time] \
|
75
|
+
# ))
|
76
|
+
|
77
|
+
are_present = np.all(np.array( \
|
78
|
+
[os.path.exists(el) for el in all_files] \
|
79
|
+
))
|
80
|
+
|
81
|
+
if not are_present:
|
82
|
+
logging.error("Rain files present in the selected directory are does not contain all the information between the desired interval.")
|
83
|
+
return
|
84
|
+
|
85
|
+
# Creating the direcory results
|
86
|
+
# Directory of the shapefile
|
87
|
+
shpDir = os.path.join(dirOut,'Grid')
|
88
|
+
if not os.path.exists(shpDir):
|
89
|
+
try:
|
90
|
+
os.mkdir(shpDir)
|
91
|
+
except OSError:
|
92
|
+
print ("Creation of the directory %s failed" % shpDir)
|
93
|
+
return
|
94
|
+
else:
|
95
|
+
print ("Successfully created the directory %s" % shpDir)
|
96
|
+
shpFile = "Grid_radar.shp"
|
97
|
+
fileOut = os.path.join(shpDir, shpFile)
|
98
|
+
else:
|
99
|
+
shpFile = "Grid_radar.shp"
|
100
|
+
fileOut = os.path.join(shpDir, shpFile)
|
101
|
+
# # Directory of the of the time series
|
102
|
+
timeSeriesDir = os.path.join(dirOut,'IRM')
|
103
|
+
if not os.path.exists(timeSeriesDir):
|
104
|
+
try:
|
105
|
+
os.mkdir(timeSeriesDir)
|
106
|
+
except OSError:
|
107
|
+
print ("Creation of the directory %s failed" % timeSeriesDir)
|
108
|
+
else:
|
109
|
+
print ("Successfully created the directory %s" % timeSeriesDir)
|
110
|
+
|
111
|
+
|
112
|
+
# =================
|
113
|
+
# CORE PROCEDURE
|
114
|
+
# After all verifications, the core procedure can now start :
|
28
115
|
# extract all the points in all the .hdf files and their values -> check whether to crop during this process of after
|
29
116
|
|
30
|
-
#
|
117
|
+
# Definition of the domaine zone
|
118
|
+
limits = vector()
|
119
|
+
limits.add_vertex(wolfvertex(coordMin[0],coordMin[1]))
|
120
|
+
limits.add_vertex(wolfvertex(coordMax[0],coordMin[1]))
|
121
|
+
limits.add_vertex(wolfvertex(coordMax[0],coordMax[1]))
|
122
|
+
limits.add_vertex(wolfvertex(coordMin[0],coordMax[1]))
|
123
|
+
|
124
|
+
# The shape file will be based on the first file read
|
125
|
+
cur_file = all_files[0]
|
126
|
+
hdf_ds = gdal.Open(cur_file, gdal.GA_ReadOnly)
|
127
|
+
values, coord, proj = wrl.georef.raster.extract_raster_dataset(hdf_ds, mode="edge", nodata=0.0)
|
31
128
|
|
32
129
|
# project the Lambert 2008 in Lambert 1972 coordinates -> let the possibility to crop either points or polygons
|
130
|
+
coord72 = np.zeros_like(coord)
|
131
|
+
proj72 = L08L72()
|
132
|
+
nbI, nbJ, nbC = np.shape(coord)
|
133
|
+
for i in range(nbI):
|
134
|
+
for j in range(nbJ):
|
135
|
+
coord72[i,j] = np.array(proj72.L08_2_72(coord[i,j,0],coord[i,j,1]))
|
136
|
+
|
137
|
+
|
138
|
+
# Creation of a list of polygons containing a list of vertices grouped in tuples
|
139
|
+
all_i, all_j = np.meshgrid(range(nbI-1),range(nbJ-1), indexing='ij')
|
140
|
+
polygons_list = [
|
141
|
+
[tuple(coord72[i][j]), tuple(coord72[i+1][j]),
|
142
|
+
tuple(coord72[i+1][j+1]), tuple(coord72[i][j+1]),
|
143
|
+
tuple(coord72[i][j])]
|
144
|
+
|
145
|
+
for i,j,v in zip(all_i.reshape(-1),all_j.reshape(-1),coord72[:-1, :-1].reshape(-1))
|
146
|
+
]
|
147
|
+
|
148
|
+
# create polygons out of the given points
|
149
|
+
polygons = zone()
|
150
|
+
zones_indices = []
|
151
|
+
i_zone = 0
|
152
|
+
for cur_poly in polygons_list:
|
153
|
+
cur_vec = vector(name=" ".join(["Zone", str(polygons.nbvectors+1)]))
|
154
|
+
is_inside = False
|
155
|
+
for cur_point in cur_poly:
|
156
|
+
cur_vec.add_vertex(wolfvertex(cur_point[0],cur_point[1]))
|
157
|
+
if limits.isinside(cur_point[0], cur_point[1]):
|
158
|
+
is_inside = True
|
159
|
+
if is_inside:
|
160
|
+
polygons.add_vector(cur_vec)
|
161
|
+
zones_indices.append(i_zone)
|
162
|
+
i_zone += 1
|
33
163
|
|
34
164
|
# save the polygons in .shp shapefile
|
165
|
+
polygons.export_shape(fileOut)
|
35
166
|
|
36
|
-
# Create a folder with the time serie for each polygone
|
37
167
|
|
38
|
-
|
168
|
+
# Create a folder with the time serie for each polygone
|
169
|
+
timeStps = [[str(t.day), str(t.month), str(t.year), str(t.hour), str(t.minute), str(t.second)] for t in time]
|
170
|
+
|
171
|
+
all_values = np.zeros((len(all_files), polygons.nbvectors))
|
172
|
+
for i in range(len(all_files)):
|
173
|
+
cur_file = all_files[i]
|
174
|
+
try:
|
175
|
+
hdf_ds = gdal.Open(cur_file, gdal.GA_ReadOnly)
|
176
|
+
values, coord, proj = wrl.georef.raster.extract_raster_dataset(hdf_ds, mode="edge", nodata=0.0)
|
177
|
+
vec_values = values.reshape(-1)
|
178
|
+
all_values[i,:] = np.nan_to_num([vec_values[i] for i in zones_indices], copy=False, nan=0.0)
|
179
|
+
# FIXME this following line -> to check !!!! -> Convert [mm/h] to accumulated rain [mm] at each time step
|
180
|
+
all_values[i,:] = all_values[i,:]*(dt/3600.0)
|
181
|
+
except:
|
182
|
+
logging.error("".join(["Something bad happened while reading hdf file :", cur_file]))
|
183
|
+
all_values[i,:] = 0.0
|
184
|
+
|
185
|
+
# Writing the file
|
186
|
+
for iVec in range(polygons.nbvectors):
|
187
|
+
with open(os.path.join(timeSeriesDir,"".join([str(iVec+1),".rain"])), 'w') as f:
|
188
|
+
f.write("".join([str(iVec+1),"\n"]))
|
189
|
+
f.write("".join([str(1),"\n"]))
|
190
|
+
f.write("".join([str(7),"\n"]))
|
191
|
+
f.write("".join([str(len(all_files)),"\n"]))
|
192
|
+
for cur_t in range(len(timeStps)):
|
193
|
+
f.write("\t".join(timeStps[cur_t] + [str(all_values[cur_t,iVec])]) + "\n")
|
194
|
+
|
195
|
+
|
196
|
+
print(are_present)
|
39
197
|
|
40
198
|
|
41
199
|
# def plot(self):
|
@@ -45,3 +203,36 @@ class RadarIRM(Element_To_Draw):
|
|
45
203
|
pass
|
46
204
|
|
47
205
|
|
206
|
+
|
207
|
+
|
208
|
+
if __name__ == "__main__":
|
209
|
+
|
210
|
+
app = wx.App()
|
211
|
+
# Selection of the working directory
|
212
|
+
idir=wx.DirDialog(None,"Please choose a IRM rain directory")
|
213
|
+
if idir.ShowModal() == wx.ID_CANCEL:
|
214
|
+
print("Operation cancelled!")
|
215
|
+
idir.Destroy()
|
216
|
+
|
217
|
+
readDir = idir.GetPath()
|
218
|
+
idir.Destroy()
|
219
|
+
|
220
|
+
idir=wx.DirDialog(None,"Please a directory to write results")
|
221
|
+
if idir.ShowModal() == wx.ID_CANCEL:
|
222
|
+
print("Operation cancelled!")
|
223
|
+
idir.Destroy()
|
224
|
+
|
225
|
+
writeDir = idir.GetPath()
|
226
|
+
idir.Destroy()
|
227
|
+
|
228
|
+
irm = RadarIRM()
|
229
|
+
coord_min = (0.0, 0.0)
|
230
|
+
coord_max = (0.0, 0.0)
|
231
|
+
db = date(year=2021, month=7, day=1, tzinfo=timezone.utc)
|
232
|
+
de = date(year=2021, month=7, day=31, hour=23, minute=55, tzinfo=timezone.utc)
|
233
|
+
dt = tdelta(minutes=5)
|
234
|
+
print(db)
|
235
|
+
|
236
|
+
irm.convert2rain(coord_min, coord_max, dateBegin=db, dateEnd=de, deltaT=dt, dirIn=readDir, dirOut=writeDir)
|
237
|
+
|
238
|
+
print("The End!")
|
wolfhece/wolf_array.py
CHANGED
@@ -82,9 +82,12 @@ def getkeyblock(i, addone=True):
|
|
82
82
|
return 'block' + str(i)
|
83
83
|
|
84
84
|
class header_wolf():
|
85
|
-
"""
|
86
|
-
|
87
|
-
|
85
|
+
"""
|
86
|
+
Header of WolfArray
|
87
|
+
|
88
|
+
In case of a mutliblock, the header have informations about all the blocks in head_blocks dictionnary.
|
89
|
+
Keys are generated by "getkeyblock" function
|
90
|
+
"""
|
88
91
|
|
89
92
|
# FIXME It'd be wise to put the multiblock case into another class.
|
90
93
|
# for example "header_wolf_MB" else one could construct hierearchies
|
@@ -119,11 +122,29 @@ class header_wolf():
|
|
119
122
|
self.nb_blocks = 0
|
120
123
|
self.head_blocks = {}
|
121
124
|
|
122
|
-
|
125
|
+
self.nbdims = 0
|
126
|
+
|
127
|
+
def __get_item__(self, key=None):
|
128
|
+
"""
|
129
|
+
return block header
|
130
|
+
|
131
|
+
:param key:int = block's index (0-based)
|
132
|
+
"""
|
133
|
+
if key is None:
|
134
|
+
return self
|
135
|
+
else:
|
136
|
+
return self.head_blocks[getkeyblock(int(key))]
|
137
|
+
|
138
|
+
def set_orig(self, x:float, y:float, z:float):
|
123
139
|
self.origx = x
|
124
140
|
self.origy = y
|
125
141
|
self.origz = z
|
126
142
|
|
143
|
+
def set_transl(self, tr_x:float, tr_y:float, tr_z:float):
|
144
|
+
self.translx = tr_x
|
145
|
+
self.transly = tr_y
|
146
|
+
self.translz = tr_z
|
147
|
+
|
127
148
|
def get_bounds(self, abs=True):
|
128
149
|
if abs:
|
129
150
|
return ([self.origx + self.translx, self.origx + self.translx + float(self.nbx) * self.dx],
|
@@ -140,18 +161,174 @@ class header_wolf():
|
|
140
161
|
[self.get_ij_from_xy(mybounds[0][0], mybounds[1][0]), self.get_ij_from_xy(mybounds[0][1], mybounds[0][0])],
|
141
162
|
[self.get_ij_from_xy(mybounds[0][0], mybounds[1][1]), self.get_ij_from_xy(mybounds[0][1], mybounds[1][1])])
|
142
163
|
|
143
|
-
def get_ij_from_xy(self, x, y, abs=True):
|
164
|
+
def get_ij_from_xy(self, x:float, y:float, z:float=0., scale:float=1., aswolf:bool=False, abs:bool=True, forcedims2:bool=False) -> Union[tuple[np.int32,np.int32], tuple[np.int32,np.int32,np.int32]]:
|
165
|
+
"""
|
166
|
+
Get indices from coordinates
|
167
|
+
|
168
|
+
:param x = X coordinate
|
169
|
+
:param y = Y coordinate
|
170
|
+
:param z = Z coordinate (optional)
|
171
|
+
:param scale = scaling of the spatial resolution (dx,dy,[dz])
|
172
|
+
:param aswolf = if True, return if one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
173
|
+
:param abs = if True, remove translation from (x, y, [z]) (coordinate from global space)
|
174
|
+
:param forcedims2 = if True, force to return only 2 indices even if z is supplied
|
175
|
+
"""
|
144
176
|
|
145
177
|
locx = np.float64(x) - self.origx
|
146
178
|
locy = np.float64(y) - self.origy
|
179
|
+
locz = np.float64(z) - self.origz
|
147
180
|
if abs:
|
148
181
|
locx = locx - self.translx
|
149
182
|
locy = locy - self.transly
|
183
|
+
locz = locz - self.translz
|
184
|
+
|
185
|
+
i = np.int32(locx / (self.dx * scale))
|
186
|
+
j = np.int32(locy / (self.dy * scale))
|
187
|
+
|
188
|
+
if aswolf:
|
189
|
+
i += 1
|
190
|
+
j += 1
|
191
|
+
|
192
|
+
if self.nbdims == 3 and not forcedims2:
|
193
|
+
k = np.int32(locz / (self.dz * scale))
|
194
|
+
if aswolf:
|
195
|
+
k += 1
|
196
|
+
return i, j, k
|
197
|
+
elif self.nbdims == 2 or forcedims2:
|
198
|
+
return i, j
|
199
|
+
|
200
|
+
def get_ij_from_xy_array(self, xy:np.ndarray, scale:float=1., aswolf:bool=False, abs:bool=True, forcedims2:bool=False) -> np.ndarray:
|
201
|
+
"""
|
202
|
+
Get indices from coordinates
|
203
|
+
|
204
|
+
:param xy = numpy array containing (x, y, [z]) coordinates
|
205
|
+
:param scale = scaling of the spatial resolution (dx,dy,[dz])
|
206
|
+
:param aswolf = if True, return if one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
207
|
+
:param abs = if True, remove translation from (x, y, [z]) (coordinate from global space)
|
208
|
+
:param forcedims2 = if True, force to return only 2 indices even if z is supplied
|
209
|
+
"""
|
210
|
+
|
211
|
+
locxy = xy.copy()
|
212
|
+
|
213
|
+
if forcedims2:
|
214
|
+
locij = np.zeros((xy.shape[0],2), dtype=np.int32)
|
215
|
+
else:
|
216
|
+
locij = np.zeros(xy.shape, dtype=np.int32)
|
217
|
+
|
218
|
+
locxy[:,0] -= self.origx
|
219
|
+
locxy[:,1] -= self.origy
|
220
|
+
|
221
|
+
if abs:
|
222
|
+
locxy[:,0] -= self.translx
|
223
|
+
locxy[:,1] -= self.transly
|
224
|
+
|
225
|
+
i = np.int32(locxy[:,0] / (self.dx * scale))
|
226
|
+
j = np.int32(locxy[:,2] / (self.dy * scale))
|
227
|
+
|
228
|
+
if aswolf:
|
229
|
+
i += 1
|
230
|
+
j += 1
|
231
|
+
|
232
|
+
if self.nbdims == 3 and not forcedims2:
|
233
|
+
locxy[:,2] -= self.origz
|
234
|
+
if abs:
|
235
|
+
locxy[:,2] -= self.translz
|
236
|
+
k = np.int32(locxy[:,3] / (self.dz * scale))
|
237
|
+
|
238
|
+
if aswolf:
|
239
|
+
k += 1
|
240
|
+
|
241
|
+
locij[:,0] = i
|
242
|
+
locij[:,1] = j
|
243
|
+
locij[:,2] = k
|
244
|
+
|
245
|
+
return locij
|
246
|
+
|
247
|
+
elif self.nbdims == 2 or forcedims2:
|
248
|
+
locij[:,0] = i
|
249
|
+
locij[:,1] = j
|
250
|
+
return locij
|
251
|
+
|
252
|
+
|
253
|
+
def get_xy_from_ij(self, i:int, j:int, k:int=0, scale:float=1., aswolf:bool=False, abs:bool=True) -> Union[tuple[np.float64,np.float64], tuple[np.float64,np.float64,np.float64]]:
|
254
|
+
"""
|
255
|
+
Get coordinates from indices
|
256
|
+
|
257
|
+
:param i = index along X coordinate
|
258
|
+
:param j = index along Y coordinate
|
259
|
+
:param k = index along Z coordinate (optional)
|
260
|
+
:param scale = scaling of the spatial resolution (dx,dy,[dz])
|
261
|
+
:param aswolf = if True, input is one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
262
|
+
:param abs = if True, add translation to results (x, y, [z]) (coordinate to global space)
|
263
|
+
"""
|
264
|
+
i = np.int32(i)
|
265
|
+
j = np.int32(j)
|
266
|
+
|
267
|
+
if aswolf:
|
268
|
+
# FIXME Put assertion here.
|
269
|
+
i += -1
|
270
|
+
j += -1
|
271
|
+
|
272
|
+
if abs:
|
273
|
+
x = (np.float64(i) + .5) * (self.dx * scale) + self.origx + self.translx
|
274
|
+
y = (np.float64(j) + .5) * (self.dy * scale) + self.origy + self.transly
|
275
|
+
else:
|
276
|
+
x = (np.float64(i) + .5) * (self.dx * scale) + self.origx
|
277
|
+
y = (np.float64(j) + .5) * (self.dy * scale) + self.origy
|
278
|
+
|
279
|
+
if self.nbdims == 3:
|
280
|
+
k = np.int32(k)
|
281
|
+
if aswolf:
|
282
|
+
k += -1
|
283
|
+
|
284
|
+
if abs:
|
285
|
+
z = (np.float64(k) - .5) * (self.dz * scale) + self.origz + self.translz
|
286
|
+
else:
|
287
|
+
z = (np.float64(k) - .5) * (self.dz * scale) + self.origz
|
288
|
+
|
289
|
+
return x, y, z
|
150
290
|
|
151
|
-
|
152
|
-
|
291
|
+
elif self.nbdims == 2:
|
292
|
+
return x, y
|
293
|
+
else:
|
294
|
+
raise Exception(_("The number of coordinates is not correct"))
|
153
295
|
|
154
|
-
|
296
|
+
def get_xy_from_ij_array(self, ij:np.ndarray, scale:float=1., aswolf:bool=False, abs:bool=True) -> np.ndarray:
|
297
|
+
"""
|
298
|
+
Converts array coordinates (numpy cells) to this array's world coodinates.
|
299
|
+
|
300
|
+
:param ij = numpy array containing (i, j, [k]) indices
|
301
|
+
:param scale = scaling of the spatial resolution (dx,dy,[dz])
|
302
|
+
:param aswolf = if True, input is one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
303
|
+
:param abs = if True, add translation to results (x, y, [z]) (coordinate to global space)
|
304
|
+
"""
|
305
|
+
|
306
|
+
if abs:
|
307
|
+
tr_x = self.translx
|
308
|
+
tr_y = self.transly
|
309
|
+
tr_z = self.translz
|
310
|
+
else:
|
311
|
+
tr_x = 0.
|
312
|
+
tr_y = 0.
|
313
|
+
tr_z = 0.
|
314
|
+
|
315
|
+
if aswolf:
|
316
|
+
decali = -1
|
317
|
+
decalj = -1
|
318
|
+
decalk = -1
|
319
|
+
else:
|
320
|
+
decali = 0
|
321
|
+
decalj = 0
|
322
|
+
decalk = 0
|
323
|
+
|
324
|
+
xy = np.zeros(ij.shape)
|
325
|
+
xy[:,0] = (np.float64( (ij[:,0])+decali) + .5) * (self.dx*scale) + self.origx + tr_x
|
326
|
+
xy[:,1] = (np.float64( (ij[:,1])+decalj) + .5) * (self.dy*scale) + self.origy + tr_y
|
327
|
+
|
328
|
+
if self.nbdims == 3 and ij.shape[2]==3:
|
329
|
+
xy[:,2] = (np.float64( (ij[:,2])+decalk) + .5) * (self.dz*scale) + self.origz + tr_z
|
330
|
+
|
331
|
+
return xy
|
155
332
|
|
156
333
|
def find_intersection(self, other, ij=False):
|
157
334
|
|
@@ -251,6 +428,8 @@ class header_wolf():
|
|
251
428
|
test &= self.nby == other.nby
|
252
429
|
test &= self.nbz == other.nbz
|
253
430
|
|
431
|
+
test &= self.nbdims == other.nbdims
|
432
|
+
|
254
433
|
return test
|
255
434
|
|
256
435
|
class NewArray(wx.Dialog):
|
@@ -2483,6 +2662,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
2483
2662
|
|
2484
2663
|
# Data type of the values
|
2485
2664
|
self.nullvalue = band.GetNoDataValue()
|
2665
|
+
if self.nullvalue is None:
|
2666
|
+
self.nullvalue = 0.
|
2486
2667
|
|
2487
2668
|
geotr = raster.GetGeoTransform()
|
2488
2669
|
self.origx = geotr[0]
|
@@ -3271,6 +3452,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3271
3452
|
|
3272
3453
|
curhead.head_blocks = self.head_blocks.copy()
|
3273
3454
|
|
3455
|
+
curhead.nbdims = self.nbdims
|
3456
|
+
|
3274
3457
|
if abs:
|
3275
3458
|
curhead.origx += curhead.translx
|
3276
3459
|
curhead.origy += curhead.transly
|
@@ -3298,6 +3481,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3298
3481
|
self.nby = header.nby
|
3299
3482
|
self.nbz = header.nbz
|
3300
3483
|
|
3484
|
+
self.nbdims = header.nbdims
|
3485
|
+
|
3301
3486
|
self.nb_blocks = header.nb_blocks
|
3302
3487
|
self.head_blocks = header.head_blocks.copy()
|
3303
3488
|
|
@@ -4021,10 +4206,11 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4021
4206
|
if self.array is None:
|
4022
4207
|
return
|
4023
4208
|
|
4024
|
-
if
|
4025
|
-
|
4026
|
-
|
4027
|
-
|
4209
|
+
if value is not None:
|
4210
|
+
if np.isnan(value) or math.isnan(value):
|
4211
|
+
self.array.mask = np.isnan(self.array.data)
|
4212
|
+
else:
|
4213
|
+
self.array.mask = self.array.data == value
|
4028
4214
|
self.nbnotnull = self.array.count()
|
4029
4215
|
|
4030
4216
|
def mask_lower(self, value):
|
@@ -4165,80 +4351,6 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4165
4351
|
|
4166
4352
|
return ([ox, ex], [oy, ey])
|
4167
4353
|
|
4168
|
-
def get_ij_from_xy(self, x, y, z=0., scale=1., aswolf=False, abs=True, forcedims2=False):
|
4169
|
-
# FIXME Use wolf_header's functions for 2D
|
4170
|
-
# FIXME aswolf, abs, etc. seems too tricky to me
|
4171
|
-
|
4172
|
-
locx = np.float64(x) - self.origx
|
4173
|
-
locy = np.float64(y) - self.origy
|
4174
|
-
locz = np.float64(z) - self.origz
|
4175
|
-
if abs:
|
4176
|
-
locx = locx - self.translx
|
4177
|
-
locy = locy - self.transly
|
4178
|
-
locz = locz - self.translz
|
4179
|
-
|
4180
|
-
i = np.int32(locx / (self.dx * scale))
|
4181
|
-
j = np.int32(locy / (self.dy * scale))
|
4182
|
-
|
4183
|
-
if aswolf:
|
4184
|
-
i += 1
|
4185
|
-
j += 1
|
4186
|
-
|
4187
|
-
if self.nbdims == 3 and not forcedims2:
|
4188
|
-
k = np.int32(locz / (self.dz * scale))
|
4189
|
-
if aswolf:
|
4190
|
-
k += 1
|
4191
|
-
return i, j, k # ATTENTION, Indices en numérotation Python --> WOLF ajouter +1
|
4192
|
-
elif self.nbdims == 2 or forcedims2:
|
4193
|
-
return i, j # ATTENTION, Indices en numérotation Python --> WOLF ajouter +1
|
4194
|
-
|
4195
|
-
def get_xy_from_ij(self, i, j, k=0, scale=1., aswolf=False, abs=True) -> Union[tuple[np.float64,np.float64], tuple[np.float64,np.float64,np.float64]]:
|
4196
|
-
# i,j are expected to be zero-based, unless `aswolf` is True in which
|
4197
|
-
# case they are expected to be one based
|
4198
|
-
|
4199
|
-
# FIXME Use wolf_header's functions for 2D ?
|
4200
|
-
i = np.int32(i)
|
4201
|
-
j = np.int32(j)
|
4202
|
-
|
4203
|
-
if aswolf:
|
4204
|
-
# FIXME Put assertion here.
|
4205
|
-
i += -1
|
4206
|
-
j += -1
|
4207
|
-
|
4208
|
-
if abs:
|
4209
|
-
x = (np.float64(i) + .5) * (self.dx * scale) + self.origx + self.translx
|
4210
|
-
y = (np.float64(j) + .5) * (self.dy * scale) + self.origy + self.transly
|
4211
|
-
else:
|
4212
|
-
x = (np.float64(i) + .5) * (self.dx * scale) + self.origx
|
4213
|
-
y = (np.float64(j) + .5) * (self.dy * scale) + self.origy
|
4214
|
-
|
4215
|
-
if self.nbdims == 3:
|
4216
|
-
k = np.int32(k)
|
4217
|
-
if aswolf:
|
4218
|
-
k += -1
|
4219
|
-
|
4220
|
-
if abs:
|
4221
|
-
z = (np.float64(k) - .5) * (self.dz * scale) + self.origz + self.translz
|
4222
|
-
else:
|
4223
|
-
z = (np.float64(k) - .5) * (self.dz * scale) + self.origz
|
4224
|
-
|
4225
|
-
return x, y, z
|
4226
|
-
|
4227
|
-
elif self.nbdims == 2:
|
4228
|
-
return x, y
|
4229
|
-
else:
|
4230
|
-
raise Exception(_("The number of coordinates is not correct"))
|
4231
|
-
|
4232
|
-
def get_xy_from_ij_array(self, ij:np.ndarray):
|
4233
|
-
# Converts array coordinates (numpy cells, 0-based)
|
4234
|
-
# to this array's world coodinates.
|
4235
|
-
|
4236
|
-
xy = np.zeros(ij.shape)
|
4237
|
-
xy[:,0] = (np.float64(ij[:,0]) + .5) * self.dx + self.origx + self.translx
|
4238
|
-
xy[:,1] = (np.float64(ij[:,1]) + .5) * self.dy + self.origy + self.transly
|
4239
|
-
|
4240
|
-
return xy
|
4241
|
-
|
4242
4354
|
def get_value(self, x, y, z=0., nullvalue=-99999):
|
4243
4355
|
|
4244
4356
|
if self.nbdims == 2:
|
@@ -4710,7 +4822,7 @@ class WolfArrayMB(WolfArray):
|
|
4710
4822
|
curarray = self.myblocks[getkeyblock(i)]
|
4711
4823
|
f.write(curarray.array.data.transpose().tobytes())
|
4712
4824
|
|
4713
|
-
def get_ij_from_xy(self, x, y, z=0
|
4825
|
+
def get_ij_from_xy(self, x:float, y:float, z:float=0., scale:float=1., aswolf:bool=False, abs:bool=True, which_block:int=1):
|
4714
4826
|
return self.myblocks[getkeyblock(which_block, False)].get_ij_from_xy(x, y, z, scale, aswolf, abs)
|
4715
4827
|
|
4716
4828
|
def get_values_as_wolf(self, i, j, which_block=1):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: wolfhece
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.9
|
4
4
|
Summary: WOLF package
|
5
5
|
Home-page: https://uee.uliege.be/hece
|
6
6
|
Author: Pierre Archambeau
|
@@ -16,6 +16,7 @@ Requires-Dist: wxpython
|
|
16
16
|
Requires-Dist: numpy
|
17
17
|
Requires-Dist: pyopengl
|
18
18
|
Requires-Dist: pandas
|
19
|
+
Requires-Dist: geopandas
|
19
20
|
Requires-Dist: scipy
|
20
21
|
Requires-Dist: owslib
|
21
22
|
Requires-Dist: pillow
|
@@ -43,6 +44,8 @@ Requires-Dist: pygltflib
|
|
43
44
|
Requires-Dist: ezdxf
|
44
45
|
Requires-Dist: pyvista
|
45
46
|
Requires-Dist: tqdm
|
47
|
+
Requires-Dist: osmnx
|
48
|
+
Requires-Dist: tifffile
|
46
49
|
|
47
50
|
Ce paquet contient l'interface graphique Python du logiciel WOLF (HECE - ULiège) de même que plusieurs outils de traitements topographique, hydraulique et hydrologique.
|
48
51
|
|