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 +211 -3
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/laz_viewer.py +19 -11
- wolfhece/models/blues.pal +65 -0
- wolfhece/models/mako.pal +1025 -0
- wolfhece/wolf_array.py +66 -6
- wolfhece/wolfresults_2D.py +79 -2
- {wolfhece-2.1.51.dist-info → wolfhece-2.1.53.dist-info}/METADATA +1 -1
- {wolfhece-2.1.51.dist-info → wolfhece-2.1.53.dist-info}/RECORD +12 -10
- {wolfhece-2.1.51.dist-info → wolfhece-2.1.53.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.51.dist-info → wolfhece-2.1.53.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.51.dist-info → wolfhece-2.1.53.dist-info}/top_level.txt +0 -0
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
wolfhece/lazviewer/laz_viewer.py
CHANGED
@@ -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
|
267
|
-
|
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
|
-
|
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
|
-
|
489
|
-
|
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])
|
641
|
-
Y_valid = (yb[0] <= 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
|