wolfhece 2.1.53__py3-none-any.whl → 2.1.55__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 +144 -76
- wolfhece/PyVertexvectors.py +33 -5
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/laz_viewer.py +4 -1
- wolfhece/wolf_array.py +78 -8
- {wolfhece-2.1.53.dist-info → wolfhece-2.1.55.dist-info}/METADATA +1 -1
- {wolfhece-2.1.53.dist-info → wolfhece-2.1.55.dist-info}/RECORD +10 -10
- {wolfhece-2.1.53.dist-info → wolfhece-2.1.55.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.53.dist-info → wolfhece-2.1.55.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.53.dist-info → wolfhece-2.1.55.dist-info}/top_level.txt +0 -0
wolfhece/PyDraw.py
CHANGED
@@ -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
|
-
|
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.
|
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.
|
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)
|
@@ -3887,7 +3885,7 @@ class WolfMapViewer(wx.Frame):
|
|
3887
3885
|
|
3888
3886
|
logging.info(_('Clip LAZ grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
|
3889
3887
|
|
3890
|
-
def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None):
|
3888
|
+
def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
|
3891
3889
|
""" select some nodes from laz data
|
3892
3890
|
|
3893
3891
|
:param array: array to fill
|
@@ -3900,55 +3898,67 @@ class WolfMapViewer(wx.Frame):
|
|
3900
3898
|
logging.error(_('No array'))
|
3901
3899
|
return
|
3902
3900
|
|
3903
|
-
|
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:
|
3901
|
+
if used_codes is None:
|
3912
3902
|
keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
|
3913
3903
|
names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
|
3914
3904
|
|
3915
3905
|
with wx.MultiChoiceDialog(None, _('Choose the codes to use'), _('Codes'), names) as dlg:
|
3916
3906
|
if dlg.ShowModal() == wx.ID_OK:
|
3917
|
-
data = {}
|
3918
3907
|
used_codes = dlg.GetSelections()
|
3919
3908
|
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
3909
|
else:
|
3924
3910
|
return
|
3925
3911
|
|
3926
|
-
|
3912
|
+
curbounds = array.get_bounds()
|
3927
3913
|
|
3928
|
-
|
3929
|
-
|
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]]
|
3930
3926
|
|
3931
|
-
|
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'))
|
3932
3930
|
|
3933
|
-
|
3931
|
+
data = {}
|
3932
|
+
for curcode in used_codes:
|
3933
|
+
data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
|
3934
3934
|
|
3935
|
-
|
3936
|
-
keys = np.unique(keys, axis=0)
|
3935
|
+
for curdata in data.values():
|
3937
3936
|
|
3938
|
-
|
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)
|
3939
3948
|
|
3940
3949
|
array.SelectionData.update_nb_nodes_selection()
|
3941
3950
|
self.Paint()
|
3942
3951
|
|
3943
3952
|
logging.info(_('Selection done'))
|
3944
3953
|
|
3945
|
-
def fill_active_array_from_laz(self, array:WolfArray = None, used_codes:list =
|
3954
|
+
def fill_active_array_from_laz(self, array:WolfArray = None, used_codes:list = [], operator:int = -1, chunk_size:float = 500.):
|
3946
3955
|
""" Fill active array with laz data
|
3947
3956
|
|
3948
3957
|
:param array: array to fill
|
3949
3958
|
:param used_codes: codes to use
|
3950
3959
|
:param operator: operator to use
|
3951
3960
|
"""
|
3961
|
+
|
3952
3962
|
if self.mylazgrid is None:
|
3953
3963
|
return
|
3954
3964
|
|
@@ -3956,15 +3966,7 @@ class WolfMapViewer(wx.Frame):
|
|
3956
3966
|
logging.error(_('No array'))
|
3957
3967
|
return
|
3958
3968
|
|
3959
|
-
|
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:
|
3969
|
+
if len(used_codes) == 0 :
|
3968
3970
|
keycode = [key for key,val in self.mylazgrid.colors.classification.items()]
|
3969
3971
|
names = [val[0] for key,val in self.mylazgrid.colors.classification.items()]
|
3970
3972
|
|
@@ -3973,14 +3975,11 @@ class WolfMapViewer(wx.Frame):
|
|
3973
3975
|
data = {}
|
3974
3976
|
used_codes = dlg.GetSelections()
|
3975
3977
|
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
3978
|
else:
|
3980
3979
|
return
|
3981
3980
|
|
3982
|
-
if operator
|
3983
|
-
with wx.SingleChoiceDialog(None, _('Choose the operator'), _('Operator'), ['max', 'min', 'mean', 'median', 'sum']) as dlg:
|
3981
|
+
if operator == -1:
|
3982
|
+
with wx.SingleChoiceDialog(None, _('Choose the operator'), _('Operator'), ['max', 'percentile 95', 'percentile 5', 'min', 'mean', 'median', 'sum']) as dlg:
|
3984
3983
|
if dlg.ShowModal() == wx.ID_OK:
|
3985
3984
|
if dlg.GetStringSelection() == 'max':
|
3986
3985
|
operator = np.max
|
@@ -3992,48 +3991,108 @@ class WolfMapViewer(wx.Frame):
|
|
3992
3991
|
operator = np.median
|
3993
3992
|
elif dlg.GetStringSelection() == 'sum':
|
3994
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)
|
3995
3998
|
else:
|
3996
3999
|
return
|
3997
4000
|
|
3998
|
-
|
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
|
3999
4006
|
|
4000
|
-
|
4001
|
-
|
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
|
4002
4029
|
|
4003
|
-
|
4030
|
+
# Test codes
|
4031
|
+
data = {}
|
4032
|
+
for curcode in used_codes:
|
4033
|
+
data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
|
4004
4034
|
|
4005
|
-
|
4006
|
-
|
4007
|
-
j = np.asarray(j, dtype=np.int32)
|
4008
|
-
z = np.asarray(curdata[:, 2], dtype=np.float32)
|
4035
|
+
# Treat data for each code
|
4036
|
+
for curdata in data.values():
|
4009
4037
|
|
4010
|
-
|
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)
|
4011
4060
|
|
4012
|
-
|
4061
|
+
# create a ijz array
|
4062
|
+
ijz = np.vstack((i, j, z)).T
|
4013
4063
|
|
4014
|
-
|
4015
|
-
|
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]))]
|
4016
4069
|
|
4017
|
-
|
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]
|
4018
4072
|
|
4019
|
-
|
4020
|
-
|
4021
|
-
idx = np.concatenate((idx, [ijz.shape[0]]))
|
4073
|
+
# add last element
|
4074
|
+
idx = np.concatenate((idx, [ijz.shape[0]]))
|
4022
4075
|
|
4023
|
-
|
4024
|
-
vals = {}
|
4025
|
-
start_ii = 0
|
4026
|
-
for ii, key in enumerate(keys):
|
4076
|
+
assert len(idx) == keys.shape[0], 'Error in filling'
|
4027
4077
|
|
4028
|
-
|
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
|
4078
|
+
logging.info(_('Cells to fill : {}'.format(len(idx))))
|
4032
4079
|
|
4033
|
-
|
4034
|
-
|
4080
|
+
# apply operator
|
4081
|
+
vals = {}
|
4082
|
+
start_ii = 0
|
4083
|
+
for ii, key in enumerate(keys):
|
4084
|
+
end_ii = idx[ii]+1
|
4035
4085
|
|
4036
|
-
|
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)
|
4037
4096
|
|
4038
4097
|
array.reset_plot()
|
4039
4098
|
self.Paint()
|
@@ -4073,7 +4132,7 @@ class WolfMapViewer(wx.Frame):
|
|
4073
4132
|
|
4074
4133
|
self.mylazgrid = xyz_laz_grids(dirlaz)
|
4075
4134
|
|
4076
|
-
dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW
|
4135
|
+
dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
|
4077
4136
|
ret = dlg.ShowModal()
|
4078
4137
|
if ret != wx.ID_OK:
|
4079
4138
|
dlg.Destroy()
|
@@ -4274,7 +4333,7 @@ class WolfMapViewer(wx.Frame):
|
|
4274
4333
|
item = self.menubar.FindItemById(event.GetId())
|
4275
4334
|
|
4276
4335
|
if item is not None:
|
4277
|
-
self.
|
4336
|
+
self.set_statusbar_text(item.GetHelp())
|
4278
4337
|
|
4279
4338
|
def _select_laz_source(self):
|
4280
4339
|
""" Select laz source """
|
@@ -7624,6 +7683,14 @@ class WolfMapViewer(wx.Frame):
|
|
7624
7683
|
self.active_bc.Show()
|
7625
7684
|
return
|
7626
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
|
+
|
7627
7694
|
def OnActivateTreeElem(self, e): #:dataview.TreeListEvent ):
|
7628
7695
|
""" Activate the selected item in the tree list """
|
7629
7696
|
curzones: Zones
|
@@ -7643,7 +7710,7 @@ class WolfMapViewer(wx.Frame):
|
|
7643
7710
|
|
7644
7711
|
myobj = self.treelist.GetItemData(myitem)
|
7645
7712
|
self.selected_object = myobj
|
7646
|
-
self.
|
7713
|
+
self.set_label_selecteditem(nameitem)
|
7647
7714
|
|
7648
7715
|
#FIXME : To generalize using draw_type
|
7649
7716
|
if type(myobj) == Zones:
|
@@ -7689,7 +7756,7 @@ class WolfMapViewer(wx.Frame):
|
|
7689
7756
|
|
7690
7757
|
txt += ' ; Type : ' + self.active_array.dtype_str
|
7691
7758
|
|
7692
|
-
self.
|
7759
|
+
self.set_statusbar_text(txt)
|
7693
7760
|
|
7694
7761
|
|
7695
7762
|
elif type(myobj) in [WolfViews]:
|
@@ -8430,9 +8497,9 @@ class WolfMapViewer(wx.Frame):
|
|
8430
8497
|
""" Message to end action """
|
8431
8498
|
|
8432
8499
|
if which == 0:
|
8433
|
-
self.
|
8500
|
+
self.set_statusbar_text(_('Action in progress... -- To quit, press "RETURN" or "double clicks RIGHT" or press "ESC"'))
|
8434
8501
|
else:
|
8435
|
-
self.
|
8502
|
+
self.set_statusbar_text('')
|
8436
8503
|
|
8437
8504
|
def start_action(self, action:str, message:str=''):
|
8438
8505
|
""" Message to start action """
|
@@ -8756,7 +8823,8 @@ class WolfMapViewer(wx.Frame):
|
|
8756
8823
|
self.active_vertex = None
|
8757
8824
|
self.active_cloud = None
|
8758
8825
|
|
8759
|
-
self.
|
8826
|
+
self.set_statusbar_text(_('Esc pressed - No more action in progress - No more active object'))
|
8827
|
+
self.set_label_selecteditem('')
|
8760
8828
|
|
8761
8829
|
elif key == ord('C'):
|
8762
8830
|
|
wolfhece/PyVertexvectors.py
CHANGED
@@ -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
wolfhece/lazviewer/laz_viewer.py
CHANGED
@@ -502,7 +502,10 @@ class xyz_laz_grids():
|
|
502
502
|
ret = [cur.scan(bounds) for cur in self.grids]
|
503
503
|
ret = [cur for cur in ret if len(cur)>0]
|
504
504
|
|
505
|
-
|
505
|
+
if len(ret)==0:
|
506
|
+
return np.asarray([])
|
507
|
+
else:
|
508
|
+
return np.concatenate(ret)
|
506
509
|
|
507
510
|
def read_dir(self, dir_grids):
|
508
511
|
dirs = listdir(dir_grids)
|
wolfhece/wolf_array.py
CHANGED
@@ -40,7 +40,7 @@ import wx
|
|
40
40
|
from scipy.interpolate import interp2d, griddata
|
41
41
|
from scipy.ndimage import laplace, label, sum_labels
|
42
42
|
import pygltflib
|
43
|
-
from shapely.geometry import Point, LineString, MultiLineString
|
43
|
+
from shapely.geometry import Point, LineString, MultiLineString, Polygon, MultiPolygon, MultiPoint
|
44
44
|
from shapely.ops import linemerge, substring, polygonize_full
|
45
45
|
from os.path import dirname,basename,join
|
46
46
|
import logging
|
@@ -1137,7 +1137,7 @@ class header_wolf():
|
|
1137
1137
|
|
1138
1138
|
return newvector
|
1139
1139
|
|
1140
|
-
def get_xy_infootprint_vect(self, myvect: vector, eps:float = 0.) -> tuple[np.ndarray,np.ndarray]:
|
1140
|
+
def get_xy_infootprint_vect(self, myvect: vector | Polygon, eps:float = 0.) -> tuple[np.ndarray,np.ndarray]:
|
1141
1141
|
"""
|
1142
1142
|
Return the coordinates of the cells in the footprint of a vector
|
1143
1143
|
|
@@ -1154,7 +1154,7 @@ class header_wolf():
|
|
1154
1154
|
|
1155
1155
|
return mypts,myptsij
|
1156
1156
|
|
1157
|
-
def get_ij_infootprint_vect(self, myvect: vector, eps:float = 0.) -> np.ndarray:
|
1157
|
+
def get_ij_infootprint_vect(self, myvect: vector | Polygon, eps:float = 0.) -> np.ndarray:
|
1158
1158
|
"""
|
1159
1159
|
Return the indices of the cells in the footprint of a vector
|
1160
1160
|
|
@@ -1162,8 +1162,16 @@ class header_wolf():
|
|
1162
1162
|
:return : numpy array of indices
|
1163
1163
|
"""
|
1164
1164
|
|
1165
|
-
|
1166
|
-
|
1165
|
+
if isinstance(myvect, Polygon):
|
1166
|
+
xmin, ymin, xmax, ymax = myvect.bounds
|
1167
|
+
elif isinstance(myvect, vector):
|
1168
|
+
xmin, ymin, xmax, ymax = myvect.xmin, myvect.ymin, myvect.xmax, myvect.ymax
|
1169
|
+
else:
|
1170
|
+
logging.error(_('The object must be a vector or a Polygon'))
|
1171
|
+
return np.array([])
|
1172
|
+
|
1173
|
+
i1, j1 = self.get_ij_from_xy(xmin+eps, ymin+eps)
|
1174
|
+
i2, j2 = self.get_ij_from_xy(xmax-eps, ymax-eps)
|
1167
1175
|
|
1168
1176
|
i1 = max(i1,0) # FIXME Why ??? How could i,j be negative ? --> because this fucntion can be called with a vector that is not in the array (e.g. a vector defined by clicks in the UI)
|
1169
1177
|
j1 = max(j1,0)
|
@@ -1412,6 +1420,11 @@ class Ops_Array(wx.Frame):
|
|
1412
1420
|
if self.wx_exists:
|
1413
1421
|
self.set_GUI()
|
1414
1422
|
|
1423
|
+
@property
|
1424
|
+
def idx(self):
|
1425
|
+
""" Return the idx of the parentarray """
|
1426
|
+
return self.parentarray.idx
|
1427
|
+
|
1415
1428
|
def get_mapviewer(self):
|
1416
1429
|
""" Retourne l'instance WolfMapViewer """
|
1417
1430
|
return self.mapviewer
|
@@ -4609,6 +4622,10 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4609
4622
|
""" Affichage des propriétés de la matrice dans une fenêtre wxPython """
|
4610
4623
|
if self.wx_exists and self.myops is not None:
|
4611
4624
|
self.myops.SetTitle(_('Operations on array: ') + self.idx)
|
4625
|
+
|
4626
|
+
if self.mapviewer is not None:
|
4627
|
+
self.myops.SetIcon(self.mapviewer.GetIcon())
|
4628
|
+
|
4612
4629
|
self.myops.Show()
|
4613
4630
|
|
4614
4631
|
self.myops.Center()
|
@@ -6601,7 +6618,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6601
6618
|
# These functions can not be stored in header_wolf, because wa can use the mask of the array to limit the search
|
6602
6619
|
# These functions are also present in WolfResults_2D, but they are not exactly the same due to the structure of the results
|
6603
6620
|
# *************************************************************************************************************************
|
6604
|
-
def get_xy_inside_polygon(self, myvect: vector, usemask:bool=True):
|
6621
|
+
def get_xy_inside_polygon(self, myvect: vector | Polygon, usemask:bool=True):
|
6605
6622
|
"""
|
6606
6623
|
Return the coordinates inside a polygon
|
6607
6624
|
|
@@ -6609,9 +6626,15 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6609
6626
|
:param usemask : limit potential nodes to unmaksed nodes
|
6610
6627
|
"""
|
6611
6628
|
|
6612
|
-
myvect
|
6629
|
+
if isinstance(myvect, vector):
|
6630
|
+
# force la mise à jour des min/max
|
6631
|
+
myvect.find_minmax()
|
6632
|
+
# Conversion des coordonnées en numpy pour plus d'efficacité (du moins on espère)
|
6633
|
+
myvert = myvect.asnparray()
|
6634
|
+
elif isinstance(myvect, Polygon):
|
6635
|
+
myvert = myvect.exterior.coords[:-1]
|
6636
|
+
|
6613
6637
|
mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect)
|
6614
|
-
myvert = myvect.asnparray()
|
6615
6638
|
path = mpltPath.Path(myvert)
|
6616
6639
|
inside = path.contains_points(mypointsxy)
|
6617
6640
|
|
@@ -6624,6 +6647,34 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6624
6647
|
|
6625
6648
|
return mypointsxy
|
6626
6649
|
|
6650
|
+
def get_xy_inside_polygon_shapely(self, myvect: vector | Polygon, usemask:bool=True):
|
6651
|
+
"""
|
6652
|
+
Return the coordinates inside a polygon
|
6653
|
+
|
6654
|
+
:param myvect : target vector
|
6655
|
+
:param usemask : limit potential nodes to unmaksed nodes
|
6656
|
+
"""
|
6657
|
+
|
6658
|
+
if isinstance(myvect, vector):
|
6659
|
+
# force la mise à jour des min/max
|
6660
|
+
myvect.find_minmax()
|
6661
|
+
polygon = myvect.asshapely_pol()
|
6662
|
+
elif isinstance(myvect, Polygon):
|
6663
|
+
polygon = myvect
|
6664
|
+
|
6665
|
+
mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect)
|
6666
|
+
|
6667
|
+
inside = np.asarray([polygon.contains(Point(x,y)) for x,y in mypointsxy])
|
6668
|
+
|
6669
|
+
mypointsxy = mypointsxy[np.where(inside)]
|
6670
|
+
|
6671
|
+
if usemask:
|
6672
|
+
mypointsij = mypointsij[np.where(inside)]
|
6673
|
+
mymask = np.logical_not(self.array.mask[mypointsij[:, 0], mypointsij[:, 1]])
|
6674
|
+
mypointsxy = mypointsxy[np.where(mymask)]
|
6675
|
+
|
6676
|
+
return mypointsxy
|
6677
|
+
|
6627
6678
|
def get_xy_under_polyline(self, myvect: vector, usemask:bool=True):
|
6628
6679
|
"""
|
6629
6680
|
Return the coordinates along a polyline
|
@@ -6664,6 +6715,23 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6664
6715
|
|
6665
6716
|
return mypointsij
|
6666
6717
|
|
6718
|
+
def intersects_polygon(self, myvect: vector | Polygon, usemask:bool=True):
|
6719
|
+
""" Return True if the array intersects the polygon
|
6720
|
+
|
6721
|
+
:param myvect : target vector
|
6722
|
+
:param usemask : limit potential nodes to unmaksed nodes
|
6723
|
+
"""
|
6724
|
+
|
6725
|
+
return self.get_xy_inside_polygon(myvect, usemask).shape[0] > 0
|
6726
|
+
|
6727
|
+
def intersects_polygon_shapely(self, myvect: vector | Polygon, eps:float = 0., usemask:bool=True):
|
6728
|
+
""" Return True if the array intersects the polygon
|
6729
|
+
|
6730
|
+
:param myvect : target vector
|
6731
|
+
:param usemask : limit potential nodes to unmaksed nodes
|
6732
|
+
"""
|
6733
|
+
return self.get_xy_inside_polygon_shapely(myvect, usemask).shape[0] > 0
|
6734
|
+
|
6667
6735
|
def get_ij_under_polyline(self, myvect: vector, usemask:bool=True):
|
6668
6736
|
"""
|
6669
6737
|
Return the indices along a polyline
|
@@ -7025,6 +7093,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7025
7093
|
else:
|
7026
7094
|
self.array = np.kron(self.array, np.ones((int(1/factor), int(1/factor)), dtype=self.array.dtype))
|
7027
7095
|
|
7096
|
+
self.mask_data(self.nullvalue)
|
7097
|
+
|
7028
7098
|
self.count()
|
7029
7099
|
|
7030
7100
|
# rebin must not change the type of the array
|
@@ -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=
|
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=
|
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,7 +48,7 @@ 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=
|
51
|
+
wolfhece/wolf_array.py,sha256=Yg3iX0hPXkdJTuwu6rXlRee2w6hL595_4RZWCUrFWKc,374869
|
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
|
@@ -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=
|
75
|
+
wolfhece/apps/version.py,sha256=POD15Cc2AZYe1VXE08EaduFN-zrnSaxN6wGC-H49Xoo,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=
|
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.
|
284
|
-
wolfhece-2.1.
|
285
|
-
wolfhece-2.1.
|
286
|
-
wolfhece-2.1.
|
287
|
-
wolfhece-2.1.
|
283
|
+
wolfhece-2.1.55.dist-info/METADATA,sha256=RauQP3GnJ5Y_HTZ_79bVAZVYSVulNhDpEsPp1dPVLHc,2541
|
284
|
+
wolfhece-2.1.55.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
285
|
+
wolfhece-2.1.55.dist-info/entry_points.txt,sha256=Q5JuIWV4odeIJI3qc6fV9MwRoz0ezqPVlFC1Ppm_vdQ,395
|
286
|
+
wolfhece-2.1.55.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
|
287
|
+
wolfhece-2.1.55.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|