wolfhece 2.1.89__py3-none-any.whl → 2.1.92__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/PyDraw.py CHANGED
@@ -622,9 +622,6 @@ class WolfMapViewer(wx.Frame):
622
622
  self.menupontgltfonebyone = self.cs_menu.Append(wx.ID_ANY, _("Create bridge and export gltf..."),
623
623
  _("Bridge gltf"))
624
624
  # self.menuimport3dfaces_from_DXF = self.toolsmenu.Append(wx.ID_ANY, _("Import triangulation..."), _("DXF"))
625
- self.menuinteractptri = self.cs_menu.Append(wx.ID_ANY, _("Interpolate on active triangulation..."), _("InterpolateTri"))
626
- self.menucomparecloud = self.cs_menu.Append(wx.ID_ANY, _("Compare cloud to array..."), _("Comparison"))
627
- self.menucomparetri = self.cs_menu.Append(wx.ID_ANY, _("Compare triangles to array..."), _("Comparison"))
628
625
 
629
626
  #Profile plots
630
627
  #The action for plotting cross section's profile is initialised.
@@ -816,6 +813,8 @@ class WolfMapViewer(wx.Frame):
816
813
  self.myfigprof = None
817
814
 
818
815
  self.cloudmenu=None
816
+ self.trianglesmenu = None
817
+
819
818
  self._configuration = None
820
819
 
821
820
  self.compare_results = None
@@ -914,14 +913,37 @@ class WolfMapViewer(wx.Frame):
914
913
  def do_quit(self):
915
914
  pass
916
915
 
916
+ def create_triangles_menu(self):
917
+ """ Menu for triangulations """
918
+
919
+ if self.trianglesmenu is None:
920
+
921
+ self.trianglesmenu = wx.Menu()
922
+ self.menubar.Append(self.trianglesmenu, _('&Triangulations'))
923
+
924
+ self._menuinteractptri = self.trianglesmenu.Append(wx.ID_ANY, _("Interpolate on active triangulation..."), _("InterpolateTri"))
925
+ self._menucomparetri = self.trianglesmenu.Append(wx.ID_ANY, _("Compare triangles to array..."), _("Comparison"))
926
+
927
+
917
928
  def create_cloud_menu(self):
929
+ """ Menu for cloud points """
918
930
 
919
931
  if self.cloudmenu is None:
920
932
  self.cloudmenu = wx.Menu()
921
933
  self.menubar.Append(self.cloudmenu, _('Cloud'))
922
934
 
923
- interpcloudonarray = self.cloudmenu.Append(wx.ID_ANY, _("Interpolate active cloud on active array..."),
924
- _("Interpolation"))
935
+ interpcloudonarray = self.cloudmenu.Append(wx.ID_ANY, _("Interpolate active cloud on active array..."),_("Interpolation"))
936
+ self._menucomparecloud = self.cloudmenu.Append(wx.ID_ANY, _("Compare cloud to array..."), _("Comparison"))
937
+ split_cloud = self.cloudmenu.Append(wx.ID_ANY, _("Split cloud..."), _("Split cloud"))
938
+
939
+ def split_cloud_by_vector(self):
940
+ """ Split cloud by vector """
941
+
942
+ inside_cloud, outside_cloud = self.active_vector.split_cloud(self.active_cloud)
943
+
944
+ self.add_object('cloud', newobj = inside_cloud, id = inside_cloud.idx)
945
+ self.add_object('cloud', newobj = outside_cloud, id = outside_cloud.idx)
946
+
925
947
 
926
948
  def get_choices_arrays(self):
927
949
  """Boîte de dialogue permettant de choisir une ou plusieurs matrices parmi celles chargées"""
@@ -2336,19 +2358,32 @@ class WolfMapViewer(wx.Frame):
2336
2358
  # palette = self.active_res2d.mypal
2337
2359
 
2338
2360
  if palette is not None:
2339
- bufpal = io.BytesIO()
2340
- palette.export_image(bufpal,'v')
2341
- bufpal.seek(0)
2361
+ if palette.values is not None:
2362
+ bufpal = io.BytesIO()
2363
+ palette.export_image(bufpal,'v')
2364
+ bufpal.seek(0)
2342
2365
 
2343
- #lecture du buffer et conversion en image avec PIL
2344
- impal = Image.open(bufpal)
2345
- impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
2366
+ #lecture du buffer et conversion en image avec PIL
2367
+ impal = Image.open(bufpal)
2368
+ impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
2346
2369
 
2347
- imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
2370
+ imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
2371
+
2372
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
2373
+ imnew.paste(im.convert('RGB'),(0,0))
2374
+ imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
2375
+ im=imnew
2376
+ else:
2377
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
2378
+
2379
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
2380
+ imnew.paste(im.convert('RGB'),(0,0))
2381
+ im=imnew
2382
+ else:
2383
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
2348
2384
 
2349
2385
  # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
2350
2386
  imnew.paste(im.convert('RGB'),(0,0))
2351
- imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
2352
2387
  im=imnew
2353
2388
 
2354
2389
  #création d'un objet bitmap wx
@@ -2724,7 +2759,11 @@ class WolfMapViewer(wx.Frame):
2724
2759
  ax.set_xlabel('X [m]')
2725
2760
  ax.set_ylabel('Y [m]')
2726
2761
 
2727
- self.palette_for_copy.export_image(None, h_or_v='v', figax=(fig,axes[1]))
2762
+ if self.palette_for_copy.values is not None:
2763
+ self.palette_for_copy.export_image(None, h_or_v='v', figax=(fig,axes[1]))
2764
+ else:
2765
+ axes[1].clear()
2766
+ axes[1].axis('off')
2728
2767
 
2729
2768
  # if self.active_array is not None:
2730
2769
  # self.active_array.mypal.export_image(None, h_or_v='v', figax=(fig,axes[1]))
@@ -3847,7 +3886,8 @@ class WolfMapViewer(wx.Frame):
3847
3886
  if curid != 'format' and curid != 'dirlaz':
3848
3887
  mycs = crosssections(curname[key_Param.VALUE],
3849
3888
  format=myproject.myparams['cross_sections']['format'][key_Param.VALUE],
3850
- dirlaz=myproject.myparams['cross_sections']['dirlaz'][key_Param.VALUE])
3889
+ dirlaz=myproject.myparams['cross_sections']['dirlaz'][key_Param.VALUE],
3890
+ mapviewer = self)
3851
3891
 
3852
3892
  self.add_object('cross_sections', newobj=mycs, id=curid)
3853
3893
 
@@ -3875,7 +3915,7 @@ class WolfMapViewer(wx.Frame):
3875
3915
  if 'vector' in myproject.myparams.keys():
3876
3916
  for curid, curname in zip(myproject.myparams['vector'].keys(), myproject.myparams['vector'].values()):
3877
3917
  if exists(curname[key_Param.VALUE]):
3878
- myvec = Zones(curname[key_Param.VALUE], parent=self)
3918
+ myvec = Zones(curname[key_Param.VALUE], parent=self, mapviewer = self)
3879
3919
  self.add_object('vector', newobj=myvec, id=curid)
3880
3920
  else:
3881
3921
  logging.info(_('Bad parameter in project file - vector : ')+ curname[key_Param.VALUE])
@@ -3884,7 +3924,7 @@ class WolfMapViewer(wx.Frame):
3884
3924
  for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
