wolfhece 2.2.37__py3-none-any.whl → 2.2.39__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.
Files changed (53) hide show
  1. wolfhece/Coordinates_operations.py +5 -0
  2. wolfhece/GraphNotebook.py +72 -1
  3. wolfhece/GraphProfile.py +1 -1
  4. wolfhece/MulticriteriAnalysis.py +1579 -0
  5. wolfhece/PandasGrid.py +62 -1
  6. wolfhece/PyCrosssections.py +194 -43
  7. wolfhece/PyDraw.py +891 -73
  8. wolfhece/PyGui.py +913 -72
  9. wolfhece/PyGuiHydrology.py +528 -74
  10. wolfhece/PyPalette.py +26 -4
  11. wolfhece/PyParams.py +33 -0
  12. wolfhece/PyPictures.py +2 -2
  13. wolfhece/PyVertex.py +32 -0
  14. wolfhece/PyVertexvectors.py +147 -75
  15. wolfhece/PyWMS.py +52 -36
  16. wolfhece/acceptability/acceptability.py +15 -8
  17. wolfhece/acceptability/acceptability_gui.py +507 -360
  18. wolfhece/acceptability/func.py +80 -183
  19. wolfhece/apps/version.py +1 -1
  20. wolfhece/compare_series.py +480 -0
  21. wolfhece/drawing_obj.py +12 -1
  22. wolfhece/hydrology/Catchment.py +228 -162
  23. wolfhece/hydrology/Internal_variables.py +43 -2
  24. wolfhece/hydrology/Models_characteristics.py +69 -67
  25. wolfhece/hydrology/Optimisation.py +893 -182
  26. wolfhece/hydrology/PyWatershed.py +267 -165
  27. wolfhece/hydrology/SubBasin.py +185 -140
  28. wolfhece/hydrology/climate_data.py +334 -0
  29. wolfhece/hydrology/constant.py +11 -0
  30. wolfhece/hydrology/cst_exchanges.py +76 -1
  31. wolfhece/hydrology/forcedexchanges.py +413 -49
  32. wolfhece/hydrology/hyetograms.py +2095 -0
  33. wolfhece/hydrology/read.py +65 -5
  34. wolfhece/hydrometry/kiwis.py +42 -26
  35. wolfhece/hydrometry/kiwis_gui.py +7 -2
  36. wolfhece/insyde_be/INBE_func.py +746 -0
  37. wolfhece/insyde_be/INBE_gui.py +1776 -0
  38. wolfhece/insyde_be/__init__.py +3 -0
  39. wolfhece/interpolating_raster.py +366 -0
  40. wolfhece/irm_alaro.py +1457 -0
  41. wolfhece/irm_qdf.py +889 -57
  42. wolfhece/lifewatch.py +6 -3
  43. wolfhece/picc.py +124 -8
  44. wolfhece/pyLandUseFlanders.py +146 -0
  45. wolfhece/pydownloader.py +2 -1
  46. wolfhece/pywalous.py +225 -31
  47. wolfhece/toolshydrology_dll.py +149 -0
  48. wolfhece/wolf_array.py +63 -25
  49. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/METADATA +3 -1
  50. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/RECORD +53 -42
  51. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/WHEEL +0 -0
  52. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/entry_points.txt +0 -0
  53. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/top_level.txt +0 -0
wolfhece/pywalous.py CHANGED
@@ -23,7 +23,7 @@ import wx.grid
23
23
  from .PyTranslate import _
24
24
  from .PyPalette import wolfpalette
25
25
 
