wolfhece 2.1.52__py3-none-any.whl → 2.1.54__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
@@ -179,7 +179,7 @@ class DragdropFileTarget(wx.FileDropTarget):
179
179
  id = id + '_1'
180
180
 
181
181
  try:
182
- newobj = WolfArray(fname=name)
182
+ newobj = WolfArray(fname=name, mapviewer= self.window)
183
183
  self.window.add_object('array', newobj = newobj, id = id)
184
184
  except:
185
185
  logging.error(_('Error while loading array : ') + name)
@@ -191,7 +191,7 @@ class DragdropFileTarget(wx.FileDropTarget):
191
191
  id = id + '_1'
192
192
 
193
193
  try:
194
- newobj = WolfArrayMB(fname=name)
194
+ newobj = WolfArrayMB(fname=name, mapviewer= self.window)
195
195
  self.window.add_object('array', newobj = newobj, id = id)
196
196
  except:
197
197
  logging.error(_('Error while loading array : ') + name)
@@ -203,7 +203,7 @@ class DragdropFileTarget(wx.FileDropTarget):
203
203
  id = id + '_1'
204
204
 
205
205
  try:
206
- newobj = Zones(filename=name, parent=self.window)
206
+ newobj = Zones(filename=name, parent=self.window, mapviewer=self.window)
207
207
  self.window.add_object('vector', newobj = newobj, id = id)
208
208
  except:
209
209
  logging.error(_('Error while loading vector : ') + name)
@@ -247,7 +247,7 @@ class WolfMapViewer(wx.Frame):
247
247
  context: GLContext # context OpenGL
248
248
  mytooltip: Wolf_Param # Objet WOLF permettant l'analyse de ce qui est sous la souris
249
249
  treelist: TreeListCtrl # Gestion des éléments sous forme d'arbre
250
- lbl_selecteditem: StaticText
250
+ _lbl_selecteditem: StaticText
251
251
  leftbox: BoxSizer
252
252
 
253
253
  # DEPRECEATED
@@ -611,7 +611,7 @@ class WolfMapViewer(wx.Frame):
611
611
 
612
612
  # ajout d'une liste en arbre des objets
613
613
  self.treelist = TreeListCtrl(self, style= wx.dataview.TL_CHECKBOX | wx.LC_EDIT_LABELS | wx.TR_FULL_ROW_HIGHLIGHT)
614
- self.lbl_selecteditem = StaticText(self, style=wx.ALIGN_CENTER_HORIZONTAL)
614
+ self._lbl_selecteditem = StaticText(self, style=wx.ALIGN_CENTER_HORIZONTAL)
615
615
  self.selected_object = None
616
616
 
617
617
  self.root = self.treelist.GetRootItem()
@@ -641,17 +641,15 @@ class WolfMapViewer(wx.Frame):
641
641
  # dimensionnement et positionnement de l'arbre
642
642
  self.leftbox = BoxSizer(orient=wx.VERTICAL)
643
643
  self.leftbox.Add(self.treelist, 1, wx.LEFT)
644
- self.leftbox.Add(self.lbl_selecteditem, 0, wx.LEFT)
644
+ self.leftbox.Add(self._lbl_selecteditem, 0, wx.LEFT)
645
645
  self.treelist.SetSize(self.treewidth, height)
646
646
 
647
647
 
648
648
  self.CreateStatusBar(1)
649
649
 
650
- # self.lbl_selecteditem.SetSize(self.treewidth,30)
651
650
  self.SetSizer(self.leftbox)
652
651
 
653
652
  # self.treelist.SetPosition((0,0))
654
- # self.lbl_selecteditem.SetPosition((0,height-30))
655
653
 
656
654
  # fenêtre ToolTip
657
655
  self.mytooltip = Wolf_Param(self, "Values", to_read=False, withbuttons=False)
@@ -879,6 +877,8 @@ class WolfMapViewer(wx.Frame):
879
877
  aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around active vector'), _('Display a Matplotlib plot with the LAZ values around the active vector/polyline'),)
880
878
  pick_aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around temporary vector'), _('Display a Matplotlib plot with the LAZ values around a temporary vector/polyline -- Right clicks to add points + Enter'),)
881
879
  updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
880
+ fillarray_laz = self.menulaz.Append(wx.ID_ANY, _('Fill active array from LAZ data'), _('Fill an array from the LAZ data'),)
881
+ selectarray_laz = self.menulaz.Append(wx.ID_ANY, _('Select cells in array from LAZ data'), _('Select nodes in active array from the LAZ data'),)
882
882
 
883
883
  def menu_wolf2d(self):
884
884
 
@@ -3885,6 +3885,220 @@ class WolfMapViewer(wx.Frame):
3885
3885
 