3885
3925
 
3886
3926
  if exists(curname[key_Param.VALUE]):
3887
- curarray = WolfArray(curname[key_Param.VALUE])
3927
+ curarray = WolfArray(curname[key_Param.VALUE], mapviewer=self)
3888
3928
  self.add_object('array', newobj=curarray, id=curid)
3889
3929
  else:
3890
3930
  logging.info(_('Bad parameter in project file - array : ')+ curname[key_Param.VALUE])
@@ -3892,7 +3932,7 @@ class WolfMapViewer(wx.Frame):
3892
3932
  if 'cloud' in myproject.myparams.keys():
3893
3933
  for curid, curname in zip(myproject.myparams['cloud'].keys(), myproject.myparams['cloud'].values()):
3894
3934
  if exists(curname[key_Param.VALUE]):
3895
- mycloud = cloud_vertices(curname[key_Param.VALUE])
3935
+ mycloud = cloud_vertices(curname[key_Param.VALUE], mapviewer=self)
3896
3936
  self.add_object('cloud', newobj=mycloud, id=curid)
3897
3937
  else:
3898
3938
  logging.info(_('Bad parameter in project file - cloud : ')+ curname[key_Param.VALUE])
@@ -3900,7 +3940,7 @@ class WolfMapViewer(wx.Frame):
3900
3940
  if 'wolf2d' in myproject.myparams.keys():
3901
3941
  for curid, curname in zip(myproject.myparams['wolf2d'].keys(), myproject.myparams['wolf2d'].values()):
3902
3942
  if exists(curname[key_Param.VALUE]):
3903
- curwolf = Wolfresults_2D(curname[key_Param.VALUE])
3943
+ curwolf = Wolfresults_2D(curname[key_Param.VALUE], mapviewer=self)
3904
3944
  self.add_object('res2d', newobj=curwolf, id=curid)
3905
3945
  else:
3906
3946
  logging.info(_('Bad parameter in project file - wolf2d : ')+ curname[key_Param.VALUE])
@@ -3912,10 +3952,10 @@ class WolfMapViewer(wx.Frame):
3912
3952
  if exists(curname[key_Param.VALUE]):
3913
3953
 
3914
3954
  if 'simul_gpu_results' in curname[key_Param.VALUE]:
3915
- curwolf = wolfres2DGPU(Path(curname[key_Param.VALUE]))
3955
+ curwolf = wolfres2DGPU(Path(curname[key_Param.VALUE]), mapviewer=self)
3916
3956
  else:
3917
3957
  if exists(join(curname[key_Param.VALUE], 'simul_gpu_results')):
3918
- curwolf = wolfres2DGPU(Path(join(curname[key_Param.VALUE], 'simul_gpu_results')))
3958
+ curwolf = wolfres2DGPU(Path(join(curname[key_Param.VALUE], 'simul_gpu_results')), mapviewer=self)
3919
3959
  else:
3920
3960
  logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
3921
3961
 
@@ -5146,6 +5186,19 @@ class WolfMapViewer(wx.Frame):
5146
5186
  autoscale = False
5147
5187
  self.compare_cloud2array()
5148
5188
 
5189
+ elif itemlabel==_("Split cloud..."):
5190
+ autoscale = False
5191
+
5192
+ if self.active_cloud is None:
5193
+ logging.warning(_('No active cloud !'))
5194
+ return
5195
+
5196
+ if self.active_vector is None:
5197
+ logging.warning(_('No active vector !'))
5198
+ return
5199
+
5200
+ self.split_cloud_by_vector()
5201
+
5149
5202
  elif itemlabel==_("Compare triangles to array..."):
5150
5203
  autoscale = False
5151
5204
  self.compare_tri2array()
@@ -6753,6 +6806,8 @@ class WolfMapViewer(wx.Frame):
6753
6806
  self.myclouds.append(newobj)
6754
6807
  self.active_cloud = newobj
6755
6808
 
6809
+ newobj.set_mapviewer(self)
6810
+
6756
6811
  self.create_cloud_menu()
6757
6812
 
6758
6813
  elif which.lower() == 'triangulation':
@@ -6768,6 +6823,8 @@ class WolfMapViewer(wx.Frame):
6768
6823
  self.mytri.append(newobj)
6769
6824
  self.active_tri = newobj
6770
6825
 
6826
+ self.create_triangles_menu()
6827
+
6771
6828
  elif which.lower() == 'other':
6772
6829
 
6773
6830
  if not newobj is None:
@@ -7376,12 +7433,21 @@ class WolfMapViewer(wx.Frame):
7376
7433
  myobj = self.selected_object
7377
7434
  if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui]:
7378
7435
  myobj.show_properties()
7436
+ elif isinstance(myobj, cloud_vertices):
7437
+ myobj.show_properties()
7379
7438
 
7380
7439
  elif text == _('Boundary conditions'):
7381
7440
  bc = self.get_boundary_manager(self.selected_object)
7382
7441
  if bc is not None:
7383
7442
  bc.Show()
7384
7443
 
7444
+ elif text == _('Contours'):
7445
+ if isinstance(self.selected_object, WolfArray):
7446
+ cont = self.selected_object.contour()
7447
+ cont.prep_listogl()
7448
+ self.add_object('vector', newobj= cont, id= cont.idx)
7449
+ self.Paint()
7450
+
7385
7451
  elif _('Convert to mono-block') in text:
7386
7452
 
7387
7453
  if isinstance(self.selected_object, WolfArrayMB):
@@ -9552,6 +9618,7 @@ class WolfMapViewer(wx.Frame):
9552
9618
 
9553
9619
  # Chaînes à supprimer
9554
9620
  tracks=[]
9621
+ tracks.append(_('Contours'))
9555
9622
  tracks.append(_('Boundary conditions'))
9556
9623
  tracks.append(_('Convert to mono-block'))
9557
9624
  tracks.append(_('Convert to mono-block (result)'))
@@ -9582,6 +9649,7 @@ class WolfMapViewer(wx.Frame):
9582
9649
  bc = self.get_boundary_manager(self.selected_object)
9583
9650
  if bc is not None:
9584
9651
  self.popupmenu.Append(wx.ID_ANY, _('Boundary conditions'), _('Boundary conditions'))
9652
+ self.popupmenu.Append(wx.ID_ANY, _('Contours'))
9585
9653
 
9586
9654
  # Add specific menu items for WolfArrayMB
9587
9655
  if isinstance(self.selected_object, WolfArrayMB):
@@ -9828,10 +9896,10 @@ class WolfMapViewer(wx.Frame):
9828
9896
  for loctri in self.mytri:
9829
9897
  if loctri.plotted or force:
9830
9898
  loctri.find_minmax(force)
9831
- xmin = min(loctri.minx, xmin)
9832
- xmax = max(loctri.maxx, xmax)
9833
- ymin = min(loctri.miny, ymin)
9834
- ymax = max(loctri.maxy, ymax)
9899
+ xmin = min(loctri.xmin, xmin)
9900
+ xmax = max(loctri.xmax, xmax)
9901
+ ymin = min(loctri.ymin, ymin)
9902
+ ymax = max(loctri.ymax, ymax)
9835
9903
  k += 1
9836
9904
 
9837
9905
  for locres2d in self.myres2D:
wolfhece/PyPalette.py CHANGED
@@ -203,6 +203,10 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
203
203
  :param : fn : filepath or io.BytesIO()
