wolfhece 2.1.104__py3-none-any.whl → 2.1.106__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
@@ -90,6 +90,7 @@ try:
90
90
  from .wolf_zi_db import ZI_Databse_Elt, PlansTerrier
91
91
  from .math_parser.calculator import Calculator
92
92
  from .wintab.wintab import Wintab
93
+ from .images_tiles import ImagesTiles
93
94
  except ImportError as e:
94
95
  print(e)
95
96
  raise ImportError("Error importing wolf_texture, xyz_file, mesh2d, PyPalette, wolfresults_2D, PyTranslate, PyVertex, RatingCurve, wolf_array, PyParams, mesh2d.bc_manager, PyVertexvectors, Results2DGPU, PyCrosssections, GraphNotebook, lazviewer, picc, wolf_zi_db, math_parser.calculator, wintab. Please check your installation.")
@@ -511,6 +512,7 @@ class draw_type(Enum):
511
512
  WMSBACK = 'wms-background'
512
513
  WMSFORE = 'wms-foreground'
513
514
  TILES = 'tiles'
515
+ IMAGESTILES = 'imagestiles'
514
516
 
515
517
  class Colors_1to9(wx.Frame):
516
518
 
@@ -1116,6 +1118,7 @@ class WolfMapViewer(wx.Frame):
1116
1118
  mywmsfore: list
1117
1119
  myres2D: list
1118
1120
  mytiles: list[Tiles]
1121
+ myimagestiles: list[ImagesTiles]
1119
1122
  mypartsystems: list[Particle_system]
1120
1123
  myviewers3d:list[Wolf_Viewer3D]
1121
1124
  sim_explorers: dict[Wolfresults_2D:Sim_Explorer]
@@ -1140,6 +1143,7 @@ class WolfMapViewer(wx.Frame):
1140
1143
  active_cs: crosssections
1141
1144
  active_tri: Triangulation
1142
1145
  active_tile: Tiles
1146
+ active_imagestiles: ImagesTiles
1143
1147
  active_particle_system: Particle_system
1144
1148
  active_viewer3d: Wolf_Viewer3D
1145
1149
 
@@ -1244,6 +1248,7 @@ class WolfMapViewer(wx.Frame):
1244
1248
  self.menusim2D_GPU = None
1245
1249
  self.menulaz = None
1246
1250
  self.menutiles = None
1251
+ self.menuimagestiles = None
1247
1252
 
1248
1253
  self.filemenu = wx.Menu()
1249
1254
  openitem = self.filemenu.Append(wx.ID_OPEN, _('Open project'), _('Open a complete project from file'))
@@ -1334,8 +1339,9 @@ class WolfMapViewer(wx.Frame):
1334
1339
  _('Add array and crop (binary file - real)'))
1335
1340
  addvector = self.menuaddobj.Append(wx.ID_FILE2, _('Add vectors...'), _('Add vectors'))
1336
1341
  addtiles = self.menuaddobj.Append(wx.ID_ANY, _('Add tiles...'), _('Add tiles'))
1342
+ addimagestiles = self.menuaddobj.Append(wx.ID_ANY, _('Add images tiles...'), _('Add georeferenced images tiles'))
1337
1343
  addtilescomp = self.menuaddobj.Append(wx.ID_ANY, _('Add tiles comparator...'), _('Add tiles comparator'))
1338
- addtiles = self.menuaddobj.Append(wx.ID_ANY, _('Add tiles GPU...'), _('Add tiles from 2D GPU model -- 2 arrays will be added'))
1344
+ addtilesgpu = self.menuaddobj.Append(wx.ID_ANY, _('Add tiles GPU...'), _('Add tiles from 2D GPU model -- 2 arrays will be added'))
1339
1345
  addcloud = self.menuaddobj.Append(wx.ID_FILE3, _('Add cloud...'), _('Add cloud'))
1340
1346
  addtri = self.menuaddobj.Append(wx.ID_ANY, _('Add triangulation...'), _('Add triangulation'))
1341
1347
  addprofiles = self.menuaddobj.Append(wx.ID_FILE4, _('Add cross sections...'), _('Add cross sections'))
@@ -1751,6 +1757,25 @@ class WolfMapViewer(wx.Frame):
1751
1757
  self.Bind(wx.EVT_MENU, self.create_data_from_tiles_activevec, data_active_polygon_tiles)
1752
1758
  self.Bind(wx.EVT_MENU, self.create_data_from_tiles_tmpvec, data_tmpvec_tiles)
1753
1759
 
1760
+ def pîck_image_tile(self, event: wx.Event):
1761
+
1762
+ if self.active_imagestiles is None:
1763
+ logging.warning(_('No active image tile -- Please load data first'))
1764
+ return
1765
+
1766
+ self.action = 'select active image tile'
1767
+ logging.info(_('Select active image tile'))
1768
+
1769
+ def menu_imagestiles(self):
1770
+ """ Menu for image tiles """
1771
+ if self.menuimagestiles is None:
1772
+ self.menuimagestiles = wx.Menu()
1773
+ self.menubar.Append(self.menuimagestiles, _('&Image tiles'))
1774
+
1775
+ picktiles = self.menuimagestiles.Append(wx.ID_ANY, _('Pick a tile and (un)load data'), _('Right click to pick a tile'))
1776
+ self.Bind(wx.EVT_MENU, self.pîck_image_tile, picktiles)
1777
+
1778
+
1754
1779
  def pick_tile(self, event: wx.Event):
1755
1780
 
1756
1781
  if self.active_tile is None:
@@ -3750,6 +3775,7 @@ class WolfMapViewer(wx.Frame):
3750
3775
  self.mypartsystems = []
3751
3776
  self.myvectors = []
3752
3777
  self.mytiles = []
3778
+ self.myimagestiles = []
3753
3779
  self.myclouds = []
3754
3780
  self.mytri = []
3755
3781
  self.myothers = []
@@ -3761,7 +3787,7 @@ class WolfMapViewer(wx.Frame):
3761
3787
  self.sim_explorers = {}
3762
3788
 
3763
3789
  # liste des éléments modifiable dans l'arbre
3764
- self.all_lists = [self.myarrays, self.myvectors, self.myclouds, self.mytri, self.myothers, self.myviews, self.myres2D, self.mytiles, self.mypartsystems, self.myviewers3d]
3790
+ self.all_lists = [self.myarrays, self.myvectors, self.myclouds, self.mytri, self.myothers, self.myviews, self.myres2D, self.mytiles, self.myimagestiles, self.mypartsystems, self.myviewers3d]
3765
3791
 
3766
3792
  self.menu_options = wx.Menu()
3767
3793
  self._change_title = self.menu_options.Append(wx.ID_ANY, _('Change title'), _('Change title of the window'))
@@ -5045,6 +5071,14 @@ class WolfMapViewer(wx.Frame):
5045
5071
 
