wolfhece 2.1.116__py3-none-any.whl → 2.1.118__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
@@ -84,7 +84,7 @@ try:
84
84
  from .Results2DGPU import wolfres2DGPU
85
85
  from .PyCrosssections import crosssections, profile, Interpolator, Interpolators
86
86
  from .GraphNotebook import PlotNotebook
87
- from .lazviewer.laz_viewer import myviewer, read_laz, clip_data_xyz, xyz_laz_grids, choices_laz_colormap, Classification_LAZ
87
+ from .lazviewer.laz_viewer import myviewer, read_laz, clip_data_xyz, xyz_laz_grids, choices_laz_colormap, Classification_LAZ, Base_LAZ_Data, viewer as viewerlaz
88
88
  from . import Lidar2002
89
89
  from .picc import Picc_data, Cadaster_data
90
90
  from .wolf_zi_db import ZI_Databse_Elt, PlansTerrier
@@ -129,6 +129,44 @@ ID_PLOTCS = 1003 #Manageactions ID for profile plots
129
129
 
130
130
  LIST_1TO9 = [wx.WXK_NUMPAD1, wx.WXK_NUMPAD2, wx.WXK_NUMPAD3, wx.WXK_NUMPAD4, wx.WXK_NUMPAD5, wx.WXK_NUMPAD6, wx.WXK_NUMPAD7, wx.WXK_NUMPAD8, wx.WXK_NUMPAD9 ] + [ord(str(cur)) for cur in range(1,10)]
131
131
 
132
+ PROJECT_ACTION = 'action'
133
+ PROJECT_CS = 'cross_sections'
134
+ PROJECT_VECTOR = 'vector'
135
+ PROJECT_ARRAY = 'array'
136
+ PROJECT_TILES = 'tiles'
137
+ PROJECT_LAZ = 'laz_grid'
138
+ PROJECT_CLOUD = 'cloud'
139
+ PROJECT_WOLF2D = 'wolf2d'
140
+ PROJECT_GPU2D = 'gpu2d'
141
+ PROJECT_PALETTE = 'palette'
142
+ PROJECT_PALETTE_ARRAY = 'palette-array'
143
+ PROJECT_LINK_CS = 'cross_sections_link'
144
+ PROJECT_LINK_VEC_ARRAY = 'vector_array_link'
145
+
146
+ PROJECT_GROUP_KEYS = {PROJECT_ACTION : {'which': 'compare_arrays'},
147
+ PROJECT_CS: {'id - file': 'id to use - full or relative path to CS file',
148
+ 'format': '(mandatory) 2000, 2022, vecz, sxy',
149
+ 'dirlaz': 'Path to LAZ data (prepro Numpy)'},
150
+ PROJECT_VECTOR: {'id - file': 'id to use - full or relative path to vector file (.vec, .vecz, .shp)'},
151
+ PROJECT_ARRAY: {'id - file': 'id to use - full or relative path to array file (.bin, .tif, .npy, .npz)'},
152
+ PROJECT_TILES : {'id': '(mandatory) id to use',
153
+ 'tiles_file': '(mandatory) Path to tiles file',
154
+ 'data_dir': '(mandatory) Path to data directory',
155
+ 'comp_dir': 'Path to comparison directory'},
156
+ PROJECT_LAZ: {'data_dir': '(mandatory) Path to data directory (prepro Numpy)',
157
+ 'classification': 'Color classification for LAZ data - default SPW-Geofit 2023',},
158
+ PROJECT_CLOUD: {'id - file': 'id to use - full or relative path to cloud file (.xyz, .txt)'},
159
+ PROJECT_WOLF2D: {'id - dir': 'id to use - full or relative path to wolf2d simulation directory'},
160
+ PROJECT_GPU2D: {'id - dir': 'id to use - full or relative path to gpu2d simulation directory'},
161
+ PROJECT_PALETTE : {'id - file': 'id to use - full or relative path to palette file (.pal)'},
162
+ PROJECT_PALETTE_ARRAY : {'idarray - idpal': 'id of array - id of palette to link'},
163
+ PROJECT_LINK_CS : {'linkzones' : '(mandatory) id of vector to link to cross sections',
164
+ 'sortzone' : '(mandatory) id of the zone to use for sorting',
165
+ 'sortname' : '(mandatory) id of the polyline to use for sorting',
166
+ 'downfirst' : 'is the first vertex downstream or upstream? (1 is True, 0 is False - default is False)'},
167
+ PROJECT_LINK_VEC_ARRAY : {'id - id vector': 'id of array/wolf2d/gpu2d - id of vector to link (only 1 vector in 1 zone)'},
168
+ }
169
+
132
170
  class Memory_View():
133
171
  """ Memory view """
134
172
 
@@ -519,6 +557,7 @@ class draw_type(Enum):
519
557
  WMSFORE = 'wms-foreground'
520
558
  TILES = 'tiles'
521
559
  IMAGESTILES = 'imagestiles'
560
+ LAZ = 'laz'
522
561
 
523
562
  class Colors_1to9(wx.Frame):
524
563
 
@@ -1133,6 +1172,8 @@ class WolfMapViewer(wx.Frame):
1133
1172
  myimagestiles: list[ImagesTiles]
1134
1173
  mypartsystems: list[Particle_system]
1135
1174
  myviewers3d:list[Wolf_Viewer3D]
1175
+ mylazdata:list[Base_LAZ_Data]
1176
+
1136
1177
  sim_explorers: dict[Wolfresults_2D:Sim_Explorer]
1137
1178
 
1138
1179
  canvas: GLCanvas # canvas OpenGL
@@ -1158,10 +1199,12 @@ class WolfMapViewer(wx.Frame):
1158
1199
  active_imagestiles: ImagesTiles
1159
1200
  active_particle_system: Particle_system
1160
1201
  active_viewer3d: Wolf_Viewer3D
1202
+ active_viewerlaz: viewerlaz
1161
1203
  active_bridges: Bridges
1162
1204
  active_bridge: Bridge
1163
1205
  active_weirs : Weirs
1164
1206
  active_weir : Weir
1207
+ active_laz : Base_LAZ_Data
1165
1208
 
1166
1209
  def __init__(self,
1167
1210
  wxparent = None,
@@ -1232,12 +1275,12 @@ class WolfMapViewer(wx.Frame):
1232
1275
  self.linkedList = None
1233
1276
  self.link_params = None
1234
1277
 
1278
+ self.project_pal = None
1279
+
1235
1280
  self.forcemimic = True
1236
1281
  self.currently_readresults = False
1237
1282
 
1238
- self.mylazdata = None
1239
- # self.mylazdata_colors = None
1240
- self.mylazgrid = None
1283
+ self.mylazgrid:xyz_laz_grids = None # LAZ grid preprocessed by Numpy
1241
1284
 
1242
1285
  self.colors1to9 = Colors_1to9(self)
1243
1286
 
@@ -1269,8 +1312,8 @@ class WolfMapViewer(wx.Frame):
1269
1312
  self.menuimagestiles = None
1270
1313
 
1271
1314
  self.filemenu = wx.Menu()
1272
- openitem = self.filemenu.Append(wx.ID_OPEN, _('Open project'), _('Open a complete project from file'))
1273
- saveproject = self.filemenu.Append(wx.ID_ANY, _('Save project'), _('Save the current project to file'))
1315
+ openitem = self.filemenu.Append(wx.ID_OPEN, _('Open/Add project'), _('Open a full project from file'))
1316
+ saveproject = self.filemenu.Append(wx.ID_ANY, _('Save project as...'), _('Save the current project to file'))
1274
1317
  self.filemenu.AppendSeparator()
1275
1318
  saveitem = self.filemenu.Append(wx.ID_SAVE, _('Save'), _('Save all checked arrays or vectors to files'))
1276
1319
  saveasitem = self.filemenu.Append(wx.ID_SAVEAS, _('Save as...'), _('Save all checked arrays or vectors to new files --> one file dialog per data'))
@@ -1495,6 +1538,7 @@ class WolfMapViewer(wx.Frame):
1495
1538
  self.active_res2d = None
1496
1539
  self.active_particle_system = None
1497
1540
  self.active_viewer3d = None
1541
+ self.active_viewerlaz = None
1498
1542
  self.active_landmap:PlansTerrier = None
1499
1543
  self.active_tile = None
1500
1544
  self.selected_treeitem = None
@@ -1503,6 +1547,7 @@ class WolfMapViewer(wx.Frame):
1503
1547
  self.active_bridge = None
1504
1548
  self.active_weirs = None
1505
1549
  self.active_weir = None
1550
+ self.active_laz = None
1506
1551
 
1507
1552
  curtool = self.tools[ID_SORTALONG] = {}
1508
1553
  curtool['menu'] = self.sortalong
@@ -1517,6 +1562,7 @@ class WolfMapViewer(wx.Frame):
1517
1562
  # Help
1518
1563
  self.helpmenu = wx.Menu()
1519
1564
  self.helpmenu.Append(wx.ID_ANY, _('Shortcuts'), _('Shortcuts'))
1565
+ self.helpmenu.Append(wx.ID_ANY, _('Project .proj'), _('A project file ".proj", what is it?'))
1520
1566
  self.helpmenu.Append(wx.ID_ANY, _('Show logs/informations'), _('Logs'))
1521
1567
  self.helpmenu.Append(wx.ID_ANY, _('Show values'), _('Data/Values'))
1522
1568
  self.helpmenu.Append(wx.ID_ANY, _('About'), _('About'))
@@ -1550,14 +1596,15 @@ class WolfMapViewer(wx.Frame):
1550
1596
 
1551
1597
  self.root = self.treelist.GetRootItem()
1552
1598
  self.treelist.AppendColumn(_('Objects to plot'))
1553
- self.myitemsarray = self.treelist.AppendItem(self.root, _("Arrays"))
1599
+ self.myitemsarray = self.treelist.AppendItem(self.root, _("Arrays"))
1554
1600
  self.myitemsvector = self.treelist.AppendItem(self.root, _("Vectors"))
1555
- self.myitemscloud = self.treelist.AppendItem(self.root, _("Clouds"))
1556
- self.myitemstri = self.treelist.AppendItem(self.root, _("Triangulations"))
1557
- self.myitemsres2d = self.treelist.AppendItem(self.root, _("Wolf2D"))
1558
- self.myitemsps = self.treelist.AppendItem(self.root, _("Particle systems"))
1601
+ self.myitemscloud = self.treelist.AppendItem(self.root, _("Clouds"))
1602
+ self.myitemslaz = self.treelist.AppendItem(self.root, _("Laz"))
1603
+ self.myitemstri = self.treelist.AppendItem(self.root, _("Triangulations"))
1604
+ self.myitemsres2d = self.treelist.AppendItem(self.root, _("Wolf2D"))
1605
+ self.myitemsps = self.treelist.AppendItem(self.root, _("Particle systems"))
1559
1606
  self.myitemsothers = self.treelist.AppendItem(self.root, _("Others"))
1560
- self.myitemsviews = self.treelist.AppendItem(self.root, _("Views"))
1607
+ self.myitemsviews = self.treelist.AppendItem(self.root, _("Views"))
1561
1608
  self.myitemswmsback = self.treelist.AppendItem(self.root, _("WMS-background"))
1562
1609
  self.myitemswmsfore = self.treelist.AppendItem(self.root, _("WMS-foreground"))
1563
1610
 
@@ -1881,17 +1928,20 @@ class WolfMapViewer(wx.Frame):
1881
1928
  self.menulaz.AppendSubMenu(self.menulazdata, _('LAZ data'))
1882
1929
  self.menulaz.AppendSubMenu(self.menulazgrid, _('LAZ grid'))
1883
1930
 
1884
- readlaz = self.menulazdata.Append(wx.ID_ANY, _('Initialize from npz'), _('LAZ from Numpy array'))
1885
- readlaz_gridinfo = self.menulazgrid.Append(wx.ID_ANY, _('Initialize from GridInfos'), _('LAZ from gridinfos - subgridding of LAZ files'), kind=wx.ITEM_CHECK)
1931
+ readlaz = self.menulazdata.Append(wx.ID_ANY, _('Initialize from laz, las or npz'), _('LAZ data from one specific file (type laz, las or npz)'))
1932
+ readlaz_gridinfo = self.menulazgrid.Append(wx.ID_ANY, _('Initialize from directory'), _('LAZ GRID stored in a directory - subgridding of LAZ files'), kind=wx.ITEM_CHECK)
1933
+ updatecolors_laz = self.menulazgrid.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
1886
1934
 
1887
- bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('LAZ Bridge'))
1888
- buildinglaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from buildings'), _('LAZ Buildings'))
1935
+ bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('Extract bridge from LAZ data as cloud points (class 10)'))
1936
+ buildinglaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from buildings'), _('Extract buildings from LAZ data as cloud points (class 1)'))
1937
+ classlaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from specified classes'), _('Extract cloud points from LAZ data (class to specify)'))
1889
1938
 
1890
1939
  croplaz = self.menulaz.Append(wx.ID_ANY, _('Clip LAZ grid on current zoom'), _('Select LAZ data based on the visible screen extent'),)
1891
1940
  viewlaz = self.menulaz.Append(wx.ID_ANY, _('Create LAZ viewer'), _('Create a LAZ Viewer based on loaded data'))
1941
+ filterlaz = self.menulaz.Append(wx.ID_ANY, _('Filter data based on codes'), _('Filter LAZ data based on codes'),)
1942
+ descimate_laz = self.menulaz.Append(wx.ID_ANY, _('Descimate LAZ data'), _('Descimate LAZ data'),)
1892
1943
  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'),)
1893
1944
  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'),)
1894
- updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
1895
1945
  fillarray_laz = self.menulaz.Append(wx.ID_ANY, _('Fill active array from LAZ data'), _('Fill an array from the LAZ data'),)
1896
1946
  selectarray_laz = self.menulaz.Append(wx.ID_ANY, _('Select cells in array from LAZ data'), _('Select nodes in active array from the LAZ data'),)
1897
1947
  countarray_laz = self.menulaz.Append(wx.ID_ANY, _('Count LAZ data in cells'), _('Count the number of LAZ data in each cell of the matrix'),)