26
- WALOUS_MAJ_NIV1 = {'Production primaire': 1.,
26
+ WALOUS_UTS_MAJ_NIV1 = {'Production primaire': 1.,
27
27
  'Production secondaire': 2.,
28
28
  'Production tertiaire': 3.,
29
29
  'Réseaux de transport, Logistique et réseaux d\'utilité publique': 4.,
@@ -31,7 +31,7 @@ WALOUS_MAJ_NIV1 = {'Production primaire': 1.,
31
31
  'Autres usages': 6.,
32
32
  'Zones naturelles': 7.}
33
33
 
34
- WALOUS_MAJ_NIV2 = {'Agriculture': 11.,
34
+ WALOUS_UTS_MAJ_NIV2 = {'Agriculture': 11.,
35
35
  'Sylviculture': 12.,
36
36
  'Industries Extractives': 13.,
37
37
  'Aquaculture et pêche':14,
@@ -54,7 +54,7 @@ WALOUS_MAJ_NIV2 = {'Agriculture': 11.,
54
54
  'Usage inconnu': 66.,
55
55
  'Zones naturelles': 70.}
56
56
 
57
- WALOUS_COLORMAP_MAJ_NIV1 = {1.: (181,230,90,255),
57
+ WALOUS_UTS_COLORMAP_MAJ_NIV1 = {1.: (181,230,90,255),
58
58
  2.: (99,99,99,255),
59
59
  3.: (159,187,215,255),
60
60
  4.: (181,121,241,255),
@@ -62,7 +62,7 @@ WALOUS_COLORMAP_MAJ_NIV1 = {1.: (181,230,90,255),
62
62
  6.: (221,221,221,255),
63
63
  7.: (255,255,190,255)}
64
64
 
65
- WALOUS_COLORMAP_MAJ_NIV2 = {11.: (153,230,0,255),
65
+ WALOUS_UTS_COLORMAP_MAJ_NIV2 = {11.: (153,230,0,255),
66
66
  12.: (55,168,0,255),
67
67
  13.: (142,181,180,255),
68
68
  14.: (172,250,192,255),
@@ -85,7 +85,61 @@ WALOUS_COLORMAP_MAJ_NIV2 = {11.: (153,230,0,255),
85
85
  66.: (206,136,102,255),
86
86
  70.: (255,255,190,255)}
87
87
 
88
- def get_palette_walous(which:Literal['MAJ_NIV1', 'MAJ_NIV2']) -> wolfpalette:
88
+ WALOUS_OCS = { "Couvert herbacé en rotation dans l'année": 1.,
89
+ "Couvert herbacé toute l'année": 2.,
90
+ "Résineux (>3 m)": 3.,
91
+ "Feuillus (> 3m)": 4.,
92
+ "Résineux (<= 3m)": 5.,
93
+ "Feuillus (<= 3m)": 6.,
94
+ "Sols nus": 7.,
95
+ "Eaux de surface": 8.,
96
+ "Revêtement artificiels au sol": 9.,
97
+ "Réseau ferroviaire": 10.,
98
+ "Constructions artificielles hors sol": 11.}
99
+
100
+ WALOUS_OCS_COLORMAP = {1.: (255,254,162,255), # Couvert herbacé en rotation dans l'année
101
+ 2.: (253,254,194,255), # Couvert herbacé toute l'année
102
+ 3.: (3,49,5,255), # Résineux (>3 m)
103
+ 4.: (55,198,61,255), # Feuillus (> 3m)
104
+ 5.: (18,119,23,255), # Résineux (<= 3m)
105
+ 6.: (185,231,179,255), # Feuillus (<= 3m)
106
+ 7.: (208,208,208,255), # Sols nus
107
+ 8.: (45,101,242,255), # Eaux de surface
108
+ 9.: (138,138,138,255), # Revêtement artificiels au sol
109
+ 10.: (78,78,78,255), # Réseau ferroviaire
110
+ 11.: (199,22,19,255), # Constructions artificielles hors sol
111
+ }
112
+
113
+ HYDROLOGY_LANDUSE_FR = {"forêt" : 1.,
114
+ "prairie" : 2.,
115
+ "culture" : 3.,
116
+ "pavés/urbain" : 4.,
117
+ "rivière" : 5.,
118
+ "plan d'eau" : 6.,
119
+ }
120
+
121
+ HYDROLOGY_LANDUSE_EN = {"forest" : 1.,
122
+ "meadow" : 2.,
123
+ "crop" : 3.,
124
+ "paved/urban" : 4.,
125
+ "river" : 5.,
126
+ "water body" : 6.,
127
+ }
128
+
129
+ MAPPING_WALOUS_TO_HYDROLOGY = {1.: 2., # Couvert herbacé en rotation dans l'année
130
+ 2.: 2., # Couvert herbacé toute l'année
131
+ 3.: 1., # Résineux (>3 m)
132
+ 4.: 1., # Feuillus (> 3m)
133
+ 5.: 3., # Résineux (<= 3m)
134
+ 6.: 3., # Feuillus (<= 3m)
135
+ 7.: 3., # Sols nus
136
+ 8.: 5., # Eaux de surface
137
+ 9.: 4., # Revêtement artificiels au sol
138
+ 10.: 4., # Constructions artificielles hors sol
139
+ 11.: 4., # Réseau ferroviaire
140
+ }
141
+
142
+ def get_palette_walous_uts(which:Literal['MAJ_NIV1', 'MAJ_NIV2']) -> wolfpalette:
89
143
  """
90
144
  Get the palette for WALOUS
91
145
 
@@ -97,17 +151,33 @@ def get_palette_walous(which:Literal['MAJ_NIV1', 'MAJ_NIV2']) -> wolfpalette:
97
151
  locpal.automatic = False
98
152
 
99
153
  if which == 'MAJ_NIV1':
100
- locpal.set_values_colors(values = list(WALOUS_MAJ_NIV1.values()),
101
- colors = list(WALOUS_COLORMAP_MAJ_NIV1.values()))
154
+ locpal.set_values_colors(values = list(WALOUS_UTS_MAJ_NIV1.values()),
155
+ colors = list(WALOUS_UTS_COLORMAP_MAJ_NIV1.values()))
102
156
  elif which == 'MAJ_NIV2':
103
- locpal.set_values_colors(values = list(WALOUS_MAJ_NIV2.values()),
104
- colors = list(WALOUS_COLORMAP_MAJ_NIV2.values()))
157
+ locpal.set_values_colors(values = list(WALOUS_UTS_MAJ_NIV2.values()),
158
+ colors = list(WALOUS_UTS_COLORMAP_MAJ_NIV2.values()))
105
159
  else:
106
160
  logging.error('Unknown WALOUS level')
107
161
 
108
162
  return locpal
109
163
 
110
- def update_palette_walous(which:Literal['MAJ_NIV1', 'MAJ_NIV2'], pal:wolfpalette):
164
+ def get_palette_walous_ocs() -> wolfpalette:
165
+ """
166
+ Get the palette for WALOUS OCS
167
+
168
+ :return : palette
169
+ """
170
+
171
+ locpal = wolfpalette()
172
+ locpal.interval_cst = True
173
+ locpal.automatic = False
174
+
175
+ locpal.set_values_colors(values = list(WALOUS_OCS_COLORMAP.keys()),
176
+ colors = list(WALOUS_OCS_COLORMAP.values()))
177
+
178
+ return locpal
179
+
180
+ def update_palette_walous_uts(which:Literal['MAJ_NIV1', 'MAJ_NIV2'], pal:wolfpalette):
111
181
  """
112
182
  Update the palette for WALOUS MAJ_NIV1
113
183
 
@@ -116,13 +186,30 @@ def update_palette_walous(which:Literal['MAJ_NIV1', 'MAJ_NIV2'], pal:wolfpalette
116
186
  """
117
187
 
118
188
  if which == 'MAJ_NIV1':
119
- for k, v in WALOUS_COLORMAP_MAJ_NIV1.items():
120
- pal.set_values_colors(values = list(WALOUS_MAJ_NIV1.values()),
121
- colors = list(WALOUS_COLORMAP_MAJ_NIV1.values()))
189
+ for k, v in WALOUS_UTS_COLORMAP_MAJ_NIV1.items():
190
+ pal.set_values_colors(values = list(WALOUS_UTS_MAJ_NIV1.values()),
191
+ colors = list(WALOUS_UTS_COLORMAP_MAJ_NIV1.values()))
122
192
  elif which == 'MAJ_NIV2':
123
- for k, v in WALOUS_COLORMAP_MAJ_NIV2.items():
124
- pal.set_values_colors(values = list(WALOUS_MAJ_NIV2.values()),
125
- colors = list(WALOUS_COLORMAP_MAJ_NIV2.values()))
193
+ for k, v in WALOUS_UTS_COLORMAP_MAJ_NIV2.items():
194
+ pal.set_values_colors(values = list(WALOUS_UTS_MAJ_NIV2.values()),
195
+ colors = list(WALOUS_UTS_COLORMAP_MAJ_NIV2.values()))
196
+
197
+ pal.interval_cst = True
198
+ pal.automatic = False
199
+
200
+ return 0
201
+
202
+ def update_palette_walous_ocs(pal:wolfpalette):
203
+ """
204
+ Update the palette for WALOUS OCS
205
+
206
+ :param pal : palette to update
207
+ :return : updated palette
208
+ """
209
+
210
+ for k, v in WALOUS_OCS_COLORMAP.items():
211
+ pal.set_values_colors(values = list(WALOUS_OCS_COLORMAP.keys()),
212
+ colors = list(WALOUS_OCS_COLORMAP.values()))
126
213
 
127
214
  pal.interval_cst = True
128
215
  pal.automatic = False
@@ -161,6 +248,40 @@ WALOUS2MANNING_MAJ_NIV2 = {11.: 0.04, # Agriculture
161
248
  66.: 0.04, # Usage inconnu
162
249
  70.: 0.05} # Zones naturelles
163
250
 
251
+ WALOUSOCS2MANNING = {1.: 0.04, # Couvert herbacé en rotation dans l'année
252
+ 2.: 0.04, # Couvert herbacé toute l'année
253
+ 3.: 0.04, # Résineux (>3 m)
254
+ 4.: 0.04, # Feuillus (> 3m)
255
+ 5.: 0.04, # Résineux (<= 3m)
256
+ 6.: 0.04, # Feuillus (<= 3m)
257
+ 7.: 0.02, # Sols nus
258
+ 8.: 0.033, # Eaux de surface
259
+ 9.: 0.02, # Revêtement artificiels au sol
260
+ 10.: 0.02, # Réseau ferroviaire
261
+ 11.: 0.02} # Constructions artificielles hors sol
262
+
263
+ """
264
+ Hydrology classification for Land Use in Wallonia:
265
+ 1 = forêt
266
+ 2 = prairie
267
+ 3 = culture
268
+ 4 = pavés/urbain
269
+ 5 = rivière
270
+ 6 = plan d'eau
271
+ """
272
+ WALOUS2HYDROLOGY = {1.: 2, # Couvert herbacé en rotation dans l'année
273
+ 2.: 2, # Couvert herbacé toute l'année
274
+ 3.: 1, # Résineux (>3 m)
275
+ 4.: 1, # Feillus (> 3m)
276
+ 5.: 3, # Résineux (<= 3m)
277
+ 6.: 3, # Feuillus (<= 3m)
278
+ 7.: 4, # Sols nus
279
+ 8.: 5, # Eaux de surface
280
+ 9.: 4, # Revêtement artificiels au sol
281
+ 10.: 4, # Réseau ferroviaire
282
+ 11.: 4, # Constructions artificielles hors sol
283
+ }
284
+
164
285
  class Walous_data():
165
286
  """
166
287
  La donnée Walous est liée à l'utilisation des sols en Wallonie
@@ -361,12 +482,12 @@ class Walous_data():
361
482
  return -2
362
483
 
363
484
 
364
- class DlgMapWalous(wx.Dialog):
485
+ class DlgMapWalous2Manning(wx.Dialog):
365
486
  """ Modal dialog for mapping WALOUS value to another ones """
366
487
 
367
488
  def __init__(self, parent, title:str = _("Mapping WALOUS value to ..."), which:str = 'MAJ_NIV1'):
368
489
 
369
- super(DlgMapWalous, self).__init__(parent, title=title, size=(450, 400))
490
+ super(DlgMapWalous2Manning, self).__init__(parent, title=title, size=(450, 400))
370
491
 
371
492
  panel = wx.Panel(self)
372
493
 
@@ -375,13 +496,13 @@ class DlgMapWalous(wx.Dialog):
375
496
  self._table = wx.grid.Grid(panel)
376
497
 
377
498
  if which == 'MAJ_NIV1':
378
- self._table.CreateGrid(len(WALOUS_MAJ_NIV1), 3)
499
+ self._table.CreateGrid(len(WALOUS_UTS_MAJ_NIV1), 3)
379
500
  self._table.SetColLabelValue(0, _("Name"))
380
- self._table.SetColLabelValue(1, _("Value"))
501
+ self._table.SetColLabelValue(1, _("Value - UTS"))
381
502
  self._table.SetColLabelValue(2, _("Manning 'n'"))
382
503
  self._table.HideRowLabels()
383
504
 
384
- for i, (k, v) in enumerate(WALOUS_MAJ_NIV1.items()):
505
+ for i, (k, v) in enumerate(WALOUS_UTS_MAJ_NIV1.items()):
385
506
  self._table.SetCellValue(i, 0, str(k))
386
507
  self._table.SetCellValue(i, 1, str(v))
387
508
  self._table.SetCellValue(i, 2, str(WALOUS2MANNING_MAJ_NIV1[v]))
@@ -389,13 +510,13 @@ class DlgMapWalous(wx.Dialog):
389
510
  self._table.SetCellAlignment(i, 2, wx.ALIGN_CENTER, wx.ALIGN_CENTER)
390
511
 
391
512
  elif which == 'MAJ_NIV2':
392
- self._table.CreateGrid(len(WALOUS_MAJ_NIV2), 3)
513
+ self._table.CreateGrid(len(WALOUS_UTS_MAJ_NIV2), 3)
393
514
  self._table.SetColLabelValue(0, _("Name"))
394
- self._table.SetColLabelValue(1, _("Value"))
515
+ self._table.SetColLabelValue(1, _("Value - UTS"))
395
516
  self._table.SetColLabelValue(2, _("Manning 'n'"))
396
517
  self._table.HideRowLabels()
397
518
 
398
- for i, (k, v) in enumerate(WALOUS_MAJ_NIV2.items()):
519
+ for i, (k, v) in enumerate(WALOUS_UTS_MAJ_NIV2.items()):
399
520
  self._table.SetCellValue(i, 0, str(k))
400
521
  self._table.SetCellValue(i, 1, str(v))
401
522
  self._table.SetCellValue(i, 2, str(WALOUS2MANNING_MAJ_NIV2[v]))
@@ -444,8 +565,43 @@ class DlgMapWalous(wx.Dialog):
444
565
 
445
566
  return retdict
446
567
 
568
+ class DlgMapWalousOCS2Manning(DlgMapWalous2Manning):
569
+ """ Modal dialog for mapping WALOUS value to another ones
570
+
571
+ This dialog is used to map WALOUS values to hydrology values.
572
+ It inherits from DlgMapWalous2Manning and overrides the initialization
573
+ to set the correct column labels and values.
574
+ """
575
+
576
+ def __init__(self, parent, title:str = _("Mapping WALOUS value to ...")):
577
+
578
+ super(DlgMapWalousOCS2Manning, self).__init__(parent, title= title)
447
579
 
448
- class WalousLegend(wx.Dialog):
580
+ self._table.SetColLabelValue(2, _("Land Use - OCS"))
581
+
582
+ for i, (k, v) in enumerate(WALOUSOCS2MANNING.items()):
583
+ self._table.SetColLabelValue(1, _("Value - OCS"))
584
+ self._table.SetCellValue(i, 2, str(v))
585
+
586
+ class DlgMapWalous2Hydrology(DlgMapWalous2Manning):
587
+ """ Modal dialog for mapping WALOUS value to another ones
588
+
589
+ This dialog is used to map WALOUS values to hydrology values.
590
+ It inherits from DlgMapWalous2Manning and overrides the initialization
591
+ to set the correct column labels and values.
592
+ """
593
+
594
+ def __init__(self, parent, title:str = _("Mapping WALOUS value to ...")):
595
+
596
+ super(DlgMapWalous2Hydrology, self).__init__(parent, title= title)
597
+
598
+ self._table.SetColLabelValue(2, _("Land Use - OCS"))
599
+
600
+ for i, (k, v) in enumerate(WALOUS2HYDROLOGY.items()):
601
+ self._table.SetColLabelValue(1, _("Value - OCS"))
602
+ self._table.SetCellValue(i, 2, str(v))
603
+
604
+ class Walous_UTS_Legend(wx.Dialog):
449
605
  """ Show the legend of WALOUS """
450
606
 
451
607
  def __init__(self, *args, **kw):
@@ -458,30 +614,30 @@ class WalousLegend(wx.Dialog):
458
614
  self._text_v2 = wx.StaticText(panel, label=_("WALOUS MAJ_NIV2"))
459
615
 
460
616
  self._legend_v1 = wx.grid.Grid(panel)
461
- self._legend_v1.CreateGrid(len(WALOUS_MAJ_NIV1), 3)
617
+ self._legend_v1.CreateGrid(len(WALOUS_UTS_MAJ_NIV1), 3)
462
618
  self._legend_v1.SetColSize(0, 200)
463
619
  self._legend_v1.SetColLabelValue(0, _("Name"))
464
620
  self._legend_v1.SetColLabelValue(1, _("Value"))
465
621
  self._legend_v1.SetColLabelValue(2, _("Color"))
466
622
  self._legend_v1.HideRowLabels()
467
623
 
468
- for i, (k, v) in enumerate(WALOUS_MAJ_NIV1.items()):
624
+ for i, (k, v) in enumerate(WALOUS_UTS_MAJ_NIV1.items()):
469
625
  self._legend_v1.SetCellValue(i, 0, str(k))
470
626
  self._legend_v1.SetCellValue(i, 1, str(v))
471
- self._legend_v1.SetCellBackgroundColour(i, 2, WALOUS_COLORMAP_MAJ_NIV1[v])
627
+ self._legend_v1.SetCellBackgroundColour(i, 2, WALOUS_UTS_COLORMAP_MAJ_NIV1[v])
472
628
 
473
629
  self._legend_v2 = wx.grid.Grid(panel)
474
- self._legend_v2.CreateGrid(len(WALOUS_MAJ_NIV2), 3)
630
+ self._legend_v2.CreateGrid(len(WALOUS_UTS_MAJ_NIV2), 3)
475
631
  self._legend_v2.SetColLabelValue(0, _("Name"))
476
632
  self._legend_v2.SetColSize(0, 200)
477
633
  self._legend_v2.SetColLabelValue(1, _("Value"))
478
634
  self._legend_v2.SetColLabelValue(2, _("Color"))
479
635
  self._legend_v2.HideRowLabels()
480
636
 
481
- for i, (k, v) in enumerate(WALOUS_MAJ_NIV2.items()):
637
+ for i, (k, v) in enumerate(WALOUS_UTS_MAJ_NIV2.items()):
482
638
  self._legend_v2.SetCellValue(i, 0, str(k))
483
639
  self._legend_v2.SetCellValue(i, 1, str(v))
484
- self._legend_v2.SetCellBackgroundColour(i, 2, WALOUS_COLORMAP_MAJ_NIV2[v])
640
+ self._legend_v2.SetCellBackgroundColour(i, 2, WALOUS_UTS_COLORMAP_MAJ_NIV2[v])
485
641
 
486
642
  sizer.Add(self._text_v1, 0, wx.EXPAND, border=5)
487
643
  sizer.Add(self._legend_v1, 1, wx.EXPAND, border=5)
@@ -498,3 +654,41 @@ class WalousLegend(wx.Dialog):
498
654
 
499
655
  def close(self):
500
656
  self.Destroy()
657
+
658
+ class Walous_OCS_Legend(wx.Dialog):
659
+ """ Show the legend of WALOUS OCS """
660
+
661
+ def __init__(self, *args, **kw):
662
+ super().__init__(*args, **kw, size = (400, 650))
663
+
664
+ panel = wx.Panel(self)
665
+ sizer = wx.BoxSizer(wx.VERTICAL)
666
+
667
+ self._text = wx.StaticText(panel, label=_("WALOUS OCS"))
668
+
669
+ self._legend = wx.grid.Grid(panel)
670
+ self._legend.CreateGrid(len(WALOUS_OCS_COLORMAP), 3)
671
+ self._legend.SetColSize(0, 200)
672
+ self._legend.SetColLabelValue(0, _("Name"))
673
+ self._legend.SetColLabelValue(1, _("Value"))
674
+ self._legend.SetColLabelValue(2, _("Color"))
675
+ self._legend.HideRowLabels()
676
+
677
+ for i, (k, v) in enumerate(WALOUS_OCS_COLORMAP.items()):
678
+ self._legend.SetCellValue(i, 0, str(k))
679
+ self._legend.SetCellValue(i, 1, str(v))
680
+ self._legend.SetCellBackgroundColour(i, 2, v)
681
+
682
+ sizer.Add(self._text, 0, wx.EXPAND, border=5)
683
+ sizer.Add(self._legend, 1, wx.EXPAND, border=5)
684
+
685
+ panel.SetSizer(sizer)
686
+ self.Center()
687
+
688
+ self.Show()
689
+
690
+ def __del__(self):
691
+ self.Destroy()
692
+
693
+ def close(self):
694
+ self.Destroy()
@@ -0,0 +1,149 @@
1
+ from pathlib import Path
2
+ import numpy as np
3
+ import ctypes as ct
4
+ import logging
5
+ import shutil
6
+
7
+ import wolf_libs
8
+ from .wolf_array import header_wolf, getkeyblock
9
+
10
+ from .os_check import isWindows
11
+
12
+ # Check if the platform is Windows
13
+ if not isWindows():
14
+ raise OSError("This module is only compatible with Windows.")
15
+
16
+ try:
17
+ import pefile
18
+ except ImportError:
19
+ logging.warning("pefile module not found. Exported functions will not be listed.")
20
+
21
+
22
+ class ToolsHydrologyFortran:
23
+ """
24
+ Fortran routines/functions available in "WolfHydrology.f90" in Wolf_OO
25
+
26
+ Ref : https://docs.python.org/3/library/ctypes.html et https://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html
27
+ Ref : https://stackoverflow.com/questions/59330863/cant-import-dll-module-in-python
28
+ """
29
+
30
+ def __init__(self, dir_simul:str | Path, debugmode:bool = False, path_to_dll:Path = None):
31
+
32
+ if debugmode:
33
+ if path_to_dll is None:
34
+ # wolflibs directory
35
+ self.dll_file = Path(wolf_libs.__path__[0]) / "WolfHydrology_debug.dll"
36
+ # self.dll_file = Path(__file__).parent / "libs" / "WolfHydrology_debug.dll"
37
+ else:
38
+ self.dll_file = path_to_dll / "WolfHydrology_debug.dll"
39
+ else:
40
+ if path_to_dll is None:
41
+ # wolflibs directory
42
+ self.dll_file = Path(wolf_libs.__path__[0]) / "WolfHydrology.dll"
43
+ # self.dll_file = Path(__file__).parent / "libs" / "WolfHydrology.dll"
44
+ else:
45
+ self.dll_file = path_to_dll / "WolfHydrology.dll"
46
+
47
+ self.dll_file = self.dll_file.absolute()
48
+
49
+ if not Path(self.dll_file).exists():
50
+ logging.error(f"File {self.dll_file} does not exist.")
51
+ return
52
+
53
+ # Load the DLL
54
+ try:
55
+ self.lib = ct.CDLL(str(self.dll_file))
56
+ except OSError as e:
57
+ logging.error(f"Could not load the DLL: {e}")
58
+ return
59
+
60
+ dir_simul = Path(dir_simul).absolute()
61
+
62
+ self.dir_simul = str(dir_simul)
63
+
64
+ if not Path(self.dir_simul).exists():
65
+ logging.error(f"File {self.dir_simul} does not exist.")
66
+ return
67
+
68
+ self._dir = Path(self.dir_simul)
69
+
70
+ # Convert to ANSI encoding - this is important for Fortran on Windows and Latin-1 encoding
71
+ self.dir_simul = self.dir_simul.encode('ansi')
72
+
73
+ # Set the directory for the Fortran routines
74
+ self.lib.set_directory_filename.restype = None
75
+ self.lib.set_directory_filename.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_char_p, ct.c_char_p,
76
+ ct.c_int, ct.c_int, ct.c_int, ct.c_int]
77
+
78
+ self.lib.write_default_parameters.restype = None
79
+ self.lib.write_default_parameters.argtypes = None
80
+
81
+ self.lib.init_hydrological_model.restype = None
82
+ self.lib.init_hydrological_model.argtypes = None
83
+
84
+ def set_directory(self):
85
+ """
86
+ Set the directory and filename for the Fortran routines.
87
+ """
88
+
89
+ dir_simul = self.dir_simul
90
+ file_name = 'simul'.encode('ansi')
91
+ dir_results = dir_simul
92
+ file_results = file_name
93
+
94
+ self.lib.set_directory_filename(dir_simul, file_name,
95
+ dir_results, file_results,
96
+ ct.c_int(len(dir_simul)),
97
+ ct.c_int(len(file_name)),
98
+ ct.c_int(len(dir_results)),
99
+ ct.c_int(len(file_results)))
100
+
101
+ def create_default_parameters(self):
102
+ """
103
+ Write the default parameters for the Fortran routines.
104
+ This will create a file named "test_opti.param" in the working directory.
105
+ """
106
+ self.set_directory()
107
+ self.lib.write_default_parameters()
108
+
109
+ default = 'Main_model.param.default'
110
+ default = self._dir / default
111
+ if default.exists():
112
+ # Make a copy wihout the .default extension
113
+ new_default = default.with_suffix('')
114
+ shutil.copyfile(default, new_default)
115
+ logging.info(f"Default parameters copied to {new_default}")
116
+ else:
117
+ logging.warning(f"Default parameters file {default} does not exist. No copy made.")
118
+
119
+ default = 'Drainage_basin.param.default'
120
+ default = self._dir / 'Characteristic_maps' / default
121
+ if default.exists():
122
+ # Make a copy wihout the .default extension
123
+ new_default = default.with_suffix('')
124
+ shutil.copyfile(default, new_default)
125
+ logging.info(f"Default DB parameters copied to {new_default}")
126
+ else:
127
+ logging.warning(f"Default DB parameters file {default} does not exist. No copy made.")
128
+
129
+ def run_preprocessing(self):
130
+ """
131
+ Run the preprocessing of the hydrology model.
132
+ This will create the characteristic maps and the whole basin data.
133
+ """
134
+ self.set_directory()
135
+ self.lib.init_hydrological_model()
136
+
137
+ def _list_exported_functions(self):
138
+ """
139
+ Fortran routines/functions available in
140
+ """
141
+
142
+ pe = pefile.PE(self.dll_file)
143
+
144
+ if not hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
145
+ print("No exported functions found.")
146
+ return
147
+
148
+ for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
149
+ print(f"Function: {exp.name.decode('utf-8') if exp.name else 'None'}, Address: {hex(exp.address)}")