wolfhece 2.2.2__py3-none-any.whl → 2.2.4__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/PandasGrid.py +67 -0
- wolfhece/PyDraw.py +732 -34
- wolfhece/PyGui.py +6 -2
- wolfhece/PyPalette.py +10 -0
- wolfhece/PyVertex.py +15 -2
- wolfhece/PyWMS.py +72 -3
- wolfhece/acceptability/acceptability_gui.py +99 -155
- wolfhece/acceptability/func.py +88 -8
- wolfhece/apps/check_install.py +6 -6
- wolfhece/apps/splashscreen.py +5 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/assets/__init__.py +1 -0
- wolfhece/assets/speedometer.py +135 -0
- wolfhece/dike.py +684 -0
- wolfhece/drowning_victims/__init__.py +0 -0
- wolfhece/drowning_victims/drowning_class.py +2124 -0
- wolfhece/drowning_victims/drowning_functions.py +1019 -0
- wolfhece/lifewatch.py +88 -0
- wolfhece/scenario/config_manager.py +4 -4
- wolfhece/wolf_array.py +34 -11
- wolfhece/wolf_texture.py +9 -2
- {wolfhece-2.2.2.dist-info → wolfhece-2.2.4.dist-info}/METADATA +3 -1
- {wolfhece-2.2.2.dist-info → wolfhece-2.2.4.dist-info}/RECORD +26 -18
- {wolfhece-2.2.2.dist-info → wolfhece-2.2.4.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.2.dist-info → wolfhece-2.2.4.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.2.dist-info → wolfhece-2.2.4.dist-info}/top_level.txt +0 -0
wolfhece/PyGui.py
CHANGED
@@ -7,14 +7,18 @@ Copyright (c) 2024 University of Liege. All rights reserved.
|
|
7
7
|
This script and its content are protected by copyright law. Unauthorized
|
8
8
|
copying or distribution of this file, via any medium, is strictly prohibited.
|
9
9
|
"""
|
10
|
+
try:
|
11
|
+
from osgeo import gdal
|
12
|
+
except ImportError as e:
|
13
|
+
print(f"Import Error: {e} - GDAL")
|
14
|
+
print("Please install GDAL for your Python version.")
|
15
|
+
|
10
16
|
try:
|
11
17
|
from os import scandir, getcwd, makedirs
|
12
18
|
from os.path import exists, join, isdir, isfile, dirname, normpath, splitext
|
13
19
|
from pathlib import Path
|
14
20
|
import numpy.ma as ma
|
15
21
|
import wx
|
16
|
-
import wx.adv
|
17
|
-
from wx.lib.busy import BusyInfo
|
18
22
|
import logging
|
19
23
|
from pathlib import Path
|
20
24
|
except ImportError as e:
|
wolfhece/PyPalette.py
CHANGED
@@ -844,6 +844,16 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
|
|
844
844
|
|
845
845
|
self.fill_segmentdata()
|
846
846
|
|
847
|
+
def defaultred_minmax(self, array: ma.masked_array, nbnotnull=99999):
|
848
|
+
"""Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
|
849
|
+
|
850
|
+
self.nb = 2
|
851
|
+
self.values = np.asarray([np.min(array), np.max(array)], dtype=np.float64)
|
852
|
+
self.colors = np.asarray([[255, 255, 255, 255], [255, 0, 0, 255]], dtype=np.int32)
|
853
|
+
self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
|
854
|
+
|
855
|
+
self.fill_segmentdata()
|
856
|
+
|
847
857
|
def defaultblue(self):
|
848
858
|
"""Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
|
849
859
|
|
wolfhece/PyVertex.py
CHANGED
@@ -822,6 +822,20 @@ class cloud_vertices(Element_To_Draw):
|
|
822
822
|
# read data
|
823
823
|
gdf:gpd.GeoDataFrame = gpd.read_file(fn, bbox=bbox)
|
824
824
|
|
825
|
+
if gdf is None:
|
826
|
+
logging.error(_('Error during import of shapefile : ')+fn)
|
827
|
+
return
|
828
|
+
|
829
|
+
# check if the file is empty
|
830
|
+
if gdf.empty:
|
831
|
+
logging.error(_('Imported shapefile is empty : ')+fn)
|
832
|
+
return
|
833
|
+
|
834
|
+
#check if the number of lines is > 0
|
835
|
+
if len(gdf) == 0:
|
836
|
+
logging.error(_('Imported shapefile is empty : ')+fn)
|
837
|
+
return
|
838
|
+
|
825
839
|
# Bouclage sur les éléments du Shapefile
|
826
840
|
if targetcolumn in gdf.columns:
|
827
841
|
k=0
|
@@ -839,8 +853,7 @@ class cloud_vertices(Element_To_Draw):
|
|
839
853
|
elif 'geometry' in gdf.columns:
|
840
854
|
|
841
855
|
try:
|
842
|
-
for k, (xx,yy) in enumerate(zip(gdf.
|
843
|
-
|
856
|
+
for k, (xx,yy) in enumerate(zip(gdf.geometry.x, gdf.geometry.y)):
|
844
857
|
curvert = wolfvertex(xx, yy)
|
845
858
|
curdict = self.myvertices[k] = {}
|
846
859
|
curdict['vertex'] = curvert
|
wolfhece/PyWMS.py
CHANGED
@@ -16,6 +16,7 @@ import urllib.parse as ul
|
|
16
16
|
import wx
|
17
17
|
import logging
|
18
18
|
from typing import Union, Literal
|
19
|
+
from enum import Enum
|
19
20
|
|
20
21
|
from .PyTranslate import _
|
21
22
|
|
@@ -112,6 +113,7 @@ def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES',
|
|
112
113
|
return BytesIO(img.read())
|
113
114
|
except:
|
114
115
|
logging.warning(_('Impossible to get data from web services'))
|
116
|
+
pass
|
115
117
|
|
116
118
|
def getVlaanderen(cat:Literal['Adpf'],
|
117
119
|
xl:float,
|
@@ -166,6 +168,7 @@ def getVlaanderen(cat:Literal['Adpf'],
|
|
166
168
|
return BytesIO(img.read())
|
167
169
|
except:
|
168
170
|
logging.warning(_('Impossible to get data from web services'))
|
171
|
+
pass
|
169
172
|
|
170
173
|
|
171
174
|
def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
|
@@ -192,7 +195,73 @@ def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
|
|
192
195
|
else:
|
193
196
|
return BytesIO(img.read())
|
194
197
|
|
198
|
+
def getLifeWatch(cat:Literal['None'],
|
199
|
+
xl:float,
|
200
|
+
yl:float,
|
201
|
+
xr:float,
|
202
|
+
yr:float,
|
203
|
+
w:int = None,
|
204
|
+
h:int = None,
|
205
|
+
tofile=True) -> BytesIO:
|
206
|
+
|
207
|
+
wms=WebMapService(f'https://maps.elie.ucl.ac.be/cgi-bin/mapserv72?map=/maps_server/lifewatch/mapfiles/LW_Ecotopes/latest/{cat}.map&SERVICE=wms',
|
208
|
+
version='1.3.0')
|
209
|
+
|
210
|
+
ppkm = 300
|
211
|
+
if w is None and h is None:
|
212
|
+
real_w = (xr-xl)/1000
|
213
|
+
real_h = (yr-yl)/1000
|
214
|
+
w = int(real_w * ppkm)
|
215
|
+
h = int(real_h * ppkm)
|
216
|
+
elif w is None:
|
217
|
+
real_w = (xr-xl)/1000
|
218
|
+
real_h = (yr-yl)/1000
|
219
|
+
ppkm = h/real_h
|
220
|
+
w = int(real_w * ppkm)
|
221
|
+
# h = int(real_h * ppkm)
|
222
|
+
elif h is None:
|
223
|
+
real_w = (xr-xl)/1000
|
224
|
+
real_h = (yr-yl)/1000
|
225
|
+
ppkm = w/real_w
|
226
|
+
# w = int(real_w * ppkm)
|
227
|
+
h = int(real_h * ppkm)
|
228
|
+
|
229
|
+
if tofile:
|
230
|
+
img=wms.getmap(layers=['lc_hr_raster'],
|
231
|
+
# styles=['default'],
|
232
|
+
srs='EPSG:31370',
|
233
|
+
bbox=(xl,yl,xr,yr),
|
234
|
+
size=(w,h),
|
235
|
+
format='image/png',
|
236
|
+
transparent=False)
|
237
|
+
|
238
|
+
out = open('LifeWatch.png', 'wb')
|
239
|
+
out.write(img.read())
|
240
|
+
out.close()
|
241
|
+
return BytesIO(b'1')
|
242
|
+
else:
|
243
|
+
mycontents=list(wms.contents)
|
244
|
+
curcont=['lc_hr_raster'] # 'MS
|
245
|
+
curstyles=['1']
|
246
|
+
|
247
|
+
try:
|
248
|
+
img=wms.getmap(layers=curcont,
|
249
|
+
# styles=curstyles,
|
250
|
+
srs='EPSG:31370',
|
251
|
+
bbox=(xl,yl,xr,yr),
|
252
|
+
size=(w,h),
|
253
|
+
format='image/png',
|
254
|
+
transparent=False)
|
255
|
+
return BytesIO(img.read())
|
256
|
+
except:
|
257
|
+
logging.warning(_('Impossible to get data from web services'))
|
258
|
+
pass
|
259
|
+
|
195
260
|
if __name__=='__main__':
|
196
|
-
me=pyproj.CRS.from_epsg(27573)
|
197
|
-
t=pyproj.Transformer.from_crs(27573,4326)
|
198
|
-
getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
|
261
|
+
# me=pyproj.CRS.from_epsg(27573)
|
262
|
+
# t=pyproj.Transformer.from_crs(27573,4326)
|
263
|
+
# getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
|
264
|
+
img = getLifeWatch('',250000,160000,252000,162000,1000,1000,False)
|
265
|
+
img = Image.open(img)
|
266
|
+
img.show()
|
267
|
+
pass
|
@@ -41,7 +41,7 @@ def nullvalue_for_hole(WA):
|
|
41
41
|
WA.nullvalue = 0.
|
42
42
|
WA.set_nullvalue_in_mask()
|
43
43
|
|
44
|
-
def read_export_z_bin(fn_read, fn_write, fn_laststep):
|
44
|
+
def read_export_z_bin(fn_read, fn_write, fn_laststep, type_extraction):
|
45
45
|
"""
|
46
46
|
Reads the free surface altitude from a GPU simulation and exports it in binary format.
|
47
47
|
Inputs:
|
@@ -49,23 +49,38 @@ def read_export_z_bin(fn_read, fn_write, fn_laststep):
|
|
49
49
|
- fn_laststep: the folder EXTRACTED_LAST_STEP defined in acceptability.
|
50
50
|
- fn_write: the path to save the output in binary format.
|
51
51
|
"""
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
52
|
+
|
53
|
+
if type_extraction == "last_step":
|
54
|
+
fn_temp = os.path.join(fn_laststep, 'temp')
|
55
|
+
os.makedirs(fn_temp, exist_ok=True)
|
56
|
+
wolfres2DGPU_test = wolfres2DGPU(fn_read)
|
57
|
+
#changer ici + vérifier si bien SF ou WD (comparer ;) )
|
58
|
+
wolfres2DGPU_test.read_oneresult(-1)
|
59
|
+
wd = wolfres2DGPU_test.get_h_for_block(1)
|
60
|
+
top = wolfres2DGPU_test.get_top_for_block(1)
|
61
|
+
nullvalue_for_hole(wd)
|
62
|
+
nullvalue_for_hole(top)
|
63
|
+
wd.array = wd.array + top.array
|
64
|
+
fn_write = fn_write.with_suffix('.bin')
|
65
|
+
wd.write_all(fn_write)
|
66
|
+
shutil.rmtree(fn_temp)
|
67
|
+
|
68
|
+
if type_extraction == "danger_map":
|
69
|
+
fn_temp = os.path.join(fn_laststep, 'temp')
|
70
|
+
os.makedirs(fn_temp, exist_ok=True)
|
71
|
+
wolfres2DGPU_last = wolfres2DGPU(fn_read)
|
72
|
+
wolfres2DGPU_last.read_oneresult(-1)
|
73
|
+
danger_map_h = wolfres2DGPU(fn_read) .danger_map_only_h(0,-1,1)
|
74
|
+
top = wolfres2DGPU_last.get_top_for_block(1)
|
75
|
+
nullvalue_for_hole(danger_map_h)
|
76
|
+
nullvalue_for_hole(top)
|
77
|
+
danger_map_h.array[danger_map_h.array != 0] += top.array[danger_map_h.array != 0]
|
78
|
+
fn_write = fn_write.with_suffix('.bin')
|
79
|
+
danger_map_h.write_all(fn_write)
|
80
|
+
shutil.rmtree(fn_temp)
|
81
|
+
|
82
|
+
|
83
|
+
def riverbed_trace(fn_read_simu, fn_output, threshold, type_extraction):
|
69
84
|
"""
|
70
85
|
Recognizes the riverbed trace based on a simulation, where water depth above a given threshold is considered part of the riverbed.
|
71
86
|
Inputs:
|
@@ -73,15 +88,28 @@ def riverbed_trace(fn_read_simu, fn_output, threshold):
|
|
73
88
|
- fn_output: the location to save the riverbed trace as a .tiff file.
|
74
89
|
- threshold: the water depth threshold above which the areas are considered riverbed.
|
75
90
|
"""
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
91
|
+
|
92
|
+
|
93
|
+
if type_extraction == "last_step":
|
94
|
+
wolfres2DGPU_test = wolfres2DGPU(fn_read_simu)
|
95
|
+
wolfres2DGPU_test.read_oneresult(-1)
|
96
|
+
wd = wolfres2DGPU_test.get_h_for_block(1)
|
97
|
+
wd.array[wd.array > 1000] = 0
|
98
|
+
wd.array[wd.array > threshold] = 1
|
99
|
+
wd.array[wd.array < threshold] = 0
|
100
|
+
wd.as_WolfArray()
|
101
|
+
wd.nodata=0
|
102
|
+
wd.write_all(Path(fn_output))
|
103
|
+
|
104
|
+
if type_extraction=="danger_map":
|
105
|
+
wd = wolfres2DGPU(fn_read_simu) .danger_map_only_h(0,-1,1)
|
106
|
+
wd.array[wd.array > 1000] = 0
|
107
|
+
wd.array[wd.array > threshold] = 1
|
108
|
+
wd.array[wd.array < threshold] = 0
|
109
|
+
wd.as_WolfArray()
|
110
|
+
wd.nodata=0
|
111
|
+
wd.write_all(Path(fn_output))
|
112
|
+
|
85
113
|
|
86
114
|
def empty_folder(folder):
|
87
115
|
"""
|
@@ -161,7 +189,7 @@ def soustraction(fn_a,fn_b,fn_result):
|
|
161
189
|
#2 - DEM (MNT) value in the buildings traces ------------------------------------------------------------------
|
162
190
|
def mask_creation_data(mask_file, ground_file, output_file):
|
163
191
|
with rasterio.open(mask_file) as mask_src:
|
164
|
-
mask = mask_src.read(1)
|
192
|
+
mask = mask_src.read(1).astype('float32')
|
165
193
|
mask_meta = mask_src.meta
|
166
194
|
|
167
195
|
indices = np.where(mask > 0)
|
@@ -170,7 +198,7 @@ def mask_creation_data(mask_file, ground_file, output_file):
|
|
170
198
|
bathy = bathy_src.read(1)
|
171
199
|
|
172
200
|
mask[indices] = bathy[indices]
|
173
|
-
mask[mask <= 0] =
|
201
|
+
mask[mask <= 0] = 99999.
|
174
202
|
|
175
203
|
output_meta = mask_meta.copy()
|
176
204
|
output_meta.update({"dtype": 'float32'})
|
@@ -400,7 +428,10 @@ class AcceptabilityGui(wx.Frame):
|
|
400
428
|
def on_button_click(self, event):
|
401
429
|
self.PopupMenu(self.menu)
|
402
430
|
|
403
|
-
def
|
431
|
+
def on_button_click2(self, event2):
|
432
|
+
self.PopupMenu(self.menu2)
|
433
|
+
|
434
|
+
def onRiverbed(self, event):
|
404
435
|
"""Two options for the 'Update Riverbed' button: either the new riverbed trace
|
405
436
|
file already exists and the user selects it, or it does not exist, and the user points to
|
406
437
|
a no-overflow simulation, allowing the code to create the trace."""
|
@@ -454,11 +485,23 @@ class AcceptabilityGui(wx.Frame):
|
|
454
485
|
"Error", wx.OK | wx.ICON_ERROR
|
455
486
|
)
|
456
487
|
break
|
457
|
-
|
458
|
-
|
459
|
-
|
488
|
+
|
489
|
+
dialog = wx.SingleChoiceDialog(
|
490
|
+
parent=None,
|
491
|
+
message=f"Threshold accepted. Considering riverbed where water depth > {threshold}[m] via",
|
492
|
+
caption="Choix",
|
493
|
+
choices=["last step", "danger map"]
|
460
494
|
)
|
461
|
-
|
495
|
+
|
496
|
+
if dialog.ShowModal() == wx.ID_OK:
|
497
|
+
choix = dialog.GetStringSelection()
|
498
|
+
if choix == "last step":
|
499
|
+
type_extraction = "last step"
|
500
|
+
else:
|
501
|
+
type_extraction = "danger_map"
|
502
|
+
dialog.Destroy()
|
503
|
+
logging.info("Detecting riverbed.")
|
504
|
+
riverbed_trace(selected_folder, fn_output, threshold, type_extraction=type_extraction)
|
462
505
|
logging.info("File created.")
|
463
506
|
with wx.MessageDialog(
|
464
507
|
self,
|
@@ -548,7 +591,11 @@ class AcceptabilityGui(wx.Frame):
|
|
548
591
|
|
549
592
|
self._but_extrinterp = wx.Button(panel, label='Reading and interpolating\n free surface')
|
550
593
|
self._but_extrinterp.SetToolTip("To read the simulation, and created the hydraulic input for\n acceptability (interpolated simulated free surfaces)")
|
551
|
-
self._but_extrinterp.Bind(wx.EVT_BUTTON, self.
|
594
|
+
self._but_extrinterp.Bind(wx.EVT_BUTTON, self.on_button_click2)
|
595
|
+
self.menu2 = wx.Menu()
|
596
|
+
self.menu2.Append(1, "Interpolate the last step of the simulation.")
|
597
|
+
self.menu2.Append(2, "Interpolate the danger map of the simulation.")
|
598
|
+
self.menu2.Bind(wx.EVT_MENU, self.OnInterpolation)
|
552
599
|
sizer_hor1_1.Add(self._but_extrinterp, 1, wx.ALL | wx.EXPAND, 0)
|
553
600
|
|
554
601
|
sizer_hor1.Add(self._but_maindir, 2, wx.ALL | wx.EXPAND, 0)
|
@@ -606,7 +653,7 @@ class AcceptabilityGui(wx.Frame):
|
|
606
653
|
self.menu = wx.Menu()
|
607
654
|
self.menu.Append(1, "File of riverbed trace exists.")
|
608
655
|
self.menu.Append(2, "Point to a low discharge simulation and calculate the riverbed trace.")
|
609
|
-
self.menu.Bind(wx.EVT_MENU, self.
|
656
|
+
self.menu.Bind(wx.EVT_MENU, self.onRiverbed)
|
610
657
|
|
611
658
|
self._but_toggle_scen = wx.ToggleButton(panel, label="Accounting for scenarios")
|
612
659
|
self._but_toggle_scen.SetToolTip("To be activated to surimpose the vuln_ files, \n and so to take into account scenarios")
|
@@ -711,7 +758,7 @@ class AcceptabilityGui(wx.Frame):
|
|
711
758
|
dlg.ShowModal()
|
712
759
|
return
|
713
760
|
else :
|
714
|
-
if (self._manager._study_area
|
761
|
+
if (self._manager._study_area == None) or (self._manager._scenario == None):
|
715
762
|
logging.error(f"No study area and/or scenario selected, no check of TEMP and OUTPUT.")
|
716
763
|
with wx.MessageDialog(self, f"INPUT is well structured, but TEMP and OUTPUT have not been checked because there is no study area and scenario selected.", "Checking", wx.OK | wx.ICON_INFORMATION) as dlg:
|
717
764
|
dlg.ShowModal()
|
@@ -1078,10 +1125,16 @@ class AcceptabilityGui(wx.Frame):
|
|
1078
1125
|
return
|
1079
1126
|
|
1080
1127
|
def OnInterpolation(self,e):
|
1081
|
-
"""Interpolates the last extracted time steps present in
|
1082
|
-
LAST_STEP_EXTRACTED using the fast marching
|
1128
|
+
"""Interpolates the last extracted time steps present in LAST_STEP_EXTRACTED using the fast marching
|
1083
1129
|
interpolation routine holes.exe, by creating a batch file
|
1084
1130
|
while performing multiple checks on the required input files."""
|
1131
|
+
menu_id = e.GetId()
|
1132
|
+
if menu_id == 1:
|
1133
|
+
type_extraction = "last_step"
|
1134
|
+
logging.info("Option 1 : last step extraction and interpolation.")
|
1135
|
+
if menu_id == 2:
|
1136
|
+
type_extraction = "danger_map"
|
1137
|
+
logging.info("Option 2 : danger map computation and interpolation.")
|
1085
1138
|
|
1086
1139
|
if not hasattr(self, 'file_paths'):
|
1087
1140
|
with wx.MessageDialog(self,
|
@@ -1109,7 +1162,7 @@ class AcceptabilityGui(wx.Frame):
|
|
1109
1162
|
name = parts[1]
|
1110
1163
|
fn_write = Path(path_LastSteps / name )
|
1111
1164
|
dx,dy,nbx,nby,X,Y = display_info_header(self.input_dx, self.input_nbxy, self.input_O, fn_write.with_suffix(".bin"))
|
1112
|
-
read_export_z_bin(fn_read, fn_write, path_LastSteps)
|
1165
|
+
read_export_z_bin(fn_read, fn_write, path_LastSteps, type_extraction = type_extraction)
|
1113
1166
|
else:
|
1114
1167
|
logging.info(f"Please, ensure your simulations are named with the return period, e.g sim_T4")
|
1115
1168
|
else:
|
@@ -1117,136 +1170,27 @@ class AcceptabilityGui(wx.Frame):
|
|
1117
1170
|
else:
|
1118
1171
|
logging.error('No simulation selected! Please select some in the checkbox.')
|
1119
1172
|
|
1120
|
-
C = None
|
1121
|
-
D = None
|
1122
|
-
for file in os.listdir(Path(self._manager.IN_SA_DEM)):
|
1123
|
-
file_path = Path(self._manager.IN_SA_DEM) / file
|
1124
|
-
if file_path.is_file() and file.startswith("MNT_") and file_path.suffix == ".bin":
|
1125
|
-
if "mask" not in file:
|
1126
|
-
D = file_path
|
1127
|
-
else:
|
1128
|
-
C = file_path
|
1129
|
-
if D is None:
|
1130
|
-
logging.info("DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'")
|
1131
|
-
with wx.MessageDialog(self,
|
1132
|
-
f"DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'",
|
1133
|
-
"Missing file",
|
1134
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1135
|
-
dlg.ShowModal()
|
1136
|
-
return
|
1137
|
-
|
1138
|
-
if C is None:
|
1139
|
-
logging.info("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'")
|
1140
|
-
with wx.MessageDialog(self,
|
1141
|
-
f"DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'",
|
1142
|
-
"Missing file",
|
1143
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1144
|
-
dlg.ShowModal()
|
1145
|
-
return
|
1146
|
-
|
1147
|
-
if not get_header_comparison([fn_write.with_suffix(".bin"), C, D]):
|
1148
|
-
logging.info("Files in DEM_FILES do not have the same properties as the simulations files. Please, fix them.")
|
1149
|
-
with wx.MessageDialog(self,
|
1150
|
-
f"Files in DEM_FILES do not have the same properties as the simulations files. Please, fix them.",
|
1151
|
-
"Error in DEM_FILES files",
|
1152
|
-
style=wx.OK | wx.ICON_INFORMATION) as dlg:
|
1153
|
-
dlg.ShowModal()
|
1154
|
-
return
|
1155
|
-
|
1156
1173
|
checked_names = self._check_listbox.GetCheckedStrings()
|
1157
1174
|
if not checked_names:
|
1158
1175
|
logging.info("No items selected. Adding all paths.")
|
1159
1176
|
checked_paths = list(self.file_paths.values())
|
1160
|
-
message_info = "No simulations were checked in the box; so the computations will consider all of them. The interpolation of the given free surface will begin when you press OK, please wait."
|
1161
1177
|
else:
|
1162
1178
|
logging.info("Adding only the selected simulations.")
|
1163
1179
|
checked_paths = [self.file_paths[name] for name in checked_names]
|
1164
|
-
message_info = "The interpolation of the given free surface will begin (for the selected simulation(s)), please wait."
|
1165
1180
|
|
1166
1181
|
if len(self.file_paths) == 0 :
|
1167
|
-
|
1168
|
-
"OK", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1169
|
-
dlg.ShowModal()
|
1170
|
-
else :
|
1171
|
-
path_Interp = Path(self._manager.IN_SA_INTERP)
|
1172
|
-
path_bat_file = os.path.join(self._manager.IN_SCEN_DIR, "process_files.bat")
|
1173
|
-
|
1174
|
-
if os.path.exists(path_bat_file):
|
1175
|
-
logging.info(f"The file {path_bat_file} already exists and will be replaced.")
|
1176
|
-
os.remove(path_bat_file)
|
1177
|
-
path_code = os.path.join(self._manager.IN_WATER_DEPTH, "holes.exe")
|
1178
|
-
|
1179
|
-
|
1180
|
-
renamed_files = []
|
1181
|
-
if True:
|
1182
|
-
A=[]
|
1183
|
-
for path in checked_paths:
|
1184
|
-
parts = path.name.split("sim_")
|
1185
|
-
A.extend([os.path.join(path_LastSteps, g) for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.bin")])
|
1186
|
-
B = [os.path.join(path_Interp, os.path.splitext(os.path.basename(f))[0]) for f in A]
|
1187
|
-
if not A or not B or not C or not D:
|
1188
|
-
logging.info("Missing files.")
|
1189
|
-
with wx.MessageDialog(self, f"The interpolation cannot go on, as some files are missing (see logs): please check the DEM_FILES or the EXTRACTED_LAST_STEP_WD folders.",
|
1190
|
-
"Missing files.", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1191
|
-
dlg.ShowModal()
|
1192
|
-
with open(path_bat_file, "w") as bat_file:
|
1193
|
-
for a, b in zip(A, B):
|
1194
|
-
line = f'"{path_code}" filling in="{a}" out="{b}" mask="{C}" dem="{D} avoid_last=1"\n'
|
1195
|
-
bat_file.write(line)
|
1196
|
-
logging.info(message_info)
|
1197
|
-
|
1198
|
-
empty_folder(self._manager.IN_SA_INTERP)
|
1199
|
-
path_bat_file = os.path.join(self._manager.IN_SCEN_DIR, "process_files.bat")
|
1200
|
-
|
1201
|
-
# FORTRAN HOLES.EXE
|
1202
|
-
subprocess.run([path_bat_file], check=True)
|
1203
|
-
path_fichier=self._manager.IN_SA_INTERP
|
1204
|
-
for file in path_fichier.glob("*.tif"):
|
1205
|
-
if "_h" in file.name:
|
1206
|
-
new_name = file.stem.split("_h")[0].replace(".bin", "") + ".tif"
|
1207
|
-
file.rename(file.with_name(new_name))
|
1208
|
-
renamed_files.append(new_name)
|
1209
|
-
#deleting the other
|
1210
|
-
for file in path_fichier.glob("*.tif"):
|
1211
|
-
if "_combl" in file.name or file.name not in renamed_files:
|
1212
|
-
file.unlink()
|
1213
|
-
else:
|
1214
|
-
#Python eikonal model
|
1215
|
-
from ..eikonal import inpaint_array, inpaint_waterlevel
|
1216
|
-
|
1217
|
-
dtm = WolfArray(D)
|
1218
|
-
|
1219
|
-
A=[]
|
1220
|
-
for path in checked_paths:
|
1221
|
-
parts = path.name.split("sim_")
|
1222
|
-
A.extend([os.path.join(path_LastSteps, g) for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.tif")])
|
1223
|
-
if not A or not C or not D:
|
1224
|
-
logging.info("Missing files.")
|
1225
|
-
with wx.MessageDialog(self, f"The interpolation cannot go on, as some files are missing (see logs): please check the DEM_FILES or the EXTRACTED_LAST_STEP_WD folders.",
|
1226
|
-
"Missing files.", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1227
|
-
dlg.ShowModal()
|
1228
|
-
|
1229
|
-
empty_folder(self._manager.IN_SA_INTERP)
|
1230
|
-
|
1231
|
-
for a in A:
|
1232
|
-
a = Path(a)
|
1233
|
-
in_wa = WolfArray(a)
|
1234
|
-
dem_wa = WolfArray(a.parent / a.stem / "_dem.tif")
|
1235
|
-
_t, _wse, _wd = inpaint_waterlevel(in_wa.array, dem_wa.array.data, dtm.array.data, ignore_last_patches=1)
|
1182
|
+
return logging.info("No files in EXTRACTED_LAST_STEP_WD. Please provide some or use the 'Load gpu simulation' button.")
|
1236
1183
|
|
1237
|
-
|
1238
|
-
new_name = Path(b).with_suffix('.tif')
|
1239
|
-
renamed_files.append(new_name)
|
1240
|
-
|
1241
|
-
in_wa.array.data[:,:] = _wd
|
1242
|
-
in_wa.array.mask[:,:] = _wd == 0.
|
1243
|
-
in_wa.write_all(new_name)
|
1184
|
+
interp_bool, renamed_files = self._manager.batch_creation_and_interpolation(checked_paths,None)
|
1244
1185
|
|
1186
|
+
if interp_bool == True:
|
1245
1187
|
logging.info("Filling completed.")
|
1246
1188
|
with wx.MessageDialog(self, f"Filling completed. Created files : {renamed_files}",
|
1247
1189
|
"Redirecting", wx.OK | wx.ICON_INFORMATION) as dlg:
|
1248
1190
|
dlg.ShowModal()
|
1249
|
-
|
1191
|
+
update_info_header(self.input_dx,self.input_nbxy,self.input_O,self._manager.IN_SA_INTERP)
|
1192
|
+
else :
|
1193
|
+
logging.error("Something went wrong for the interpolation.")
|
1250
1194
|
|
1251
1195
|
def OnToggle(self,e):
|
1252
1196
|
"""Creates a toggle button to be activated if the scenarios vuln_ have to be taken into account."""
|
wolfhece/acceptability/func.py
CHANGED
@@ -15,6 +15,7 @@ from ..PyVertexvectors import Zones, zone, vector, wolfvertex, getIfromRGB
|
|
15
15
|
from ..PyTranslate import _
|
16
16
|
from ..scenario. config_manager import Config_Manager_2D_GPU
|
17
17
|
|
18
|
+
import subprocess
|
18
19
|
import geopandas as gpd
|
19
20
|
import pandas as pd
|
20
21
|
import numpy as np
|
@@ -94,6 +95,23 @@ def cleaning_directory(dir:Path):
|
|
94
95
|
if item.is_file():
|
95
96
|
os.remove(item)
|
96
97
|
|
98
|
+
def empty_folder(folder):
|
99
|
+
"""
|
100
|
+
Empties the content of a directory if it exists.
|
101
|
+
"""
|
102
|
+
if os.path.exists(folder):
|
103
|
+
for files in os.listdir(folder):
|
104
|
+
fn = os.path.join(folder, files)
|
105
|
+
try:
|
106
|
+
if os.path.isfile(fn) or os.path.islink(fn):
|
107
|
+
os.unlink(fn)
|
108
|
+
elif os.path.isdir(fn):
|
109
|
+
shutil.rmtree(fn)
|
110
|
+
except Exception as e:
|
111
|
+
print(f"Error when deleting file {fn}: {e}")
|
112
|
+
else:
|
113
|
+
print("The folder does not exist.")
|
114
|
+
|
97
115
|
class Accept_Manager():
|
98
116
|
"""
|
99
117
|
Structure to store the directories and names of the files.
|
@@ -608,10 +626,8 @@ class Accept_Manager():
|
|
608
626
|
for i in range(1, len(rt)-1):
|
609
627
|
# Full formula
|
610
628
|
# pond.append((1./float(rt[i-1]) - 1./float(rt[i]))/2. + (1./float(rt[i]) - 1./float(rt[i+1]))/2.)
|
611
|
-
|
612
629
|
# More compact formula
|
613
630
|
pond.append((1./float(rt[i-1]) - 1./float(rt[i+1]))/2.)
|
614
|
-
|
615
631
|
pond.append(1./float(rt[-1]) + (1./float(rt[-2]) - 1./float(rt[-1]))/2.)
|
616
632
|
|
617
633
|
return pd.DataFrame(pond, columns=["Ponderation"], index=rt)
|
@@ -898,15 +914,15 @@ class Accept_Manager():
|
|
898
914
|
|
899
915
|
if len(code) == 0:
|
900
916
|
logging.error("The code rasters do not exist")
|
901
|
-
return
|
917
|
+
return False
|
902
918
|
|
903
919
|
if len(vuln) == 0:
|
904
920
|
logging.error("The vulnerability rasters do not exist")
|
905
|
-
return
|
921
|
+
return False
|
906
922
|
|
907
923
|
if len(code) != len(vuln):
|
908
924
|
logging.error("The number of code and vulnerability rasters do not match")
|
909
|
-
return
|
925
|
+
return False
|
910
926
|
|
911
927
|
# we take a reference raster
|
912
928
|
ref = gdal.Open(str(code[0]))
|
@@ -1041,9 +1057,73 @@ class Accept_Manager():
|
|
1041
1057
|
else :
|
1042
1058
|
logging.error("No Masked_River_extent files. Please provide them.")
|
1043
1059
|
return trace
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1060
|
+
|
1061
|
+
# Interpolation
|
1062
|
+
# -----------------------------
|
1063
|
+
def batch_creation_and_interpolation(self, checked_paths, iftest):
|
1064
|
+
"""Creates a batch file to launch holes.exe from the selected simulations and launches it.
|
1065
|
+
-Every files in EXTRACTED_LAST_STEP are interpolated for tests (iftest==True).
|
1066
|
+
-Only the check simulations of the windows are interpolated for the GUI (iftest!=True)."""
|
1067
|
+
path_LastSteps = Path(self.IN_SA_EXTRACTED)
|
1068
|
+
C = None
|
1069
|
+
D = None
|
1070
|
+
for file in os.listdir(Path(self.IN_SA_DEM)):
|
1071
|
+
file_path = Path(self.IN_SA_DEM) / file
|
1072
|
+
if file_path.is_file() and file.startswith("MNT_") and file_path.suffix == ".bin":
|
1073
|
+
if "mask" not in file:
|
1074
|
+
D = file_path
|
1075
|
+
else:
|
1076
|
+
C = file_path
|
1077
|
+
if D == None:
|
1078
|
+
return logging.error("DEM (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and CANNOT include the word 'mask'")
|
1079
|
+
|
1080
|
+
if C == None:
|
1081
|
+
return logging.error("DEM mask (.bin) not found in DEM_FILES. The file must begins by 'MNT_' and MUST include the word 'mask'")
|
1082
|
+
|
1083
|
+
path_Interp = Path(self.IN_SA_INTERP)
|
1084
|
+
path_bat_file = os.path.join(self.IN_SCEN_DIR, "process_files.bat")
|
1085
|
+
|
1086
|
+
if os.path.exists(path_bat_file):
|
1087
|
+
logging.info(f"The file {path_bat_file} already exists and will be replaced.")
|
1088
|
+
os.remove(path_bat_file)
|
1089
|
+
path_code = os.path.join(self.IN_WATER_DEPTH, "holes.exe")
|
1090
|
+
A, B = [], []
|
1091
|
+
if iftest == True:
|
1092
|
+
#no checked box in the tests
|
1093
|
+
path_Interp = Path(self.IN_SA_INTERP)
|
1094
|
+
path_LastSteps = Path(self.IN_SA_EXTRACTED)
|
1095
|
+
A = [os.path.join(path_LastSteps,f) for f in os.listdir(path_LastSteps) if f.endswith('.bin') and not f.endswith('.bin.txt')]
|
1096
|
+
B = [os.path.join(path_Interp, os.path.splitext(os.path.basename(f))[0]) for f in A]
|
1097
|
+
|
1098
|
+
else :
|
1099
|
+
for path in checked_paths:
|
1100
|
+
parts = path.name.split("sim_")
|
1101
|
+
A.extend([os.path.join(path_LastSteps, g) for g in os.listdir(path_LastSteps) if g.endswith(f"{parts[1]}.bin")])
|
1102
|
+
B = [os.path.join(path_Interp, os.path.splitext(os.path.basename(f))[0]) for f in A]
|
1103
|
+
if not A or not B or not C or not D:
|
1104
|
+
return logging.error("Missing files.")
|
1105
|
+
with open(path_bat_file, "w") as bat_file:
|
1106
|
+
for a, b in zip(A, B):
|
1107
|
+
line = f'"{path_code}" filling in="{a}" out="{b}" mask="{C}" dem="{D} avoid_last=1"\n'
|
1108
|
+
bat_file.write(line)
|
1109
|
+
|
1110
|
+
empty_folder(self.IN_SA_INTERP)
|
1111
|
+
path_bat_file = os.path.join(self.IN_SCEN_DIR, "process_files.bat")
|
1112
|
+
subprocess.run([path_bat_file], check=True)
|
1113
|
+
|
1114
|
+
renamed_files = []
|
1115
|
+
path_fichier=self.IN_SA_INTERP
|
1116
|
+
for file in path_fichier.glob("*.tif"):
|
1117
|
+
if "_h" in file.name:
|
1118
|
+
new_name = file.stem.split("_h")[0].replace(".bin", "") + ".tif"
|
1119
|
+
file.rename(file.with_name(new_name))
|
1120
|
+
renamed_files.append(new_name)
|
1121
|
+
#deleting the other
|
1122
|
+
for file in path_fichier.glob("*.tif"):
|
1123
|
+
if "_combl" in file.name or file.name not in renamed_files:
|
1124
|
+
file.unlink()
|
1125
|
+
|
1126
|
+
return True, renamed_files
|
1047
1127
|
|
1048
1128
|
def clip_layer(layer:str,
|
1049
1129
|
file_path:str,
|