@@ -3849,10 +3899,13 @@ class WolfMapViewer(wx.Frame):
3849
3899
  self.mywmsfore = []
3850
3900
  self.myres2D = []
3851
3901
  self.myviewers3d = []
3902
+ self.myviewerslaz = []
3903
+ self.mylazdata = []
3904
+
3852
3905
  self.sim_explorers = {}
3853
3906
 
3854
3907
  # liste des éléments modifiable dans l'arbre
3855
- self.all_lists = [self.myarrays, self.myvectors, self.myclouds, self.mytri, self.myothers, self.myviews, self.myres2D, self.mytiles, self.myimagestiles, self.mypartsystems, self.myviewers3d]
3908
+ self.all_lists = [self.myarrays, self.myvectors, self.myclouds, self.mytri, self.myothers, self.myviews, self.myres2D, self.mytiles, self.myimagestiles, self.mypartsystems, self.myviewers3d, self.myviewerslaz]
3856
3909
 
3857
3910
  self.menu_options = wx.Menu()
3858
3911
  self._change_title = self.menu_options.Append(wx.ID_ANY, _('Change title'), _('Change title of the window'))
@@ -4872,258 +4925,589 @@ class WolfMapViewer(wx.Frame):
4872
4925
  """
4873
4926
  curdir = Path(os.getcwd())
4874
4927
 
4875
- myproject = Wolf_Param(None, filename=fn, toShow=False)
4876
-
4877
- mykeys = ['cross_sections', 'vector', 'array']
4928
+ real_ids = {}
4878
4929
 
4879
- if 'which' in myproject.myparams.keys():
4880
- which = myproject.myparams['which']['action'][key_Param.VALUE]
4881
- if which == 'compare':
4882
- ListCompare = []
4883
- if 'array' in myproject.myparams.keys():
4884
- for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4885
- ListCompare.append(WolfArray(normpath(curname[key_Param.VALUE])))
4930
+ myproject = Wolf_Param(None, filename=fn, toShow=False)
4886
4931
 
4887
- self.set_compare(ListCompare)
4888
- return
4932
+ def check_params(myproject, curgroup) -> bool:
4889
4933
 
4890
- if 'cross_sections' in myproject.myparams.keys():
4891
- for curid, curname in zip(myproject.myparams['cross_sections'].keys(),
4892
- myproject.myparams['cross_sections'].values()):
4893
- if curid != 'format' and curid != 'dirlaz':
4894
- mycs = crosssections(curname[key_Param.VALUE],
4895
- format=myproject.myparams['cross_sections']['format'][key_Param.VALUE],
4896
- dirlaz=myproject.myparams['cross_sections']['dirlaz'][key_Param.VALUE],
4897
- mapviewer = self)
4934
+ check = True
4935
+ pot_keys = list(PROJECT_GROUP_KEYS[curgroup].keys())
4898
4936
 
4899
- self.add_object('cross_sections', newobj=mycs, id=curid)
4937
+ for curkey in pot_keys:
4938
+ if 'mandatory' in PROJECT_GROUP_KEYS[curgroup][curkey]:
4939
+ if not myproject.is_in(curgroup, curkey):
4940
+ logging.warning(_('Missing key : ')+ curkey)
4941
+ check = False
4942
+ return check
4900
4943
 
4944
+ def sanit_id(id:str, drawtype:draw_type) -> str:
4945
+ existing_id = self.get_list_keys(drawtype, None)
4901
4946
 
4902
- if myproject.get_group('tiles') is not None:
4947
+ while id in existing_id:
4948
+ logging.warning(_('ID already exists - Changing it...'))
4949
+ id = id + '_'
4903
4950
 
4904
- curid = myproject.get_param('tiles', 'id')
4905
- curfile = myproject.get_param('tiles', 'tiles_file')
4906
- curdatadir = myproject.get_param('tiles', 'data_dir')
4907
- curcompdir = myproject.get_param('tiles', 'comp_dir')
4951
+ return id
4908
4952
 
4909
- if exists(curfile):
4910
- mytiles = Tiles(filename= curfile, parent=self, linked_data_dir=curdatadir)
4911
- mytiles.set_comp_dir(curcompdir)
4912
- self.add_object('tiles', newobj=mytiles, id=curid)
4913
- else:
4914
- logging.info(_('Bad parameter in project file - tiles : ')+ curfile)
4953
+ # COMPLEX ACTIONS
4954
+ curgroup = PROJECT_ACTION
4955
+ if myproject.is_in(curgroup):
4915
4956
 
4916
- if myproject.get_group('laz_grid') is not None:
4957
+ pot_keys = list(PROJECT_GROUP_KEYS[curgroup].keys())
4917
4958
 
4918
- curdatadir = myproject.get_param('laz_grid', 'data_dir')
4959
+ for curkey in pot_keys:
4960
+ which = myproject[(curgroup, curkey)]
4919
4961
 
4920
- self.init_laz_from_gridinfos(curdatadir)
4962
+ pot_val = list(PROJECT_GROUP_KEYS[curgroup][curkey].keys())
4921
4963
 
4922
- if 'vector' in myproject.myparams.keys():
4923
- for curid, curname in zip(myproject.myparams['vector'].keys(), myproject.myparams['vector'].values()):
4924
- if exists(curname[key_Param.VALUE]):
4925
- myvec = Zones(curname[key_Param.VALUE], parent=self, mapviewer = self)
4926
- self.add_object('vector', newobj=myvec, id=curid)
4927
- else:
4928
- logging.info(_('Bad parameter in project file - vector : ')+ curname[key_Param.VALUE])
4964
+ if which in pot_val:
4965
+ if which == 'compare_arrays':
4929
4966
 
4930
- if 'array' in myproject.myparams.keys():
4931
- for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4967
+ # Comparaison de plusieurs matrices
4932
4968
 
4933
- if exists(curname[key_Param.VALUE]):
4934
- curarray = WolfArray(curname[key_Param.VALUE], mapviewer=self)
4935
- self.add_object('array', newobj=curarray, id=curid)
4936
- else:
4937
- logging.info(_('Bad parameter in project file - array : ')+ curname[key_Param.VALUE])
4969
+ logging.info(_('Compare action - Searching for arrays to compare...'))
4970
+ ListCompare = []
4971
+ if myproject.is_in('array'):
4972
+ for curval in myproject.get_group('array').values():
4973
+ curid = curval[key_Param.NAME]
4974
+ logging.info(_('Array to compare : ')+ curid)
4975
+ ListCompare.append(WolfArray(Path(myproject[('array', curid)])))
4976
+ else:
4977
+ logging.warning(_('No array to compare - Aborting !'))
4978
+ return
4938
4979
 
4939
- if 'cloud' in myproject.myparams.keys():
4940
- for curid, curname in zip(myproject.myparams['cloud'].keys(), myproject.myparams['cloud'].values()):
4941
- if exists(curname[key_Param.VALUE]):
4942
- mycloud = cloud_vertices(curname[key_Param.VALUE], mapviewer=self)
4943
- self.add_object('cloud', newobj=mycloud, id=curid)
4980
+ logging.info(_('Setting compare...'))
4981
+ self.set_compare(ListCompare)
4982
+ logging.info(_('Compare set !'))
4983
+ return
4944
4984
  else:
4945
- logging.info(_('Bad parameter in project file - cloud : ')+ curname[key_Param.VALUE])
4985
+ logging.error(_('Bad parameter in project file - action : ')+ which)
4986
+
4987
+ # CROSS SECTIONS
4988
+ curgroup = PROJECT_CS
4989
+ if myproject.is_in(curgroup):
4990
+ if check_params(myproject, curgroup):
4991
+ for curval in myproject.get_group(curgroup).values():
4992
+ curid = curval[key_Param.NAME]
4993
+ if curid != 'format' and curid != 'dirlaz':
4994
+ mycs = crosssections(myproject[(curgroup, curid)],
4995
+ format = myproject[(curgroup, 'format')],
4996
+ dirlaz = myproject[(curgroup, 'dirlaz')],
4997
+ mapviewer = self)
4998
+
4999
+ locid = real_ids[(draw_type.VECTORS, curid)] = sanit_id(curid, draw_type.VECTORS)
5000
+
5001
+ self.add_object(curgroup, newobj=mycs, id=locid)
5002
+ else:
5003
+ logging.warning(_('Bad parameter in project file - cross_sections'))
5004
+
5005
+ # TILES
5006
+ curgroup = PROJECT_TILES
5007
+ if myproject.is_in(curgroup):
5008
+ if check_params(myproject, curgroup):
5009
+ curid = myproject.get_param(curgroup, 'id')
5010
+ curfile = myproject.get_param(curgroup, 'tiles_file')
5011
+ curdatadir = myproject.get_param(curgroup, 'data_dir')
5012
+ curcompdir = myproject.get_param(curgroup, 'comp_dir')
5013
+
5014
+ if exists(curfile):
5015
+ try:
5016
+ mytiles = Tiles(filename= curfile, parent=self, linked_data_dir=curdatadir)
5017
+ mytiles.set_comp_dir(curcompdir)
4946
5018
 
4947
- if 'wolf2d' in myproject.myparams.keys():
4948
- for curid, curname in zip(myproject.myparams['wolf2d'].keys(), myproject.myparams['wolf2d'].values()):
4949
- if exists(curname[key_Param.VALUE]):
4950
- curwolf = Wolfresults_2D(curname[key_Param.VALUE], mapviewer=self)
4951
- self.add_object('res2d', newobj=curwolf, id=curid)
5019
+ locid = real_ids[(draw_type.TILES, curid)] = sanit_id(curid, draw_type.TILES)
5020
+ self.add_object(curgroup, newobj=mytiles, id=locid)
5021
+ except Exception as e:
5022
+ logging.error(_('Error in tiles import : ')+ str(e))
4952
5023
  else:
4953
- logging.info(_('Bad parameter in project file - wolf2d : ')+ curname[key_Param.VALUE])
5024
+ logging.warning(_('File does not exist : ')+ curfile)
5025
+ else:
5026
+ logging.warning(_('Bad parameter in project file - tiles'))
4954
5027
 
4955
- self.menu_wolf2d()
5028
+ # LAZ GRID
5029
+ curgroup = PROJECT_LAZ
5030
+ if myproject.is_in(curgroup):
5031
+ if check_params(myproject, curgroup):
5032
+ try:
5033
+ self.init_laz_from_gridinfos(myproject[curgroup, 'data_dir'], myproject[(curgroup, 'classification')])
5034
+ except Exception as e:
5035
+ logging.error(_('Error in laz_grid import : ')+ str(e))
5036
+ else:
5037
+ logging.warning(_('Bad parameter in project file - laz_grid'))
5038
+
5039
+ # VECTOR DATA
5040
+ curgroup = PROJECT_VECTOR
5041
+ if myproject.is_in(curgroup):
5042
+ if check_params(myproject, curgroup):
5043
+ for curval in myproject.get_group(curgroup).values():
5044
+ curid = curval[key_Param.NAME]
5045
+ name = curval[key_Param.VALUE]
5046
+ if exists(name):
5047
+ try:
5048
+ myvec = Zones(name, parent = self, mapviewer = self)
5049
+
5050
+ locid = real_ids[(draw_type.VECTORS, curid)] = sanit_id(curid, draw_type.VECTORS)
5051
+ self.add_object(curgroup, newobj = myvec, id = locid)
5052
+ except Exception as e:
5053
+ logging.error(_('Error in vector import : ')+ str(e))
5054
+ else:
5055
+ logging.info(_('File does not exist : ') + name)
5056
+ else:
5057
+ logging.warning(_('Bad parameter in project file - vector'))
5058
+
5059
+ # ARRAY DATA
5060
+ curgroup = PROJECT_ARRAY
5061
+ if myproject.is_in(curgroup):
5062
+ if check_params(myproject, curgroup):
5063
+ for curval in myproject.get_group(curgroup).values():
5064
+ curid = curval[key_Param.NAME]
5065
+ name = curdir / Path(curval[key_Param.VALUE])
5066
+ if exists(name):
5067
+ try:
5068
+ curarray = WolfArray(name, mapviewer = self)
5069
+
5070
+ locid = real_ids[(draw_type.ARRAYS, curid)] = sanit_id(curid, draw_type.ARRAYS)
5071
+ self.add_object('array', newobj=curarray, id = locid)
5072
+ except Exception as e:
5073
+ logging.error(_('Error in array import : ')+ str(e))
5074
+ else:
5075
+ logging.info(_('File does not exist : ') + name)
5076
+ else:
5077
+ logging.warning(_('Bad parameter in project file - array'))
5078
+
5079
+ # CLOUD DATA
5080
+ curgroup = PROJECT_CLOUD
5081
+ if myproject.is_in(curgroup):
5082
+ if check_params(myproject, curgroup):
5083
+ for curval in myproject.get_group(curgroup).values():
5084
+ curid = curval[key_Param.NAME]
5085
+ name = curval[key_Param.VALUE]
5086
+ if exists(name):
5087
+ try:
5088
+ mycloud = cloud_vertices(name, mapviewer = self)
5089
+
5090
+ locid = real_ids[(draw_type.CLOUD, curid)] = sanit_id(curid, draw_type.CLOUD)
5091
+ self.add_object('cloud', newobj = mycloud, id = locid)
5092
+ except Exception as e:
5093
+ logging.error(_('Error in cloud import : ') + str(e))
5094
+ else:
5095
+ logging.info(_('File does not exist : ') + name)
5096
+ else:
5097
+ logging.warning(_('Bad parameter in project file - cloud'))
5098
+
5099
+ # 2D RESULTS
5100
+
5101
+ # CPU code
5102
+ curgroup = PROJECT_WOLF2D
5103
+ if myproject.is_in(curgroup):
5104
+ if check_params(myproject, curgroup):
5105
+ for curval in myproject.get_group(curgroup).values():
5106
+ curid = curval[key_Param.NAME]
5107
+ simdir = Path(curval[key_Param.VALUE])
5108
+ if simdir.exists():
5109
+ try:
5110
+ curwolf = Wolfresults_2D(simdir, mapviewer = self)
5111
+
5112
+ locid = real_ids[(draw_type.RES2D, curid)] = sanit_id(curid, draw_type.RES2D)
5113
+ self.add_object('res2d', newobj = curwolf, id = locid)
5114
+ except Exception as e:
5115
+ logging.error(_('Error in wolf2d import : ')+ str(e))
5116
+ else:
5117
+ logging.info(_('Directory does not exist ')) + simdir
4956
5118
 
4957
- if 'gpu2d' in myproject.myparams.keys():
5119
+ self.menu_wolf2d()
5120
+ else:
5121
+ logging.warning(_('Bad parameter in project file - wolf2d'))
5122
+
5123
+ # GPU code
5124
+ curgroup = PROJECT_GPU2D
5125
+ if myproject.is_in(curgroup):
5126
+ if check_params(myproject, curgroup):
5127
+
5128
+ pgbar = wx.ProgressDialog(_('Loading GPU results'), _('Loading GPU results'), maximum=len(myproject.myparams[curgroup].keys()), parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
5129
+
5130
+ for curval in myproject.get_group(curgroup).values():
5131
+ curid = curval[key_Param.NAME]
5132
+ simdir = Path(curval[key_Param.VALUE])
5133
+ if simdir.exists():
5134
+ try:
5135
+ curwolf = wolfres2DGPU(curdir / simdir, mapviewer = self)
5136
+
5137
+ locid = real_ids[(draw_type.RES2D, curid)] = sanit_id(curid, draw_type.RES2D)
5138
+ self.add_object('res2d', newobj = curwolf, id = locid)
5139
+ except Exception as e:
5140
+ logging.error(_('Error in gpu2d import : ')+ str(e))
5141
+ else:
5142
+ logging.info(_('Bad directory : ') + simdir)
4958
5143
 
4959
- pgbar = wx.ProgressDialog(_('Loading GPU results'), _('Loading GPU results'), maximum=len(myproject.myparams['gpu2d'].keys()), parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
5144
+ pgbar.Update(pgbar.GetValue() + 1)
4960
5145
 
4961
- for curid, curname in zip(myproject.myparams['gpu2d'].keys(), myproject.myparams['gpu2d'].values()):
4962
- if exists(curname[key_Param.VALUE]):
5146
+ pgbar.Destroy()
4963
5147
 
4964
- if 'simul_gpu_results' in curname[key_Param.VALUE]:
4965
- curwolf = wolfres2DGPU(curdir / Path(curname[key_Param.VALUE]), mapviewer=self)
4966
- else:
4967
- if exists(join(curname[key_Param.VALUE], 'simul_gpu_results')):
4968
- curwolf = wolfres2DGPU(curdir / Path(join(curname[key_Param.VALUE], 'simul_gpu_results')), mapviewer=self)
5148
+ self.menu_wolf2d()
5149
+ self.menu_2dgpu()
5150
+ else:
5151
+ logging.warning(_('Bad parameter in project file - gpu2d'))
5152
+
5153
+ # PALETTE/COLORMAP
5154
+ curgroup = PROJECT_PALETTE
5155
+ if myproject.is_in(curgroup):
5156
+ if check_params(myproject, curgroup):
5157
+ self.project_pal = {}
5158
+ for curval in myproject.get_group(curgroup).values():
5159
+ curid = curval[key_Param.NAME]
5160
+ name = Path(curval[key_Param.VALUE])
5161
+ if name.exists():
5162
+ if name.suffix == '.pal':
5163
+ mypal = wolfpalette(None, '')
5164
+ mypal.readfile(name)
5165
+ mypal.automatic = False
5166
+
5167
+ self.project_pal[curid] = mypal
4969
5168
  else:
4970
- logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
5169
+ logging.warning(_('Bad palette file : ')+ name)
5170
+ else:
5171
+ logging.info(_('Bad parameter in project file - palette : ')+ name)
5172
+ else:
5173
+ logging.warning(_('Bad parameter in project file - palette'))
4971
5174
 
4972
- self.add_object('res2d', newobj=curwolf, id=curid)
5175
+ # LINKS
5176
+ curgroup = PROJECT_PALETTE_ARRAY
5177
+ if myproject.is_in(curgroup):
5178
+ if check_params(myproject, curgroup):
5179
+ curarray: WolfArray
5180
+ if self.project_pal is not None:
5181
+
5182
+ for curval in myproject.get_group(curgroup).keys():
5183
+ id_array = curval[key_Param.NAME]
5184
+ id_pal = curval[key_Param.VALUE]
5185
+ if id_pal in self.project_pal.keys():
5186
+ try:
5187
+ curarray = self.getobj_from_id(real_ids[(draw_type.ARRAYS, id_array)])
5188
+ if curarray is not None:
5189
+ mypal:wolfpalette
5190
+ mypal = self.project_pal[id_pal]
5191
+ curarray.mypal = mypal
5192
+ if mypal.automatic:
5193
+ curarray.myops.palauto.SetValue(1)
5194
+ else:
5195
+ curarray.myops.palauto.SetValue(0)
5196
+ curarray.updatepalette(0)
5197
+ curarray.reset_plot()
5198
+ else:
5199
+ logging.warning(_('Bad parameter in project file - palette-array : ')+ id_array)
5200
+ except Exception as e:
5201
+ logging.error(_('Error in palette-array link : ')+ str(e))
5202
+ else:
5203
+ logging.warning(_('Bad parameter in project file - palette-array : ')+ id_pal)
4973
5204
  else:
4974
- logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
5205
+ logging.warning(_('No palettes found in project file ! -- Add palette group in the .proj'))
5206
+ else:
5207
+ logging.warning(_('Bad parameter in project file - palette-array'))
4975
5208
 
4976
- pgbar.Update(pgbar.GetValue() + 1)
5209
+ curgroup = PROJECT_LINK_CS
5210
+ if myproject.is_in(curgroup):
5211
+ if self.active_cs is not None:
5212
+ if check_params(myproject, curgroup):
4977
5213
 
4978
- pgbar.Destroy()
5214
+ idx = real_ids[(draw_type.VECTORS, myproject[(curgroup, 'linkzones')])]
5215
+ curzones = self.get_obj_from_id(idx, draw_type.VECTORS)
4979
5216
 
4980
- self.menu_wolf2d()
4981
- self.menu_2dgpu()
5217
+ if curzones is not None:
5218
+ self.active_cs.link_external_zones(curzones)
5219
+
5220
+ zonename = myproject[(curgroup, 'sortzone')]
5221
+ vecname = myproject[(curgroup, 'sortname')]
5222
+ downfirst = myproject[(curgroup, 'downfirst')]
4982
5223
 
4983
- if 'palette' in myproject.myparams.keys():
4984
- self.project_pal = {}
4985
- for curid, curname in zip(myproject.myparams['palette'].keys(), myproject.myparams['palette'].values()):
4986
- if exists(curname[key_Param.VALUE]):
4987
- mypal = wolfpalette(None, '')
4988
- mypal.readfile(curname[key_Param.VALUE])
4989
- mypal.automatic = False
5224
+ downfirst = False
5225
+ if downfirst == 1 or str(downfirst).lower() == 'true':
5226
+ downfirst = True
4990
5227
 
4991
- self.project_pal[curid] = mypal
5228
+ if zonename != '' and vecname != '':
5229
+ curvec = curzones[(zonename, vecname)]
5230
+ if curvec is not None:
5231
+ try:
5232
+ self.active_cs.sort_along(curvec.asshapely_ls(), curvec.myname, downfirst)
5233
+ except Exception as e:
5234
+ logging.error(_('Error in cross_sections_link sorting : ')+ str(e))
5235
+ else:
5236
+ logging.warning(_('Bad id for sorting vector in project file - cross_sections_link'))
4992
5237
  else:
4993
- logging.info(_('Bad parameter in project file - palette : ')+ curname[key_Param.VALUE])
5238
+ logging.warning(_('Bad parameter in project file - cross_sections_link'))
5239
+ else:
5240
+ logging.warning(_('No active cross section to link !'))
4994
5241
 
4995
- if 'palette-array' in myproject.myparams.keys():
4996
- curarray: WolfArray
4997
- if self.project_pal is not None:
4998
- for curid, curname in zip(myproject.myparams['palette-array'].keys(),
4999
- myproject.myparams['palette-array'].values()):
5000
- if curname[key_Param.VALUE] in self.project_pal.keys():
5001
- curarray = self.getobj_from_id(curid)
5002
- if curarray is not None:
5003
- mypal:wolfpalette
5004
- mypal = self.project_pal[curname[key_Param.VALUE]]
5005
- curarray.mypal = mypal
5006
- if mypal.automatic:
5007
- curarray.myops.palauto.SetValue(1)
5242
+ curgroup = PROJECT_LINK_VEC_ARRAY
5243
+ # Useful to mask data outside of the linked contour
5244
+ if myproject.is_in(curgroup):
5245
+ if check_params(myproject, curgroup):
5246
+ for curval in myproject.get_group(curgroup).keys():
5247
+
5248
+ id_array = real_ids[(draw_type.ARRAYS, curval[key_Param.NAME])]
5249
+ id_zones = real_ids[(draw_type.VECTORS, curval[key_Param.VALUE])]
5250
+
5251
+ locarray:WolfArray
5252
+ locvec:Zones
5253
+
5254
+ locarray = self.get_obj_from_id(id_array, draw_type.ARRAYS)
5255
+ if locarray is None:
5256
+ locarray = self.get_obj_from_id(id_array, draw_type.RES2D)
5257
+
5258
+ locvec = self.get_obj_from_id(id_zones, draw_type.VECTORS)
5259
+
5260
+ if locvec is not None and locarray is not None:
5261
+ try:
5262
+ if locvec.nbzones == 1:
5263
+ if locvec.myzones[0].nbvectors == 1:
5264
+ locarray.linkedvec = locvec.myzones[0].myvectors[0]
5265
+ else:
5266
+ logging.warning(_('In vec-array association, You must have only 1 zone and 1 polyline !'))
5008
5267
  else:
5009
- curarray.myops.palauto.SetValue(0)
5010
- curarray.updatepalette(0)
5011
- curarray.delete_lists()
5012
- else:
5013
- logging.warning(_('Bad parameter in project file - palette-array : ')+ curid)
5268
+ logging.warning(_('In vec-array association, You must have only 1 zone and 1 polyline !'))
5014
5269
 
5015
- if 'cross_sections_link' in myproject.myparams.keys():
5016
- if 'linkzones' in myproject.myparams['cross_sections_link'].keys():
5017
- idx = myproject.myparams['cross_sections_link']['linkzones'][key_Param.VALUE]
5270
+ except Exception as e:
5271
+ logging.error(_('Error in vector_array_link : ')+ str(e))
5272
+ else:
5273
+ logging.warning(_('Bad vec-array association in project file !'))
5274
+ else:
5275
+ logging.warning(_('Bad parameter in project file - vector_array_link'))
5018
5276
 
5019
- for curzones in self.iterator_over_objects(draw_type.VECTORS):
5020
- curzones: Zones
5021
- if curzones.idx == idx:
5022
- self.active_cs.link_external_zones(curzones)
5277
+ def save_project(self, fn, absolute:bool = True):
5278
+ """ Save project file """
5023
5279
 
5024
- zonename = ''
5025
- vecname = ''
5026
-
5027
- if 'sortzone' in myproject.myparams['cross_sections_link'].keys():
5028
- zonename = myproject.myparams['cross_sections_link']['sortzone'][key_Param.VALUE]
5029
- if 'sortname' in myproject.myparams['cross_sections_link'].keys():
5030
- vecname = myproject.myparams['cross_sections_link']['sortname'][key_Param.VALUE]
5031
-
5032
- if zonename != '' and vecname != '':
5033
- names = [cur.myname for cur in curzones.myzones]
5034
- idx = names.index(zonename)
5035
- curzone = curzones.myzones[idx]
5036
- names = [cur.myname for cur in curzone.myvectors]
5037
- idx = names.index(vecname)
5038
- curvec = curzone.myvectors[idx]
5039
-
5040
- if curvec is not None:
5041
- curvec: vector
5042
- self.active_cs.sort_along(curvec.asshapely_ls(), curvec.myname, False)
5043
-
5044
- if 'vector_array_link' in myproject.myparams.keys():
5045
- for curid, curname in zip(myproject.myparams['vector_array_link'].keys(), myproject.myparams['vector_array_link'].values()):
5046
-
5047
- locvec = None
5048
- locarray = None
5049
- for curvec in self.myvectors:
5050
- if curvec.idx == curname[key_Param.VALUE].lower():
5051
- locvec=curvec
5052
- break
5280
+ dirproj = Path(fn).parent
5053
5281
 
5054
- for curarray in self.myarrays:
5055
- if curarray.idx == curid.lower():
5056
- locarray=curarray
5057
- break
5282
+ def new_path(drawtype:draw_type, id:str) -> str:
5283
+ logging.info(_('Empty path but I need a path !'))
5058
5284
 
5059
- if locvec is not None and locarray is not None:
5285
+ path = ''
5060
5286
 
5061
- locarray.linkedvec = locvec.myzones[0].myvectors[0]
5287
+ ext = 'All files (*.*)|*.*'
5288
+ if drawtype == draw_type.ARRAYS:
5289
+ ext += '|Binary files (*.bin)|*.bin|Tiff files (*.tif)|*.tif|Numpy files (*.npy)|*.npy'
5290
+ elif drawtype == draw_type.VECTORS:
5291
+ ext += '|VecZ files (*.vecz)|*.vecz|Vec files (*.vec)|*.vec'
5292
+ elif drawtype == draw_type.CLOUD:
5293
+ ext += '|Cloud files (*.xyz)|*.xyz'
5062
5294
 
5063
- else:
5295
+ dlg = wx.FileDialog(None, _('Choose a filename for ') + id, str(dirproj), '', ext, wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
5296
+ ret = dlg.ShowModal()
5064
5297
 
5065
- logging.warning(_('Bad vec-array association in project file !'))
5066
- logging.warning(curid)
5067
- logging.warning(curname[key_Param.VALUE])
5298
+ if ret == wx.ID_OK:
5299
+ path = Path(dlg.GetPath())
5068
5300
 
5069
- def save_project(self, fn):
5070
- myproject = Wolf_Param(None, toShow=False)
5301
+ return path
5302
+
5303
+ def sanit_path(path:Path, absolute:bool, drawtype:draw_type) -> str:
5304
+
5305
+ path = Path(path)
5306
+
5307
+ if not path.exists():
5308
+ logging.info(_('Path does not exist : ')+ str(path))
5309
+
5310
+ if absolute:
5311
+ return str(path)
5312
+ else:
5313
+ try:
5314
+ return os.path.relpath(path, dirproj)
5315
+ except:
5316
+ logging.error(_('Error in relative path : ')+ str(path) + " - " + str(dirproj))
5317
+ logging.info(_('Returning absolute path instead !'))
5318
+ return str(path.absolute())
5319
+
5320
+ myproject = Wolf_Param(None, toShow=False, to_read=False, filename=fn, init_GUI=False)
5071
5321
 
5072
- mykeys = ['cross_sections', 'vector', 'array', 'wolf2d']
5073
- for curkey in mykeys:
5074
- myproject[curkey] = {}
5075
- """
5076
- # myproject.myparams['which']={}
5077
- # myproject.myparams['which']['action']={}
5078
- # myproject.myparams['which']['action'][key_Param.VALUE]
5079
-
5080
- # mycs = self.active_cs
5081
- # if mycs is not None:
5082
- # myproject.myparams['cross_sections']={}
5083
- # myproject.myparams['cross_sections']['mycs']={}
5084
- # myproject.myparams['cross_sections']['mycs'][key_Param.VALUE]=mycs.filename
5085
-
5086
- # myproject.myparams['vector']={}
5087
- # myproject.myparams['vector']['river']={}
5088
- ## myproject.myparams['vector']['river'][key_Param.VALUE]=self.added[draw_type.VECTORS.value][0].filename
5089
-
5090
- # if 'array' in myproject.myparams.key():
5091
- # for curid,curname in zip(myproject.myparams['array'].keys(),myproject.myparams['array'].values()):
5092
- # curarray=WolfArray(curname[key_Param.VALUE])
5093
- # self.add_object('array',newobj=curarray,id=curid)
5094
- """
5095
5322
  # matrices
5096
5323
  try:
5324
+ curgroup = PROJECT_ARRAY
5097
5325
  for curel in self.iterator_over_objects(draw_type.ARRAYS):
5098
- myproject['array'][curel.idx] = {}
5099
- myproject['array'][curel.idx][key_Param.VALUE] = curel.filename
5326
+ curel:WolfArray
5327
+ if curel.filename == '':
5328
+ newpath = new_path(draw_type.ARRAYS, curel.idx)
5329
+ if newpath == '':
5330
+ logging.warning(_('No path for array : ')+ curel.idx + _(' - Ignoring it !'))
5331
+ continue
5332
+ curel.write_all(newpath)
5100
5333
 
5334
+ curpath = sanit_path(curel.filename, absolute, draw_type.ARRAYS)
5335
+
5336
+ myproject.add_param(curgroup, curel.idx, curpath)
5101
5337
  except:
5102
- pass
5338
+ logging.error(_('Error in saving arrays'))
5103
5339
 
5104
5340
  # résultats 2D
5105
5341
  try:
5342
+ curgroup = PROJECT_WOLF2D
5106
5343
  for curel in self.iterator_over_objects(draw_type.RES2D):
5107
- myproject['wolf2d'][curel.idx] = {}
5108
- myproject['wolf2d'][curel.idx][key_Param.VALUE] = curel.filename
5344
+ if type(curel) == Wolfresults_2D:
5345
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.RES2D))
5109
5346
 
5347
+ curgroup = PROJECT_GPU2D
5348
+ for curel in self.iterator_over_objects(draw_type.RES2D):
5349
+ if type(curel) == wolfres2DGPU:
5350
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.RES2D))
5110
5351
  except:
5111
- pass
5352
+ logging.error(_('Error in saving 2D results'))
5112
5353
 
5113
5354
  # vecteurs
5114
5355
  try:
5356
+ curgroup = PROJECT_VECTOR
5115
5357
  for curel in self.iterator_over_objects(draw_type.VECTORS):
5116
- myproject['vector'][curel.idx] = {}
5117
- myproject['vector'][curel.idx][key_Param.VALUE] = curel.filename
5358
+ if isinstance(curel, crosssections):
5359
+ continue
5360
+
5361
+ curel:Zones
5362
+ if curel.filename == '':
5363
+ newpath = new_path(draw_type.VECTORS, curel.idx)
5364
+ if newpath == '':
5365
+ logging.warning(_('No path for vector : ')+ curel.idx + _(' - Ignoring it !'))
5366
+ continue
5367
+ curel.saveas(newpath)
5118
5368
 
5369
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.VECTORS))
5119
5370
  except:
5120
- pass
5371
+ logging.error(_('Error in saving vectors'))
5372
+
5373
+ # cross sections
5374
+ try:
5375
+ curgroup = PROJECT_CS
5376
+ for curel in self.iterator_over_objects(draw_type.VECTORS):
5377
+ if isinstance(curel, crosssections):
5378
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.VECTORS))
5379
+ except:
5380
+ logging.error(_('Error in saving cross sections'))
5381
+
5382
+ # nuages de points
5383
+ try:
5384
+ curgroup = PROJECT_CLOUD
5385
+ for curel in self.iterator_over_objects(draw_type.CLOUD):
5386
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.CLOUD))
5387
+ except:
5388
+ logging.error(_('Error in saving clouds'))
5389
+
5390
+ # palettes
5391
+ try:
5392
+ if self.project_pal is not None:
5393
+ curgroup = PROJECT_PALETTE
5394
+ for curel in self.project_pal.keys():
5395
+ myproject.add_param(curgroup, curel, sanit_path(self.project_pal[curel].filename, absolute, draw_type.OTHER))
5396
+ except:
5397
+ logging.error(_('Error in saving palettes'))
5398
+
5399
+ # tiles
5400
+ try:
5401
+ curgroup = PROJECT_TILES
5402
+ for curel in self.iterator_over_objects(draw_type.TILES):
5403
+ myproject.add_param(curgroup, curel.idx, sanit_path(curel.filename, absolute, draw_type.OTHER))
5404
+ myproject.add_param(curgroup, 'data_dir', sanit_path(curel.linked_data_dir, absolute, draw_type.OTHER))
5405
+ myproject.add_param(curgroup, 'comp_dir', sanit_path(curel.linked_data_dir_comp, absolute, draw_type.OTHER))
5406
+ except:
5407
+ logging.error(_('Error in saving tiles'))
5408
+
5409
+ # LAZ GRID
5410
+ try:
5411
+ if self.mylazgrid is not None:
5412
+ curgroup = PROJECT_LAZ
5413
+ myproject.add_param(curgroup, 'data_dir', sanit_path(self.mylazgrid.dir, absolute, draw_type.OTHER))
5414
+ myproject.add_param(curgroup, 'classification', self.mylazgrid.colors.class_name)
5415
+ except:
5416
+ logging.error(_('Error in saving laz grid'))
5417
+
5418
+ myproject.Save(fn)
5419
+
5420
+
5421
+ def help_project(self):
5422
+ """ Help for project file.
5423
+
5424
+ Define which elements can be saved in a project file.
5425
+
5426
+ """
5427
+
5428
+ logging.info(_('Project file help'))
5429
+
5430
+ logging.info(_('Project file is a file containing some information about the current project.'))
5431
+
5432
+ logging.info(_('It can contain the following informations :'))
5433
+
5434
+ logging.info(_(' - Arrays :'))
5435
+ logging.info(_(' - id'))
5436
+ logging.info(_(' - filename in relative or absolute path'))
5437
+
5438
+ logging.info(_(' - Cross sections :'))
5439
+ logging.info(_(' - id'))
5440
+ logging.info(_(' - filename in relative or absolute path'))
5441
+
5442
+ logging.info(_(' - Vectors :'))
5443
+ logging.info(_(' - id'))
5444
+ logging.info(_(' - filename in relative or absolute path'))
5445
+
5446
+ logging.info(_(' - Clouds :'))
5447
+ logging.info(_(' - id'))
5448
+ logging.info(_(' - filename in relative or absolute path'))
5449
+
5450
+ logging.info(_(' - Tiles :'))
5451
+ logging.info(_(' - id'))
5452
+ logging.info(_(' - filename in relative or absolute path'))
5453
+
5454
+ logging.info(_(' - LAZ grid :'))
5455
+ logging.info(_(' - data_dir : directory containing the NUMPY grid'))
5456
+ logging.info(_(' - classification : classification of the laz files'))
5457
+
5458
+ logging.info(_(' - Palettes :'))
5459
+ logging.info(_(' - id'))
5460
+ logging.info(_(' - filename in relative or absolute path'))
5461
+
5462
+ logging.info(_(' - Wolf2D CPU results :'))
5463
+ logging.info(_(' - id'))
5464
+ logging.info(_(' - filename in relative or absolute path'))
5465
+
5466
+ logging.info(_(' - Wolf2D GPU results :'))
5467
+ logging.info(_(' - id'))
5468
+ logging.info(_(' - filename in relative or absolute path'))
5469
+
5470
+ logging.info(_(' - Palette-Array links :'))
5471
+ logging.info(_(' - id of the array'))
5472
+ logging.info(_(' - id of the palette'))
5473
+
5474
+ logging.info(_(' - Vector-Array links :'))
5475
+ logging.info(_(' - id of the array'))
5476
+ logging.info(_(' - id of the vector (containing only 1 zone and 1 vector)'))
5477
+
5478
+ logging.info(_(' - Cross section links :'))
5479
+ logging.info(_(' - id of the cross section'))
5480
+ logging.info(_(' - id of the vector to sort along'))
5481
+ logging.info(_(' - id of the zone to link'))
5482
+ logging.info(_(' - downfirst : True or False'))
5483
+
5484
+ logging.info('')
5485
+ logging.info(_('A tabulation is used to separate the value and the key.'))
5486
+ logging.info('')
5487
+
5488
+ logging.info(_('Exemple :'))
5489
+
5490
+ logging.info('')
5491
+
5492
+ logging.info('array:')
5493
+ logging.info('myid1\tmyfilename_array1')
5494
+ logging.info('myid2\tmy../filename_array2')
5495
+ logging.info('vector:')
5496
+ logging.info('myvec1\tmy../../filename_vecz1')
5497
+ logging.info('myvec2\tmyfilename_vecz2')
5498
+ logging.info('laz_grid:')
5499
+ logging.info('data_dir\tD:\\MODREC-Vesdre\\LAZ_Vesdre\\2023\\grids_flt32')
5500
+ logging.info('classification\tSPW-Geofit 2023')
5121
5501
 
5122
5502
  def plot_laz_around_active_vec(self):
5503
+ """ Plot laz data around active vector """
5504
+
5123
5505
  if self.active_vector is None:
5506
+ logging.warning(_('Please activate a vector'))
5124
5507
  return
5125
5508
 
5126
5509
  if self.mylazgrid is None:
5510
+ logging.warning(_('No laz grid'))
5127
5511
  return
5128
5512
 
5129
5513
  dlg = wx.NumberEntryDialog(None, _('Enter the size of the window around the active vector [cm]'), _('Window size'),_('Window size'), 500, 0, 2000)
@@ -5145,31 +5529,73 @@ class WolfMapViewer(wx.Frame):
5145
5529
  s,z = copy_vec.get_sz()
5146
5530
  notmasked = np.where(z != -99999.)
5147
5531
 
5148
- fig.plot(s,z, c='black', linewidth=2.0)
5149
-
5150
- # ax.plot(s[notmasked], z[notmasked], c='black', linewidth=2.0)
5532
+ fig.plot(s[notmasked],z[notmasked], c='black', linewidth=2.0)
5151
5533
 
5152
- # fig.show()
5153
5534
 
5154
5535
  def clip_laz_gridded(self):
5155
5536
  """ Clip laz grid on current zoom """
5156
5537
 
5157
5538
  if self.mylazgrid is None:
5539
+ logging.warning(_('No laz grid -- Please initialize it !'))
5158
5540
  return
5159
5541
 
5160
5542
  curbounds = [[self.xmin, self.xmin + self.width], [self.ymin, self.ymin + self.height]]
5161
5543
 
5162
- self.mylazdata = self.mylazgrid.scan(curbounds)
5544
+ if self.active_laz is None:
5545
+ newobj = Base_LAZ_Data()
5546
+ newobj.classification = self.mylazgrid.colors
5547
+ newobj.from_grid(self.mylazgrid, curbounds)
5548
+
5549
+ self.add_object('laz', newobj= newobj)
5550
+
5551
+ else:
5552
+ dlg = wx.MessageDialog(None, _('Do you want to keep the current data ?'), _('Keep data ?'), wx.YES_NO | wx.ICON_QUESTION)
5553
+ ret = dlg.ShowModal()
5554
+
5555
+ if ret == wx.ID_YES:
5556
+ newobj = Base_LAZ_Data()
5557
+ newobj.classification = self.mylazgrid.colors
5558
+ newobj.from_grid(self.mylazgrid, curbounds)
5559
+
5560
+ self.add_object('laz', newobj= newobj)
5561
+
5562
+ else:
5563
+
5564
+ self.active_laz.from_grid(self.mylazgrid, curbounds)
5565
+
5566
+ logging.info(_('Clip LAZ grid on current zoom'))
5567
+ logging.info(_('Bounds {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5568
+ logging.info(_('Nb points : {}').format(self.active_laz.num_points))
5569
+
5570
+ def filter_active_laz(self):
5571
+ """ Filter active laz data """
5572
+
5573
+ if self.active_laz is None:
5574
+ logging.warning(_('No laz data'))
5575
+ return
5576
+
5577
+ codes = self.active_laz.codes_unique()
5578
+
5579
+ names = [self.active_laz.classification.classification[curcode][0] for curcode in codes]
5580
+
5581
+ with wx.MultiChoiceDialog(None, _('Choose the codes to keep'), _('Codes'), names) as dlg:
5582
+ if dlg.ShowModal() == wx.ID_OK:
5583
+ used_codes = dlg.GetSelections()
5584
+ used_codes = [codes[cur] for cur in used_codes]
5585
+ self.active_laz.filter_data(used_codes)
5163
5586
 
5164
- logging.info(_('Clip LAZ grid on current zoom {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5587
+ logging.info(_('Filter done - Nb points : {}').format(self.active_laz.num_points))
5588
+ else:
5589
+ logging.info(_('Filter cancelled'))
5165
5590
 
5166
- def decimate_data(self, factor:int = 10):
5591
+ def decimate_laz_data(self, factor:int = 10):
5167
5592
  """ Decimate data """
5168
5593
 
5169
- if self.mylazdata is None:
5594
+ if self.active_laz is None:
5595
+ logging.warning(_('No laz data'))
5170
5596
  return
5171
5597
 
5172
- self.mylazdata = self.mylazdata[::factor]
5598
+ self.active_laz.decimate(factor)
5173
5599
 
5174
5600
  def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
5175
5601
  """ select some nodes from laz data