204
204
  :param : h_or_v : configuration to save 'h' = horizontal, 'v' = vertical, '' = both
205
205
  """
206
+ if self.values is None:
207
+ logging.warning('No values in palette - Nothing to do !')
208
+ return None, None
209
+
206
210
  if fn == '':
207
211
  file = wx.FileDialog(None, "Choose .pal file", wildcard="png (*.png)|*.png|all (*.*)|*.*", style=wx.FD_SAVE)
208
212
  if file.ShowModal() == wx.ID_CANCEL:
wolfhece/PyParams.py CHANGED
@@ -18,6 +18,7 @@ from typing import Union, Literal
18
18
  from enum import Enum
19
19
  from copy import deepcopy
20
20
  import numpy as np
21
+ from pathlib import Path
21
22
 
22
23
  try:
23
24
  from .PyTranslate import _
@@ -39,19 +40,17 @@ class Type_Param(Enum):
39
40
  Strings are also used by Fortran Code -- modify with care
40
41
  """
41
42
  Integer_or_Float = 'Integer_or_Float'
42
- Integer = 'integer'
43
+ Integer = 'Integer'
43
44
  Logical = 'Logical'
44
45
  Float = 'Float'
45
46
  File = 'File'
46
- file = 'file'
47
47
  Directory = 'Directory'
48
- directory = 'directory'
49
48
  Color = 'Color'
50
49
  Fontname = 'Fontname'
51
50
  String = 'String'
52
51
  Empty = ''
53
- Double = 'double'
54
- Real = 'real'
52
+ Double = 'Double'
53
+ Real = 'Real'
55
54
 
56
55
 
57
56
  class key_Param(Enum):