5046
5072
  logging.info(_('Clip LAZ grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5047
5073
 
5074
+ def decimate_data(self, factor:int = 10):
5075
+ """ Decimate data """
5076
+
5077
+ if self.mylazdata is None:
5078
+ return
5079
+
5080
+ self.mylazdata = self.mylazdata[::factor]
5081
+
5048
5082
  def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
5049
5083
  """ select some nodes from laz data
5050
5084
 
@@ -6394,6 +6428,27 @@ class WolfMapViewer(wx.Frame):
6394
6428
  autoscale=False
6395
6429
  self.clip_laz_gridded()
6396
6430
 
6431
+ if self.mylazdata is None:
6432
+ return
6433
+
6434
+ if self.mylazdata.shape[0] > 100_000_000:
6435
+
6436
+ # Choose a decimation factor - integer
6437
+ dlg = wx.NumberEntryDialog(None, _('Your data selection is very large (>100 M)\nWould you like to decimate?'),
6438
+ _('Decaimate factor'), _('Decimation'), 0, 0, 100)
6439
+
6440
+ ret = dlg.ShowModal()
6441
+
6442
+ if ret == wx.ID_CANCEL:
6443
+ dlg.Destroy()
6444
+ return
6445
+
6446
+ decimate_fact = dlg.GetValue()
6447
+ dlg.Destroy()
6448
+
6449
+ if decimate_fact > 0:
6450
+ self.decimate_data(decimate_fact)
6451
+
6397
6452
  elif itemlabel == _('Fill active array from LAZ data'):
6398
6453
  if self.mylazgrid is None:
6399
6454
  logging.warning('')
@@ -6530,6 +6585,9 @@ class WolfMapViewer(wx.Frame):
6530
6585
  elif itemlabel == _('Add tiles...'):
6531
6586
  self.add_object(which='tiles', ToCheck=True)
6532
6587
 
6588
+ elif itemlabel ==_('Add images tiles...'):
6589
+ self.add_object(which='imagestiles', ToCheck=True)
6590
+
6533
6591
  elif itemlabel == _('Add tiles comparator...'):
6534
6592
  self.add_object(which='tilescomp', ToCheck=True)
6535
6593
 
@@ -6914,7 +6972,7 @@ class WolfMapViewer(wx.Frame):
6914
6972
  # print("Simulation")
6915
6973
  # load_sim_to_gpu()
6916
6974
 
6917
- if len(self.myarrays) + len(self.myvectors) + len(self.myclouds) + len(self.mytri) + len(self.myres2D) + len(self.mytiles) + len(self.mypartsystems) == 2 and autoscale:
6975
+ if len(self.myarrays) + len(self.myvectors) + len(self.myclouds) + len(self.mytri) + len(self.myres2D) + len(self.mytiles) + len(self.myimagestiles) + len(self.mypartsystems) == 2 and autoscale:
6918
6976
  # Trouve les bornzs si un seul élément est présent, sinon on conserve l'état du zoom
6919
6977
  self.Autoscale()
6920
6978
 
@@ -7439,7 +7497,8 @@ class WolfMapViewer(wx.Frame):
7439
7497
  'res2d_gpu',
7440
7498
  'particlesystem',
7441
7499
  'wmsback',
7442
- 'wmsfore'] = 'array',
7500
+ 'wmsfore',
7501
+ 'imagestiles'] = 'array',
7443
7502
  filename='',
7444
7503
  newobj=None,
7445
7504
  ToCheck=True,
@@ -7463,6 +7522,8 @@ class WolfMapViewer(wx.Frame):
7463
7522
  # ouverture d'une boîte de dialogue
7464
7523
  if which.lower() == 'array' or which.lower() == 'array_crop':
7465
7524
  file = wx.FileDialog(self, "Choose file", wildcard=filterArray)
7525
+ elif which.lower() == 'imagestiles':
7526
+ file = wx.DirDialog(self, "Choose directory containing images")
7466
7527
  elif which.lower() == 'particlesystem':
7467
7528
  file = wx.FileDialog(self, "Choose file", wildcard=filterjson)
7468
7529
  elif which.lower() == 'array_lidar_first' or which.lower() == 'array_lidar_second':
@@ -7670,6 +7731,21 @@ class WolfMapViewer(wx.Frame):
7670
7731
 
7671
7732
  return
7672
7733
 
7734
+
7735
+ elif which.lower() == 'imagestiles':
7736
+
7737
+ curdict = self.myimagestiles
7738
+ curtree = self.myitemsvector
7739
+
7740
+ if newobj is None:
7741
+
7742
+ newobj = ImagesTiles('', parent=self, mapviewer=self)
7743
+ newobj.scan_dir(Path(filename))
7744
+
7745
+ self.myimagestiles.append(newobj)
7746
+ self.active_imagestiles = newobj
7747
+ self.menu_imagestiles()
7748
+
7673
7749
  elif which.lower() == 'bridges':
7674
7750
  curdict = self.myvectors
7675
7751
  curtree = self.myitemsvector
@@ -7975,10 +8051,23 @@ class WolfMapViewer(wx.Frame):
7975
8051
  if ret == wx.ID_YES:
7976
8052
  loadhead = True
7977
8053
 
7978
- with wx.lib.busy.BusyInfo(_('Importing cloud points')):
7979
- wait = wx.BusyCursor()
7980
- newobj = cloud_vertices(filename, header=loadhead, mapviewer=self)
7981
- del wait
8054
+ types = None
8055
+
8056
+ elif filename.endswith('.dxf'):
8057
+ types = ['POLYLINE','LWPOLYLINE','LINE', 'MTEXT', 'INSERT']
8058
+
8059
+ dlg = wx.MultiChoiceDialog(None, _('Choose the types of entities to import'), _('Choose entities'), types)
8060
+ dlg.SetSelections = [3,4]
8061
+
8062
+ ret = dlg.ShowModal()
8063
+ if ret == wx.ID_CANCEL:
8064
+ dlg.Destroy()
8065
+ return -1
8066
+
8067
+ types = [types[i] for i in dlg.GetSelections()]
8068
+ dlg.Destroy()
8069
+
8070
+ newobj = cloud_vertices(filename, header=loadhead, mapviewer=self, dxf_imported_elts=types)
7982
8071
 
7983
8072
  self.myclouds.append(newobj)
7984
8073
  self.active_cloud = newobj
@@ -8181,6 +8270,8 @@ class WolfMapViewer(wx.Frame):
8181
8270
  return self.mywmsback
8182
8271
  elif drawing_type == draw_type.WMSFORE:
8183
8272
  return self.mywmsfore
8273
+ elif drawing_type == draw_type.IMAGESTILES:
8274
+ return self.myimagestiles
8184
8275
  else:
8185
8276
  logging.error('Unknown drawing type : ' + drawing_type)
8186
8277
  return None
@@ -9032,6 +9123,13 @@ class WolfMapViewer(wx.Frame):
9032
9123
 
9033
9124
  self.add_object('array', newobj = tilearray, ToCheck=True, id=id_label)
9034
9125
 
9126
+ elif self.action == 'select active image tile':
9127
+ # select active image tile
9128
+
9129
+ self.active_imagestiles.select_vectors_from_point(x, y, True)
9130
+ active_tile = self.active_imagestiles.get_selected_vectors()
9131
+ active_tile.myprop.imagevisible = not active_tile.myprop.imagevisible
9132
+
9035
9133
  elif self.action.find('select active vector') > -1:
9036
9134
  # Select active vector
9037
9135
 
@@ -11012,6 +11110,7 @@ class WolfMapViewer(wx.Frame):
11012
11110
 
11013
11111
  # Dessin des tuiles
11014
11112
  self._plotting(draw_type.TILES)
11113
+ self._plotting(draw_type.IMAGESTILES)
11015
11114
 
11016
11115
  if self.active_vector is not None:
11017
11116
  if self.active_vector.parentzone is None:
@@ -11098,6 +11197,16 @@ class WolfMapViewer(wx.Frame):
11098
11197
  ymax = max(locvector.ymax, ymax)
11099
11198
  k += 1
11100
11199
 
11200
+ for locvector in self.myimagestiles:
11201
+ if locvector.plotted or force:
11202
+ locvector.find_minmax()
11203
+ if isinstance(locvector,ImagesTiles):
11204
+ xmin = min(locvector.xmin, xmin)
11205
+ xmax = max(locvector.xmax, xmax)
11206
+ ymin = min(locvector.ymin, ymin)
11207
+ ymax = max(locvector.ymax, ymax)
11208
+ k += 1
11209
+
11101
11210
  for locvector in self.mytiles:
11102
11211
  if locvector.plotted or force:
11103
11212
  if locvector.idx != 'grid':
wolfhece/PyGui.py CHANGED
@@ -178,14 +178,23 @@ class MapManager(GenMapManager):
178
178
 
179
179
 
180
180
  # Set directory for hydrometry data, relative to the current file
181
- dir_hydro = Path(__file__).parent / "data/hydrometry"
182
- if not exists(dir_hydro):
183
- makedirs(dir_hydro, exist_ok=True)
181
+ dir_data = Path(__file__).parent / "data"
182
+ dir_hydro = dir_data / "hydrometry"
183
+ if not dir_hydro.exists():
184
+ dir_hydro.mkdir(parents=True, exist_ok=True)
185
+
186
+ dir_cadaster = dir_data / "Cadaster"
187
+ if not dir_cadaster.exists():
188
+ dir_cadaster.mkdir(parents=True, exist_ok=True)
189
+
190
+ dir_picc = dir_data / "PICC"
191
+ if not dir_picc.exists():
192
+ dir_picc.mkdir(parents=True, exist_ok=True)
184
193
 
185
194
  try:
186
195
  self.SPWhydrometry = hydrometry_wolfgui(dir=dir_hydro, idx = 'SPW hydrometry', mapviewer=self.mapviewer, parent = self, plotted=False)
187
- self.picc = Picc_data(data_dir=Path(r'data/PICC'), mapviewer=self.mapviewer)
188
- self.cadaster = Cadaster_data(data_dir=Path(r'data/Cadaster'), mapviewer=self.mapviewer)
196
+ self.picc = Picc_data(data_dir=dir_picc, mapviewer=self.mapviewer)
197
+ self.cadaster = Cadaster_data(data_dir=dir_cadaster, mapviewer=self.mapviewer)
189
198
  self.landmaps = PlansTerrier(mapviewer=self.mapviewer, parent = self, idx='LandMaps', plotted=True)
190
199
 
191
200
  self.mapviewer.add_object(which='other',
wolfhece/PyVertex.py CHANGED
@@ -468,7 +468,8 @@ class cloud_vertices(Element_To_Draw):
468
468
  plotted: bool = True,
469
469
  mapviewer=None,
470
470
  need_for_wx: bool = False,
471
- bbox:Polygon = None) -> None:
471
+ bbox:Polygon = None,
472
+ dxf_imported_elts = ['MTEXT', 'INSERT']) -> None:
472
473
  """
473
474
  Init cloud of vertices
474
475
 
@@ -508,7 +509,7 @@ class cloud_vertices(Element_To_Draw):
508
509
  if self.filename != '':
509
510
  if toload:
510
511
  if Path(fname).suffix.lower() == '.dxf':
511
- self.import_from_dxf(self.filename)
512
+ self.import_from_dxf(self.filename, imported_elts=dxf_imported_elts)
512
513
  elif Path(fname).suffix.lower() == '.shp':
513
514
  self.import_shapefile(self.filename, bbox=bbox)
514
515
  else:
@@ -703,7 +704,7 @@ class cloud_vertices(Element_To_Draw):
703
704
 
704
705
  self.loaded = True
705
706
 
706
- def import_from_dxf(self,fn:str=''):
707
+ def import_from_dxf(self, fn:str='', imported_elts=['MTEXT', 'INSERT']):
707
708
  """
708
709
  Importing DXF file using ezdxf library
709
710
 
@@ -717,27 +718,73 @@ class cloud_vertices(Element_To_Draw):
717
718
  import ezdxf
718
719
 
719
720
  # Lecture du fichier dxf et identification du modelspace
721
+ logging.info(_('Reading DXF file : ')+fn)
720
722
  doc = ezdxf.readfile(fn)
721
723
  msp = doc.modelspace()
722
724
 
725
+ logging.info(_('Number of entities : ')+str(len(msp)))
726
+ logging.info(_('Number of layers : ')+str(len(doc.layers)))
727
+ logging.info(_('Treating entities... '))
728
+
723
729
  # Bouclage sur les éléments du DXF
724
730
  k=0
725
731
  for e in msp:
726
- if e.dxftype() == "MTEXT" or e.dxftype()=='INSERT':
727
- x = e.dxf.insert[0]
728
- y = e.dxf.insert[1]
729
- z = e.dxf.insert[2]
732
+ if doc.layers.get(e.dxf.layer).is_on():
733
+ if e.dxftype() in imported_elts:
734
+ if e.dxftype() == "MTEXT" or e.dxftype()=='INSERT':
735
+ x = e.dxf.insert[0]
736
+ y = e.dxf.insert[1]
737
+ z = e.dxf.insert[2]
738
+
739
+ if z!=0.:
740
+ curvert = wolfvertex(x, y, z)
741
+ curdict = self.myvertices[k] = {}
742
+ curdict['vertex'] = curvert
743
+ k += 1
744
+
745
+ elif e.dxftype() == "POLYLINE":
746
+ # récupération des coordonnées
747
+ verts = [cur.dxf.location.xyz for cur in e.vertices]
748
+ for cur in verts:
749
+ curvert = wolfvertex(cur[0],cur[1],cur[2])
750
+ curdict = self.myvertices[k] = {}
751
+ curdict['vertex'] = curvert
752
+ k += 1
753
+
754
+ elif e.dxftype() == "LWPOLYLINE":
755
+ # récupération des coordonnées
756
+ verts = np.array(e.lwpoints.values)
757
+ verts = verts.reshape([verts.size // 5,5])[:,:2] # in ezdxf 1.3.5, the lwpoints.values attribute is a np.ndarray [n,5]
758
+ verts = np.column_stack([verts,[e.dxf.elevation]*len(verts)])
759
+
760
+ for cur in verts:
761
+ curvert = wolfvertex(cur[0],cur[1],cur[2])
762
+ curdict = self.myvertices[k] = {}
763
+ curdict['vertex'] = curvert
764
+ k += 1
765
+
766
+ elif e.dxftype() == "LINE":
767
+ # récupération des coordonnées
768
+ curvert = wolfvertex(e.dxf.start[0],e.dxf.start[1],e.dxf.start[2])
769
+ curdict = self.myvertices[k] = {}
770
+ curdict['vertex'] = curvert
771
+ k += 1
772
+
773
+ curvert = wolfvertex(e.dxf.end[0],e.dxf.end[1],e.dxf.end[2])
774
+ curdict = self.myvertices[k] = {}
775
+ curdict['vertex'] = curvert
776
+ k += 1
730
777
 
731
- if z!=0.:
732
- curvert = wolfvertex(x, y, z)
733
- curdict = self.myvertices[k] = {}
734
- curdict['vertex'] = curvert
735
- k += 1
778
+ else:
779
+ logging.warning(_('DXF element not supported/ignored : ') + e.dxftype())
780
+ else:
781
+ logging.info(_('Layer {} is off'.format(e.dxf.layer)))
736
782
 
737
783
  self.find_minmax(True)
738
784
  self.loaded = True
739
785
 
740
786
  logging.info(_('Number of imported points : ')+str(k))
787
+ logging.info(_('Importation finished'))
741
788
 
742
789
  return k
743
790
 
@@ -48,7 +48,7 @@ from .wolf_texture import Text_Image_Texture,Text_Infos
48
48
  from .drawing_obj import Element_To_Draw
49
49
 
50
50
  class Triangulation(Element_To_Draw):
51
- def __init__(self, fn='', pts=[],tri=[], idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
51
+ def __init__(self, fn='', pts=[], tri=[], idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
52
52
  super().__init__(idx, plotted, mapviewer, need_for_wx)
53
53
 
54
54
  self.filename = ''
@@ -62,6 +62,8 @@ class Triangulation(Element_To_Draw):
62
62
  if fn !='':
63
63
  self.filename=fn
64
64
  self.read(fn)
65
+ else:
66
+ self.valid_format()
65
67
  pass
66
68
 
67
69
  def valid_format(self):
@@ -3354,6 +3356,105 @@ class zone:
3354
3356
 
3355
3357
  return mytri
3356
3358
 
3359
+ def create_constrainedDelaunay(self, nb=None) -> Triangulation:
3360
+ """
3361
+ Création d'une triangulation Delaunay contrainte sur base des vecteurs
3362
+
3363
+ Utilisation de la librairie "triangle" (https://www.cs.cmu.edu/~quake/triangle.delaunay.html)
3364
+
3365
+ :param nb: nombre de points de découpe des vecteurs (0 pour ne rien redécouper)
3366
+ """
3367
+
3368
+ wx_exists = wx.App.Get() is not None
3369
+
3370
+ # Transformation des vecteurs en polylines shapely
3371
+ # Utile pour le redécoupage
3372
+ myls = []
3373
+ for curv in self.myvectors:
3374
+ myls.append(curv.asshapely_ls())
3375
+
3376
+ meanlength = np.mean([curline.length for curline in myls])
3377
+
3378
+ if nb is None and wx_exists:
3379
+ dlg=wx.NumberEntryDialog(None,
3380
+ _('How many points along polylines ? (0 to use as it is)')+'\n'+
3381
+ _('Mean length size is {} meters').format(meanlength),
3382
+ 'nb',
3383
+ 'dl size',
3384
+ 100,
3385
+ 0,
3386
+ 10000)
3387
+ ret=dlg.ShowModal()
3388
+ if ret==wx.ID_CANCEL:
3389
+ dlg.Destroy()
3390
+ return
3391
+
3392
+ nb=int(dlg.GetValue())
3393
+ dlg.Destroy()
3394
+ else:
3395
+ logging.warning( _('Bad parameter nb'))
3396
+
3397
+ if nb==0:
3398
+ # no decimation
3399
+ newls = myls
3400
+ else:
3401
+ # redécoupage des polylines
3402
+ s = np.linspace(0.,1.,num=nb,endpoint=True)
3403
+
3404
+ newls = [LineString([curls.interpolate(curs,True) for curs in s]) for curls in myls]
3405
+
3406
+ # Récupération des coordonnées des points
3407
+ xyz = [np.asarray(curls.coords[:]) for curls in newls]
3408
+ xyz = np.concatenate(xyz)
3409
+
3410
+ # Recherche du minimum pour recentrer les coordonnées et éviter des erreurs de calcul
3411
+ xmin = xyz[:,0].min()
3412
+ ymin = xyz[:,1].min()
3413
+
3414
+ xyz[:,0] -= xmin
3415
+ xyz[:,1] -= ymin
3416
+
3417
+ # Remove duplicate points
3418
+ xyz, indices = np.unique(xyz, axis=0, return_inverse=True)
3419
+
3420
+ # Numérotation des segments
3421
+ segments = []
3422
+ k = 0
3423
+ for cur in newls:
3424
+ for i in range(len(cur.coords)-1):
3425
+ segments.append([indices[k], indices[k+1]])
3426
+ k+=1
3427
+
3428
+ # Création de la géométrie pour la triangulation
3429
+ geom = {'vertices' : [[x,y] for x,y in xyz[:,:2]],
3430
+ 'segments' : segments}
3431
+
3432
+ try:
3433
+ # Triangulation
3434
+ delaunay = triangle.triangulate(geom, 'p') # d'autres options sont possibles (voir la doc de triangle)
3435
+
3436
+ # Recover z values from xyz for each vertex
3437
+ # Searching value in xyz is not the best way
3438
+ # We create a dictionary to avoid searching manually
3439
+ xyz_dict = {(curxyz[0], curxyz[1]): curxyz[2] for curxyz in xyz}
3440
+ allvert = []
3441
+ for curvert in delaunay['vertices']:
3442
+ x = curvert[0]
3443
+ y = curvert[1]
3444
+ z = xyz_dict.get((x, y), 0.)
3445
+ allvert.append([x + xmin, y + ymin, z])
3446
+
3447
+ # Create the Triangulation object
3448
+ mytri=Triangulation(pts= allvert,
3449
+ tri= [curtri for curtri in delaunay['triangles']])
3450
+ mytri.find_minmax(True)
3451
+
3452
+ except Exception as e:
3453
+ logging.error(_('Error in constrained Delaunay triangulation - {e}'))
3454
+ return None
3455
+
3456
+ return mytri
3457
+
3357
3458
  def createmultibin_proj(self, nb=None, nb2=0) -> Triangulation:
3358
3459
  """
3359
3460
  Création d'une triangulation sur base des vecteurs par projection au plus proche du vecteur central
@@ -4562,6 +4663,8 @@ class Zones(wx.Frame, Element_To_Draw):
4562
4663
  for idx, row in content.iterrows():
4563
4664
  if 'NAME' in row.keys():
4564
4665
  name = row['NAME']
4666
+ elif 'name' in row.keys():
4667
+ name = row['name']
4565
4668
  elif 'MAJ_NIV3T' in row.keys():
4566
4669
  # WALOUS
4567
4670
  name = row['MAJ_NIV3T']
@@ -4818,28 +4921,31 @@ class Zones(wx.Frame, Element_To_Draw):
4818
4921
  # Bouclage sur les éléments du DXF pour identifier les layers utiles et ensuite créer les zones adhoc
4819
4922
  for e in msp:
4820
4923
  if doc.layers.get(e.dxf.layer).is_on():
4821
- if e.dxftype() == "POLYLINE":
4822
- if e.dxf.layer not in used_layers.keys():
4823
- curlayer = used_layers[e.dxf.layer]={}
4824
- else:
4825
- curlayer = used_layers[e.dxf.layer]
4826
- curlayer[e.dxftype().lower()]=0
4924
+ if e.dxftype() in imported_elts:
4925
+ if e.dxftype() == "POLYLINE":
4926
+ if e.dxf.layer not in used_layers.keys():
4927
+ curlayer = used_layers[e.dxf.layer]={}
4928
+ else:
4929
+ curlayer = used_layers[e.dxf.layer]
4930
+ curlayer[e.dxftype().lower()]=0
4827
4931
 
4828
- elif e.dxftype() == "LWPOLYLINE":
4829
- if e.dxf.layer not in used_layers.keys():
4830
- curlayer = used_layers[e.dxf.layer]={}
4831
- else:
4832
- curlayer = used_layers[e.dxf.layer]
4833
- curlayer[e.dxftype().lower()]=0
4932
+ elif e.dxftype() == "LWPOLYLINE":
4933
+ if e.dxf.layer not in used_layers.keys():
4934
+ curlayer = used_layers[e.dxf.layer]={}
4935
+ else:
4936
+ curlayer = used_layers[e.dxf.layer]
4937
+ curlayer[e.dxftype().lower()]=0
4834
4938
 
4835
- elif e.dxftype() == "LINE": # dans ce cas spécifique, ce sont a priori les lignes composant les croix sur les points levés
4836
- if e.dxf.layer not in used_layers.keys():
4837
- curlayer = used_layers[e.dxf.layer]={}
4838
- else:
4839
- curlayer = used_layers[e.dxf.layer]
4840
- curlayer[e.dxftype().lower()]=0
4939
+ elif e.dxftype() == "LINE": # dans ce cas spécifique, ce sont a priori les lignes composant les croix sur les points levés
4940
+ if e.dxf.layer not in used_layers.keys():
4941
+ curlayer = used_layers[e.dxf.layer]={}
4942
+ else:
4943
+ curlayer = used_layers[e.dxf.layer]
4944
+ curlayer[e.dxftype().lower()]=0
4945
+ else:
4946
+ logging.warning(_('DXF element not supported : ') + e.dxftype())
4841
4947
  else:
4842
- pass
4948
+ logging.info(_('Layer {} is off'.format(e.dxf.layer)))
4843
4949
 
4844
4950
  # Création des zones
4845
4951
  for curlayer in used_layers.keys():
@@ -4870,7 +4976,8 @@ class Zones(wx.Frame, Element_To_Draw):
4870
4976
  nbid+=1
4871
4977
  # récupération des coordonnées
4872
4978
  verts = np.array(e.lwpoints.values)
4873
- verts = verts.reshape([int(len(verts)/5),5])[:,:2]
4979
+ verts = verts.reshape([verts.size // 5,5])[:,:2] # in ezdxf 1.3.5, the lwpoints.values attribute is a np.ndarray [n,5]
4980
+ # verts = verts.reshape([len(verts) // 5,5])[:,:2] # in ezdxf 1.2.0, the lwpoints.values attribute was flattened
4874
4981
  verts = np.column_stack([verts,[e.dxf.elevation]*len(verts)])
4875
4982
 
4876
4983
  curzone = used_layers[e.dxf.layer][e.dxftype().lower()]
@@ -5206,6 +5313,10 @@ class Zones(wx.Frame, Element_To_Draw):
5206
5313
  self.trifromall_proj.SetToolTip(_("Create a triangular mesh based on all vectors in the currently active zone.\nGenerate vertices by projecting the central polyline, or the nearest one if there is an even number of polylines, onto the other polylines.\nAdd the resulting mesh to the GUI.\nThis can be useful in certain interpolation methods."))
5207
5314
  self.trifromall_proj.Bind(wx.EVT_BUTTON,self.Oncreatemultibin_project)
5208
5315
 
5316
+ self.constrainedDelaunay = wx.Button(self,label=_('Constrained Delaunay'))
5317
+ self.constrainedDelaunay.SetToolTip(_("Create a triangular mesh based on all vectors in the currently active zone."))
5318
+ self.constrainedDelaunay.Bind(wx.EVT_BUTTON,self.OnconstrainedDelaunay)
5319
+
5209
5320
  self.polyfrompar = wx.Button(self,label=_('Create polygons from parallels'))
5210
5321
  self.polyfrompar.SetToolTip(_("Create polygons in a new zone from parallels defined by " + _('Add and parallel') + _(" and a 2D curvilinear distance \n Useful for plotting some results or analyse data inside each polygon")))
5211
5322
  self.polyfrompar.Bind(wx.EVT_BUTTON,self.Oncreatepolygons)
@@ -5335,6 +5446,7 @@ class Zones(wx.Frame, Element_To_Draw):
5335
5446
  boxtri.Add(self.binfrom3,1,wx.EXPAND)
5336
5447
  boxtri.Add(self.trifromall,1,wx.EXPAND)
5337
5448
  boxtri.Add(self.trifromall_proj,1,wx.EXPAND)
5449
+ boxtri.Add(self.constrainedDelaunay,1,wx.EXPAND)
5338
5450
  boxtri.Add(self.polyfrompar,1,wx.EXPAND)
5339
5451
  boxtri.Add(self.slidingpoly,1,wx.EXPAND)
5340
5452
 
@@ -6122,6 +6234,21 @@ class Zones(wx.Frame, Element_To_Draw):
6122
6234
  self.mapviewer.add_object('triangulation',newobj=mytri)
6123
6235
  self.mapviewer.Refresh()
6124
6236
 
6237
+ def OnconstrainedDelaunay(self, event:wx.MouseEvent):
6238
+ """
6239
+ Create a constrained Delaunay triangulation from the active zone
6240
+ """
6241
+ if self.wx_exists:
6242
+ if self.active_zone is None:
6243
+ return
6244
+
6245
+ myzone = self.active_zone
6246
+
6247
+ mytri = myzone.create_constrainedDelaunay()
6248
+
6249
+ self.mapviewer.add_object('triangulation',newobj=mytri)
6250
+ self.mapviewer.Refresh()
6251
+
6125
6252
  def Oncreatemultibin_project(self, event:wx.MouseEvent):
6126
6253
  """
6127
6254
  Création d'une triangulation sur base de plusieurs vecteurs
@@ -6917,5 +7044,5 @@ class Grid(Zones):
6917
7044
  contour.add_vertex(newvert)
6918
7045
  newvert=wolfvertex(locox,locey)
6919
7046
  contour.add_vertex(newvert)
6920
-
7047
+
6921
7048
  self.find_minmax(True)
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 = 104
8
+ self.patch = 106
9
9
 
10
10
  def __str__(self):
11
11
 
@@ -0,0 +1,84 @@
1
+ from osgeo import gdal
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ from .PyTranslate import _
6
+ from .wolf_array import WolfArray, WolfArrayMB
7
+ from .PyVertexvectors import zone,Zones,vector, wolfvertex
8
+
9
+
10
+ class ImagesTiles(Zones):
11
+ """ Class to manage images tiles.
12
+
13
+ Images must be stored in the same directory.
14
+ """
15
+
16
+ def __init__(self,
17
+ filename = '',
18
+ ox = 0, oy = 0,
19
+ tx = 0, ty = 0,
20
+ parent=None, is2D=True,
21
+ idx = '', plotted = True,
22
+ mapviewer=None, need_for_wx = False,
23
+ bbox = None, find_minmax = True,
24
+ shared = False, colors = None):
25
+
26
+ super().__init__(filename, ox, oy, tx, ty, parent, is2D, idx, plotted, mapviewer, need_for_wx, bbox, find_minmax, shared, colors)
27
+
28
+ def scan_dir(self, directory:Path, extensions:list[str] = ['tif', 'tiff']):
29
+ """ Scan directory for images tiles.
30
+
31
+ :param directory: directory to scan.
32
+ :param extensions: list of extensions to search for.
33
+ """
34
+
35
+ self.myzones = []
36
+ for ext in extensions:
37
+ self.myzones += self.scan_dir_ext(directory, ext)
38
+
39
+ self.find_minmax(True)
40
+
41
+ def scan_dir_ext(self, directory:Path, ext:str, force_visible:bool = False):
42
+ """ Scan directory for images tiles with a specific extension.
43
+
44
+ :param directory: directory to scan.
45
+ :param ext: extension to search for.
46
+ """
47
+
48
+ all_files = directory.glob(f'*.{ext}')
49
+
50
+ zones = []
51
+ for file in all_files:
52
+ try:
53
+ ds:gdal.Dataset
54
+ ds = gdal.Open(str(file))
55
+ if ds is None:
56
+ logging.error(f'Could not open {file}')
57
+ continue
58
+
59
+ ulx, xres, xskew, uly, yskew, yres = ds.GetGeoTransform()
60
+ lrx = ulx + (ds.RasterXSize * xres)
61
+ lry = uly + (ds.RasterYSize * yres)
62
+
63
+ xmin, xmax = min(ulx, lrx), max(ulx, lrx)
64
+ ymin, ymax = min(uly, lry), max(uly, lry)
65
+
66
+ loczone = zone(name = file, parent= self)
67
+ vect = vector(name='image', parentzone=loczone)
68
+ loczone.add_vector(vect)
69
+
70
+ vect.myprop.attachedimage = Path(file)
71
+ vect.myprop.imagevisible = True if ds.RasterXSize * ds.RasterYSize < 8_000_000 or force_visible else False
72
+
73
+ vect.add_vertex(wolfvertex(xmin, ymin))
74
+ vect.add_vertex(wolfvertex(xmax, ymin))
75
+ vect.add_vertex(wolfvertex(xmax, ymax))
76
+ vect.add_vertex(wolfvertex(xmin, ymax))
77
+ vect.close_force()
78
+
79
+ zones.append(loczone)
80
+
81
+ except Exception as e:
82
+ logging.error(f'Error while opening {file}: {e}')
83
+
84
+ return zones
@@ -451,6 +451,11 @@ class xyz_laz_grid():
451
451
  self.endy = ybounds[1]
452
452
  self.nbx = gridsize[0]
453
453
  self.nby = gridsize[1]
454
+
455
+ if self.nbx == 0 or self.nby == 0:
456
+ logging.error(_('Grid size is 0 - abort !'))
457
+ return
458
+
454
459
  self.dx = (self.endx-self.origx)/float(self.nbx)
455
460
  self.dy = (self.endy-self.origy)/float(self.nby)
456
461
  self.genfile=fn_out+'_'+'x1'+'_'+'y1'+'_xyz.bin'
@@ -503,9 +508,12 @@ class xyz_laz_grids():
503
508
  ret = [cur for cur in ret if len(cur)>0]
504
509
 
505
510
  if len(ret)==0:
511
+ logging.info(_('No data found'))
506
512
  return np.asarray([])
507
513
  else:
508
- return np.concatenate(ret)
514
+ ret = np.concatenate(ret)
515
+ logging.info(_('Data found -- {} points'.format(ret.shape[0])))
516
+ return ret
509
517
 
510
518
  def read_dir(self, dir_grids):
511
519
  dirs = listdir(dir_grids)
@@ -633,6 +641,9 @@ class xyz_laz_grids():
633
641
  vec = vecs.get_zone(file_wo_suf)
634
642
  bounds = vec.myvectors[0].get_bounds()
635
643
 
644
+ bounds = [[math.floor(bounds[0][0]/ds)*ds, math.floor(bounds[0][1]/ds)*ds],
645
+ [math.ceil(bounds[1][0]/ds)*ds, math.ceil(bounds[1][1]/ds)*ds]]
646
+
636
647
  dx = bounds[1][0] -bounds[0][0]
637
648
  dy = bounds[1][1] -bounds[0][1]
638
649
  nb = max(int(dx/ds), int(dy/ds))
@@ -640,7 +651,7 @@ class xyz_laz_grids():
640
651
  self.grids.append(newlaz._sort_grid_np(entry.path,
641
652
  join(dirname, file_wo_suf),
642
653
  bounds=[[bounds[0][0], bounds[1][0]], [bounds[0][1], bounds[1][1]]],
643
- gridsize=[int(dx/ds), int(dy/ds)],
654
+ gridsize=[max(int(dx/ds),1), max(int(dy/ds),1)],
644
655
  force_format=force_format))
645
656
 
646
657
  def find_pointsXYZ(xyz:np.ndarray, bounds:Union[tuple[tuple[float,float],tuple[float,float]], list[list[float, float],list[float, float]]]) -> np.ndarray:
wolfhece/wolf_array.py CHANGED
@@ -5614,21 +5614,32 @@ class WolfArray(Element_To_Draw, header_wolf):
5614
5614
  if reset_plot:
5615
5615
  self.reset_plot()
5616
5616
 
5617
- def export_geotif(self, outdir='', extent = '', EPSG:int = 31370):
5617
+ def export_geotif(self, outdir:str= '', extent:str= '', EPSG:int = 31370):
5618
5618
  """
5619
5619
  Export de la matrice au format Geotiff (Lambert 72 - EPSG:31370)
5620
5620
 
5621
+ Pour sauvegarder l'objet au format Geotiff, il est recommandé d'utiliser
5622
+ la fonction write_all plutôt que celle-ci directement.
5623
+
5621
5624
  Formats supportés :
5622
5625
  - Int32
5626
+ - Int16
5627
+ - Int8
5628
+ - Byte
5623
5629
  - Float32
5624
5630
  - Float64
5625
5631
 
5626
- :param outdir: directory
5627
- :param extent: suffix to add to the filename before the extension '.tif'
5632
+ :param outdir: directory - If provided, the file will be savd as "outdir/idx+extent.tif"
5633
+ If not provided, we use the filename attribute
5634
+
5635
+ :param extent: suffix to add to the filename before the extension '.tif' (only if outdir is provided)
5628
5636
  :param EPSG: EPSG code, by default 31370 (Lambert 72)
5629
5637
  """
5630
5638
  from osgeo import gdal, osr, gdalconst
5631
5639
 
5640
+ outdir = str(outdir)
5641
+ extent = str(extent)
5642
+
5632
5643
  srs = osr.SpatialReference()
5633
5644
  srs.ImportFromEPSG(EPSG)
5634
5645
 
@@ -5650,6 +5661,9 @@ class WolfArray(Element_To_Draw, header_wolf):
5650
5661
  elif arr.dtype == np.int16:
5651
5662
  arr_type = gdal.GDT_Int16
5652
5663
  nullvalue = int(self.nullvalue)
5664
+ elif arr.dtype == np.uint8:
5665
+ arr_type = gdal.GDT_Byte
5666
+ nullvalue = int(self.nullvalue)
5653
5667
  else:
5654
5668
  arr_type = gdal.GDT_Int32
5655
5669
  nullvalue = int(self.nullvalue)
@@ -5668,7 +5682,12 @@ class WolfArray(Element_To_Draw, header_wolf):
5668
5682
  else:
5669
5683
  options = ['COMPRESS=LZW']
5670
5684
 
5671
- out_ds = driver.Create(filename, arr.shape[0], arr.shape[1], 1, arr_type, options=options)
5685
+ out_ds = driver.Create(str(filename), arr.shape[0], arr.shape[1], 1, arr_type, options=options)
5686
+
5687
+ if out_ds is None:
5688
+ logging.error(_('Could not create the file {filename}'))
5689
+ return
5690
+
5672
5691
  out_ds.SetProjection(srs.ExportToWkt())
5673
5692
 
5674
5693
 
@@ -7688,7 +7707,7 @@ class WolfArray(Element_To_Draw, header_wolf):
7688
7707
  if newpath is not None:
7689
7708
  self.filename = newpath
7690
7709
 
7691
- if self.filename.endswith('.tif'):
7710
+ if self.filename.endswith('.tif') or self.filename.endswith('.tiff'):
7692
7711
  self.export_geotif(EPSG=EPSG)
7693
7712
  elif self.filename.endswith('.npy'):
7694
7713
 
wolfhece/wolf_tiles.py CHANGED
@@ -44,8 +44,8 @@ class Tiles(Zones):
44
44
  need_for_wx: bool = False,
45
45
  linked_data_dir=None) -> None:
46
46
  """
47
- filename : le fichier de forme (ShapeFile) de tuilage
48
- linked_data_dir : le répertoire des données .tif
47
+ :param filename: le fichier de forme (ShapeFile) de tuilage
48
+ :param linked_data_dir: le répertoire des données .tif
49
49
  """
50
50
  super().__init__(filename, ox, oy, tx, ty, parent, is2D, idx, plotted, mapviewer, need_for_wx)
51
51
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wolfhece
3
- Version: 2.1.104
3
+ Version: 2.1.106
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
@@ -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=Bb1T8qjgKMChadJYDrHO9uo6CwItiAXScZpYkDXqZF8,11387
9
9
  wolfhece/PyCrosssections.py,sha256=FnmM9DWY_SAF2EDH9Gu2PojXNtSTRF4-aYQuAAJXBh4,112771
10
- wolfhece/PyDraw.py,sha256=p1lxn2ScM3f5QI97r80XDg4pgWSc6T-craaPVPfcX2Y,476586
11
- wolfhece/PyGui.py,sha256=jyeYF7srKH3HLZQGQIqcRW3u308KUDA-oLwzX-jkDzQ,143843
10
+ wolfhece/PyDraw.py,sha256=pSNMh5KuYXgw4CMA0b5tbGni2QfEc2V2IRVmPMz4ntM,480761
11
+ wolfhece/PyGui.py,sha256=pD_t3leVt8U9tzFnSMGsF-Ds4m0qPwLb_Tc8fQT34GQ,144147
12
12
  wolfhece/PyGuiHydrology.py,sha256=f60E8K9eGTnRq5RDF6yvt-ahf2AYegwQ9t25zZ2Mk1A,14946
13
13
  wolfhece/PyHydrographs.py,sha256=jwtSNMMACwarxrtN1UeQYth99UNrhwPx1IGgUwcooHA,3774
14
14
  wolfhece/PyPalette.py,sha256=81n1P-olOe4wElTLv-miSDhqvJU_RHcxgfpHt794dSw,31436
15
15
  wolfhece/PyParams.py,sha256=GRp1zZDUJIjs8PtjwScDdov-E9orr1JWOntDazN5AOw,98577
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=3-1zV8-U8bcf9wUL0mJao54Sf3Ew-wmzxhRWUajnGXM,42210
19
- wolfhece/PyVertexvectors.py,sha256=bwXWtZ9qjrrf94G8n_Ne5qETExB9p4oUR6GDDuCBVH0,253864
18
+ wolfhece/PyVertex.py,sha256=0TATf_Se6E7_P-kR1_DMEzRw_zy8-5cGFnc3yAod7yQ,44754
19
+ wolfhece/PyVertexvectors.py,sha256=F2ZtinpWk1ms7e-lDG_9WzD3waLbkVTKXTD5k6BhMpw,258966
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
@@ -32,6 +32,7 @@ wolfhece/drawing_obj.py,sha256=7vY04B6r08nurTTFmBXHyR5tVIF1YzAEw_uz4pqTDIw,4233
32
32
  wolfhece/flow_SPWMI.py,sha256=XDAelwAY-3rYOR0WKW3fgYJ_r8DU4IP6Y5xULW421tk,20956
33
33
  wolfhece/friction_law.py,sha256=MtZJLo-pTj3-Fw-w12z1LSgSIDrH-JGR0iD9wer_fpQ,5498
34
34
  wolfhece/gpuview.py,sha256=Jql8pLZ0PpvZ_ScT-U4jsXANZ9j4-m_RWhsLA2HISuQ,24544
35
+ wolfhece/images_tiles.py,sha256=npR3IJTVEsmgNQP0opVD8g40sBruxLNdmq29A90cVUY,2929
35
36
  wolfhece/import_ascfiles.py,sha256=6Zl8qBR9c6VtyziookQ8YE9KC0GtW_J9WFt5ubyGp-s,4465
36
37
  wolfhece/ins.py,sha256=uUeLMS1n3GPnfJhxl0Z2l-UXpmPUgthuwct282OOEzk,36184
37
38
  wolfhece/irm_qdf.py,sha256=KyrIk0Gu50Q702EWxRpwKTWI2KGjtHA1l8CL-Y469O0,26394
@@ -51,10 +52,10 @@ wolfhece/pywalous.py,sha256=mWB7UxlYMIbPxNUDlONQEjcOOy9VSaRU9aYWZ5IFLu8,19164
51
52
  wolfhece/rain_SPWMI.py,sha256=qCfcmF7LajloOaCwnTrrSMzyME03YyilmRUOqrPrv3U,13846
52
53
  wolfhece/textpillow.py,sha256=map7HsGYML_o5NHRdFg2s_TVQed_lDnpYNDv27MM0Vw,14130
53
54
  wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
54
- wolfhece/wolf_array.py,sha256=ZJ_HvlN2GeuW4lNJ15-HZSOK5iNc_t5eN4YmL3lJYbY,420268
55
+ wolfhece/wolf_array.py,sha256=_UYxRGF8T0rHTv-1uDJ9opHHwBE7bh39XXnhhUgIcKM,421010
55
56
  wolfhece/wolf_hist.py,sha256=7jeVrgSkM3ErJO6SRMH_PGzfLjIdw8vTy87kesldggk,3582
56
57
  wolfhece/wolf_texture.py,sha256=DS5eobLxrq9ljyebYfpMSQPn8shkUAZZVfqrOKN_QUU,16951
57
- wolfhece/wolf_tiles.py,sha256=2Ho2I20rHRY81KXxjgLOYISdF4OkJ2d6omeY4shDoGI,10386
58
+ wolfhece/wolf_tiles.py,sha256=VWaWtKlS0RMv_qb5qiPmZdKFJRGgJ3DQEeV_ryfCRMo,10398
58
59
  wolfhece/wolf_vrt.py,sha256=NcPZYW4bu06IpqQuiutoAhCvDkeZ3TzOVb8z4wTQ1h8,14319
59
60
  wolfhece/wolf_zi_db.py,sha256=baE0niMCzybWGSvPJc5FNxo9ZxsGfU4p-FmfiavFHAs,12967
60
61
  wolfhece/wolfresults_2D.py,sha256=Z-SKkipwbChyf9V4777nacKNd5p0aimORjC6evg5zeI,184819
@@ -79,7 +80,7 @@ wolfhece/apps/curvedigitizer.py,sha256=Yps4bcayzbsz0AoVc_dkSk35dEhhn_esIBy1Ziefg
79
80
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
80
81
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
81
82
  wolfhece/apps/splashscreen.py,sha256=SrustmIQeXnsiD-92OzjdGhBi-S7c_j-cSvuX4T6rtg,2929
82
- wolfhece/apps/version.py,sha256=n7akH_alRd4UzgK20bebXm0Lqdk8wOrmsDS7aC8QH_E,389
83
+ wolfhece/apps/version.py,sha256=U-1Ed3Iyh77BiyLsxRW_EJiRSbsCERPs30JqPCz2o6s,389
83
84
  wolfhece/apps/wolf.py,sha256=j_CgvsL8rwixbVvVD5Z0s7m7cHZ86gmFLojKGuetMls,729
84
85
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
85
86
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -153,7 +154,7 @@ wolfhece/lagrangian/particles.py,sha256=S52_-3rzgVhift6l4Gznvsf_RTggzvNaD1dPvQUr
153
154
  wolfhece/lagrangian/velocity_field.py,sha256=oGVjNm98gEpawreFIrC1lDyC5bEhkk2CsyYAlF1Kq50,10574
154
155
  wolfhece/lazviewer/__init__.py,sha256=lz60EpQOBZ-zjvYzff6Y11jzAmC7mjOaxRYAfoqizQs,473
155
156
  wolfhece/lazviewer/_add_path.py,sha256=GDwPnzHuGRXGriDNcu1SQ6HetFDGIApeAQZEzYArGvI,605
156
- wolfhece/lazviewer/laz_viewer.py,sha256=zuXMSh50HZGcduD5dWsrxrNu9qcxg-NfQr6Rg5sKxO8,42746
157
+ wolfhece/lazviewer/laz_viewer.py,sha256=woY6BTu6_Qomx_UsVxHXPuD8j-r9CemM0pJ-H9OMNU8,43244
157
158
  wolfhece/lazviewer/libs/Qt5Core.dll,sha256=sTJ_ctYFY9KHMNytF-lzH_078zIvnKTjN-71FDkOWPw,4924928
158
159
  wolfhece/lazviewer/libs/Qt5Gui.dll,sha256=07BeaOeYByraGkKYeDiSDYLawHM8tyd55pVJlKbZ4Y0,5436416
159
160
  wolfhece/lazviewer/libs/Qt5Network.dll,sha256=U-9FiLE9LUKru8r8EQxTnwwlMpwS8JzUtenhkKTCox0,1038336
@@ -292,8 +293,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
292
293
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
293
294
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
294
295
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
295
- wolfhece-2.1.104.dist-info/METADATA,sha256=ccImhLoF0Q0GeJKNyWSqPXzau2pP4yJQNfwWdsJO4Z4,2618
296
- wolfhece-2.1.104.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
297
- wolfhece-2.1.104.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
298
- wolfhece-2.1.104.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
299
- wolfhece-2.1.104.dist-info/RECORD,,
296
+ wolfhece-2.1.106.dist-info/METADATA,sha256=zF3O-oD6-npmbSexAZwCntdKPYpjKbK8GvjIoufqoU8,2618
297
+ wolfhece-2.1.106.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
298
+ wolfhece-2.1.106.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
299
+ wolfhece-2.1.106.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
300
+ wolfhece-2.1.106.dist-info/RECORD,,