@@ -5178,6 +5604,7 @@ class WolfMapViewer(wx.Frame):
5178
5604
  :param used_codes: codes to use
5179
5605
  """
5180
5606
  if self.mylazgrid is None:
5607
+ logging.info(_('No laz grid - Aborting !'))
5181
5608
  return
5182
5609
 
5183
5610
  if array is None:
@@ -5211,19 +5638,19 @@ class WolfMapViewer(wx.Frame):
5211
5638
  curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
5212
5639
 
5213
5640
  logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5214
- self.mylazdata = self.mylazgrid.scan(curbounds)
5641
+ mylazdata = self.mylazgrid.scan(curbounds)
5215
5642
  # logging.info(_('Scan done'))
5216
5643
 
5217
5644
  data = {}
5218
5645
  for curcode in used_codes:
5219
- data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
5646
+ data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
5220
5647
 
5221
5648
  for curdata in data.values():
5222
5649
 
5223
5650
  if curdata.shape[0] == 0:
5224
5651
  continue
5225
5652
 
5226
- i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
5653
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
5227
5654
 
5228
5655
  keys = np.vstack((i,j)).T
5229
5656
 
@@ -5246,6 +5673,7 @@ class WolfMapViewer(wx.Frame):
5246
5673
  """
5247
5674
 