@@ -99,17 +98,17 @@ def new_infos_incr(groupname:str= None, paramname:str='nb', min:int=1, max:int=1
99
98
  def search_type(chain:str) -> Type_Param:
100
99
  """ recherche du typage dans une chaîne de caractères """
101
100
 
102
- if chain.lower().find(Type_Param.Integer.value)>-1 and chain.find(Type_Param.Double.value)>-1:
101
+ if chain.lower().find(Type_Param.Integer.value.lower())>-1 and chain.find(Type_Param.Double.value.lower())>-1:
103
102
  return Type_Param.Integer_or_Float
104
- elif chain.lower().find(Type_Param.Integer.value)>-1:
103
+ elif chain.lower().find(Type_Param.Integer.value.lower())>-1:
105
104
  return Type_Param.Integer
106
- elif chain.find(Type_Param.Logical.value)>-1:
105
+ elif chain.lower().find(Type_Param.Logical.value.lower())>-1:
107
106
  return Type_Param.Logical
108
- elif chain.find(Type_Param.Double.value)>-1 or chain.find('dble')>-1 or chain.find(Type_Param.Real.value)>-1:
107
+ elif chain.lower().find(Type_Param.Double.value.lower())>-1 or chain.find('dble')>-1 or chain.find(Type_Param.Real.value.lower())>-1:
109
108
  return Type_Param.Float
110
- elif chain.find('({})'.format(Type_Param.file))>-1:
109
+ elif chain.lower().find('({})'.format(Type_Param.File.value.lower()))>-1:
111
110
  return Type_Param.File
112
- elif chain.find('({})'.format(Type_Param.directory))>-1 or chain.find('(dir)')>-1:
111
+ elif chain.lower().find('({})'.format(Type_Param.Directory.value.lower()))>-1 or chain.find('(dir)')>-1:
113
112
  return Type_Param.Directory
114
113
  else:
115
114
  return Type_Param.String
@@ -1511,13 +1510,13 @@ class Wolf_Param(wx.Frame):
1511
1510
  # recherche du type dans le commentaire
1512
1511
  curparam[key_Param.TYPE]=search_type(paramloc[2])
1513
1512
  if curparam[key_Param.TYPE] == Type_Param.String:
1514
- # recherche du type dans la châine complète
1513
+ # recherche du type dans la chaîne complète
1515
1514
  type_in_fulchain = search_type(param)
1516
1515
 
1517
1516
  if type_in_fulchain != Type_Param.String:
1518
1517
  curparam[key_Param.TYPE] = type_in_fulchain
1519
1518
  try:
1520
- # tentaive de recherche du type dans les valeurs par défaut
1519
+ # tentative de recherche du type dans les valeurs par défaut
1521
1520
  param_def=self.myparams_default[groupname][paramloc[0]]
1522
1521
  curparam[key_Param.TYPE]=param_def[key_Param.TYPE]
1523
1522
  except:
@@ -1903,14 +1902,21 @@ class Wolf_Param(wx.Frame):
1903
1902
 
1904
1903
  if isinstance(value, float):
1905
1904
  return Type_Param.Float
1906
- elif isinstance(value, int):
1907
- return Type_Param.Integer
1905
+ # ATTEENTION : les booléens sont des entiers --> il faut les traiter avant
1908
1906
  elif isinstance(value, bool):
1909
1907
  return Type_Param.Logical
1908
+ elif isinstance(value, int):
1909
+ return Type_Param.Integer
1910
1910
  elif isinstance(value, tuple):
1911
1911
  return Type_Param.Color
1912
1912
  else:
1913
- return Type_Param.String
1913
+ tmp_path = Path(value)
1914
+ if tmp_path.is_file():
1915
+ return Type_Param.File
1916
+ elif tmp_path.is_dir():
1917
+ return Type_Param.Directory
1918
+ else:
1919
+ return Type_Param.String
1914
1920
 
1915
1921
  def change_param(self, group:str, name:str, value:Union[float, int, str, bool]):
1916
1922
  """ Modify the value of the parameter if found, otherwise None obj """
wolfhece/PyVertex.py CHANGED
@@ -843,6 +843,20 @@ class cloud_vertices(Element_To_Draw):
843
843
  self._updatebounds(newcloud=cloud)
844
844
  pass
845
845
 
846
+ def add_vertices(self, vertices:list[wolfvertex]):
847
+ """ Add a list of vertices to the cloud """
848
+
849
+ first_id = len(self.myvertices)
850
+ for curid, curvert in enumerate(vertices):
851
+ self.myvertices[first_id + curid] = {}
852
+ self.myvertices[first_id + curid]['vertex'] = curvert
853
+ self._updatebounds(curvert)
854
+
855
+ def get_vertices(self):
856
+ """ Return the vertices as a list """
857
+
858
+ return [self.myvertices[item]['vertex'] for item in self.myvertices]
859
+
846
860
  # def _create_textures(self):
847
861
  # """ Create textures for the cloud """
848
862
 
@@ -879,11 +893,29 @@ class cloud_vertices(Element_To_Draw):
879
893
 
880
894
  mapviewer = self.get_mapviewer()
881
895
 
896
+ which_legend = self.myprop.legendtext
897
+
882
898
  for id, item in enumerate(self.myvertices):
899
+
883
900
  curvert = self.myvertices[item]['vertex']
884
901
 
885
902
  if curvert.x > xmin and curvert.x < xmax and curvert.y > ymin and curvert.y < ymax:
886
903
 
904
+ if which_legend == '':
905
+ text_legend = str(item)
906
+ elif which_legend == 'ID':
907
+ text_legend = str(id)
908
+ elif which_legend == 'X':
909
+ text_legend = str(curvert.x)
910
+ elif which_legend == 'Y':
911
+ text_legend = str(curvert.y)
912
+ elif which_legend == 'Z':
913
+ text_legend = str(curvert.z)
914
+ elif which_legend in self.myvertices[item]:
915
+ text_legend = self.myvertices[item][which_legend]
916
+ else:
917
+ text_legend = which_legend
918
+
887
919
  r,g,b = getRGBfromI(self.myprop.legendcolor)
888
920
 
889
921
  curtxt_infos = Text_Infos(self.myprop.legendpriority,
@@ -896,7 +928,7 @@ class cloud_vertices(Element_To_Draw):
896
928
  relative_position=self.myprop.legendrelpos
897
929
  )
898
930
 
899
- text = Text_Image_Texture(item, mapviewer, curtxt_infos, None, curvert.x, curvert.y)
931
+ text = Text_Image_Texture(text_legend, mapviewer, curtxt_infos, None, curvert.x, curvert.y)
900
932
 
901
933
  text.paint()
902
934
 
@@ -18,7 +18,7 @@ from wx.core import BoxSizer, FlexGridSizer, TreeItemId
18
18
  from OpenGL.GL import *
19
19
  from shapely.geometry import LineString, MultiLineString,Point,MultiPoint,Polygon,JOIN_STYLE, MultiPolygon
20
20
  from shapely.ops import nearest_points,substring, split, polygonize
21
- from shapely import delaunay_triangles
21
+ from shapely import delaunay_triangles, prepare, is_prepared, destroy_prepared
22
22
  import pygltflib
23
23
  from scipy.interpolate import interp1d
24
24
  import matplotlib.pyplot as plt
@@ -39,7 +39,7 @@ from .wolf_texture import genericImagetexture
39
39
  from .textpillow import Font_Priority
40
40
  from .PyTranslate import _
41
41
  from .CpGrid import CpGrid
42
- from .PyVertex import wolfvertex,getIfromRGB,getRGBfromI
42
+ from .PyVertex import wolfvertex,getIfromRGB,getRGBfromI, cloud_vertices
43
43
  from .PyParams import Wolf_Param, key_Param, Type_Param, new_json, new_infos_incr
44
44
  from .lazviewer.laz_viewer import myviewer
45
45
  from .wolf_texture import Text_Image_Texture,Text_Infos
@@ -1010,6 +1010,7 @@ class vector:
1010
1010
  self.myprop=vectorproperties(parent=self)
1011
1011
 
1012
1012
  self.linestring = None
1013
+ self.polygon = None
1013
1014
 
1014
1015
  # Utile surtout pour les sections en travers
1015
1016
  self.zdatum = 0.
@@ -1276,13 +1277,26 @@ class vector:
1276
1277
  xyz[:,2]+=self.zdatum
1277
1278
  return xyz
1278
1279
 
1279
- def prepare_shapely(self):
1280
+ def prepare_shapely(self, prepare_shapely:bool = True):
1280
1281
  """
1281
1282
  Conversion Linestring Shapely et rétention de l'objet afin d'éviter de multiples appel
1282
- par ex. dans une boucle
1283
+ par ex. dans une boucle.
1284
+
1285
+ :param prepare_shapely: Préparation de l'objet Shapely pour une utilisation optimisée
1286
+ - True par défaut
1287
+ - see https://shapely.readthedocs.io/en/stable/reference/shapely.prepare.html
1288
+
1283
1289
  """
1284
1290
 
1291
+ self.reset_linestring()
1292
+
1285
1293
  self.linestring = self.asshapely_ls()
1294
+ self.polygon = self.asshapely_pol()
1295
+
1296
+ if prepare_shapely:
1297
+ prepare(self.linestring)
1298
+ prepare(self.polygon)
1299
+
1286
1300
 
1287
1301
  def projectontrace(self, trace):
1288
1302
  """
@@ -1343,7 +1357,7 @@ class vector:
1343
1357
  else:
1344
1358
  return None
1345
1359
 
1346
- def intersection(self, vec2 = None, eval_dist=False,norm=False, force_single=False):
1360
+ def intersection(self, vec2:"vector" = None, eval_dist=False,norm=False, force_single=False):
1347
1361
  """
1348
1362
  Calcul de l'intersection avec un autre vecteur
1349
1363
 
@@ -1380,7 +1394,20 @@ class vector:
1380
1394
  def reset(self):
1381
1395
  """Remise à zéro"""
1382
1396
  self.myvertices=[]
1383
- self.linestring=None
1397
+ self.reset_linestring()
1398
+
1399
+ def reset_linestring(self):
1400
+ """Remise à zéro de l'objet Shapely"""
1401
+
1402
+ if self.linestring is not None:
1403
+ if is_prepared(self.linestring):
1404
+ destroy_prepared(self.linestring)
1405
+ self.linestring=None
1406
+
1407
+ if self.polygon is not None:
1408
+ if is_prepared(self.polygon):
1409
+ destroy_prepared(self.polygon)
1410
+ self.polygon=None
1384
1411
 
1385
1412
  def add_vertex(self,addedvert: Union[list[wolfvertex], wolfvertex]):
1386
1413
  """
@@ -1817,7 +1844,7 @@ class vector:
1817
1844
  while k<self.nbvertices:
1818
1845
  self.myvertices.pop(k)
1819
1846
 
1820
- if self.linestring is not None:
1847
+ if self.linestring is not None or self.polygon is not None:
1821
1848
  self.prepare_shapely()
1822
1849
 
1823
1850
  self._reset_listogl()
@@ -2391,11 +2418,11 @@ class vector:
2391
2418
  return np.asarray([[curvert.x, curvert.y, curvert.in_use] for curvert in self.myvertices])
2392
2419
 
2393
2420
  @property
2394
- def sz(self):
2421
+ def sz_curvi(self):
2395
2422
  return self.get_sz()
2396
2423
 
2397
2424
  @property
2398
- def s(self):
2425
+ def s_curvi(self):
2399
2426
  sz = self.get_sz()
2400
2427
  return sz[0]
2401
2428
 
@@ -2649,6 +2676,40 @@ class vector:
2649
2676
  self.parentzone.reset_listogl()
2650
2677
 
2651
2678
 
2679
+ def select_points_inside(self, xy:cloud_vertices | np.ndarray):
2680
+ """ Select the points inside a polygon
2681
+
2682
+ :param xy: cloud_vertices or np.ndarray with x,y coordinates
2683
+ :return: list of boolean
2684
+ """
2685
+
2686
+ self.prepare_shapely()
2687
+
2688
+ if isinstance(xy, cloud_vertices):
2689
+ xy = xy.get_xyz()[:,0:2]
2690
+
2691
+ inside = [self.polygon.contains(Point(curxy)) for curxy in xy]
2692
+
2693
+ return inside
2694
+
2695
+ def split_cloud(self, cloud_to_split:cloud_vertices):
2696
+ """ Split a cloud of vertices on the vector """
2697
+
2698
+ inside = self.select_points_inside(cloud_to_split)
2699
+
2700
+ cloud_inside = cloud_vertices(idx = 'inside_'+cloud_to_split.idx)
2701
+ cloud_outside = cloud_vertices(idx = 'outside_'+cloud_to_split.idx)
2702
+
2703
+ vertices = cloud_to_split.get_vertices()
2704
+
2705
+ for idx, (locinside, curvert) in enumerate(zip(inside, vertices)):
2706
+ if locinside:
2707
+ cloud_inside.add_vertex(curvert)
2708
+ else:
2709
+ cloud_outside.add_vertex(curvert)
2710
+
2711
+ return cloud_inside, cloud_outside
2712
+
2652
2713
  class zone:
2653
2714
  """
2654
2715
  Objet de gestion d'informations vectorielles
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 1
8
- self.patch = 89
8
+ self.patch = 92
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/gpuview.py CHANGED
@@ -277,7 +277,15 @@ class VectorField(Element_To_Draw):
277
277
 
278
278
  super().__init__(idx, plotted, mapviewer, need_for_wx)
279
279
 
280
- self.mapviewer.SetCurrentContext()
280
+ if self.mapviewer is None:
281
+ logging.error("No mapviewer defined for VectorField")
282
+ return
283
+
284
+ try:
285
+ self.mapviewer.SetCurrentContext()
286
+ except:
287
+ logging.error("Error during OpenGL context setup -- VectorField")
288
+ return
281
289
 
282
290
  self._gpu_program_ref = 1
283
291
  while self._gpu_program_ref in _global_gpu_state:
wolfhece/pyshields.py CHANGED
@@ -278,7 +278,7 @@ def get_Rouse(d:float, q:float, h:float, K:float, rhom:float=2650., rho:float=RH
278
278
  """
279
279
  # tau_cr = (q/K)**2 / h**(7/3) * rho * GRAVITY
280
280
  # shear_vel = math.sqrt(tau_cr/rho)
281
- shear_vel = q/K / h**(7/6)* math.sqrt(GRAVITY)
281
+ shear_vel = q/K / h**(7./6.)* math.sqrt(GRAVITY)
282
282
  ws = get_settling_vel(d,rhom,rho)
283
283
  # von Kármán constant
284
284
  k = 0.40
@@ -513,6 +513,39 @@ def shieldsdia_dim(figax=None) -> tuple[plt.Figure,plt.Axes]:
513
513
 
514
514
  return fig,ax
515
515
 
516
+ def get_friction_slope_2D_Manning(q:float, h:float, n:float) -> float:
517
+ """
518
+ Compute friction slope j for 2D flow with Manning/Strickler friction law
519
+
520
+ :param q : discharge [m3/s]
521
+ :param h : water depth [m]
522
+ :param n : Manning friction coefficient [m-1/3.s]
523
+ """
524
+
525
+ denom = h**(4./3.)
526
+ if denom > 0.:
527
+ j = (q/h * n)**2.0 / denom
528
+ else:
529
+ j = 0.
530
+
531
+ return j
532
+
533
+ def get_shear_velocity_2D_Manning(q:float, h:float, n:float) -> float:
534
+ """
535
+ Compute shear velocity u_* for 2D flow with Manning/Strickler friction law
536
+
537
+ :param j : friction slope [-]
538
+ :param h : water depth [m]
539
+ :param q : discharge [m3/s]
540
+ :param n : Manning friction coefficient [m-1/3.s]
541
+ """
542
+
543
+ j = get_friction_slope_2D_Manning(q,h,n)
544
+
545
+ ushear = (h*j*GRAVITY)**0.5
546
+
547
+ return ushear
548
+
516
549
  def get_Shields_2D_Manning(s:float, d:float, q:float, h:float, n:float) -> float:
517
550
  """
518
551
  Compute Shields dimensionless parameter for 2D flow with Manning/Strickler friction law
@@ -528,11 +561,7 @@ def get_Shields_2D_Manning(s:float, d:float, q:float, h:float, n:float) -> float
528
561
  # calcul de terme de pente de frottement
529
562
 
530
563
  # j = (q/h)**2.0 / K**2. / h**(4./3.)
531
- denom = h**(4./3.)
532
- if denom > 0.:
533
- j = (q/h * n)**2.0 / denom
534
- else:
535
- j = 0.
564
+ j = get_friction_slope_2D_Manning(q,h,n)
536
565
 
537
566
  shields = j*h / (d*(s-1))
538
567
 
wolfhece/rem/REMMaker.py CHANGED
@@ -10,13 +10,13 @@ from osgeo import ogr
10
10
  from shapely.geometry import box # for cropping centerlines to extent of DEM
11
11
  import geopandas as gpd
12
12
  from geopandas import clip, read_file
13
- import osmnx # for querying OpenStreetMaps data to get river centerlines
13
+ import logging
14
+
14
15
  import requests
15
16
  from scipy.spatial import KDTree as KDTree # for finding nearest neighbors/interpolating
16
17
  from itertools import combinations
17
18
  import time
18
19
  from .RasterViz import RasterViz
19
- import logging
20
20
 
21
21
  level = logging.INFO
22
22
  fmt = '[%(levelname)s] %(asctime)s - %(message)s'
@@ -281,6 +281,14 @@ class REMMaker(object):
281
281
 
282
282
  def get_river_centerline(self):
283
283
  """Find centerline of river(s) within DEM area using OSM Ways"""
284
+
285
+ try:
286
+ import osmnx # for querying OpenStreetMaps data to get river centerlines
287
+ except ImportError:
288
+ logging.error("osmnx not installed. Please install osmnx to use this script.")
289
+ logging.error("Install with: 'pip install osmnx' but beware of dependencies especially Shapely, which may be forced to an older version.")
290
+ raise ImportError("osmnx not installed. Please install osmnx to use this script.")
291
+
284
292
  logging.info("Finding river centerline.")
285
293
  # get OSM Ways within bbox of DEM (returns geopandas geodataframe)
286
294
  osmnx.settings.cache_folder = './.osm_cache'
wolfhece/wolf_array.py CHANGED
@@ -1484,6 +1484,8 @@ class Ops_Array(wx.Frame):
1484
1484
 
1485
1485
  self.myzones.mapviewer = mapviewer
1486
1486
 
1487
+ self._levels = []
1488
+
1487
1489
  if self.wx_exists:
1488
1490
  self.set_GUI()
1489
1491
 
@@ -1746,12 +1748,20 @@ class Ops_Array(wx.Frame):
1746
1748
 
1747
1749
  self.extract_selection = wx.Button(self.tools, wx.ID_ANY, _("Extract selection"), wx.DefaultPosition,wx.DefaultSize, 0)
1748
1750
 
1751
+ cont_sizer = wx.BoxSizer(wx.HORIZONTAL)
1752
+ self._contour_int = wx.Button(self.tools, wx.ID_ANY, _("Contour"), wx.DefaultPosition, wx.DefaultSize, 0)
1753
+ self._contour_list = wx.Button(self.tools, wx.ID_ANY, _("Contour specific"), wx.DefaultPosition, wx.DefaultSize, 0)
1754
+
1755
+ cont_sizer.Add(self._contour_int, 1, wx.EXPAND)
1756
+ cont_sizer.Add(self._contour_list, 1, wx.EXPAND)
1757
+
1749
1758
  Toolssizer.Add(hbox, 0, wx.EXPAND)
1750
1759
  Toolssizer.Add(self.ApplyTools, 1, wx.EXPAND)
1751
1760
  Toolssizer.Add(self.nullborder, 1, wx.EXPAND)
1752
1761
  Toolssizer.Add(self.filter_zone, 1, wx.EXPAND)
1753
1762
  Toolssizer.Add(self.labelling, 1, wx.EXPAND)
1754
1763
  Toolssizer.Add(self.extract_selection, 1, wx.EXPAND)
1764
+ Toolssizer.Add(cont_sizer, 1, wx.EXPAND)
1755
1765
 
1756
1766
  self.ApplyTools.SetToolTip(_("Apply Nullvalue into memory/object"))
1757
1767
  self.nullborder.SetToolTip(_("Set null value on the border of the array\n\nYou will be asked for the width of the border (in cells)"))
@@ -2130,6 +2140,8 @@ class Ops_Array(wx.Frame):
2130
2140
  self.filter_zone.Bind(wx.EVT_BUTTON, self.OnFilterZone)
2131
2141
  self.labelling.Bind(wx.EVT_BUTTON, self.OnLabelling)
2132
2142
  self.extract_selection.Bind(wx.EVT_BUTTON, self.OnExtractSelection)
2143
+ self._contour_int.Bind(wx.EVT_BUTTON, self.OnContourInt)
2144
+ self._contour_list.Bind(wx.EVT_BUTTON, self.OnContourList)
2133
2145
 
2134
2146
  self.SelectOp.Bind(wx.EVT_BUTTON, self.OnApplyOpSelect)
2135
2147
  self.palapply.Bind(wx.EVT_BUTTON, self.Onupdatepal)
@@ -2586,6 +2598,70 @@ class Ops_Array(wx.Frame):
2586
2598
 
2587
2599
  self.parentarray.extract_selection()
2588
2600
 
2601
+ def OnContourInt(self, event:wx.MouseEvent):
2602
+ """ Create contour - number of contours """
2603
+
2604
+ with wx.NumberEntryDialog(None, 'Number of contours', 'Number of contours', 'Number of contours', 20, 1, 1000) as dlg:
2605
+ if dlg.ShowModal() == wx.ID_OK:
2606
+ nbcontours = dlg.GetValue()
2607
+
2608
+ logging.info(_('Baking contour'))
2609
+ cont = self.parentarray.contour(levels = nbcontours)
2610
+ logging.info(_('Add contour to viewer'))
2611
+ cont.prep_listogl()
2612
+ mapv = self.get_mapviewer()
2613
+ mapv.add_object('vector', newobj = cont, id = cont.idx)
2614
+ self.get_mapviewer().Paint()
2615
+ logging.info(_('Done !'))
2616
+
2617
+ def OnContourList(self, event:wx.MouseEvent):
2618
+ """ Create contour - list of values """
2619
+
2620
+ with wx.TextEntryDialog(None, 'List of specific values separated by comma or tuple (min;max;step)',
2621
+ 'List of values', f'{self.parentarray.array.min()}, {self.parentarray.array.max()}') as dlg:
2622
+
2623
+ if dlg.ShowModal() == wx.ID_OK:
2624
+ txt = dlg.GetValue()
2625
+
2626
+ self._levels = []
2627
+ if ',' in txt:
2628
+ for cur in txt.split(','):
2629
+ if '(' in cur:
2630
+ cur = cur.replace('(', '').replace(')', '')
2631
+ cur = cur.split(';')
2632
+ if len(cur) == 3:
2633
+ minval = float(cur[0])
2634
+ maxval = float(cur[1])
2635
+ step = float(cur[2])
2636
+ self._levels.extend(np.arange(minval, maxval, step))
2637
+ elif '(' in txt:
2638
+ cur = txt.replace('(', '').replace(')', '')
2639
+ cur = cur.split(';')
2640
+ if len(cur) == 3:
2641
+ minval = float(cur[0])
2642
+ maxval = float(cur[1])
2643
+ step = float(cur[2])
2644
+ self._levels.extend(np.arange(minval, maxval, step))
2645
+ else:
2646
+ try:
2647
+ self._levels = float(txt)
2648
+ except:
2649
+ logging.error('Error in chain text to float')
2650
+ return
2651
+
2652
+ if isinstance(self._levels, list):
2653
+ if len(self._levels) == 0:
2654
+ logging.error('Nothing to do !')
2655
+ return
2656
+
2657
+ logging.info(_('Baking contour'))
2658
+ cont = self.parentarray.contour(levels = self._levels)
2659
+ logging.info(_('Add contour to viewer'))
2660
+ cont.prep_listogl()
2661
+ self.get_mapviewer().add_object('vector', newobj = cont, id = cont.idx)
2662
+ self.get_mapviewer().Paint()
2663
+ logging.info(_('Done !'))
2664
+
2589
2665
  def OnApplyOpMath(self, event:wx.MouseEvent):
2590
2666
  """ Apply math operator to the array """
2591
2667
 
@@ -8978,6 +9054,28 @@ class WolfArray(Element_To_Draw, header_wolf):
8978
9054
  Array3 = WolfArray(output_raster_path, nullvalue=-9999)
8979
9055
  return Array3
8980
9056
 
9057
+ def contour(self, levels:Union[int, list[float]] = 10) -> Zones:
9058
+ """ Compute contour lines """
9059
+
9060
+ if isinstance(levels, int):
9061
+ levels = np.linspace(self.array.min(), self.array.max(), levels)
9062
+
9063
+ x, y = self.meshgrid()
9064
+ cs = plt.contour(x, y, self.array, levels=levels)
9065
+
9066
+ zones = Zones(idx = self.idx + '_contour', mapviewer = self.get_mapviewer())
9067
+ for collection, level in zip(cs.collections, cs.levels):
9068
+ zone_level = zone(name=f'Contour {level}')
9069
+ for idx, path in enumerate(collection.get_paths()):
9070
+ vector_level = vector(name=f'Contour {level} - {idx}')
9071
+ for vertices in path.to_polygons(closed_only=False):
9072
+ for vertex in vertices:
9073
+ vector_level.add_vertex(wolfvertex(vertex[0], vertex[1]))
9074
+ zone_level.add_vector(vector_level, forceparent=True)
9075
+ zones.add_zone(zone_level, forceparent=True)
9076
+
9077
+ return zones
9078
+
8981
9079
  class WolfArrayMB(WolfArray):
8982
9080
  """
8983
9081
  Matrice multiblocks
@@ -35,7 +35,7 @@ from .drawing_obj import Element_To_Draw
35
35
  from .PyPalette import wolfpalette
36
36
  from .PyTranslate import _
37
37
  from .gpuview import GRID_N, Rectangle, VectorField
38
- from .pyshields import get_d_cr, get_d_cr_susp, izbach_d_cr, get_Shields_2D_Manning
38
+ from .pyshields import get_d_cr, get_d_cr_susp, izbach_d_cr, get_Shields_2D_Manning, get_friction_slope_2D_Manning, get_shear_velocity_2D_Manning
39
39
  from .pyviews import WolfViews
40
40
  from .mesh2d.wolf2dprev import prev_parameters_simul, blocks_file
41
41
  from .GraphNotebook import PlotPanel
@@ -1414,6 +1414,7 @@ class views_2D(Enum):
1414
1414
  TURB_VISC_3D = _('Turbulent viscosity 3D')
1415
1415
  VECTOR_FIELD_Q = _('Discharge vector field')
1416
1416
  VECTOR_FIELD_U = _('Velocity vector field')
1417
+ U_SHEAR = _('Shear velocity [ms-1]')
1417
1418
  SHIELDS_NUMBER = _('Shields number - Manning-Strickler')
1418
1419
  CRITICAL_DIAMETER_SHIELDS = _('Critical grain diameter - Shields')
1419
1420
  CRITICAL_DIAMETER_IZBACH = _('Critical grain diameter - Izbach')
@@ -1726,6 +1727,13 @@ class OneWolfResult:
1726
1727
 
1727
1728
  nullvalue = self.waterdepth.nullvalue
1728
1729
 
1730
+ elif which==views_2D.U_SHEAR:
1731
+ self.U_Shear = self.get_u_shear()
1732
+ self._current = self.U_Shear
1733
+ self._view = WolfViews()
1734
+
1735
+ nullvalue = self.waterdepth.nullvalue
1736
+
1729
1737
  elif which==views_2D.SHIELDS_NUMBER:
1730
1738
  if self.ShieldsNumber is None or self._force_update_shields:
1731
1739
  self.ShieldsNumber = self.get_shieldsnumber()
@@ -1891,6 +1899,33 @@ class OneWolfResult:
1891
1899
  logging.info(_('End of computing critical diameters'))
1892
1900
 
1893
1901
  return diamcrit
1902
+
1903
+ def get_u_shear(self) -> WolfArray:
1904
+ """
1905
+ Calcul de la vitesse de cisaillement
1906
+ """
1907
+
1908
+ def compute() -> WolfArray:
1909
+
1910
+ ij = np.argwhere(self.waterdepth.array>0.)
1911
+
1912
+ u_shear = WolfArray(mold=self.waterdepth)
1913
+ qnorm = (self.qx**2.+self.qy**2.)**.5
1914
+ qnorm.array.mask=self.waterdepth.array.mask
1915
+
1916
+ _u_shear = np.asarray([get_shear_velocity_2D_Manning(qnorm.array[i,j],
1917
+ self.waterdepth.array[i,j],
1918
+ self.rough_n.array.data[i,j]) for i,j in ij])
1919
+
1920
+ u_shear.array[ij[:,0],ij[:,1]] = _u_shear
1921
+
1922
+ return u_shear
1923
+
1924
+ logging.info(_('Computing shear velocity'))
1925
+ u_shear = compute()
1926
+ logging.info(_('End of computing shear velocity'))
1927
+
1928
+ return u_shear
1894
1929
 
1895
1930
  def get_shieldsnumber(self) -> WolfArray:
1896
1931
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wolfhece
3
- Version: 2.1.89
3
+ Version: 2.1.92
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  License: Copyright (c) 2024 University of Liege. All rights reserved.
6
6
  Project-URL: Homepage, https://uee.uliege.be/hece
@@ -51,7 +51,6 @@ Requires-Dist: pygltflib
51
51
  Requires-Dist: ezdxf
52
52
  Requires-Dist: pyvista
53
53
  Requires-Dist: tqdm==4.64.*
54
- Requires-Dist: osmnx
55
54
  Requires-Dist: tifffile
56
55
  Requires-Dist: numba==0.58.*
57
56
  Requires-Dist: xmltodict
@@ -7,16 +7,16 @@ wolfhece/ManageParams.py,sha256=EeuUI5Vvh9ixCvYf8YShMC1s1Yacc7OxOCN7q81gqiQ,517
7
7
  wolfhece/Model1D.py,sha256=SI4oNF_J3MdjiWZoizS8kuRXLMVyymX9dYfYJNVCQVI,476989
8
8
  wolfhece/PyConfig.py,sha256=UNtl5UzZ399JqjJT67-4DWaIkv76sc1FiEsSDJpXlL0,10458
9
9
  wolfhece/PyCrosssections.py,sha256=FnmM9DWY_SAF2EDH9Gu2PojXNtSTRF4-aYQuAAJXBh4,112771
10
- wolfhece/PyDraw.py,sha256=3pd5ynlveRs43Qr5eOhcNdkywxPifuq-qnsT5gabImo,425009
10
+ wolfhece/PyDraw.py,sha256=-WHY2_slvEwaK2FilmI8oLRcXZGTk2pkBwDt1qd66zY,427847
11
11
  wolfhece/PyGui.py,sha256=HY0beOMSp1JEyq8-vfVynzVrmKxvaO_sJSMwlNqCNrg,105289
12
12
  wolfhece/PyGuiHydrology.py,sha256=f60E8K9eGTnRq5RDF6yvt-ahf2AYegwQ9t25zZ2Mk1A,14946
13
13
  wolfhece/PyHydrographs.py,sha256=jwtSNMMACwarxrtN1UeQYth99UNrhwPx1IGgUwcooHA,3774
14
- wolfhece/PyPalette.py,sha256=3ehK6H2PvqSe0zICR1HyNs6KQokR1DmnAh4LwYnLIcU,28009
15
- wolfhece/PyParams.py,sha256=LGt9uBFRVeS0F_kObJw8bPkWFqYSzf5pUTscxVU5Mxo,97725
14
+ wolfhece/PyPalette.py,sha256=QCzXBnYlv7YfHjpJWyO_8F-uOLOe7O_RbkyrnMYzgM4,28146
15
+ wolfhece/PyParams.py,sha256=6fREK5cUCGw84SDyPvuSzidnX-9BXOX3fve5XBG1K_I,98114
16
16
  wolfhece/PyPictures.py,sha256=m1kY0saW6Y9Q0bDCo47lW6XxDkBrbQG-Fd8uVn8G5ic,2514
17
17
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
18
- wolfhece/PyVertex.py,sha256=MtZVjIWIi62QX_oqNosb56xPgjhOGVeGz-XsD82tsNg,40614
19
- wolfhece/PyVertexvectors.py,sha256=mKwu_gMHMPTayfBNscbXEvi4cEVU3TUMz4ZBwfTSflo,249665
18
+ wolfhece/PyVertex.py,sha256=aj1Xp6n0pMb_q6AMADHnQ9pgjjRU4EQm0m4Tmc1uoEM,41912
19
+ wolfhece/PyVertexvectors.py,sha256=BLIs97SN45nFQn2T1brzN9c4FIzNNzB0WaM1kUd-E1g,251815
20
20
  wolfhece/PyWMS.py,sha256=fyyzm2HFwq8aRwVYHKiBatcZOeKnFi6DWhv4nfscySQ,4602
21
21
  wolfhece/RatingCurve.py,sha256=bUjIrQjvIjkD4V-z8bZmA6pe1ILtYNM0-3fT6YUY1RU,22498
22
22
  wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
@@ -30,7 +30,7 @@ wolfhece/color_constants.py,sha256=Snc5RX11Ydi756EkBp_83C7DiAQ_Z1aHD9jFIBsosAU,3
30
30
  wolfhece/drawing_obj.py,sha256=7vY04B6r08nurTTFmBXHyR5tVIF1YzAEw_uz4pqTDIw,4233
31
31
  wolfhece/flow_SPWMI.py,sha256=XDAelwAY-3rYOR0WKW3fgYJ_r8DU4IP6Y5xULW421tk,20956
32
32
  wolfhece/friction_law.py,sha256=MtZJLo-pTj3-Fw-w12z1LSgSIDrH-JGR0iD9wer_fpQ,5498
33
- wolfhece/gpuview.py,sha256=ggFoxBntUjHqsoxwTZQOE-UsbtC8YAIwZD1i3veAe-o,24204
33
+ wolfhece/gpuview.py,sha256=Rrq8R4Bjp_CCJbJ08gmolpYjXKIzV5qmnJJTiQLhFTY,24463
34
34
  wolfhece/import_ascfiles.py,sha256=6Zl8qBR9c6VtyziookQ8YE9KC0GtW_J9WFt5ubyGp-s,4465
35
35
  wolfhece/ins.py,sha256=uUeLMS1n3GPnfJhxl0Z2l-UXpmPUgthuwct282OOEzk,36184
36
36
  wolfhece/irm_qdf.py,sha256=KyrIk0Gu50Q702EWxRpwKTWI2KGjtHA1l8CL-Y469O0,26394
@@ -42,19 +42,19 @@ wolfhece/pybridges.py,sha256=xbZPuX40c4EKqws4OKNbUVUBPKIzLTbSdYVyrNf_kIE,57418
42
42
  wolfhece/pydike.py,sha256=hPBQsmSTW4QAp1wcOzb-TL3L7eet2WT1sJx2q-WNQ-Q,2241
43
43
  wolfhece/pylogging.py,sha256=4TI8hgBB65z-zpvU5Rfa2jkPXPhJaqXjHVPwbcdzTNc,4528
44
44
  wolfhece/pypolygons_scen.py,sha256=C0qxVUsBHWZVkurZV-DI1GMN1J1B-ul93n2fs16UjoI,39718
45
- wolfhece/pyshields.py,sha256=7k-qe2EJgr9fJE62jyPmlWQwRj8T0DK4iuMU844ZhYs,23281
45
+ wolfhece/pyshields.py,sha256=6YncgmcA6QvbyIl4jbFRf24uJVjhiSplQKWtZH42lXI,24108
46
46
  wolfhece/pyviews.py,sha256=5Hqqo9MRw1eiomYkmc7QywNu1KmEkytLJG-wH_aG38Y,13748
47
47
  wolfhece/pywalous.py,sha256=yRaWJjKckXef1d9D5devP0yFHC9uc6kRV4G5x9PNq9k,18972
48
48
  wolfhece/rain_SPWMI.py,sha256=qCfcmF7LajloOaCwnTrrSMzyME03YyilmRUOqrPrv3U,13846
49
49
  wolfhece/textpillow.py,sha256=map7HsGYML_o5NHRdFg2s_TVQed_lDnpYNDv27MM0Vw,14130
50
50
  wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
51
- wolfhece/wolf_array.py,sha256=L6OV70nFSmzfO_beNbPRQ_VoklC_cx6fyhoslI3AMXg,401812
51
+ wolfhece/wolf_array.py,sha256=HasKFOCiFzM55YSXPvpWJ7O4tOoxyTm_LHytE2ZQq8o,406444
52
52
  wolfhece/wolf_hist.py,sha256=7jeVrgSkM3ErJO6SRMH_PGzfLjIdw8vTy87kesldggk,3582
53
53
  wolfhece/wolf_texture.py,sha256=DS5eobLxrq9ljyebYfpMSQPn8shkUAZZVfqrOKN_QUU,16951
54
54
  wolfhece/wolf_tiles.py,sha256=2Ho2I20rHRY81KXxjgLOYISdF4OkJ2d6omeY4shDoGI,10386
55
55
  wolfhece/wolf_vrt.py,sha256=89XoDhCJMHiwPQUuOduxtTRKuIa8RDxgNqX65S4xp9M,10569
56
56
  wolfhece/wolf_zi_db.py,sha256=baE0niMCzybWGSvPJc5FNxo9ZxsGfU4p-FmfiavFHAs,12967
57
- wolfhece/wolfresults_2D.py,sha256=5RAvOfO0ua-5hMEdtXKZWznh4NN_q-PLfZdANm7W33M,168478
57
+ wolfhece/wolfresults_2D.py,sha256=p0v3FT6CAzf6aP4AEEXNkuHG01c2Eqbio_a8ghJIt7k,169709
58
58
  wolfhece/xyz_file.py,sha256=Se4nCPwYAYLSA5i0zsbnZUKoAMAD0mK1FJea5WSZUkk,5755
59
59
  wolfhece/acceptability/Parallels.py,sha256=h4tu3SpC_hR5Hqa68aruxhtAyhs8u666YuZ40_fR5zg,3979
60
60
  wolfhece/acceptability/__init__.py,sha256=hfgoPKLDpX7drN1Vpvux-_5Lfyc_7feT2C2zQr5v-Os,258
@@ -75,7 +75,7 @@ wolfhece/apps/curvedigitizer.py,sha256=Yps4bcayzbsz0AoVc_dkSk35dEhhn_esIBy1Ziefg
75
75
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
76
76
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
77
77
  wolfhece/apps/splashscreen.py,sha256=SrustmIQeXnsiD-92OzjdGhBi-S7c_j-cSvuX4T6rtg,2929
78
- wolfhece/apps/version.py,sha256=gKztaJeoBX2Q6XCl3TmwMp6Xp9OnTRA-2mTDn5PQ7Z4,388
78
+ wolfhece/apps/version.py,sha256=_TUgNtGFMedLigBPzswBYH6ZQUUs5BrsfxgN7xUDxWI,388
79
79
  wolfhece/apps/wolf.py,sha256=j_CgvsL8rwixbVvVD5Z0s7m7cHZ86gmFLojKGuetMls,729
80
80
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
81
81
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -254,7 +254,7 @@ wolfhece/pythonfortran/example_numpy_memory.py,sha256=o3hzJDw7YtE4v0FXI3-l2VzupC
254
254
  wolfhece/pythonfortran/tools.py,sha256=oYh9MguRYEGNGKVbHqQW2V9okZJLs3n4Qs-vLWPmBe4,2462
255
255
  wolfhece/radar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
256
256
  wolfhece/radar/wolfradar.py,sha256=mvsVf6-4KCqVF6kWsKfPuM7KPqRdYHuIZAbb8kzXAZU,10032
257
- wolfhece/rem/REMMaker.py,sha256=k1kOb_69kNw00HRPbTc_E2XTypiyV0mADDbW5etkBAs,31079
257
+ wolfhece/rem/REMMaker.py,sha256=zkiAo36MmusPhgv1qJmpDgtoTWbh_eJ6qJqtCfeC1M8,31480
258
258
  wolfhece/rem/RasterViz.py,sha256=fnyMfAJZDoS-rjagsNRGLndS-UYNUzMY4DgenjD3Y_4,29068
259
259
  wolfhece/rem/__init__.py,sha256=S2-J5uEGK_VaMFjRUYFIdSScJjZyuXH4RmMmnG3OG7I,19
260
260
  wolfhece/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -285,8 +285,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
285
285
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
286
286
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
287
287
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
288
- wolfhece-2.1.89.dist-info/METADATA,sha256=SdYAj8yeKFdq3QpmcSFCy-WAbIThcct1H2RnLGWBn7k,2570
289
- wolfhece-2.1.89.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
290
- wolfhece-2.1.89.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
291
- wolfhece-2.1.89.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
292
- wolfhece-2.1.89.dist-info/RECORD,,
288
+ wolfhece-2.1.92.dist-info/METADATA,sha256=B4LcZnRdMaSUQCv2aRIMVjVyH07wlmRL60l-8kWXXck,2548
289
+ wolfhece-2.1.92.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
290
+ wolfhece-2.1.92.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
291
+ wolfhece-2.1.92.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
292
+ wolfhece-2.1.92.dist-info/RECORD,,