wolfhece 2.1.51__py3-none-any.whl → 2.1.53__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)
@@ -879,6 +879,8 @@ class WolfMapViewer(wx.Frame):
879
879
  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
880
  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
881
  updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
882
+ fillarray_laz = self.menulaz.Append(wx.ID_ANY, _('Fill active array from LAZ data'), _('Fill an array from the LAZ data'),)
883
+ 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
884
 
883
885
  def menu_wolf2d(self):
884
886
 
@@ -3885,6 +3887,159 @@ class WolfMapViewer(wx.Frame):
3885
3887
 
3886
3888
  logging.info(_('Clip LAZ grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
3887
3889
 
3890
+ def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None):
3891
+ """ select some nodes from laz data
3892
+
3893
+ :param array: array to fill
3894
+ :param used_codes: codes to use
3895
+ """
3896
+ if self.mylazgrid is None:
3897
+ return
3898
+
3899
+ if array is None:
3900
+ logging.error(_('No array'))
3901
+ return
3902
+
3903
+ curbounds = array.get_bounds()
3904
+
3905
+ logging.info(_('Scan Laz grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
3906
+ self.mylazdata = self.mylazgrid.scan(curbounds)
3907
+ logging.info(_('Scan done'))
3908
+
3909
+ if used_codes is not None:
3910
+ self.mylazdata = self.mylazdata[self.mylazdata[:, 3] in np.asarray(used_codes, dtype=np.float32)]
3911
+ else:
3912
+ keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
3913
+ names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
3914
+
3915
+ with wx.MultiChoiceDialog(None, _('Choose the codes to use'), _('Codes'), names) as dlg:
3916
+ if dlg.ShowModal() == wx.ID_OK:
3917
+ data = {}
3918
+ used_codes = dlg.GetSelections()
3919
+ used_codes = [float(keycode[cur]) for cur in used_codes]
3920
+
3921
+ for curcode in used_codes:
3922
+ data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
3923
+ else:
3924
+ return
3925
+
3926
+ for curdata in data.values():
3927
+
3928
+ if curdata.shape[0] == 0:
3929
+ continue
3930
+
3931
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
3932
+
3933
+ keys = np.vstack((i,j)).T
3934
+
3935
+ # unique keys
3936
+ keys = np.unique(keys, axis=0)
3937
+
3938
+ array.SelectionData._add_nodes_to_selectionij(keys, verif = False)
3939
+
3940
+ array.SelectionData.update_nb_nodes_selection()
3941
+ self.Paint()
3942
+
3943
+ logging.info(_('Selection done'))
3944
+
3945
+ def fill_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, operator:int = None):
3946
+ """ Fill active array with laz data
3947
+
3948
+ :param array: array to fill
3949
+ :param used_codes: codes to use
3950
+ :param operator: operator to use
3951
+ """
3952
+ if self.mylazgrid is None:
3953
+ return
3954
+
3955
+ if array is None:
3956
+ logging.error(_('No array'))
3957
+ return
3958
+
3959
+ curbounds = array.get_bounds()
3960
+
3961
+ logging.info(_('Scan Laz grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
3962
+ self.mylazdata = self.mylazgrid.scan(curbounds)
3963
+ logging.info(_('Scan done'))
3964
+
3965
+ if used_codes is not None:
3966
+ self.mylazdata = self.mylazdata[self.mylazdata[:, 3] in np.asarray(used_codes, dtype=np.float32)]
3967
+ else:
3968
+ keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
3969
+ names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
3970
+
3971
+ with wx.MultiChoiceDialog(None, _('Choose the codes to use'), _('Codes'), names) as dlg:
3972
+ if dlg.ShowModal() == wx.ID_OK:
3973
+ data = {}
3974
+ used_codes = dlg.GetSelections()
3975
+ used_codes = [float(keycode[cur]) for cur in used_codes]
3976
+
3977
+ for curcode in used_codes:
3978
+ data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
3979
+ else:
3980
+ return
3981
+
3982
+ if operator is None:
3983
+ with wx.SingleChoiceDialog(None, _('Choose the operator'), _('Operator'), ['max', 'min', 'mean', 'median', 'sum']) as dlg:
3984
+ if dlg.ShowModal() == wx.ID_OK:
3985
+ if dlg.GetStringSelection() == 'max':
3986
+ operator = np.max
3987
+ elif dlg.GetStringSelection() == 'min':
3988
+ operator = np.min
3989
+ elif dlg.GetStringSelection() == 'mean':
3990
+ operator = np.mean
3991
+ elif dlg.GetStringSelection() == 'median':
3992
+ operator = np.median
3993
+ elif dlg.GetStringSelection() == 'sum':
3994
+ operator = np.sum
3995
+ else:
3996
+ return
3997
+
3998
+ for curdata in data.values():
3999
+
4000
+ if curdata.shape[0] == 0:
4001
+ continue
4002
+
4003
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
4004
+
4005
+ # sort i, j and z
4006
+ i = np.asarray(i, dtype=np.int32)
4007
+ j = np.asarray(j, dtype=np.int32)
4008
+ z = np.asarray(curdata[:, 2], dtype=np.float32)
4009
+
4010
+ keys = np.vstack((i,j)).T
4011
+
4012
+ ijz = np.hstack((keys,z.reshape(-1,1)))
4013
+
4014
+ # unique keys
4015
+ keys = np.unique(keys, axis=0)
4016
+
4017
+ ijz = ijz[np.lexsort((ijz[:,1], ijz[:,0]))]
4018
+
4019
+ # find first element of each key
4020
+ idx = np.where(np.diff(ijz[:,0]) + np.diff(ijz[:,1]) != 0)[0]
4021
+ idx = np.concatenate((idx, [ijz.shape[0]]))
4022
+
4023
+ # apply operator
4024
+ vals = {}
4025
+ start_ii = 0
4026
+ for ii, key in enumerate(keys):
4027
+
4028
+ end_ii = idx[ii]+1
4029
+ if key[0] >=0 and key[0] < array.nbx and key[1] >=0 and key[1] < array.nby:
4030
+ vals[(key[0], key[1])] = operator(ijz[start_ii:end_ii,2])
4031
+ start_ii = end_ii
4032
+
4033
+ # create a new ijz array
4034
+ newijz = np.asarray([[key[0], key[1], val] for key, val in vals.items()], dtype = np.float32)
4035
+
4036
+ array.fillin_from_ijz(newijz)
4037
+
4038
+ array.reset_plot()
4039
+ self.Paint()
4040
+
4041
+ logging.info(_('Filling done'))
4042
+
3888
4043
  def init_laz_from_numpy(self, fn=None):
3889
4044
  """ Read LAZ data stored in numpy array"""
3890
4045
 
@@ -4840,6 +4995,28 @@ class WolfMapViewer(wx.Frame):
4840
4995
  autoscale=False
4841
4996
  self.clip_laz_gridded()
4842
4997
 
4998
+ elif itemlabel == _('Fill active array from LAZ data'):
4999
+ if self.mylazgrid is None:
5000
+ logging.warning('')
5001
+ return
5002
+ if self.active_array is None:
5003
+ logging.warning(_('No active array -- select an array first and retry!'))
5004
+ return
5005
+
5006
+ autoscale = False
5007
+ self.fill_active_array_from_laz(self.active_array)
5008
+
5009
+ elif itemlabel == _('Select cells in array from LAZ data'):
5010
+ if self.mylazgrid is None:
5011
+ logging.warning('')
5012
+ return
5013
+ if self.active_array is None:
5014
+ logging.warning(_('No active array -- select an array first and retry!'))
5015
+ return
5016
+
5017
+ autoscale = False
5018
+ self.select_active_array_from_laz(self.active_array)
5019
+
4843
5020
  elif itemlabel == _('Plot LAZ around active vector'):
4844
5021
 
4845
5022
  self.plot_laz_around_active_vec()
@@ -8136,6 +8313,9 @@ class WolfMapViewer(wx.Frame):
8136
8313
  # i : interpolation2D sur base de la sélection sur la matrice courante\n \
8137
8314
  # +,- (numpad) : augmente ou diminue la taille des flèches de resultats 2D\n \
8138
8315
  # \n \
8316
+ # o, O : Gestion de la transparence de la matrice courante\n \
8317
+ # CTRL+o, CTRL+O : Gestion de la transparence du résultat courant\n \
8318
+ # \n \
8139
8319
  # !! ACTIONs !!\n \
8140
8320
  # N : sélection noeud par noeud de la matrice courante\n \
8141
8321
  # B : sélection par vecteur temporaire de la matrice courante\n \
@@ -8179,6 +8359,11 @@ class WolfMapViewer(wx.Frame):
8179
8359
  'c or C': _('Drawing : copy canvas to Clipboard wo axes'),
8180
8360
  'CTRL+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
8181
8361
 
8362
+ 'CTRL+o': _('Results : increase transparency of the current result'),
8363
+ 'CTRL+O': _('Results : decrease transparency of the current result'),
8364
+ 'o': _('Arrays : increase transparency of the current array'),
8365
+ 'O': _('Arrays : decrease transparency of the current array'),
8366
+
8182
8367
  'F9': _('Arrays : select all cells'),
8183
8368
  'F11': _('Arrays : select by criteria'),
8184
8369
  'F12': _('Arrays : operations'),
@@ -8701,6 +8886,29 @@ class WolfMapViewer(wx.Frame):
8701
8886
  self.active_array.myops.reset_selection()
8702
8887
  self.Refresh()
8703
8888
 
8889
+ elif key == ord('O'):
8890
+ # Active Opacity for the active array
8891
+
8892
+ if ctrldown:
8893
+ if self.active_res2d is None:
8894
+ logging.warning(_('No active result 2D to change the opacity !'))
8895
+ return
8896
+
8897
+ if shiftdown:
8898
+ self.active_res2d.set_opacity(self.active_res2d.alpha + 0.25)
8899
+ else:
8900
+ self.active_res2d.set_opacity(self.active_res2d.alpha - 0.25)
8901
+
8902
+ else:
8903
+ if self.active_array is None:
8904
+ logging.warning(_('No active array to change the opacity !'))
8905
+ return
8906
+
8907
+ if shiftdown:
8908
+ self.active_array.set_opacity(self.active_array.alpha + 0.25)
8909
+ else:
8910
+ self.active_array.set_opacity(self.active_array.alpha - 0.25)
8911
+
8704
8912
  elif key == wx.WXK_UP:
8705
8913
  self.mousey = self.mousey + self.height / 10.
8706
8914
  self.setbounds()
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 = 51
8
+ self.patch = 53
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,11 +495,9 @@ 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]
@@ -637,8 +645,8 @@ def find_pointsXYZ(xyz:np.ndarray, bounds:Union[tuple[tuple[float,float],tuple[f
637
645
  xb=bounds[0]
638
646
  yb=bounds[1]
639
647
  # 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])
648
+ X_valid = np.logical_and((xb[0] <= xyz[:,0]), (xb[1] >= xyz[:,0]))
649
+ Y_valid = np.logical_and((yb[0] <= xyz[:,1]), (yb[1] >= xyz[:,1]))
642
650
  good_indices = np.where(X_valid & Y_valid)[0]
643
651
 
644
652
  return xyz[good_indices]
@@ -0,0 +1,65 @@
1
+ 16
2
+ 0.0
3
+ 247
4
+ 251
5
+ 255
6
+ 0.06666666666666667
7
+ 233
8
+ 242
9
+ 250
10
+ 0.13333333333333333
11
+ 220
12
+ 233
13
+ 246
14
+ 0.2
15
+ 207
16
+ 225
17
+ 242
18
+ 0.26666666666666666
19
+ 192
20
+ 216
21
+ 237
22
+ 0.3333333333333333
23
+ 171
24
+ 207
25
+ 229
26
+ 0.39999999999999997
27
+ 147
28
+ 196
29
+ 222
30
+ 0.4666666666666666
31
+ 120
32
+ 181
33
+ 216
34
+ 0.5333333333333333
35
+ 96
36
+ 166
37
+ 209
38
+ 0.6
39
+ 74
40
+ 151
41
+ 201
42
+ 0.6666666666666666
43
+ 55
44
+ 135
45
+ 192
46
+ 0.7333333333333333
47
+ 37
48
+ 117
49
+ 183
50
+ 0.7999999999999999
51
+ 23
52
+ 100
53
+ 171
54
+ 0.8666666666666666
55
+ 9
56
+ 83
57
+ 157
58
+ 0.9333333333333332
59
+ 8
60
+ 65
61
+ 133
62
+ 0.9999999999999999
63
+ 8
64
+ 48
65
+ 107