5248
5675
  if self.mylazgrid is None:
5676
+ logging.info(_('No laz grid - Aborting !'))
5249
5677
  return
5250
5678
 
5251
5679
  if array is None:
@@ -5309,16 +5737,16 @@ class WolfMapViewer(wx.Frame):
5309
5737
  curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
5310
5738
 
5311
5739
  logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5312
- self.mylazdata = self.mylazgrid.scan(curbounds)
5740
+ mylazdata = self.mylazgrid.scan(curbounds)
5313
5741
  # logging.info(_('Scan done'))
5314
5742
 
5315
- if len(self.mylazdata) == 0:
5743
+ if len(mylazdata) == 0:
5316
5744
  continue
5317
5745
 
5318
5746
  # Test codes
5319
5747
  data = {}
5320
5748
  for curcode in used_codes:
5321
- data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
5749
+ data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
5322
5750
 
5323
5751
  # Treat data for each code
5324
5752
  for curdata in data.values():
@@ -5329,7 +5757,7 @@ class WolfMapViewer(wx.Frame):
5329
5757
  logging.info(_('Code {} : {} points'.format(curdata[0,3], curdata.shape[0])))
5330
5758
 
5331
5759
  # get i,j from x,y
5332
- i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
5760
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
5333
5761
 
5334
5762
  # keep only valid points -- inside the array