3886
3886
  logging.info(_('Clip LAZ grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
3887
3887
 
3888
+ def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
3889
+ """ select some nodes from laz data
3890
+
3891
+ :param array: array to fill
3892
+ :param used_codes: codes to use
3893
+ """
3894
+ if self.mylazgrid is None:
3895
+ return
3896
+
3897
+ if array is None:
3898
+ logging.error(_('No array'))
3899
+ return
3900
+
3901
+ if used_codes is None:
3902
+ keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
3903
+ names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
3904
+
3905
+ with wx.MultiChoiceDialog(None, _('Choose the codes to use'), _('Codes'), names) as dlg:
3906
+ if dlg.ShowModal() == wx.ID_OK:
3907
+ used_codes = dlg.GetSelections()
3908
+ used_codes = [float(keycode[cur]) for cur in used_codes]
3909
+ else:
3910
+ return
3911
+
3912
+ curbounds = array.get_bounds()
3913
+
3914
+ # align bounds on chunk_size
3915
+ curbounds[0][0] = curbounds[0][0] - curbounds[0][0] % chunk_size
3916
+ curbounds[0][1] = curbounds[0][1] + chunk_size - curbounds[0][1] % chunk_size
3917
+ curbounds[1][0] = curbounds[1][0] - curbounds[1][0] % chunk_size
3918
+ curbounds[1][1] = curbounds[1][1] + chunk_size - curbounds[1][1] % chunk_size
3919
+
3920
+ chunck_x = np.arange(curbounds[0][0], curbounds[0][1], chunk_size)
3921
+ chunck_y = np.arange(curbounds[1][0], curbounds[1][1], chunk_size)
3922
+
3923
+ for curx in tqdm(chunck_x, 'Chunks'):
3924
+ for cury in chunck_y:
3925
+ curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
3926
+
3927
+ logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
3928
+ self.mylazdata = self.mylazgrid.scan(curbounds)
3929
+ # logging.info(_('Scan done'))
3930
+
3931
+ data = {}
3932
+ for curcode in used_codes:
3933
+ data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
3934
+
3935
+ for curdata in data.values():
3936
+
3937
+ if curdata.shape[0] == 0:
3938
+ continue
3939
+
3940
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
3941
+
3942
+ keys = np.vstack((i,j)).T
3943
+
3944
+ # unique keys
3945
+ keys = np.unique(keys, axis=0)
3946
+
3947
+ array.SelectionData._add_nodes_to_selectionij(keys, verif = False)
3948
+
3949
+ array.SelectionData.update_nb_nodes_selection()
3950
+ self.Paint()
3951
+
3952
+ logging.info(_('Selection done'))
3953
+
3954
+ def fill_active_array_from_laz(self, array:WolfArray = None, used_codes:list = [], operator:int = -1, chunk_size:float = 500.):
3955
+ """ Fill active array with laz data
3956
+
3957
+ :param array: array to fill
3958
+ :param used_codes: codes to use
3959
+ :param operator: operator to use
3960
+ """
3961
+
3962
+ if self.mylazgrid is None:
3963
+ return
3964
+
3965
+ if array is None:
3966
+ logging.error(_('No array'))
3967
+ return
3968
+
3969
+ if len(used_codes) == 0 :
3970
+ keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
3971
+ names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
3972
+
3973
+ with wx.MultiChoiceDialog(None, _('Choose the codes to use'), _('Codes'), names) as dlg:
3974
+ if dlg.ShowModal() == wx.ID_OK:
3975
+ data = {}
3976
+ used_codes = dlg.GetSelections()
3977
+ used_codes = [float(keycode[cur]) for cur in used_codes]
3978
+ else:
3979
+ return
3980
+
3981
+ if operator == -1:
3982
+ with wx.SingleChoiceDialog(None, _('Choose the operator'), _('Operator'), ['max', 'percentile 95', 'percentile 5', 'min', 'mean', 'median', 'sum']) as dlg:
3983
+ if dlg.ShowModal() == wx.ID_OK:
3984
+ if dlg.GetStringSelection() == 'max':
3985
+ operator = np.max
3986
+ elif dlg.GetStringSelection() == 'min':
3987
+ operator = np.min
3988
+ elif dlg.GetStringSelection() == 'mean':
3989
+ operator = np.mean
3990
+ elif dlg.GetStringSelection() == 'median':
3991
+ operator = np.median
3992
+ elif dlg.GetStringSelection() == 'sum':
3993
+ operator = np.sum
3994
+ elif dlg.GetStringSelection() == 'percentile 95':
3995
+ operator = lambda x: np.percentile(x, 95)
3996
+ elif dlg.GetStringSelection() == 'percentile 5':
3997
+ operator = lambda x: np.percentile(x, 5)
3998
+ else:
3999
+ return
4000
+
4001
+ with wx.NumberEntryDialog(None, _('Minimum number of points to operate'), _('Minimum'), _('Minimum points'), 1, 1, 20) as dlg:
4002
+ if dlg.ShowModal() == wx.ID_OK:
4003
+ minpoints = dlg.GetValue()
4004
+ else:
4005
+ return
4006
+
4007
+ bounds = array.get_bounds()
4008
+
4009
+ # align bounds on chunk_size
4010
+ bounds[0][0] = bounds[0][0] - bounds[0][0] % chunk_size
4011
+ bounds[0][1] = bounds[0][1] + chunk_size - bounds[0][1] % chunk_size
4012
+ bounds[1][0] = bounds[1][0] - bounds[1][0] % chunk_size
4013
+ bounds[1][1] = bounds[1][1] + chunk_size - bounds[1][1] % chunk_size
4014
+
4015
+ chunks_x = np.arange(bounds[0][0], bounds[0][1], chunk_size)
4016
+ chunks_y = np.arange(bounds[1][0], bounds[1][1], chunk_size)
4017
+
4018
+ for curx in tqdm(chunks_x, 'Chunks'):
4019
+ for cury in chunks_y:
4020
+
4021
+ curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
4022
+
4023
+ logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
4024
+ self.mylazdata = self.mylazgrid.scan(curbounds)
4025
+ # logging.info(_('Scan done'))
4026
+
4027
+ if len(self.mylazdata) == 0:
4028
+ continue
4029
+
4030
+ # Test codes
4031
+ data = {}
4032
+ for curcode in used_codes:
4033
+ data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
4034
+
4035
+ # Treat data for each code
4036
+ for curdata in data.values():
4037
+
4038
+ if curdata.shape[0] == 0:
4039
+ continue
4040
+ else:
4041
+ logging.info(_('Code {} : {} points'.format(curdata[0,3], curdata.shape[0])))
4042
+
4043
+ # get i,j from x,y
4044
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
4045
+
4046
+ # keep only valid points -- inside the array
4047
+ used = np.where((i >=0) & (i < array.nbx) & (j >=0) & (j < array.nby))[0]
4048
+
4049
+ if len(used) == 0:
4050
+ continue
4051
+
4052
+ i = i[used]
4053
+ j = j[used]
4054
+ z = curdata[used, 2]
4055
+
4056
+ # create a key array
4057
+ keys = np.vstack((i,j)).T
4058
+ # find unique keys
4059
+ keys = np.unique(keys, axis=0)
4060
+
4061
+ # create a ijz array
4062
+ ijz = np.vstack((i, j, z)).T
4063
+
4064
+ # sort ijz array according to keys
4065
+ #
4066
+ # the most important indice is the last one enumerated in lexsort
4067
+ # see : https://numpy.org/doc/stable/reference/generated/numpy.lexsort.html
4068
+ ijz = ijz[np.lexsort((ijz[:,1], ijz[:,0]))]
4069
+
4070
+ # find first element of each key
4071
+ idx = np.where(np.abs(np.diff(ijz[:,0])) + np.abs(np.diff(ijz[:,1])) != 0)[0]
4072
+
4073
+ # add last element
4074
+ idx = np.concatenate((idx, [ijz.shape[0]]))
4075
+
4076
+ assert len(idx) == keys.shape[0], 'Error in filling'
4077
+
4078
+ logging.info(_('Cells to fill : {}'.format(len(idx))))
4079
+
4080
+ # apply operator
4081
+ vals = {}
4082
+ start_ii = 0
4083
+ for ii, key in enumerate(keys):
4084
+ end_ii = idx[ii]+1
4085
+
4086
+ if end_ii - start_ii >= minpoints:
4087
+ vals[(key[0], key[1])] = operator(ijz[start_ii:end_ii,2])
4088
+
4089
+ start_ii = end_ii
4090
+
4091
+ if len(vals) > 0:
4092
+ # create a new ijz array
4093
+ newijz = np.asarray([[key[0], key[1], val] for key, val in vals.items()], dtype = np.float32)
4094
+
4095
+ array.fillin_from_ijz(newijz)
4096
+
4097
+ array.reset_plot()
4098
+ self.Paint()
4099
+
4100
+ logging.info(_('Filling done'))
4101
+
3888
4102
  def init_laz_from_numpy(self, fn=None):
3889
4103
  """ Read LAZ data stored in numpy array"""
3890
4104
 
@@ -3918,7 +4132,7 @@ class WolfMapViewer(wx.Frame):
3918
4132
 
3919
4133
  self.mylazgrid = xyz_laz_grids(dirlaz)
3920
4134
 
3921
- dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW 2013-2014', 'SPW-Geofit 2023'], wx.CHOICEDLG_STYLE)
4135
+ dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
3922
4136
  ret = dlg.ShowModal()
3923
4137
  if ret != wx.ID_OK:
3924
4138
  dlg.Destroy()
@@ -4119,7 +4333,7 @@ class WolfMapViewer(wx.Frame):
4119
4333
  item = self.menubar.FindItemById(event.GetId())
4120
4334
 
4121
4335
  if item is not None:
4122
- self.StatusBar.SetStatusText(item.GetHelp())
4336
+ self.set_statusbar_text(item.GetHelp())
4123
4337
 
4124
4338
  def _select_laz_source(self):
4125
4339
  """ Select laz source """
@@ -4840,6 +5054,28 @@ class WolfMapViewer(wx.Frame):
4840
5054
  autoscale=False
4841
5055
  self.clip_laz_gridded()
4842
5056
 
5057
+ elif itemlabel == _('Fill active array from LAZ data'):
5058
+ if self.mylazgrid is None:
5059
+ logging.warning('')
5060
+ return
5061
+ if self.active_array is None:
5062
+ logging.warning(_('No active array -- select an array first and retry!'))
5063
+ return
5064
+
5065
+ autoscale = False
5066
+ self.fill_active_array_from_laz(self.active_array)
5067
+
5068
+ elif itemlabel == _('Select cells in array from LAZ data'):
5069
+ if self.mylazgrid is None:
5070
+ logging.warning('')
5071
+ return
5072
+ if self.active_array is None:
5073
+ logging.warning(_('No active array -- select an array first and retry!'))
5074
+ return
5075
+
5076
+ autoscale = False
5077
+ self.select_active_array_from_laz(self.active_array)
5078
+
4843
5079
  elif itemlabel == _('Plot LAZ around active vector'):
4844
5080
 
4845
5081
  self.plot_laz_around_active_vec()
@@ -7447,6 +7683,14 @@ class WolfMapViewer(wx.Frame):
7447
7683
  self.active_bc.Show()
7448
7684
  return
7449
7685
 
7686
+ def set_statusbar_text(self, txt:str):
7687
+ """ Set the status bar text """
7688
+ self.StatusBar.SetStatusText(txt)
7689
+
7690
+ def set_label_selecteditem(self, nameitem:str):
7691
+ """ Set the label of the selected item in the tree list """
7692
+ self._lbl_selecteditem.SetLabel(nameitem)
7693
+
7450
7694
  def OnActivateTreeElem(self, e): #:dataview.TreeListEvent ):
7451
7695
  """ Activate the selected item in the tree list """
7452
7696
  curzones: Zones
@@ -7466,7 +7710,7 @@ class WolfMapViewer(wx.Frame):
7466
7710
 
7467
7711
  myobj = self.treelist.GetItemData(myitem)
7468
7712
  self.selected_object = myobj
7469
- self.lbl_selecteditem.SetLabel(nameitem)
7713
+ self.set_label_selecteditem(nameitem)
7470
7714
 
7471
7715
  #FIXME : To generalize using draw_type
7472
7716
  if type(myobj) == Zones:
@@ -7512,7 +7756,7 @@ class WolfMapViewer(wx.Frame):
7512
7756
 
7513
7757
  txt += ' ; Type : ' + self.active_array.dtype_str
7514
7758
 
7515
- self.StatusBar.SetStatusText(txt)
7759
+ self.set_statusbar_text(txt)
7516
7760
 
7517
7761
 
7518
7762
  elif type(myobj) in [WolfViews]:
@@ -8136,6 +8380,9 @@ class WolfMapViewer(wx.Frame):
8136
8380
  # i : interpolation2D sur base de la sélection sur la matrice courante\n \
8137
8381
  # +,- (numpad) : augmente ou diminue la taille des flèches de resultats 2D\n \
8138
8382
  # \n \
8383
+ # o, O : Gestion de la transparence de la matrice courante\n \
8384
+ # CTRL+o, CTRL+O : Gestion de la transparence du résultat courant\n \
8385
+ # \n \
8139
8386
  # !! ACTIONs !!\n \
8140
8387
  # N : sélection noeud par noeud de la matrice courante\n \
8141
8388
  # B : sélection par vecteur temporaire de la matrice courante\n \
@@ -8179,6 +8426,11 @@ class WolfMapViewer(wx.Frame):
8179
8426
  'c or C': _('Drawing : copy canvas to Clipboard wo axes'),
8180
8427
  'CTRL+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
8181
8428
 
8429
+ 'CTRL+o': _('Results : increase transparency of the current result'),
8430
+ 'CTRL+O': _('Results : decrease transparency of the current result'),
8431
+ 'o': _('Arrays : increase transparency of the current array'),
8432
+ 'O': _('Arrays : decrease transparency of the current array'),
8433
+
8182
8434
  'F9': _('Arrays : select all cells'),
8183
8435
  'F11': _('Arrays : select by criteria'),
8184
8436
  'F12': _('Arrays : operations'),
@@ -8245,9 +8497,9 @@ class WolfMapViewer(wx.Frame):
8245
8497
  """ Message to end action """
8246
8498
 
8247
8499
  if which == 0:
8248
- self.StatusBar.SetStatusText(_('Action in progress... -- To quit, press "RETURN" or "double clicks RIGHT" or press "ESC"'))
8500
+ self.set_statusbar_text(_('Action in progress... -- To quit, press "RETURN" or "double clicks RIGHT" or press "ESC"'))
8249
8501
  else:
8250
- self.StatusBar.SetStatusText('')
8502
+ self.set_statusbar_text('')
8251
8503
 
8252
8504
  def start_action(self, action:str, message:str=''):
8253
8505
  """ Message to start action """
@@ -8571,7 +8823,8 @@ class WolfMapViewer(wx.Frame):
8571
8823
  self.active_vertex = None
8572
8824
  self.active_cloud = None
8573
8825
 
8574
- self.StatusBar.SetStatusText(_('Esc pressed - No more action in progress'))
8826
+ self.set_statusbar_text(_('Esc pressed - No more action in progress - No more active object'))
8827
+ self.set_label_selecteditem('')
8575
8828
 
8576
8829
  elif key == ord('C'):
8577
8830
 
@@ -8701,6 +8954,29 @@ class WolfMapViewer(wx.Frame):
8701
8954
  self.active_array.myops.reset_selection()
8702
8955
  self.Refresh()
8703
8956
 
8957
+ elif key == ord('O'):
8958
+ # Active Opacity for the active array
8959
+
8960
+ if ctrldown:
8961
+ if self.active_res2d is None:
8962
+ logging.warning(_('No active result 2D to change the opacity !'))
8963
+ return
8964
+
8965
+ if shiftdown:
8966
+ self.active_res2d.set_opacity(self.active_res2d.alpha + 0.25)
8967
+ else:
8968
+ self.active_res2d.set_opacity(self.active_res2d.alpha - 0.25)
8969
+
8970
+ else:
8971
+ if self.active_array is None:
8972
+ logging.warning(_('No active array to change the opacity !'))
8973
+ return
8974
+
8975
+ if shiftdown:
8976
+ self.active_array.set_opacity(self.active_array.alpha + 0.25)
8977
+ else:
8978
+ self.active_array.set_opacity(self.active_array.alpha - 0.25)
8979
+
8704
8980
  elif key == wx.WXK_UP:
8705
8981
  self.mousey = self.mousey + self.height / 10.
8706
8982
  self.setbounds()
@@ -886,6 +886,18 @@ if :\n \
886
886
  self.myprops.Show()
887
887
 
888
888
  self.myprops.SetTitle(_('Vector properties - {}'.format(self.parent.myname)))
889
+
890
+ if self.parent.get_mapviewer() is not None:
891
+ self.myprops.SetIcon(self.parent.get_mapviewer().GetIcon())
892
+ else:
893
+ try:
894
+ icon = wx.Icon()
895
+ icon_path = Path(__file__).parent / "apps/wolf_logo.bmp"
896
+ icon.CopyFromBitmap(wx.Bitmap(str(icon_path), wx.BITMAP_TYPE_ANY))
897
+ self.myprops.SetIcon(icon)
898
+ except Exception as e:
899
+ logging.warning('Problem with icon for properties window : {}'.format(e))
900
+
889
901
  self.myprops.Center()
890
902
  self.myprops.Raise()
891
903
 
@@ -1017,6 +1029,15 @@ class vector:
1017
1029
  if fromshapely is not None:
1018
1030
  self.import_shapelyobj(fromshapely)
1019
1031
 
1032
+ def get_mapviewer(self):
1033
+ """
1034
+ Retourne l'instance de la mapviewer
1035
+ """
1036
+ if self.parentzone is not None:
1037
+ return self.parentzone.get_mapviewer()
1038
+ else:
1039
+ return None
1040
+
1020
1041
  def show_properties(self):
1021
1042
  """ Show the properties """
1022
1043
 
@@ -1029,11 +1050,6 @@ class vector:
1029
1050
  if self.myprop is not None:
1030
1051
  self.myprop.hide_properties()
1031
1052
 
1032
- def get_mapviewer(self):
1033
- """ Return the mapviewer """
1034
-
1035
- return self.parentzone.get_mapviewer()
1036
-
1037
1053
  def get_normal_segments(self) -> np.ndarray:
1038
1054
  """
1039
1055
  Return the normals of each segment
@@ -4866,6 +4882,18 @@ class Zones(wx.Frame, Element_To_Draw):
4866
4882
 
4867
4883
  self.SetSizer(box)
4868
4884
 
4885
+ if self.get_mapviewer() is not None:
4886
+ self.SetIcon(self.get_mapviewer().GetIcon())
4887
+
4888
+ if self.idx == '':
4889
+ if self.parent is not None:
4890
+ try:
4891
+ self.SetTitle(_('Zones associated to : {}'.format(self.parent.idx)))
4892
+ except:
4893
+ logging.warning(_('No parent idx found'))
4894
+ else:
4895
+ self.SetTitle(_('Zones : {}'.format(self.idx)))
4896
+
4869
4897
  self.init_struct=False
4870
4898
 
4871
4899
 
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 = 52
8
+ self.patch = 54
9
9
 
10
10
  def __str__(self):
11
11
 
@@ -261,13 +261,23 @@ class xyz_laz():
261
261
  y=np.frombuffer(f.read(blocsize),dtype_file)
262
262
  z=np.frombuffer(f.read(nbloc*4),np.float32)
263
263
  classi=np.frombuffer(f.read(nbloc),np.int8)
264
+
264
265
  count+=4+(2*blocsize+nbloc*(4+1))
265
266
 
266
- if len(myret)==0:
267
- # dt=[('x',np.float32),('y',np.float32),('z',np.float32),('classification',np.int8)]
268
- myret=np.array([x,y,z,classi]).transpose()
267
+ if classi.shape[0] != nbloc:
268
+ logging.warning(_('Bad classification size - file {}'.format(fn)))
269
269
  else:
270
- myret=np.concatenate((myret,np.array([x,y,z,classi]).transpose()))
270
+ if len(myret)==0:
271
+ # dt=[('x',np.float32),('y',np.float32),('z',np.float32),('classification',np.int8)]
272
+ myret=np.array([x,y,z,classi]).transpose()
273
+ else:
274
+ if len(x)>1:
275
+ added = np.array([x,y,z,classi]).transpose()
276
+
277
+ if myret.shape[1] == added.shape[1]:
278
+ myret=np.concatenate((myret,added))
279
+ else:
280
+ logging.warning(_('Incompatible shapes'))
271
281
 
272
282
  # Format Numpy
273
283
  self.data = myret
@@ -485,16 +495,17 @@ class xyz_laz_grids():
485
495
  """
486
496
  Scan all LAZ to find used data
487
497
 
488
- Args:
489
- bounds (Union[tuple[tuple[float,float],tuple[float,float]], list[list[float, float],list[float, float]]]): [[xmin,xmax], [ymin,ymax]]
490
-
491
- Returns:
492
- _type_: np.ndarray
498
+ :param bounds: [[xmin,xmax], [ymin,ymax]]
499
+ :type bounds: Union[tuple[tuple[float,float],tuple[float,float]], list[list[float, float],list[float, float]]]
500
+ :return: np.ndarray
493
501
  """
494
502
  ret = [cur.scan(bounds) for cur in self.grids]
495
503
  ret = [cur for cur in ret if len(cur)>0]
496
504
 
497
- return np.concatenate(ret)
505
+ if len(ret)==0:
506
+ return np.asarray([])
507
+ else:
508
+ return np.concatenate(ret)
498
509
 
499
510
  def read_dir(self, dir_grids):
500
511
  dirs = listdir(dir_grids)
@@ -637,8 +648,8 @@ def find_pointsXYZ(xyz:np.ndarray, bounds:Union[tuple[tuple[float,float],tuple[f
637
648
  xb=bounds[0]
638
649
  yb=bounds[1]
639
650
  # Get arrays which indicate invalid X, Y, or Z values.
640
- X_valid = (xb[0] <= xyz[:,0]) & (xb[1] >= xyz[:,0])
641
- Y_valid = (yb[0] <= xyz[:,1]) & (yb[1] >= xyz[:,1])
651
+ X_valid = np.logical_and((xb[0] <= xyz[:,0]), (xb[1] >= xyz[:,0]))
652
+ Y_valid = np.logical_and((yb[0] <= xyz[:,1]), (yb[1] >= xyz[:,1]))
642
653
  good_indices = np.where(X_valid & Y_valid)[0]
643
654
 
644
655
  return xyz[good_indices]
wolfhece/wolf_array.py CHANGED
@@ -1412,6 +1412,11 @@ class Ops_Array(wx.Frame):
1412
1412
  if self.wx_exists:
1413
1413
  self.set_GUI()
1414
1414
 
1415
+ @property
1416
+ def idx(self):
1417
+ """ Return the idx of the parentarray """
1418
+ return self.parentarray.idx
1419
+
1415
1420
  def get_mapviewer(self):
1416
1421
  """ Retourne l'instance WolfMapViewer """
1417
1422
  return self.mapviewer
@@ -2732,9 +2737,13 @@ class Ops_Array(wx.Frame):
2732
2737
  curarray.shading = True
2733
2738
 
2734
2739
  alpha = float(self.palalphahillshade.GetValue()) / 100.
2735
- if curarray.shaded.alpha != alpha:
2736
- curarray.shaded.alpha = alpha
2737
- curarray.shading = True
2740
+
2741
+ if curarray.shaded is None:
2742
+ logging.error('No shaded array')
2743
+ else:
2744
+ if curarray.shaded.alpha != alpha:
2745
+ curarray.shaded.alpha = alpha
2746
+ curarray.shading = True
2738
2747
 
2739
2748
  if dellists:
2740
2749
  self.refresh_array()
@@ -4444,6 +4453,25 @@ class WolfArray(Element_To_Draw, header_wolf):
4444
4453
 
4445
4454
  self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
4446
4455
 
4456
+ def set_opacity(self, alpha:float):
4457
+ """ Set the transparency of the array """
4458
+
4459
+ if alpha <0.:
4460
+ alpha = 0.
4461
+
4462
+ if alpha > 1.:
4463
+ alpha = 1.
4464
+
4465
+ self.alpha = alpha
4466
+
4467
+ if self.myops is not None:
4468
+ self.myops.palalpha.SetValue(0)
4469
+ self.myops.palalphaslider.SetValue(int(alpha*100))
4470
+
4471
+ self.reset_plot()
4472
+
4473
+ return self.alpha
4474
+
4447
4475
  @property
4448
4476
  def memory_usage(self):
4449
4477
  """
@@ -4586,6 +4614,10 @@ class WolfArray(Element_To_Draw, header_wolf):
4586
4614
  """ Affichage des propriétés de la matrice dans une fenêtre wxPython """
4587
4615
  if self.wx_exists and self.myops is not None:
4588
4616
  self.myops.SetTitle(_('Operations on array: ') + self.idx)
4617
+
4618
+ if self.mapviewer is not None:
4619
+ self.myops.SetIcon(self.mapviewer.GetIcon())
4620
+
4589
4621
  self.myops.Show()
4590
4622
 
4591
4623
  self.myops.Center()
@@ -5802,6 +5834,10 @@ class WolfArray(Element_To_Draw, header_wolf):
5802
5834
  def hillshade(self, azimuth:float, angle_altitude:float):
5803
5835
  """ Create a hillshade array -- see "hillshade" function accelerated by JIT"""
5804
5836
 
5837
+ if self.shaded is None:
5838
+ logging.error(_('No shaded array'))
5839
+ return
5840
+
5805
5841
  self.shaded.set_header(self.get_header())
5806
5842
  self.shaded.array = hillshade(self.array.data, azimuth, angle_altitude)
5807
5843
  self.shaded.delete_lists()
@@ -7215,6 +7251,29 @@ class WolfArray(Element_To_Draw, header_wolf):
7215
7251
  else:
7216
7252
  logging.warning(_('Type not supported : ')+str(self.dtype))
7217
7253
 
7254
+ def fillin_from_ijz(self, ijz:np.ndarray):
7255
+ """ Remplissage du tableau à partir d'un tableau ijz """
7256
+
7257
+ try:
7258
+ i = ijz[:, 0].astype(int)
7259
+ j = ijz[:, 1].astype(int)
7260
+ except Exception as e:
7261
+ logging.error(_('Error in conversion of ijz to int : ')+str(e))
7262
+ return
7263
+
7264
+ if self.dtype == np.float32:
7265
+ self.array.data[i, j] = np.float32(ijz[:, 2])
7266
+ elif self.dtype == np.float64:
7267
+ self.array.data[i, j] = np.float64(ijz[:, 2])
7268
+ elif self.dtype == np.int32:
7269
+ self.array.data[i, j] = np.int32(ijz[:, 2])
7270
+ elif self.dtype == np.int16:
7271
+ self.array.data[i, j] = np.int16(ijz[:, 2])
7272
+ elif self.dtype == np.int8:
7273
+ self.array.data[i, j] = np.int8(ijz[:, 2])
7274
+ else:
7275
+ logging.warning(_('Type not supported : ')+str(self.dtype))
7276
+
7218
7277
  def mask_force_null(self):
7219
7278
  """
7220
7279
  Force to unmask all and mask null value
@@ -1769,6 +1769,18 @@ class OneWolfResult:
1769
1769
 
1770
1770
  self.mngselection = SelectionData(self._current)
1771
1771
 
1772
+ def set_opacity(self, alpha:float):
1773
+ """ Set the transparency of the array """
1774
+
1775
+ if alpha <0.:
1776
+ alpha = 0.
1777
+
1778
+ if alpha > 1.:
1779
+ alpha = 1.
1780
+
1781
+ self.alpha = alpha
1782
+
1783
+ return self.alpha
1772
1784
 
1773
1785
  @property
1774
1786
  def min_field_size(self):
@@ -2232,6 +2244,16 @@ class Wolfresults_2D(Element_To_Draw):
2232
2244
  self.myops = None
2233
2245
  self._active_blocks = 0
2234
2246
 
2247
+
2248
+ def set_opacity(self, alpha:float):
2249
+ """ Set the transparency of the array """
2250
+
2251
+ self.alpha = alpha
2252
+
2253
+ self.reset_plot()
2254
+
2255
+ return self.alpha
2256
+
2235
2257
  @property
2236
2258
  def SelectionData(self) -> SelectionDataMB:
2237
2259
  """ Return the data of the selection """
@@ -2399,6 +2421,13 @@ class Wolfresults_2D(Element_To_Draw):
2399
2421
 
2400
2422
  @alpha.setter
2401
2423
  def alpha(self, value:float):
2424
+
2425
+ if value <0.:
2426
+ value = 0.
2427
+
2428
+ if value > 1.:
2429
+ value = 1.
2430
+
2402
2431
  for i in range(self.nb_blocks):
2403
2432
  self[i].alpha = value
2404
2433
 
@@ -4184,6 +4213,7 @@ class Wolfresults_2D(Element_To_Draw):
4184
4213
 
4185
4214
  def reset_plot(self,whichpal=0):
4186
4215
  """Reset du dessin"""
4216
+
4187
4217
  self.delete_lists()
4188
4218
  self.get_working_array()
4189
4219
  self.updatepalette(whichpal)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wolfhece
3
- Version: 2.1.52
3
+ Version: 2.1.54
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,7 +7,7 @@ wolfhece/ManageParams.py,sha256=EeuUI5Vvh9ixCvYf8YShMC1s1Yacc7OxOCN7q81gqiQ,517
7
7
  wolfhece/Model1D.py,sha256=uL1DJVmDI2xVSE7H6n3icn3QbsPtTHeg8E-6wkDloKw,476914
8
8
  wolfhece/PyConfig.py,sha256=FB8u0belXOXTb03Ln6RdVWvMgjzi3oGPCmw2dWa3lNg,8332
9
9
  wolfhece/PyCrosssections.py,sha256=FnmM9DWY_SAF2EDH9Gu2PojXNtSTRF4-aYQuAAJXBh4,112771
10
- wolfhece/PyDraw.py,sha256=_Rfx59LMopR0Cx00d1RRF5Gb-WNxfA2v2RjkOfm84Yo,390847
10
+ wolfhece/PyDraw.py,sha256=Ib7Rix3QAjR9X0o1E-80_91QsKhWtxmnR2QA89WIPQU,402676
11
11
  wolfhece/PyGui.py,sha256=aRWv9tBpRl7sKEd2gHWj8Bss0ZOKbGlUYIehWHFm8WY,105008
12
12
  wolfhece/PyGuiHydrology.py,sha256=f60E8K9eGTnRq5RDF6yvt-ahf2AYegwQ9t25zZ2Mk1A,14946
13
13
  wolfhece/PyHydrographs.py,sha256=jwtSNMMACwarxrtN1UeQYth99UNrhwPx1IGgUwcooHA,3774
@@ -16,7 +16,7 @@ wolfhece/PyParams.py,sha256=wwgmP-_7wiiPLTcyX8a5jR6FyC1D2c4oBPc1VWQqtSA,97383
16
16
  wolfhece/PyPictures.py,sha256=m1kY0saW6Y9Q0bDCo47lW6XxDkBrbQG-Fd8uVn8G5ic,2514
17
17
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
18
18
  wolfhece/PyVertex.py,sha256=MtZVjIWIi62QX_oqNosb56xPgjhOGVeGz-XsD82tsNg,40614
19
- wolfhece/PyVertexvectors.py,sha256=KMXJB_zFi54I73jk_fGtSTxqTQhnCwngeEjJyLdgGDo,235914
19
+ wolfhece/PyVertexvectors.py,sha256=mZlu2IeCQH-VdDQrw_fYbns3NQ_qdfbb3ndqzfjC_nI,237049
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
@@ -48,13 +48,13 @@ 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=4B0rihTY4yu0t8mrt99aV_3VCf0PP_K72SAFFkycclc,370660
51
+ wolfhece/wolf_array.py,sha256=VRy6F5ChUfqB8ziDAI8XrE54XWrtAicYVQyMieLaIXU,372460
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=J6GBaLlwtRQKRsFnZzvxc-5m9QVSzN0xCiMJA-yXIHs,167541
57
+ wolfhece/wolfresults_2D.py,sha256=1rzkcZtS6Y8bn8izX-kTePpstrPi9TiOkw9XBueG1fk,168078
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
@@ -72,7 +72,7 @@ wolfhece/apps/check_install.py,sha256=SG024u18G7VRLKynbp7DKD1jImtHwuWwN4bJWHm-YH
72
72
  wolfhece/apps/curvedigitizer.py,sha256=_hRR2PWow7PU7rTHIbc6ykZ08tCXcK9uy7RFrb4EKkE,5196
73
73
  wolfhece/apps/isocurrent.py,sha256=MuwTodHxdc6PrqNpphR2ntYf1NLL2n9klTPndGrOHDQ,4109
74
74
  wolfhece/apps/splashscreen.py,sha256=SrustmIQeXnsiD-92OzjdGhBi-S7c_j-cSvuX4T6rtg,2929
75
- wolfhece/apps/version.py,sha256=9OZ-YcusCh_gbdccX8m4dCLa-9wqi_9uiTxPepfbdRA,388
75
+ wolfhece/apps/version.py,sha256=CMpY0e6nzRUMGj9Dheyh-mTZLDI1l4fvptoARGgcN9I,388
76
76
  wolfhece/apps/wolf.py,sha256=mM6Tyi4DlKQILmO49cDUCip9fYVy-hLXkY3YhZgIeUQ,591
77
77
  wolfhece/apps/wolf2D.py,sha256=yPQGee7fsegoQ8GfWKrWEjX1Az_ApL-UWlBiqPvaIyY,565
78
78
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -143,7 +143,7 @@ wolfhece/lagrangian/particles.py,sha256=S52_-3rzgVhift6l4Gznvsf_RTggzvNaD1dPvQUr
143
143
  wolfhece/lagrangian/velocity_field.py,sha256=oGVjNm98gEpawreFIrC1lDyC5bEhkk2CsyYAlF1Kq50,10574
144
144
  wolfhece/lazviewer/__init__.py,sha256=0SNDEKGad6e2AwxjalcPqb2bdW6crmXQFxWUY13PiVU,223
145
145
  wolfhece/lazviewer/_add_path.py,sha256=GDwPnzHuGRXGriDNcu1SQ6HetFDGIApeAQZEzYArGvI,605
146
- wolfhece/lazviewer/laz_viewer.py,sha256=EHg-7MGRASevT3tmOwIGWdZZqo8cvEbTt8J2Ei9v1X8,42205
146
+ wolfhece/lazviewer/laz_viewer.py,sha256=zuXMSh50HZGcduD5dWsrxrNu9qcxg-NfQr6Rg5sKxO8,42746
147
147
  wolfhece/lazviewer/libs/Qt5Core.dll,sha256=sTJ_ctYFY9KHMNytF-lzH_078zIvnKTjN-71FDkOWPw,4924928
148
148
  wolfhece/lazviewer/libs/Qt5Gui.dll,sha256=07BeaOeYByraGkKYeDiSDYLawHM8tyd55pVJlKbZ4Y0,5436416
149
149
  wolfhece/lazviewer/libs/Qt5Network.dll,sha256=U-9FiLE9LUKru8r8EQxTnwwlMpwS8JzUtenhkKTCox0,1038336
@@ -280,8 +280,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
280
280
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
281
281
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
282
282
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
283
- wolfhece-2.1.52.dist-info/METADATA,sha256=dUwuLJdHXEFQCK3QEjlpob02jeFO6Ix1VENGT7JnBSk,2541
284
- wolfhece-2.1.52.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
285
- wolfhece-2.1.52.dist-info/entry_points.txt,sha256=Q5JuIWV4odeIJI3qc6fV9MwRoz0ezqPVlFC1Ppm_vdQ,395
286
- wolfhece-2.1.52.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
287
- wolfhece-2.1.52.dist-info/RECORD,,
283
+ wolfhece-2.1.54.dist-info/METADATA,sha256=7QrfsLJM8f7GK2x3Gg8xH6vJfGWupV1EmqcST4rlVw8,2541
284
+ wolfhece-2.1.54.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
285
+ wolfhece-2.1.54.dist-info/entry_points.txt,sha256=Q5JuIWV4odeIJI3qc6fV9MwRoz0ezqPVlFC1Ppm_vdQ,395
286
+ wolfhece-2.1.54.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
287
+ wolfhece-2.1.54.dist-info/RECORD,,