5335
5763
  used = np.where((i >=0) & (i < array.nbx) & (j >=0) & (j < array.nby))[0]
@@ -5396,6 +5824,7 @@ class WolfMapViewer(wx.Frame):
5396
5824
  """
5397
5825
 
5398
5826
  if self.mylazgrid is None:
5827
+ logging.info(_('No laz grid - Aborting !'))
5399
5828
  return
5400
5829
 
5401
5830
  if array is None:
@@ -5431,15 +5860,15 @@ class WolfMapViewer(wx.Frame):
5431
5860
  curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
5432
5861
 
5433
5862
  logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
5434
- self.mylazdata = self.mylazgrid.scan(curbounds)
5863
+ mylazdata = self.mylazgrid.scan(curbounds)
5435
5864
 
5436
- if len(self.mylazdata) == 0:
5865
+ if len(mylazdata) == 0:
5437
5866
  continue
5438
5867
 
5439
5868
  # Test codes
5440
5869
  data = {}
5441
5870
  for curcode in used_codes:
5442
- data[curcode] = self.mylazdata[self.mylazdata[:, 3] == curcode]
5871
+ data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
5443
5872
 
5444
5873
  # Treat data for each code
5445
5874
  for curdata in data.values():
@@ -5450,7 +5879,7 @@ class WolfMapViewer(wx.Frame):
5450
5879
  logging.info(_('Code {} : {} points'.format(curdata[0,3], curdata.shape[0])))
5451
5880
 
5452
5881
  # get i,j from x,y
5453
- i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1]) #= np.float32(self.mylazdata[:, 2])
5882
+ i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
5454
5883
 
5455
5884
  # keep only valid points -- inside the array
5456
5885
  used = np.where((i >=0) & (i < array.nbx) & (j >=0) & (j < array.nby))[0]
@@ -5507,28 +5936,50 @@ class WolfMapViewer(wx.Frame):
5507
5936
 
5508
5937
  logging.info(_('Counting done'))
5509
5938
 
5510
- def init_laz_from_numpy(self, fn=None):
5511
- """ Read LAZ data stored in numpy array"""
5939
+ def init_laz_from_lazlasnpz(self, fn=None):
5940
+ """ Read LAZ data stored in one file
5941
+
5942
+ :param fn: filename (extension .laz, .las, .npz)
5943
+ """
5512
5944
 
5513
5945
  if fn is None:
5514
5946
  filternpz = "npz (*.npz)|*.npz|LAZ (*.laz)|*.laz|LAS (*.las)|*.las|all (*.*)|*.*"
5515
- dlg = wx.FileDialog(None, _('Choose LAS file'), wildcard=filternpz)
5947
+ dlg = wx.FileDialog(None, _('Choose a file containing LAS data'), wildcard=filternpz)
5516
5948
  ret = dlg.ShowModal()
5517
5949
  if ret != wx.ID_OK:
5950
+ dlg.Destroy()
5518
5951
  return
5519
5952
 
5520
5953
  fn = dlg.GetPath()
5954
+ dlg.Destroy()
5521
5955
 
5522
- self.mylazdata = read_laz(fn)
5523
- # self.mylazdata_colors = Classification_LAZ()
5524
- # self.mylazdata_colors.init_2023()
5956
+ self.mylazdata.append(Base_LAZ_Data())
5957
+ self.active_laz = self.mylazdata[-1]
5958
+ self.active_laz.from_file(fn)
5959
+
5960
+ logging.info(_('LAZ data read from file : ')+ fn)
5961
+ logging.info(_('Stored in internal variable'))
5525
5962
 
5526
5963
  if self.linked:
5527
5964
  if len(self.linkedList) > 0:
5528
5965
  for curframe in self.linkedList:
5529
- curframe.mylazdata = self.mylazdata
5966
+ if not curframe is self:
5967
+ curframe.mylazdata.append(self.active_laz)
5968
+
5969
+ def _choice_laz_classification(self):
5970
+
5971
+ dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
5972
+ ret = dlg.ShowModal()
5973
+ if ret != wx.ID_OK:
5974
+ dlg.Destroy()
5975
+ return None
5976
+
5977
+ classification = dlg.GetStringSelection()
5978
+ dlg.Destroy()
5979
+
5980
+ return classification
5530
5981
 
5531
- def init_laz_from_gridinfos(self, dirlaz:str = None):
5982
+ def init_laz_from_gridinfos(self, dirlaz:str = None, classification:Literal['SPW-Geofit 2023', 'SPW 2013-2014'] = 'SPW-Geofit 2023'):
5532
5983
 
5533
5984
  if dirlaz is None:
5534
5985
  dlg = wx.DirDialog(None, _('Choose directory where LAZ data/gridinfo are stored'))
@@ -5540,19 +5991,18 @@ class WolfMapViewer(wx.Frame):
5540
5991
 
5541
5992
  self.mylazgrid = xyz_laz_grids(dirlaz)
5542
5993
 
5543
- dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
5544
- ret = dlg.ShowModal()
5545
- if ret != wx.ID_OK:
5546
- dlg.Destroy()
5547
- return
5994
+ if classification not in ['SPW-Geofit 2023', 'SPW 2013-2014']:
5995
+
5996
+ classification = self._choice_laz_classification()
5548
5997
 
5549
- if dlg.GetStringSelection() == 'SPW 2013-2014':
5998
+ if classification is None:
5999
+ logging.warning(_('No classification chosen - Abort !'))
6000
+ return
6001
+ elif classification == 'SPW 2013-2014':
5550
6002
  self.mylazgrid.colors.init_2013()
5551
6003
  else:
5552
6004
  self.mylazgrid.colors.init_2023()
5553
6005
 
5554
- dlg.Destroy()
5555
-
5556
6006
  if self.linked:
5557
6007
  if len(self.linkedList) > 0:
5558
6008
  for curframe in self.linkedList:
@@ -5758,15 +6208,15 @@ class WolfMapViewer(wx.Frame):
5758
6208
  def _select_laz_source(self):
5759
6209
  """ Select laz source """
5760
6210
 
5761
- if self.mylazdata is None and self.mylazgrid is None:
6211
+ if self.active_laz is None and self.mylazgrid is None:
5762
6212
  logging.warning(_('No LAZ data loaded !'))
5763
6213
  return None
5764
- elif self.mylazdata is None:
6214
+ elif self.active_laz is None:
5765
6215
  laz_source = self.mylazgrid
5766
6216
  elif self.mylazgrid is None:
5767
- laz_source = self.mylazdata
6217
+ laz_source = self.active_laz
5768
6218
  else:
5769
- choices = [_('From current loaded data'), _('From GridInfos')]
6219
+ choices = [_('From active LAZ data'), _('From newly extracted data')]
5770
6220
  dlg = wx.SingleChoiceDialog(None, _("Pick a data source"), "Choices", choices)
5771
6221
  ret = dlg.ShowModal()
5772
6222
  if ret == wx.ID_CANCEL:
@@ -5778,12 +6228,32 @@ class WolfMapViewer(wx.Frame):
5778
6228
  dlg.Destroy()
5779
6229
 
5780
6230
  if idx == 0:
5781
- laz_source = self.mylazdata
6231
+ laz_source = self.active_laz
5782
6232
  else:
5783
6233
  laz_source = self.mylazgrid
5784
6234
 
5785
6235
  return laz_source
5786
6236
 
6237
+ def _choice_laz_colormap(self) -> int:
6238
+
6239
+ choices, ass_values = choices_laz_colormap()
6240
+ dlg = wx.SingleChoiceDialog(None, _("Pick a colormap"), "Choices", choices)
6241
+
6242
+ if self.active_laz is not None:
6243
+ dlg.SetSelection(self.active_laz.associated_color)
6244
+
6245
+ ret = dlg.ShowModal()
6246
+ if ret == wx.ID_CANCEL:
6247
+ dlg.Destroy()
6248
+ return
6249
+
6250
+ colormap = dlg.GetStringSelection()
6251
+ idx = choices.index(colormap)
6252
+ dlg.Destroy()
6253
+
6254
+ return ass_values[idx]
6255
+
6256
+
5787
6257
  def OnMenubar(self, event: wx.MenuEvent):
5788
6258
  """
5789
6259
  Gestion des clicks sur le menu quel que soit le niveau
@@ -5806,12 +6276,14 @@ class WolfMapViewer(wx.Frame):
5806
6276
 
5807
6277
  itemlabel = item.ItemLabel
5808
6278
 
5809
- autoscale = True
6279
+ autoscale = False
5810
6280
 
5811
6281
  if id == wx.ID_OPEN:
6282
+ autoscale = True
5812
6283
  filterProject = "proj (*.proj)|*.proj|param (*.param)|*.param|all (*.*)|*.*"
5813
6284
  file = wx.FileDialog(self, "Choose file", wildcard=filterProject)
5814
- if file.ShowModal() == wx.ID_CANCEL:
6285
+ ret = file.ShowModal()
6286
+ if ret == wx.ID_CANCEL:
5815
6287
  file.Destroy()
5816
6288
  return
5817
6289
  else:
@@ -5827,30 +6299,28 @@ class WolfMapViewer(wx.Frame):
5827
6299
  elif itemlabel == _('Shortcuts'):
5828
6300
  # show shortcuts in log
5829
6301
  self.print_shortcuts(True)
5830
- autoscale = False
6302
+
6303
+ elif itemlabel == _('Project .proj'):
6304
+ # show shortcuts in log
6305
+ self.help_project()
5831
6306
 
5832
6307
  elif itemlabel == _('Show logs/informations'):
5833
6308
  self.check_logging()
5834
- autoscale = False
5835
6309
 
5836
6310
  elif itemlabel == _('Show values'):
5837
6311
  self.check_tooltip()
5838
- autoscale = False
5839
6312
 
5840
6313
  elif itemlabel == _('About'):
5841
6314
  #print About Frame
5842
6315
  self.print_About()
5843
- autoscale = False
5844
6316
 
5845
6317
  elif itemlabel == _('Check for updates'):
5846
6318
  # check for new version
5847
6319
 
5848
6320
  self.check_for_updates()
5849
- autoscale = False
5850
6321
 
5851
6322
  elif itemlabel == _("Plot integrated Q along active vector..."):
5852
6323
  """ Integrate Q along active vector """
5853
- autoscale = False
5854
6324
 
5855
6325
  if self.active_vector is None:
5856
6326
  logging.warning(_('No active vector !'))
@@ -5868,7 +6338,6 @@ class WolfMapViewer(wx.Frame):
5868
6338
 
5869
6339
  elif itemlabel == _("Plot integrated Q along active zone..."):
5870
6340
  """ Integrate Q along active zone """
5871
- autoscale = False
5872
6341
 
5873
6342
  if self.active_zone is None:
5874
6343
  logging.warning(_('No active zone !'))
@@ -5881,7 +6350,6 @@ class WolfMapViewer(wx.Frame):
5881
6350
  self.active_res2d.plot_q(self.active_zone.myvectors, ['border'] * self.active_zone.nbvectors, toshow=True)
5882
6351
 
5883
6352
  elif itemlabel == _("Export integrated Q along active vector..."):
5884
- autoscale = False
5885
6353
 
5886
6354
  if self.active_vector is None:
5887
6355
  logging.warning(_('No active vector !'))
@@ -5936,7 +6404,6 @@ class WolfMapViewer(wx.Frame):
5936
6404
 
5937
6405
 
5938
6406
  elif itemlabel == _("Export integrated Q along all vectors in active zone..."):
5939
- autoscale = False
5940
6407
 
5941
6408
  if self.active_zone is None:
5942
6409
  logging.warning(_('No active zone !'))
@@ -5991,7 +6458,6 @@ class WolfMapViewer(wx.Frame):
5991
6458
 
5992
6459
 
5993
6460
  elif itemlabel == _("Plot stats unknown (selected nodes)..."):
5994
- autoscale = False
5995
6461
 
5996
6462
  if self.active_res2d is None:
5997
6463
  logging.warning(_('No active 2D result !'))
@@ -6025,7 +6491,6 @@ class WolfMapViewer(wx.Frame):
6025
6491
  fig.show()
6026
6492
 
6027
6493
  elif itemlabel == _("Plot stats unknown (inside active vector)..."):
6028
- autoscale = False
6029
6494
 
6030
6495
  if self.active_res2d is None:
6031
6496
  logging.warning(_('No active 2D result !'))
@@ -6055,7 +6520,6 @@ class WolfMapViewer(wx.Frame):
6055
6520
  fig, ax = self.active_res2d.plot_h(self.active_vector, unknown, toshow=True)
6056
6521
 
6057
6522
  elif itemlabel == _("Plot stats unknown (inside active zone)..."):
6058
- autoscale = False
6059
6523
 
6060
6524
  if self.active_res2d is None:
6061
6525
  logging.warning(_('No active 2D result !'))
@@ -6092,7 +6556,6 @@ class WolfMapViewer(wx.Frame):
6092
6556
 
6093
6557
  elif itemlabel == _("Plot active vector..."):
6094
6558
  """ Plot data along active vector """
6095
- autoscale = False
6096
6559
 
6097
6560
  if self.active_vector is None:
6098
6561
  logging.warning(_('No active vector !'))
@@ -6168,36 +6631,24 @@ class WolfMapViewer(wx.Frame):
6168
6631
  fig.canvas.flush_events()
6169
6632
 
6170
6633
  elif itemlabel == _("Compute and apply unique colormap on all..."):
6171
- autoscale = False
6172
-
6173
6634
  self.uniquecolormap()
6174
6635
 
6175
6636
  elif itemlabel == _("Load and apply unique colormap on all..."):
6176
- autoscale = False
6177
-
6178
6637
  self.uniquecolormap(True)
6179
6638
 
6180
6639
  elif itemlabel == _("Force uniform in parts on all..."):
6181
- autoscale = False
6182
6640
  self.uniforminparts_all(True)
6183
6641
 
6184
6642
  elif itemlabel == _("Force linear interpolation on all..."):
6185
- autoscale = False
6186
6643
  self.uniforminparts_all(False)
6187
6644
 
6188
6645
  elif itemlabel == _("Load and apply mask (nap)..."):
6189
- autoscale = False
6190
-
6191
6646
  self.loadnap_and_apply()
6192
6647
 
6193
6648
  elif itemlabel == _("Filter inundation arrays..."):
6194
- autoscale = False
6195
-
6196
6649
  self.filter_inundation()
6197
6650
 
6198
6651
  elif itemlabel == _("Plot active polygons..."):
6199
- autoscale = False
6200
-
6201
6652
  if self.active_zone is None:
6202
6653
  logging.warning(_('No active zone ! -- please select a zone containing polygons !'))
6203
6654
  return
@@ -6273,7 +6724,7 @@ class WolfMapViewer(wx.Frame):
6273
6724
  fig.show()
6274
6725
 
6275
6726
  elif itemlabel == _("Manage banks..."):
6276
- autoscale = False
6727
+
6277
6728
  if self.active_vector is None:
6278
6729
  msg = _('Active vector is None\nPlease activate the one desired')
6279
6730
  msg += _('\n')
@@ -6284,13 +6735,11 @@ class WolfMapViewer(wx.Frame):
6284
6735
  self.managebanks()
6285
6736
 
6286
6737
  elif itemlabel == _("Create banks from vertices..."):
6287
- autoscale = False
6288
6738
 
6289
6739
  self.active_cs.create_zone_from_banksbed()
6290
6740
  self.active_cs.linked_zones.showstructure()
6291
6741
 
6292
6742
  elif itemlabel == _("Link cross sections to active zones"):
6293
- autoscale = False
6294
6743
 
6295
6744
  if self.active_cs is None:
6296
6745
  msg = _('Active cross sections is None\nPlease activate the one desired')
@@ -6309,7 +6758,6 @@ class WolfMapViewer(wx.Frame):
6309
6758
  self.active_cs.link_external_zones(self.active_zones)
6310
6759
 
6311
6760
  elif itemlabel == _("Rename cross sections..."):
6312
- autoscale = False
6313
6761
 
6314
6762
  dlg = wx.TextEntryDialog(None, _('Which starting point?'))
6315
6763
  ret = dlg.ShowModal()
@@ -6325,15 +6773,12 @@ class WolfMapViewer(wx.Frame):
6325
6773
  # self.import_3dfaces()
6326
6774
 
6327
6775
  elif itemlabel == _("Interpolate on active triangulation..."):
6328
- autoscale = False
6329
6776
  self.interpolate_triangulation()
6330
6777
 
6331
6778
  elif itemlabel==_("Compare cloud to array..."):
6332
- autoscale = False
6333
6779
  self.compare_cloud2array()
6334
6780
 
6335
6781
  elif itemlabel==_("Split cloud..."):
6336
- autoscale = False
6337
6782
 
6338
6783
  if self.active_cloud is None:
6339
6784
  logging.warning(_('No active cloud !'))
@@ -6346,26 +6791,21 @@ class WolfMapViewer(wx.Frame):
6346
6791
  self.split_cloud_by_vector()
6347
6792
 
6348
6793
  elif itemlabel==_("Compare triangles to array..."):
6349
- autoscale = False
6350
6794
  self.compare_tri2array()
6351
6795
 
6352
6796
  elif itemlabel == _("Move triangles..."):
6353
- autoscale = False
6354
6797
  self.move_triangles()
6355
6798
 
6356
6799
  elif itemlabel == _("Rotate triangles..."):
6357
- autoscale = False
6358
6800
  self.rotate_triangles()
6359
6801
 
6360
6802
  elif itemlabel == _("Create contour from checked arrays..."):
6361
- autoscale = False
6362
6803
 
6363
6804
  # Create contour from checked arrays and add it to the list of objects
6364
6805
  newzones = self.create_Zones_from_arrays(self.get_list_objects(draw_type.ARRAYS, checked_state=True))
6365
6806
  self.add_object('vector', newobj=newzones, ToCheck=True, id='Contours from arrays')
6366
6807
 
6367
6808
  elif itemlabel == _("Calculator..."):
6368
- autoscale = False
6369
6809
 
6370
6810
  if self.calculator is None:
6371
6811
  self.calculator = Calculator(mapviewer = self)
@@ -6373,12 +6813,10 @@ class WolfMapViewer(wx.Frame):
6373
6813
  self.calculator.Show()
6374
6814
 
6375
6815
  elif itemlabel == _('Image digitizer...'):
6376
- autoscale = False
6377
6816
 
6378
6817
  new_digitizer = Digitizer()
6379
6818
 
6380
6819
  elif itemlabel == _("Memory views..."):
6381
- autoscale = False
6382
6820
 
6383
6821
  if self.memory_views is None:
6384
6822
  self.memory_views = Memory_Views()
@@ -6390,7 +6828,6 @@ class WolfMapViewer(wx.Frame):
6390
6828
  self._memory_views_gui.Show()
6391
6829
 
6392
6830
  elif itemlabel == _("Create bridge and export gltf..."):
6393
- autoscale = False
6394
6831
 
6395
6832
  if self.active_cs is None:
6396
6833
  msg = _('Active cross sections is None\nPlease activate the one desired')
@@ -6402,7 +6839,6 @@ class WolfMapViewer(wx.Frame):
6402
6839
  self.start_action('bridge gltf', _('Create bridge and export gltf...'))
6403
6840
 
6404
6841
  elif itemlabel == _("Export cross sections to gltf..."):
6405
- autoscale = False
6406
6842
 
6407
6843
  if self.active_cs is None:
6408
6844
  msg = _('Active cross sections is None\nPlease activate the one desired')
@@ -6432,21 +6868,20 @@ class WolfMapViewer(wx.Frame):
6432
6868
  self.active_cs.export_gltf(zmin, fn)
6433
6869
 
6434
6870
  elif itemlabel == _("New cloud Viewer..."):
6435
- autoscale = False
6871
+
6436
6872
  if self.myinterp is not None:
6437
6873
  self.myinterp.viewer_interpolator()
6438
6874
 
6439
6875
  elif itemlabel == _("Interpolate on active array..."):
6440
- autoscale = False
6876
+
6441
6877
  if self.myinterp is not None:
6442
6878
  self.interpolate_cs()
6443
6879
 
6444
6880
  elif itemlabel == _("Interpolate active cloud on active array..."):
6445
- autoscale = False
6446
6881
  self.interpolate_cloud()
6447
6882
 
6448
- elif itemlabel == _('Save project'):
6449
- autoscale = False
6883
+ elif itemlabel == _('Save project as...'):
6884
+
6450
6885
  filterProject = "proj (*.proj)|*.proj|param (*.param)|*.param|all (*.*)|*.*"
6451
6886
  file = wx.FileDialog(self, "Name your file", wildcard=filterProject, style=wx.FD_SAVE)
6452
6887
  if file.ShowModal() == wx.ID_CANCEL:
@@ -6457,23 +6892,28 @@ class WolfMapViewer(wx.Frame):
6457
6892
  filename = file.GetPath()
6458
6893
  file.Destroy()
6459
6894
 
6460
- self.save_project(filename)
6895
+ abspath = True
6896
+ dlg = wx.MessageDialog(None, _('Do you want to save the paths in absolute mode ?'), _('Relative paths'), style=wx.YES_NO)
6897
+ ret = dlg.ShowModal()
6898
+ if ret == wx.ID_NO:
6899
+ abspath = False
6900
+
6901
+ self.save_project(filename, absolute= abspath)
6461
6902
 
6462
- elif itemlabel == _('Initialize from npz'):
6463
- autoscale=False
6464
- self.init_laz_from_numpy()
6903
+ elif itemlabel == _('Initialize from laz, las or npz'):
6904
+ self.init_laz_from_lazlasnpz()
6465
6905
 
6466
- elif itemlabel == _('Initialize from GridInfos'):
6467
- autoscale=False
6906
+ elif itemlabel == _('Initialize from directory'):
6468
6907
  self.init_laz_from_gridinfos()
6469
6908
 
6470
6909
  elif itemlabel == _('Create cloud points from bridges'):
6471
- autoscale=False
6472
- if self.mylazdata is None:
6473
- self.init_laz_from_numpy()
6474
6910
 
6475
- mybridges = self.mylazdata[np.where(self.mylazdata[:, 3] == 10)]
6911
+ if self.active_laz is None:
6912
+ self.init_laz_from_lazlasnpz()
6913
+
6914
+ mybridges = self.active_laz.get_data_class(10)
6476
6915
  mycloud = cloud_vertices()
6916
+
6477
6917
  mycloud.init_from_nparray(mybridges)
6478
6918
  mycloud.myprop.style = 2
6479
6919
  mycloud.myprop.color = getIfromRGB([255, 102, 102])
@@ -6487,12 +6927,13 @@ class WolfMapViewer(wx.Frame):
6487
6927
  self.add_object('cloud', newobj=mycloud, ToCheck=True, id='Bridges')
6488
6928
 
6489
6929
  elif itemlabel == _('Create cloud points from buildings'):
6490
- autoscale=False
6491
- if self.mylazdata is None:
6492
- self.init_laz_from_numpy()
6493
6930
 
6494
- mybuildings = self.mylazdata[np.where(self.mylazdata[:, 3] == 1)]
6931
+ if self.active_laz is None:
6932
+ self.init_laz_from_lazlasnpz()
6933
+
6934
+ mybuildings = self.active_laz.get_data_class(1)
6495
6935
  mycloud = cloud_vertices()
6936
+
6496
6937
  mycloud.init_from_nparray(mybuildings)
6497
6938
  mycloud.myprop.style = 2
6498
6939
  mycloud.myprop.color = getIfromRGB([102, 102, 102])
@@ -6504,25 +6945,15 @@ class WolfMapViewer(wx.Frame):
6504
6945
  else:
6505
6946
  self.add_object('cloud', newobj=mycloud, ToCheck=True, id='Buildings')
6506
6947
 
6507
- elif itemlabel == _('Create LAZ viewer'):
6948
+ elif itemlabel == _('Create cloud points from specified classes'):
6949
+ pass
6508
6950
 
6509
- autoscale = False
6951
+ elif itemlabel == _('Create LAZ viewer'):
6510
6952
 
6511
6953
  laz_source = self._select_laz_source()
6512
6954
  if laz_source is None:
6513
6955
  return
6514
6956
 
6515
- choices, ass_values = choices_laz_colormap()
6516
- dlg = wx.SingleChoiceDialog(None, _("Pick a colormap"), "Choices", choices)
6517
- ret = dlg.ShowModal()
6518
- if ret == wx.ID_CANCEL:
6519
- dlg.Destroy()
6520
- return
6521
-
6522
- colormap = dlg.GetStringSelection()
6523
- idx = choices.index(colormap)
6524
- dlg.Destroy()
6525
-
6526
6957
  if laz_source is self.mylazgrid:
6527
6958
  if self.mylazgrid is None:
6528
6959
  logging.warning(_('No gridded LAZ data loaded !'))
@@ -6530,21 +6961,57 @@ class WolfMapViewer(wx.Frame):
6530
6961
  autoscale=False
6531
6962
  self.clip_laz_gridded()
6532
6963
 
6533
- self.myviewer = myviewer(self.mylazdata, ass_values[idx], palette_classif = self.mylazgrid.colors)
6964
+ self.active_laz.create_viewer(self._choice_laz_colormap(), self.mylazgrid.colors)
6965
+ self.myviewerslaz.append(self.active_laz.viewer)
6966
+ self.active_viewerlaz = self.myviewerslaz[-1]
6967
+
6968
+ # self.myviewer = myviewer(self.active_laz.data, ass_values[idx], palette_classif = self.mylazgrid.colors)
6534
6969
  else:
6535
- self.myviewer = myviewer(laz_source, ass_values[idx]) #, palette_classif = self.mylazdata_colors)
6970
+ self.active_laz.create_viewer(classification= self.mylazgrid.colors)
6971
+ self.myviewerslaz.append(self.active_laz.viewer)
6972
+ self.active_viewerlaz = self.myviewerslaz[-1]
6973
+
6974
+ # self.myviewer = myviewer(laz_source.data, ass_values[idx], palette_classif= laz_source.classification)
6975
+
6976
+ elif itemlabel == _('Filter data based on codes'):
6977
+
6978
+ self.filter_active_laz()
6979
+
6980
+ elif itemlabel == _('Descimate LAZ data'):
6981
+
6982
+ if self.active_laz is None:
6983
+ return
6984
+
6985
+ # Choose a decimation factor - integer
6986
+ dlg = wx.NumberEntryDialog(None, _('Your dataset contains {} points.\nWould you like to decimate?').format(self.active_laz.num_points),
6987
+ _('Decaimate factor'), _('Decimation'), 0, 0, 100)
6988
+
6989
+ ret = dlg.ShowModal()
6990
+
6991
+ if ret == wx.ID_CANCEL:
6992
+ dlg.Destroy()
6993
+ return
6994
+
6995
+ decimate_fact = dlg.GetValue()
6996
+ dlg.Destroy()
6997
+
6998
+ if decimate_fact > 0:
6999
+ self.active_laz.decimate(decimate_fact)
7000
+ logging.info(_('New count : {}').format(self.active_laz.num_points))
6536
7001
 
6537
7002
  elif itemlabel == _('Clip LAZ grid on current zoom'):
7003
+
6538
7004
  if self.mylazgrid is None:
6539
7005
  logging.warning(_('No gridded LAZ data loaded !'))
6540
7006
  return
6541
- autoscale=False
7007
+
6542
7008
  self.clip_laz_gridded()
6543
7009
 
6544
- if self.mylazdata is None:
7010
+ if self.active_laz is None:
7011
+ logging.error(_('No data found'))
6545
7012
  return
6546
7013
 
6547
- if self.mylazdata.shape[0] > 100_000_000:
7014
+ if self.active_laz.data.shape[0] > 100_000_000:
6548
7015
 
6549
7016
  # Choose a decimation factor - integer
6550
7017
  dlg = wx.NumberEntryDialog(None, _('Your data selection is very large (>100 M)\nWould you like to decimate?'),
@@ -6560,9 +7027,10 @@ class WolfMapViewer(wx.Frame):
6560
7027
  dlg.Destroy()
6561
7028
 
6562
7029
  if decimate_fact > 0:
6563
- self.decimate_data(decimate_fact)
7030
+ self.decimate_laz_data(decimate_fact)
6564
7031
 
6565
7032
  elif itemlabel == _('Fill active array from LAZ data'):
7033
+
6566
7034
  if self.mylazgrid is None:
6567
7035
  logging.warning('')
6568
7036
  return
@@ -6570,10 +7038,10 @@ class WolfMapViewer(wx.Frame):
6570
7038
  logging.warning(_('No active array -- select an array first and retry!'))
6571
7039
  return
6572
7040
 
6573
- autoscale = False
6574
7041
  self.fill_active_array_from_laz(self.active_array)
6575
7042
 
6576
7043
  elif itemlabel == _('Count LAZ data in cells'):
7044
+
6577
7045
  if self.mylazgrid is None:
6578
7046
  logging.warning('')
6579
7047
  return
@@ -6581,7 +7049,6 @@ class WolfMapViewer(wx.Frame):
6581
7049
  logging.warning(_('No active array -- select an array first and retry!'))
6582
7050
  return
6583
7051
 
6584
- autoscale = False
6585
7052
  self.count_active_array_from_laz(self.active_array)
6586
7053
 
6587
7054
  elif itemlabel == _('Select cells in array from LAZ data'):
@@ -6592,15 +7059,13 @@ class WolfMapViewer(wx.Frame):
6592
7059
  logging.warning(_('No active array -- select an array first and retry!'))
6593
7060
  return
6594
7061
 
6595
- autoscale = False
6596
7062
  self.select_active_array_from_laz(self.active_array)
6597
7063
 
6598
7064
  elif itemlabel == _('Plot LAZ around active vector'):
6599
- autoscale = False
6600
7065
  self.plot_laz_around_active_vec()
6601
7066
 
6602
7067
  elif itemlabel == _('Plot LAZ around temporary vector'):
6603
- autoscale = False
7068
+
6604
7069
  self.active_vector = vector()
6605
7070
  self.active_vector.add_vertex(wolfvertex(0.,0.))
6606
7071
  self.mimicme()
@@ -6610,11 +7075,10 @@ class WolfMapViewer(wx.Frame):
6610
7075
  elif itemlabel == _('Change colors - Classification'):
6611
7076
 
6612
7077
  if self.mylazgrid is not None:
6613
- autoscale = False
6614
7078
  self.mylazgrid.colors.interactive_update_colors()
6615
7079
 
6616
7080
  elif itemlabel == _('Multiviewer'):
6617
- autoscale = False
7081
+
6618
7082
  dlg = wx.NumberEntryDialog(self, _("Additional viewers"), _("How many?"), _("How many additional viewers?"),1, 0, 5)
6619
7083
  ret = dlg.ShowModal()
6620
7084
 
@@ -6658,8 +7122,6 @@ class WolfMapViewer(wx.Frame):
6658
7122
  self.active_viewer3d.add_array(curarray.idx, curarray._array3d)
6659
7123
  self.active_viewer3d.autoscale()
6660
7124
 
6661
- pass
6662
-
6663
7125
  elif itemlabel == _('Create/Open multiblock model'):
6664
7126
 
6665
7127
  self.create_2D_MB_model()
@@ -6678,6 +7140,8 @@ class WolfMapViewer(wx.Frame):
6678
7140
 
6679
7141
  elif itemlabel == _('Set comparison'):
6680
7142
 
7143
+ autoscale = True
7144
+
6681
7145
  # Comparaison de deux résultats ou de deux matrices
6682
7146
 
6683
7147
  self.compare_results = Compare_Arrays_Results(self, share_cmap_array= True, share_cmap_diff= True)
@@ -6694,6 +7158,7 @@ class WolfMapViewer(wx.Frame):
6694
7158
  self.compare_results.bake()
6695
7159
 
6696
7160
  elif id == wx.ID_EXIT:
7161
+
6697
7162
  dlg = wx.MessageDialog(None,_('Do you really want to quit?'), style = wx.YES_NO|wx.NO_DEFAULT)
6698
7163
  ret=dlg.ShowModal()
6699
7164
  if ret == wx.ID_YES:
@@ -6779,6 +7244,7 @@ class WolfMapViewer(wx.Frame):
6779
7244
  self.add_object(which='array_lidar_second', ToCheck=True)
6780
7245
 
6781
7246
  elif id == wx.ID_FILE5:
7247
+
6782
7248
  def addscandir(mydir):
6783
7249
  for entry in scandir(mydir):
6784
7250
  if entry.is_dir():
@@ -6801,7 +7267,7 @@ class WolfMapViewer(wx.Frame):
6801
7267
  ToCheck=True,
6802
7268
  id=join(mydir, entry.name))
6803
7269
 
6804
- elif entry.name.endswith('.bin'):
7270
+ elif entry.name.endswith(('.bin', '.tif', '.npy')):
6805
7271
  self.add_object(which='array',
6806
7272
  filename=join(mydir, entry.name),
6807
7273
  ToCheck=True,
@@ -6825,26 +7291,22 @@ class WolfMapViewer(wx.Frame):
6825
7291
  self.add_object('array', newobj=newarray)
6826
7292
 
6827
7293
  elif itemlabel == _('Create view...'):
6828
- autoscale = False
6829
7294
 
6830
7295
  # Création d'une nouvelle vue
6831
7296
  newview = WolfViews(mapviewer=self)
6832
7297
  self.add_object('views', newobj=newview)
6833
7298
 
6834
7299
  elif itemlabel==_('Create Wolf2D manager ...'):
6835
- autoscale = False
6836
7300
 
6837
7301
  from .mesh2d.config_manager import config_manager_2D
6838
7302
  newmanager = config_manager_2D(mapviewer=self)
6839
7303
 
6840
7304
  elif itemlabel==_('Create scenarios manager ...'):
6841
- autoscale = False
6842
7305
 
6843
7306
  from .scenario.config_manager import Config_Manager_2D_GPU
6844
7307
  newmanager = Config_Manager_2D_GPU(mapviewer=self, create_ui_if_wx=True)
6845
7308
 
6846
7309
  elif itemlabel == _('Create acceptability manager...'):
6847
- autoscale = False
6848
7310
 
6849
7311
  from .acceptability.acceptability_gui import AcceptabilityGui
6850
7312
  newmanager = AcceptabilityGui()
@@ -6852,7 +7314,6 @@ class WolfMapViewer(wx.Frame):
6852
7314
  newmanager.Show()
6853
7315
 
6854
7316
  elif itemlabel==_('Create BC manager Wolf2D...'):
6855
- autoscale = False
6856
7317
 
6857
7318
  if self.active_array is not None:
6858
7319
 
@@ -6885,27 +7346,26 @@ class WolfMapViewer(wx.Frame):
6885
7346
  self.active_bc = self.mybc[-1]
6886
7347
 
6887
7348
  elif itemlabel == _('Create Wolf1D...'):
6888
- autoscale = False
7349
+
6889
7350
  self.frame_create1Dfrom2D = GuiNotebook1D(mapviewer= self)
6890
7351
  logging.info(_(f'New window available - Wolf1D.'))
6891
7352
 
6892
7353
  elif id == wx.ID_FILE7:
6893
- autoscale = False
7354
+
6894
7355
  # Création de nouveaux vecteurs
6895
7356
  newzones = Zones(parent=self)
6896
7357
  self.add_object('vector', newobj=newzones)
7358
+
6897
7359
  elif id == wx.ID_FILE8:
6898
- autoscale = False
6899
7360
  # Création d'un nouveau nuage de point
6900
7361
  newcloud = cloud_vertices()
6901
7362
  self.add_object('cloud', newobj=newcloud)
7363
+
6902
7364
  elif id in self.tools.keys():
6903
7365
  # gestion des actions
6904
7366
  self.ManageActions(id)
6905
- autoscale = False
6906
7367
 
6907
7368
  elif id == wx.ID_SAVE:
6908
- autoscale = False
6909
7369
 
6910
7370
  for obj in self.iterator_over_objects(draw_type.ARRAYS):
6911
7371
  obj: WolfArray
@@ -6924,7 +7384,6 @@ class WolfMapViewer(wx.Frame):
6924
7384
  obj.saveas()
6925
7385
 
6926
7386
  elif itemlabel == 'Save to image...':
6927
- autoscale = False
6928
7387
 
6929
7388
  fn, ds = self.save_canvasogl(mpl=True)
6930
7389
 
@@ -6932,11 +7391,11 @@ class WolfMapViewer(wx.Frame):
6932
7391
  self.assembly_images(all_images, mode= self.assembly_mode)
6933
7392
 
6934
7393
  elif itemlabel == _('Copy image...'):
6935
- autoscale = False
7394
+
6936
7395
  self.copy_canvasogl()
6937
7396
 
6938
7397
  elif itemlabel == _('Export...'):
6939
- autoscale = False
7398
+
6940
7399
  curarray: WolfArray
6941
7400
  curvec: vector
6942
7401
 
@@ -6984,7 +7443,7 @@ class WolfMapViewer(wx.Frame):
6984
7443
  del wait
6985
7444
 
6986
7445
  elif itemlabel == _('Import...'):
6987
- autoscale = False
7446
+
6988
7447
  curarray: WolfArray
6989
7448
 
6990
7449
  msg = ''
@@ -7038,7 +7497,7 @@ class WolfMapViewer(wx.Frame):
7038
7497
  del wait
7039
7498
 
7040
7499
  elif itemlabel == _('Compare...'):
7041
- autoscale = False
7500
+
7042
7501
  msg = ''
7043
7502
  if self.active_array is None:
7044
7503
  msg += _('Active array is None\n')
@@ -7055,7 +7514,6 @@ class WolfMapViewer(wx.Frame):
7055
7514
  self.update_blender_sculpting()
7056
7515
 
7057
7516
  elif itemlabel == _('Update...'):
7058
- autoscale = False
7059
7517
 
7060
7518
  msg = ''
7061
7519
  if self.active_array is None:
@@ -7071,7 +7529,7 @@ class WolfMapViewer(wx.Frame):
7071
7529
  self.update_blender_sculpting()
7072
7530
 
7073
7531
  elif id == wx.ID_SAVEAS:
7074
- autoscale = False
7532
+
7075
7533
  for obj in self.iterator_over_objects(draw_type.ARRAYS):
7076
7534
  obj: WolfArray
7077
7535
 
@@ -7095,11 +7553,6 @@ class WolfMapViewer(wx.Frame):
7095
7553
  if ret == wx.ID_OK:
7096
7554
  obj.saveas(fdlg.GetPath())
7097
7555
 
7098
- # elif id == ID_RUN_SIMULATION:
7099
- # from ..debug.test_glsim.wolf_gpu import load_sim_to_gpu
7100
- # print("Simulation")
7101
- # load_sim_to_gpu()
7102
-
7103
7556
  if len(self.myarrays) + len(self.myvectors) + len(self.myclouds) + len(self.mytri) + len(self.myres2D) + len(self.mytiles) + len(self.myimagestiles) + len(self.mypartsystems) == 2 and autoscale:
7104
7557
  # Trouve les bornzs si un seul élément est présent, sinon on conserve l'état du zoom
7105
7558
  self.Autoscale()
@@ -7667,7 +8120,7 @@ class WolfMapViewer(wx.Frame):
7667
8120
  'weirs',
7668
8121
  'vector',
7669
8122
  'tiles', 'tilescomp'
7670
- 'cloud',
8123
+ 'cloud', 'laz',
7671
8124
  'triangulation',
7672
8125
  'cross_sections',
7673
8126
  'other',
@@ -7687,12 +8140,13 @@ class WolfMapViewer(wx.Frame):
7687
8140
  Add object to current Frame/Drawing area
7688
8141
  """
7689
8142
 
7690
- filterArray = "All supported formats|*.bin;*.tif;*.tiff;*.top;*.flt;*.npy;*.npz|bin (*.bin)|*.bin|Elevation WOLF2D (*.top)|*.top|Geotif (*.tif)|*.tif|Float ESRI (*.flt)|*.flt|Numpy (*.npy)|*.npy|Numpy named arrays(*.npz)|*.npz|all (*.*)|*.*"
8143
+ filterArray = "All supported formats|*.bin;*.tif;*.tiff;*.top;*.flt;*.npy;*.npz;*.vrt|bin (*.bin)|*.bin|Elevation WOLF2D (*.top)|*.top|Geotif (*.tif)|*.tif|Float ESRI (*.flt)|*.flt|Numpy (*.npy)|*.npy|Numpy named arrays(*.npz)|*.npz|all (*.*)|*.*"
7691
8144
  filterjson = "json (*.json)|*.json|all (*.*)|*.*"
7692
8145
  filterall = "all (*.*)|*.*"
7693
8146
  filterres2d = "all (*.*)|*.*"
7694
8147
  filterVector = "All supported formats|*.vec;*.vecz;*.dxf;*.shp|vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|dxf (*.dxf)|*.dxf|shp (*.shp)|*.shp|all (*.*)|*.*"
7695
8148
  filterCloud = "xyz (*.xyz)|*.xyz|dxf (*.dxf)|*.dxf|text (*.txt)|*.txt|shp (*.shp)|*.shp|all (*.*)|*.*"
8149
+ filterlaz = "laz (*.laz)|*.laz|las (*.las)|*.las|Numpy (*.npz)|*.npz|all (*.*)|*.*"
7696
8150
  filtertri = "tri (*.tri)|*.tri|text (*.txt)|*.txt|dxf (*.dxf)|*.dxf|gltf (*.gltf)|*.gltf|gltf binary (*.glb)|*.glb|*.*'all (*.*)|*.*"
7697
8151
  filterCs = "vecz WOLF (*.vecz)|*.vecz|txt 2022 (*.txt)|*.txt|WOLF (*.sxy)|*.sxy|text 2000 (*.txt)|*.txt|all (*.*)|*.*"
7698
8152
  filterimage = "Geotif (*.tif)|*.tif|all (*.*)|*.*"
@@ -7719,6 +8173,8 @@ class WolfMapViewer(wx.Frame):
7719
8173
  file = wx.FileDialog(self, "Choose file", wildcard=filterVector)
7720
8174
  elif which.lower() == 'cloud':
7721
8175
  file = wx.FileDialog(self, "Choose file", wildcard=filterCloud)
8176
+ elif which.lower() == 'laz':
8177
+ file = wx.FileDialog(self, "Choose file", wildcard=filterlaz)
7722
8178
  elif which.lower() == 'triangulation':
7723
8179
  file = wx.FileDialog(self, "Choose file", wildcard=filtertri)
7724
8180
  elif which.lower() == 'cross_sections':
@@ -8219,6 +8675,19 @@ class WolfMapViewer(wx.Frame):
8219
8675
  self.myvectors.append(newobj)
8220
8676
  newobj.mapviewer = self
8221
8677
 
8678
+ elif which.lower() =='laz':
8679
+ curdict = self.mylazdata
8680
+ curtree = self.myitemslaz
8681
+
8682
+ if newobj is None:
8683
+ newobj = Base_LAZ_Data(mapviewer=self)
8684
+ newobj.from_file(filename)
8685
+
8686
+ self.mylazdata.append(newobj)
8687
+ self.active_laz = newobj
8688
+
8689
+ newobj.set_mapviewer(self)
8690
+
8222
8691
  elif which.lower() == 'cloud':
8223
8692
 
8224
8693
  curdict = self.myclouds
@@ -8460,6 +8929,8 @@ class WolfMapViewer(wx.Frame):
8460
8929
  return self.mywmsfore
8461
8930
  elif drawing_type == draw_type.IMAGESTILES:
8462
8931
  return self.myimagestiles
8932
+ elif drawing_type == draw_type.LAZ:
8933
+ return self.mylazdata
8463
8934
  else:
8464
8935
  logging.error('Unknown drawing type : ' + drawing_type)
8465
8936
  return None
@@ -8893,7 +9364,7 @@ class WolfMapViewer(wx.Frame):
8893
9364
  elif text == _('Properties'):
8894
9365
 
8895
9366
  myobj = self.selected_object
8896
- if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir]:
9367
+ if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir, Base_LAZ_Data]:
8897
9368
  myobj.show_properties()
8898
9369
 
8899
9370
  elif isinstance(myobj, cloud_vertices):
@@ -9041,6 +9512,92 @@ class WolfMapViewer(wx.Frame):
9041
9512
  self.selected_object.export_active_zone_to_shapefile(fdlg.GetPath())
9042
9513
  fdlg.Destroy()
9043
9514
 
9515
+ elif _('Set colormap') in text:
9516
+
9517
+ if isinstance(self.selected_object, Base_LAZ_Data):
9518
+ self.selected_object.associated_color = self._choice_laz_colormap()
9519
+
9520
+ elif _('Edit colormap') in text:
9521
+
9522
+ if isinstance(self.selected_object, Base_LAZ_Data):
9523
+ self.selected_object.interactive_update_colors()
9524
+
9525
+ elif _('Set classification') in text:
9526
+
9527
+ if isinstance(self.selected_object, Base_LAZ_Data):
9528
+ self.selected_object.set_classification(self._choice_laz_classification())
9529
+
9530
+ elif _('All to cloud') in text:
9531
+
9532
+ if isinstance(self.selected_object, Base_LAZ_Data):
9533
+
9534
+ if self.selected_object.num_points > 100000:
9535
+ dlg = wx.MessageDialog(None, _('The number of points is high, it could take some time to convert to cloud.\nDo you want to continue ?'), _('Warning'), wx.YES_NO | wx.NO_DEFAULT)
9536
+ ret = dlg.ShowModal()
9537
+
9538
+ if ret != wx.ID_YES:
9539
+ dlg.Destroy()
9540
+
9541
+ return
9542
+
9543
+ newcloud = cloud_vertices()
9544
+ newcloud.init_from_nparray(self.selected_object.xyz)
9545
+ self.add_object('cloud', newobj=newcloud, id=self.selected_object.idx + '_cloud')
9546
+
9547
+ elif _('Selection to cloud') in text:
9548
+
9549
+ if isinstance(self.selected_object, Base_LAZ_Data):
9550
+
9551
+ xyz = self.selected_object.xyz_selected
9552
+ if xyz.shape[0] ==0:
9553
+ logging.warning('No points selected')
9554
+ return
9555
+
9556
+ if xyz.shape[0] > 100000:
9557
+ dlg = wx.MessageDialog(None, _('The number of points is high, it could take some time to convert to cloud.\nDo you want to continue ?'), _('Warning'), wx.YES_NO | wx.NO_DEFAULT)
9558
+ ret = dlg.ShowModal()
9559
+
9560
+ if ret != wx.ID_YES:
9561
+ dlg.Destroy()
9562
+
9563
+ return
9564
+
9565
+ newcloud = cloud_vertices()
9566
+ newcloud.init_from_nparray(xyz)
9567
+ self.add_object('cloud', newobj=newcloud, id=self.selected_object.idx + '_cloud_sel')
9568
+
9569
+ elif _('Play') in text:
9570
+
9571
+ if isinstance(self.selected_object, Base_LAZ_Data):
9572
+ self.selected_object.play_flight()
9573
+
9574
+ elif _('Record') in text:
9575
+
9576
+ if isinstance(self.selected_object, Base_LAZ_Data):
9577
+
9578
+ dlg = wx.DirDialog(self, _('Choose a directory to save the video'), style=wx.DD_DEFAULT_STYLE)
9579
+ if dlg.ShowModal() == wx.ID_OK:
9580
+ self.selected_object.record_flight(dlg.GetPath())
9581
+
9582
+ dlg.Destroy()
9583
+
9584
+ elif _('Load flight') in text:
9585
+
9586
+ if isinstance(self.selected_object, Base_LAZ_Data):
9587
+ dlg = wx.FileDialog(self, _('Choose a file to load the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_OPEN)
9588
+ if dlg.ShowModal() == wx.ID_OK:
9589
+ self.selected_object.load_flight(dlg.GetPath())
9590
+
9591
+ dlg.Destroy()
9592
+
9593
+ elif _('Save flight') in text:
9594
+
9595
+ if isinstance(self.selected_object, Base_LAZ_Data):
9596
+ dlg = wx.FileDialog(self, _('Choose a file to save the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_SAVE)
9597
+ if dlg.ShowModal() == wx.ID_OK:
9598
+ self.selected_object.save_flight(dlg.GetPath())
9599
+
9600
+ dlg.Destroy()
9044
9601
 
9045
9602
  def OnClose(self, event):
9046
9603
  """ Close the application """
@@ -9827,6 +10384,13 @@ class WolfMapViewer(wx.Frame):
9827
10384
  if ctrl:
9828
10385
  myobj.show_properties()
9829
10386
 
10387
+ elif type(myobj) == Base_LAZ_Data:
10388
+
10389
+ self.active_laz = myobj
10390
+
10391
+ if ctrl:
10392
+ myobj.show_properties()
10393
+
9830
10394
  elif type(myobj) == Bridge:
9831
10395
  self.active_bridge = myobj
9832
10396
 
@@ -11501,6 +12065,10 @@ class WolfMapViewer(wx.Frame):
11501
12065
  self.mousex = self.mousex + self.width / 10.
11502
12066
  self.setbounds()
11503
12067
 
12068
+ elif key == ord('A'):
12069
+ if self.active_laz is not None:
12070
+ self.active_laz.add_pose_in_memory()
12071
+
11504
12072
  def paste_values(self,fromarray:WolfArray):
11505
12073
  """ Paste selected values from a WolfArray to the active array """
11506
12074
 
@@ -11551,6 +12119,19 @@ class WolfMapViewer(wx.Frame):
11551
12119
  tracks.append(_('Export active zone to Shape file'))
11552
12120
  tracks.append(_('Rebin'))
11553
12121
  tracks.append(_('Set NullValue'))
12122
+ tracks.append(_('Set colormap'))
12123
+ tracks.append(_('Edit colormap'))
12124
+ tracks.append(_('Set classification'))
12125
+ tracks.append(_('Convert to...'))
12126
+ tracks.append(_('All to cloud'))
12127
+ tracks.append(_('Selection to cloud'))
12128
+
12129
+ tracks.append(_('Colormap'))
12130
+ tracks.append(_('Movie'))
12131
+ tracks.append(_('Play'))
12132
+ tracks.append(_('Record'))
12133
+ tracks.append(_('Load flight'))
12134
+ tracks.append(_('Save flight'))
11554
12135
 
11555
12136
  # Récupération des items du menu contextuel
11556
12137
  menuitems = self.popupmenu.GetMenuItems()
@@ -11593,6 +12174,29 @@ class WolfMapViewer(wx.Frame):
11593
12174
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
11594
12175
  self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
11595
12176
 
12177
+ if isinstance(self.selected_object, Base_LAZ_Data):
12178
+
12179
+ colrmapmenu = wx.Menu()
12180
+ self.popupmenu.AppendSubMenu(colrmapmenu, _('Colormap'))
12181
+
12182
+ colrmapmenu.Append(wx.ID_ANY, _('Set colormap'), _('Change colormap'))
12183
+ colrmapmenu.Append(wx.ID_ANY, _('Edit colormap'), _('Edit colormap'))
12184
+ colrmapmenu.Append(wx.ID_ANY, _('Set classification'), _('Change classification'))
12185
+
12186
+ converttomenu = wx.Menu()
12187
+ self.popupmenu.AppendSubMenu(converttomenu, _('Convert to...'))
12188
+
12189
+ converttomenu.Append(wx.ID_ANY, _('All to cloud'), _('Convert all to cloud'))
12190
+ converttomenu.Append(wx.ID_ANY, _('Selection to cloud'), _('Convert selection to cloud'))
12191
+
12192
+ moviemenu = wx.Menu()
12193
+ self.popupmenu.AppendSubMenu(moviemenu, _('Movie'))
12194
+
12195
+ moviemenu.Append(wx.ID_ANY, _('Play'), _('Play'))
12196
+ moviemenu.Append(wx.ID_ANY, _('Record'), _('Record'))
12197
+ moviemenu.Append(wx.ID_ANY, _('Load flight'), _('Load flight'))
12198
+ moviemenu.Append(wx.ID_ANY, _('Save flight'), _('Save flight'))
12199
+
11596
12200
  self.treelist.PopupMenu(self.popupmenu)
11597
12201
 
11598
12202
  def update(self):