wolfhece 2.1.118__py3-none-any.whl → 2.1.120__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
@@ -25,9 +25,11 @@ try:
25
25
  import glob
26
26
  import traceback
27
27
  from datetime import datetime, timedelta
28
+ from sklearn import linear_model, datasets
29
+
28
30
  except ImportError as e:
29
31
  print(e)
30
- raise ImportError("Error importing wxPython, numpy, PIL, json, glob, traceback. Please check your installation.")
32
+ raise ImportError("Error importing wxPython, numpy, PIL, json, glob, traceback, sklearn. Please check your installation.")
31
33
 
32
34
  try:
33
35
  from osgeo import gdal
@@ -73,7 +75,7 @@ try:
73
75
  from .xyz_file import xyz_scandir, XYZFile
74
76
  from .mesh2d import wolf2dprev
75
77
  from .PyPalette import wolfpalette
76
- from .wolfresults_2D import Wolfresults_2D, views_2D
78
+ from .wolfresults_2D import Wolfresults_2D, views_2D, Extractable_results
77
79
  from .PyTranslate import _
78
80
  from .PyVertex import cloud_vertices, getIfromRGB
79
81
  from .RatingCurve import SPWMIGaugingStations, SPWDCENNGaugingStations
@@ -84,7 +86,7 @@ try:
84
86
  from .Results2DGPU import wolfres2DGPU
85
87
  from .PyCrosssections import crosssections, profile, Interpolator, Interpolators
86
88
  from .GraphNotebook import PlotNotebook
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
89
+ from .lazviewer.laz_viewer import myviewer, read_laz, clip_data_xyz, xyz_laz_grids, choices_laz_colormap, Classification_LAZ, Wolf_LAZ_Data, viewer as viewerlaz
88
90
  from . import Lidar2002
89
91
  from .picc import Picc_data, Cadaster_data
90
92
  from .wolf_zi_db import ZI_Databse_Elt, PlansTerrier
@@ -112,6 +114,7 @@ try:
112
114
  from .lagrangian.particle_system_ui import Particle_system_to_draw as Particle_system
113
115
  from .opengl.py3d import Wolf_Viewer3D
114
116
  from .pyGui1D import GuiNotebook1D
117
+ from .matplotlib_fig import Matplotlib_Figure as MplFig, PRESET_LAYOUTS
115
118
  except ImportError as e:
116
119
  print(e)
117
120
  raise ImportError("Error importing pyshields, pyviews, PyConfig, GraphProfile, pybridges, tools_mpl, wolf_tiles, lagrangian.particle_system_ui, opengl.py3d, pyGui1D. Please check your installation.")
@@ -167,6 +170,48 @@ PROJECT_GROUP_KEYS = {PROJECT_ACTION : {'which': 'compare_arrays'},
167
170
  PROJECT_LINK_VEC_ARRAY : {'id - id vector': 'id of array/wolf2d/gpu2d - id of vector to link (only 1 vector in 1 zone)'},
168
171
  }
169
172
 
173
+ class MplFigViewer(MplFig):
174
+
175
+ def __init__(self, layout = None, idx:str='',
176
+ mapviewer:"WolfMapViewer" = None,
177
+ caption:str = '', size:tuple = (800, 600),
178
+ style:int = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER):
179
+
180
+ super().__init__(layout)
181
+ self._mapviewer = mapviewer
182
+ self._idx = idx
183
+
184
+ self.SetTitle(caption)
185
+
186
+ self.SetSize(size)
187
+
188
+ dpi = self.fig.get_dpi()
189
+ size_x = (size[0]-16)/dpi
190
+ size_y = (size[1]-240)/dpi
191
+
192
+ self.fig.set_size_inches(size_x, size_y)
193
+
194
+
195
+ self.SetWindowStyle(style)
196
+
197
+ self.Bind(wx.EVT_CLOSE, self.OnClose)
198
+
199
+ def OnClose(self, event):
200
+ """ Close the window """
201
+
202
+ if self.mapviewer is not None:
203
+ self.mapviewer.destroy_fig_by_id(self.idx)
204
+ else:
205
+ self.Destroy()
206
+
207
+ @property
208
+ def mapviewer(self):
209
+ return self._mapviewer
210
+
211
+ @property
212
+ def idx(self):
213
+ return self._idx
214
+
170
215
  class Memory_View():
171
216
  """ Memory view """
172
217
 
@@ -1151,6 +1196,166 @@ class Sim_Explorer(wx.Frame):
1151
1196
  self._step_time.Set(['{:.3f} - {}'.format(i, datetime.strftime(self._starting_date + timedelta(seconds=i), '%Y-%m-%d %H:%M:%S')) for i in self._all_times_steps[0]])
1152
1197
  self._step_num.Set([str(i) for i in self._all_times_steps[1]])
1153
1198
 
1199
+
1200
+ class Select_Begin_end_interval_step(wx.Dialog):
1201
+ """ wx.frame to select the begin and end of the interval to extract """
1202
+
1203
+ def __init__(self, parent, title, sim:Wolfresults_2D, checkbox:bool = False):
1204
+
1205
+ super(Select_Begin_end_interval_step, self).__init__(parent, title=title, size=(500, 350), style = wx.DEFAULT_FRAME_STYLE & ~ (wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX))
1206
+
1207
+ # ajout d'un slider pour choisir le début et la fin de l'intervalle -> selrange
1208
+ # ajout d'un slider pour choisir le pas de l'intervalle
1209
+
1210
+
1211
+ # + les mêmes informations mais sous forme de TextCtrl
1212
+
1213
+ # ajout d'un bouton pour valider
1214
+ # ajout d'un bouton pour annuler
1215
+
1216
+ self._panel = wx.Panel(self)
1217
+
1218
+ sizer = wx.BoxSizer(wx.VERTICAL)
1219
+
1220
+ self.begin = 1
1221
+ self.end = sim.get_nbresults(True)
1222
+ self.step = 1
1223
+ self.check_all = True
1224
+ self.check_violin = False
1225
+
1226
+ self._slider_begin = wx.Slider(self._panel, minValue=self.begin, maxValue=self.end, style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_MIN_MAX_LABELS | wx.SL_LABELS)
1227
+ self._slider_begin.SetToolTip(_('Select the first result to export'))
1228
+ self._slider_begin.SetValue(self.begin)
1229
+
1230
+ self._slider_begin.Bind(wx.EVT_SLIDER, self.OnSliderBegin)
1231
+ sizer.Add(self._slider_begin, 1, wx.EXPAND | wx.ALL, 2)
1232
+
1233
+ self._slider_end = wx.Slider(self._panel, minValue=self.begin, maxValue=self.end, style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_MIN_MAX_LABELS | wx.SL_LABELS)
1234
+ self._slider_end.SetToolTip(_('Select the last result to export - If step is > 1, this value will be forced if not already captured'))
1235
+ self._slider_end.SetValue(self.end)
1236
+ self._slider_end.Bind(wx.EVT_SLIDER, self.OnSliderEnd)
1237
+
1238
+ sizer.Add(self._slider_end, 1, wx.EXPAND | wx.ALL, 2)
1239
+
1240
+ sizer_txt1 = wx.BoxSizer(wx.HORIZONTAL)
1241
+ self._label_range = wx.StaticText(self._panel, label=_('Range'))
1242
+ self._text_range = wx.TextCtrl(self._panel, value='1 - {}'.format(sim.get_nbresults(True)))
1243
+
1244
+ sizer_txt1.Add(self._label_range, 0, wx.EXPAND | wx.ALL, 2)
1245
+ sizer_txt1.Add(self._text_range, 1, wx.EXPAND | wx.ALL, 2)
1246
+
1247
+ sizer.Add(sizer_txt1, 0, wx.EXPAND | wx.ALL, 2)
1248
+
1249
+ self._slider_step = wx.Slider(self._panel, minValue=1, maxValue=sim.get_nbresults(True), style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_MIN_MAX_LABELS | wx.SL_LABELS)
1250
+ self._slider_step.SetToolTip(_('Export one result every N steps'))
1251
+ self._slider_step.Bind(wx.EVT_SLIDER, self.OnSliderStep)
1252
+ sizer.Add(self._slider_step, 1, wx.EXPAND | wx.ALL, 2)
1253
+
1254
+ sizer_txt2 = wx.BoxSizer(wx.HORIZONTAL)
1255
+ self._label_step = wx.StaticText(self._panel, label=_('Step'))
1256
+ self._text_step = wx.TextCtrl(self._panel, value='1')
1257
+
1258
+ sizer_txt2.Add(self._label_step, 0, wx.EXPAND | wx.ALL, 2)
1259
+ sizer_txt2.Add(self._text_step, 0, wx.EXPAND | wx.ALL, 2)
1260
+
1261
+ sizer.Add(sizer_txt2, 0, wx.EXPAND | wx.ALL, 2)
1262
+
1263
+ sizer_but = wx.BoxSizer(wx.HORIZONTAL)
1264
+ self._cmd_apply = wx.Button(self._panel, wx.ID_APPLY, _('Apply'))
1265
+ self._cmd_apply.Bind(wx.EVT_BUTTON, self.OnApply)
1266
+
1267
+ self._cmd_ok = wx.Button(self._panel, wx.ID_OK, _('OK'))
1268
+ self._cmd_ok.Bind(wx.EVT_BUTTON, self.OnOK)
1269
+
1270
+ self._cmd_cancel = wx.Button(self._panel, wx.ID_CANCEL, _('Cancel'))
1271
+ self._cmd_cancel.Bind(wx.EVT_BUTTON, self.OnCancel)
1272
+
1273
+ sizer_but.Add(self._cmd_apply, 1, wx.EXPAND | wx.ALL, 2)
1274
+ sizer_but.Add(self._cmd_ok, 1, wx.EXPAND | wx.ALL, 2)
1275
+ sizer_but.Add(self._cmd_cancel, 1, wx.EXPAND | wx.ALL, 2)
1276
+
1277
+ sizer.Add(sizer_but, 1, wx.EXPAND | wx.ALL, 2)
1278
+
1279
+ if checkbox:
1280
+ sizer_check = wx.BoxSizer(wx.HORIZONTAL)
1281
+ self._check_all = wx.CheckBox(self._panel, label=_('Statistics and values'), style=wx.CHK_2STATE)
1282
+ self._check_all.SetToolTip(_('If checked, export statistics and all values for each step'))
1283
+ self._check_all.SetValue(True)
1284
+ self._check_all.Bind(wx.EVT_CHECKBOX, self.OnCheckAll)
1285
+ sizer_check.Add(self._check_all, 1, wx.EXPAND | wx.ALL, 2)
1286
+ sizer.Add(sizer_check, 1, wx.EXPAND | wx.ALL, 2)
1287
+
1288
+ self._check_violin= wx.CheckBox(self._panel, label=_('Violin plot (experimental)'), style=wx.CHK_2STATE)
1289
+ self._check_violin.SetToolTip(_('If checked, create a violin plot for each step'))
1290
+ self._check_violin.SetValue(False)
1291
+ self._check_violin.Bind(wx.EVT_CHECKBOX, self.OnCheckViolin)
1292
+ sizer_check.Add(self._check_violin, 1, wx.EXPAND | wx.ALL, 2)
1293
+
1294
+ self._panel.SetSizer(sizer)
1295
+
1296
+ self.CenterOnScreen()
1297
+
1298
+ self.SetIcon(wx.Icon(str(Path(__file__).parent / "apps/wolf_logo2.bmp")))
1299
+
1300
+ self.Show()
1301
+
1302
+
1303
+ def OnCheckAll(self, event):
1304
+ self.check_all = self._check_all.IsChecked()
1305
+
1306
+ def OnCheckViolin(self, event):
1307
+ self.check_violin = self._check_violin.IsChecked()
1308
+
1309
+ def OnSliderBegin(self, event):
1310
+
1311
+ self.begin = min(self._slider_begin.GetValue(), self.end)
1312
+ self._slider_begin.SetValue(self.begin)
1313
+ self._text_range.SetValue('{} - {}'.format(self.begin, self.end))
1314
+
1315
+ def OnSliderEnd(self, event):
1316
+
1317
+ self.end = max(self._slider_end.GetValue(), self.begin)
1318
+ self._slider_end.SetValue(self.end)
1319
+ self._text_range.SetValue('{} - {}'.format(self.begin, self.end))
1320
+
1321
+ def OnSliderStep(self, event):
1322
+
1323
+ self.step = self._slider_step.GetValue()
1324
+ self._text_step.SetValue(str(self.step))
1325
+
1326
+ def OnApply(self, event):
1327
+
1328
+ try:
1329
+ txt_begin, txt_end = self._text_range.GetValue().split('-')
1330
+ except:
1331
+ self._text_range.SetValue('{} - {}'.format(self.begin, self.end))
1332
+
1333
+ txt_step = self._text_step.GetValue()
1334
+
1335
+ try:
1336
+ if self.step != int(txt_step):
1337
+ self._slider_step.SetValue(int(txt_step))
1338
+ except:
1339
+ logging.error('Error while parsing the step')
1340
+ return
1341
+
1342
+ try:
1343
+ if int(txt_begin) != self.begin or int(txt_end) != self.end:
1344
+ self._slider_begin.SetRange(int(txt_begin), int(txt_end))
1345
+ except:
1346
+ logging.error('Error while parsing the range')
1347
+ return
1348
+
1349
+ def OnOK(self, event):
1350
+ self.Hide()
1351
+
1352
+ def OnCancel(self, event):
1353
+ self.begin = -1
1354
+ self.end = -1
1355
+ self.step = -1
1356
+
1357
+ self.Hide()
1358
+
1154
1359
  class WolfMapViewer(wx.Frame):
1155
1360
  """
1156
1361
  Fenêtre de visualisation de données WOLF grâce aux WxWidgets
@@ -1172,7 +1377,9 @@ class WolfMapViewer(wx.Frame):
1172
1377
  myimagestiles: list[ImagesTiles]
1173
1378
  mypartsystems: list[Particle_system]
1174
1379
  myviewers3d:list[Wolf_Viewer3D]
1175
- mylazdata:list[Base_LAZ_Data]
1380
+ mylazdata:list[Wolf_LAZ_Data]
1381
+
1382
+ mymplfigs:list[MplFigViewer]
1176
1383
 
1177
1384
  sim_explorers: dict[Wolfresults_2D:Sim_Explorer]
1178
1385
 
@@ -1204,7 +1411,9 @@ class WolfMapViewer(wx.Frame):
1204
1411
  active_bridge: Bridge
1205
1412
  active_weirs : Weirs
1206
1413
  active_weir : Weir
1207
- active_laz : Base_LAZ_Data
1414
+ active_laz : Wolf_LAZ_Data
1415
+
1416
+ active_fig: MplFigViewer
1208
1417
 
1209
1418
  def __init__(self,
1210
1419
  wxparent = None,
@@ -1471,34 +1680,44 @@ class WolfMapViewer(wx.Frame):
1471
1680
  _("Linear colormap"))
1472
1681
 
1473
1682
  self.analyzemenu = wx.Menu()
1474
- plotvect = self.analyzemenu.Append(wx.ID_ANY, _("Plot active vector..."),
1683
+
1684
+ self.analyzeplot = wx.Menu()
1685
+ self.analyzeexport = wx.Menu()
1686
+
1687
+ plotvect = self.analyzeplot.Append(wx.ID_ANY, _("Plot active vector..."),
1475
1688
  _("Plot the active vector and linked arrays"))
1476
- plotpoly = self.analyzemenu.Append(wx.ID_ANY, _("Plot active polygons..."),
1689
+ plotpoly = self.analyzeplot.Append(wx.ID_ANY, _("Plot active polygons..."),
1477
1690
  _("Plot the active polygons and linked arrays"))
1478
1691
 
1479
- masksimul = self.analyzemenu.Append(wx.ID_ANY, _("Load and apply mask (nap)..."),
1480
- _("Apply mask from sim2D"))
1481
- filterinund = self.analyzemenu.Append(wx.ID_ANY, _("Filter inundation arrays..."),
1482
- _("Filter arrays"))
1692
+ self.analyzeplot.AppendSeparator()
1693
+
1694
+ self.analyzemenu.Append(wx.ID_ANY,_('Plot...'),self.analyzeplot)
1695
+ self.analyzemenu.Append(wx.ID_ANY,_('Export...'),self.analyzeexport)
1696
+ self.analyzemenu.AppendSeparator()
1697
+
1698
+ masksimul = self.analyzemenu.Append(wx.ID_ANY, _("Load and apply mask (nap)..."), _("Apply mask from sim2D"))
1699
+ filterinund = self.analyzemenu.Append(wx.ID_ANY, _("Filter inundation arrays..."), _("Filter arrays"))
1700
+
1483
1701
  # Plot hydrographs
1484
- self.menuHydrographs = wx.Menu()
1485
- self.analyzemenu.Append(wx.ID_ANY,_('Integrate Q...'),self.menuHydrographs)
1486
- plotqvect = self.menuHydrographs.Append(wx.ID_ANY, _("Plot integrated Q along active vector..."),
1487
- _("Integrate Q along the active vector and plot"))
1488
- plotqvect = self.menuHydrographs.Append(wx.ID_ANY, _("Plot integrated Q along active zone..."),
1489
- _("Integrate Q along the active zone and plot"))
1490
- self.menuHydrographs.AppendSeparator()
1491
- exportqvect = self.menuHydrographs.Append(wx.ID_ANY, _("Export integrated Q along active vector..."),
1492
- _("Integrate Q along the active vector and export"))
1493
- exportqvect = self.menuHydrographs.Append(wx.ID_ANY, _("Export integrated Q along all vectors in active zone..."),
1494
- _("Integrate Q along ALL VECTORS of the active zone and export"))
1495
-
1496
- plothselect = self.analyzemenu.Append(wx.ID_ANY, _("Plot stats unknown (selected nodes)..."),
1497
- _("Compute stats and plot on the selected nodes"))
1498
- plothvector = self.analyzemenu.Append(wx.ID_ANY, _("Plot stats unknown (inside active vector)..."),
1499
- _("Compute stats and plot on nodes inside the active vector"))
1500
- plothzone = self.analyzemenu.Append(wx.ID_ANY, _("Plot stats unknown (inside active zone)..."),
1501
- _("Compute stats and plot on nodes inside the active zone"))
1702
+
1703
+ plotqvect = self.analyzeplot.Append(wx.ID_ANY, _("Plot integrated Q along active vector..."), _("Integrate Q along the active vector and plot"))
1704
+ plotqvect = self.analyzeplot.Append(wx.ID_ANY, _("Plot integrated Q along active zone..."), _("Integrate Q along the active zone and plot"))
1705
+
1706
+ self.analyzeplot.AppendSeparator()
1707
+
1708
+
1709
+ exportqvect = self.analyzeexport.Append(wx.ID_ANY, _("Export integrated Q along active vector..."), _("Integrate Q along the active vector and export"))
1710
+ exportqvect = self.analyzeexport.Append(wx.ID_ANY, _("Export integrated Q along all vectors in active zone..."), _("Integrate Q along ALL VECTORS of the active zone and export"))
1711
+
1712
+ self.analyzeexport.AppendSeparator()
1713
+
1714
+ plothselect = self.analyzeplot.Append(wx.ID_ANY, _("Plot stats unknown (selected nodes)..."), _("Compute stats and plot on the selected nodes"))
1715
+ plothvector = self.analyzeplot.Append(wx.ID_ANY, _("Plot stats unknown (inside active vector)..."), _("Compute stats and plot on nodes inside the active vector"))
1716
+ plothzone = self.analyzeplot.Append(wx.ID_ANY, _("Plot stats unknown (inside active zone)..."), _("Compute stats and plot on nodes inside the active zone"))
1717
+
1718
+ exporthselect = self.analyzeexport.Append(wx.ID_ANY, _("Export stats unknown (selected nodes)..."), _("Compute stats and export on the selected nodes"))
1719
+ exporthvector = self.analyzeexport.Append(wx.ID_ANY, _("Export stats unknown (inside active vector)..."), _("Compute stats and export on nodes inside the active vector"))
1720
+ exporthzone = self.analyzeexport.Append(wx.ID_ANY, _("Export stats unknown (inside active zone)..."), _("Compute stats and export on nodes inside the active zone"))
1502
1721
 
1503
1722
  self.filemenu.AppendSeparator()
1504
1723
  menuquit = self.filemenu.Append(wx.ID_EXIT, _('&Quit\tCTRL+Q'), _('Quit application'))
@@ -1549,6 +1768,8 @@ class WolfMapViewer(wx.Frame):
1549
1768
  self.active_weir = None
1550
1769
  self.active_laz = None
1551
1770
 
1771
+ self.active_fig = None
1772
+
1552
1773
  curtool = self.tools[ID_SORTALONG] = {}
1553
1774
  curtool['menu'] = self.sortalong
1554
1775
  curtool['name'] = 'Sort along vector'
@@ -1687,6 +1908,90 @@ class WolfMapViewer(wx.Frame):
1687
1908
  # # print(msg)
1688
1909
  # return 0
1689
1910
 
1911
+ def _check_id_for_fig(self, idx:str):
1912
+ """ Check if an ID is already used for a figure """
1913
+
1914
+ ids = [cur.idx for cur in self.mymplfigs]
1915
+
1916
+ if idx in ids:
1917
+ return True
1918
+
1919
+ return False
1920
+
1921
+ def _create_id_for_fig(self):
1922
+
1923
+ idx = 'Figure'
1924
+ while not self._check_id_for_fig(idx):
1925
+ idx += '_'
1926
+
1927
+ return idx
1928
+
1929
+ def _validate_id_for_fig(self, idx:str):
1930
+ """ Validate an ID for a figure """
1931
+
1932
+ if idx is None:
1933
+ return self._create_id_for_fig()
1934
+
1935
+ while self._check_id_for_fig(idx):
1936
+ idx += '_'
1937
+
1938
+ return idx
1939
+
1940
+ def new_fig(self, caption:str, idx:str = None, layout = PRESET_LAYOUTS.DEFAULT, size = (800,600), show:bool = True) -> MplFigViewer:
1941
+ """ Create a new figure """
1942
+
1943
+ if idx is None:
1944
+ with wx.TextEntryDialog(self, _('Enter an id for the figure'), _('Figure id'), _('Figure')) as dlg:
1945
+ dlg: wx.TextEntryDialog
1946
+ if dlg.ShowModal() == wx.ID_CANCEL:
1947
+ return None
1948
+
1949
+ idx = dlg.GetValue()
1950
+
1951
+ idx = self._validate_id_for_fig(idx)
1952
+ else:
1953
+ idx = self._validate_id_for_fig(idx)
1954
+
1955
+ logging.info(f'Figure ID: {idx}')
1956
+
1957
+ added_fig = MplFigViewer(layout, idx= idx, mapviewer = self, caption = caption, size= size)
1958
+
1959
+ if show:
1960
+ added_fig.Show()
1961
+ else:
1962
+ added_fig.Hide()
1963
+
1964
+ self.mymplfigs.append(added_fig)
1965
+
1966
+ return added_fig
1967
+
1968
+ def destroy_fig_by_id(self, idx:str) -> bool:
1969
+ """ Destroy a figure by its ID """
1970
+
1971
+ for id, fig in enumerate(self.mymplfigs):
1972
+ if fig.idx == idx:
1973
+ if self.active_fig is fig:
1974
+ self.active_fig = None
1975
+ fig.Destroy()
1976
+ self.mymplfigs.pop(id)
1977
+ return True
1978
+
1979
+ return False
1980
+
1981
+ def get_fig(self, idx:str) -> MplFigViewer:
1982
+ """ Get a figure by its ID """
1983
+
1984
+ for cur in self.mymplfigs:
1985
+ if cur.idx == idx:
1986
+ return cur
1987
+
1988
+ return None
1989
+
1990
+ def list_ids_figs(self) -> list[str]:
1991
+ """ List all IDs of figures """
1992
+
1993
+ return [cur.idx for cur in self.mymplfigs]
1994
+
1690
1995
  @property
1691
1996
  def viewer_name(self):
1692
1997
  return self.GetTitle()
@@ -1930,6 +2235,7 @@ class WolfMapViewer(wx.Frame):
1930
2235
 
1931
2236
  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
2237
  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)
2238
+ copylaz_gridinfo = self.menulazgrid.Append(wx.ID_ANY, _('Copy from current zoom'), _('Make a copy of the used files'))
1933
2239
  updatecolors_laz = self.menulazgrid.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
1934
2240
 
1935
2241
  bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('Extract bridge from LAZ data as cloud points (class 10)'))
@@ -3902,6 +4208,8 @@ class WolfMapViewer(wx.Frame):
3902
4208
  self.myviewerslaz = []
3903
4209
  self.mylazdata = []
3904
4210
 
4211
+ self.mymplfigs = []
4212
+
3905
4213
  self.sim_explorers = {}
3906
4214
 
3907
4215
  # liste des éléments modifiable dans l'arbre
@@ -4007,7 +4315,7 @@ class WolfMapViewer(wx.Frame):
4007
4315
  self.ymin = self.mousey - height / 2.
4008
4316
  self.ymax = self.ymin + height
4009
4317
 
4010
- def setbounds(self,updatescale=True):
4318
+ def setbounds(self, updatescale=True):
4011
4319
  """
4012
4320
  Calcule les limites visibles de la fenêtrte graphique sur base des
4013
4321
  facteurs d'échelle courants
@@ -5542,7 +5850,7 @@ class WolfMapViewer(wx.Frame):
5542
5850
  curbounds = [[self.xmin, self.xmin + self.width], [self.ymin, self.ymin + self.height]]
5543
5851
 
5544
5852
  if self.active_laz is None:
5545
- newobj = Base_LAZ_Data()
5853
+ newobj = Wolf_LAZ_Data()
5546
5854
  newobj.classification = self.mylazgrid.colors
5547
5855
  newobj.from_grid(self.mylazgrid, curbounds)
5548
5856
 
@@ -5553,7 +5861,7 @@ class WolfMapViewer(wx.Frame):
5553
5861
  ret = dlg.ShowModal()
5554
5862
 
5555
5863
  if ret == wx.ID_YES:
5556
- newobj = Base_LAZ_Data()
5864
+ newobj = Wolf_LAZ_Data()
5557
5865
  newobj.classification = self.mylazgrid.colors
5558
5866
  newobj.from_grid(self.mylazgrid, curbounds)
5559
5867
 
@@ -5588,14 +5896,14 @@ class WolfMapViewer(wx.Frame):
5588
5896
  else:
5589
5897
  logging.info(_('Filter cancelled'))
5590
5898
 
5591
- def decimate_laz_data(self, factor:int = 10):
5592
- """ Decimate data """
5899
+ def descimate_laz_data(self, factor:int = 10):
5900
+ """ Descimate data """
5593
5901
 
5594
5902
  if self.active_laz is None:
5595
5903
  logging.warning(_('No laz data'))
5596
5904
  return
5597
5905
 
5598
- self.active_laz.decimate(factor)
5906
+ self.active_laz.descimate(factor)
5599
5907
 
5600
5908
  def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
5601
5909
  """ select some nodes from laz data
@@ -5953,7 +6261,7 @@ class WolfMapViewer(wx.Frame):
5953
6261
  fn = dlg.GetPath()
5954
6262
  dlg.Destroy()
5955
6263
 
5956
- self.mylazdata.append(Base_LAZ_Data())
6264
+ self.mylazdata.append(Wolf_LAZ_Data())
5957
6265
  self.active_laz = self.mylazdata[-1]
5958
6266
  self.active_laz.from_file(fn)
5959
6267
 
@@ -6209,14 +6517,22 @@ class WolfMapViewer(wx.Frame):
6209
6517
  """ Select laz source """
6210
6518
 
6211
6519
  if self.active_laz is None and self.mylazgrid is None:
6212
- logging.warning(_('No LAZ data loaded !'))
6520
+ logging.warning(_('No LAZ data loaded/initialized !'))
6213
6521
  return None
6214
6522
  elif self.active_laz is None:
6523
+ # No active laz data
6215
6524
  laz_source = self.mylazgrid
6216
6525
  elif self.mylazgrid is None:
6526
+ # No laz grid
6217
6527
  laz_source = self.active_laz
6218
6528
  else:
6529
+ # We have both
6219
6530
  choices = [_('From active LAZ data'), _('From newly extracted data')]
6531
+
6532
+ keys = self.get_list_keys(draw_type.LAZ, None)
6533
+ if len(keys) > 1:
6534
+ choices.append(_('From multiple LAZ data'))
6535
+
6220
6536
  dlg = wx.SingleChoiceDialog(None, _("Pick a data source"), "Choices", choices)
6221
6537
  ret = dlg.ShowModal()
6222
6538
  if ret == wx.ID_CANCEL:
@@ -6229,8 +6545,22 @@ class WolfMapViewer(wx.Frame):
6229
6545
 
6230
6546
  if idx == 0:
6231
6547
  laz_source = self.active_laz
6232
- else:
6548
+ elif idx == 1:
6233
6549
  laz_source = self.mylazgrid
6550
+ else:
6551
+ dlg = wx.MultiChoiceDialog(None, _('Choose the LAZ data to use\n\nIf multiple, a new one will be created !'), _('LAZ data'), keys)
6552
+ if dlg.ShowModal() == wx.ID_OK:
6553
+ used_keys = dlg.GetSelections()
6554
+ used_keys = [keys[cur] for cur in used_keys]
6555
+ laz_source = Wolf_LAZ_Data()
6556
+ for curkey in used_keys:
6557
+ laz_source.merge(self.get_obj_from_id(curkey, draw_type.LAZ))
6558
+
6559
+ self.add_object('laz', newobj=laz_source, id = 'Merged LAZ data')
6560
+ dlg.Destroy()
6561
+ else:
6562
+ dlg.Destroy()
6563
+ return None
6234
6564
 
6235
6565
  return laz_source
6236
6566
 
@@ -6240,7 +6570,7 @@ class WolfMapViewer(wx.Frame):
6240
6570
  dlg = wx.SingleChoiceDialog(None, _("Pick a colormap"), "Choices", choices)
6241
6571
 
6242
6572
  if self.active_laz is not None:
6243
- dlg.SetSelection(self.active_laz.associated_color)
6573
+ dlg.SetSelection(ass_values.index(self.active_laz.associated_color))
6244
6574
 
6245
6575
  ret = dlg.ShowModal()
6246
6576
  if ret == wx.ID_CANCEL:
@@ -6334,7 +6664,8 @@ class WolfMapViewer(wx.Frame):
6334
6664
  logging.warning(_('No active 2D result !'))
6335
6665
  return
6336
6666
 
6337
- self.active_res2d.plot_q(self.active_vector, 'border', toshow=True)
6667
+ fig = self.new_fig(_('Q along active vector'), 'Q_along_active_vector', show=False, size=(800, 600))
6668
+ self.active_res2d.plot_q_wx(self.active_vector, 'border', toshow=True, fig= fig)
6338
6669
 
6339
6670
  elif itemlabel == _("Plot integrated Q along active zone..."):
6340
6671
  """ Integrate Q along active zone """
@@ -6347,7 +6678,8 @@ class WolfMapViewer(wx.Frame):
6347
6678
  logging.warning(_('No active 2D result !'))
6348
6679
  return
6349
6680
 
6350
- self.active_res2d.plot_q(self.active_zone.myvectors, ['border'] * self.active_zone.nbvectors, toshow=True)
6681
+ fig = self.new_fig(_('Q along active zone'), 'Q_along_active_zone', show=False, size=(800, 600))
6682
+ self.active_res2d.plot_q_wx(self.active_zone.myvectors, ['border'] * self.active_zone.nbvectors, toshow=True, fig = fig)
6351
6683
 
6352
6684
  elif itemlabel == _("Export integrated Q along active vector..."):
6353
6685
 
@@ -6463,32 +6795,105 @@ class WolfMapViewer(wx.Frame):
6463
6795
  logging.warning(_('No active 2D result !'))
6464
6796
  return
6465
6797
 
6466
- dlg = wx.SingleChoiceDialog(None, _('Choose the unknown to plot'), _('Unknown'), [_('Water depth'), _('Water level'), _('Head')])
6798
+ all_selected = []
6799
+ for curblock in self.active_res2d.myblocks.values():
6800
+ if curblock.SelectionData.nb > 0:
6801
+ all_selected += curblock.SelectionData.myselection
6802
+
6803
+ if len(all_selected) == 0:
6804
+ logging.warning(_('No selected nodes - Nothing to do !'))
6805
+ return
6806
+
6807
+ keys = Extractable_results.get_list()
6808
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
6467
6809
 
6468
6810
  ret = dlg.ShowModal()
6469
6811
  if ret == wx.ID_CANCEL:
6812
+ logging.info(_('No unknown chosen - Aborting !'))
6470
6813
  dlg.Destroy()
6471
6814
  return
6472
6815
 
6473
- unknown = dlg.GetStringSelection()
6816
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
6474
6817
  dlg.Destroy()
6475
6818
 
6476
- if unknown == _('Water depth'):
6477
- unknown = 'h'
6478
- elif unknown == _('Water level'):
6479
- unknown = 'z'
6480
- elif unknown == _('Head'):
6481
- unknown = 'head'
6819
+ try:
6820
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
6821
+ ret = choice_bes.ShowModal()
6822
+
6823
+ begin = choice_bes.begin
6824
+ end = choice_bes.end
6825
+ interval = choice_bes.step
6826
+
6827
+ finally:
6828
+ choice_bes.Destroy()
6829
+
6830
+ if begin == -1:
6831
+ logging.info(_('No interval chosen - Aborting !'))
6832
+ return
6833
+
6834
+ newfig = self.new_fig(_('Series of {} - {} (nodes)').format(which.value[0], self.active_res2d.idx), 'series_'+self.active_res2d.idx, show=False, size= (800,600))
6835
+
6836
+ figax = self.active_res2d.plot_some_values(all_selected, which, toshow=False, figax=newfig, for_steps= (begin-1, end-1, interval))
6482
6837
 
6483
- figax = None
6838
+ newfig.Show()
6839
+
6840
+ elif itemlabel == _("Export stats unknown (selected nodes)..."):
6841
+
6842
+ if self.active_res2d is None:
6843
+ logging.warning(_('No active 2D result !'))
6844
+ return
6845
+
6846
+ all_selected = []
6484
6847
  for curblock in self.active_res2d.myblocks.values():
6485
6848
  if curblock.SelectionData.nb > 0:
6849
+ all_selected += curblock.SelectionData.myselection
6850
+
6851
+ if len(all_selected) == 0:
6852
+ logging.warning(_('No selected nodes - Nothing to do !'))
6853
+ return
6854
+
6855
+ keys = Extractable_results.get_list()
6856
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
6857
+
6858
+ ret = dlg.ShowModal()
6859
+ if ret == wx.ID_CANCEL:
6860
+ logging.info(_('No unknown chosen - Aborting !'))
6861
+ dlg.Destroy()
6862
+ return
6863
+
6864
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
6865
+ dlg.Destroy()
6866
+
6867
+ dlg = wx.FileDialog(None, _('Choose the file to export'), wildcard='csv (*.csv)|*.csv', style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
6868
+ ret = dlg.ShowModal()
6869
+ if ret == wx.ID_CANCEL:
6870
+ logging.info(_('No file chosen - Aborting !'))
6871
+ dlg.Destroy()
6872
+ return
6873
+
6874
+ filename = Path(dlg.GetPath())
6875
+ dlg.Destroy()
6876
+
6877
+
6878
+ try:
6879
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
6880
+ ret = choice_bes.ShowModal()
6486
6881
 
6487
- figax = self.active_res2d.plot_h(curblock.SelectionData.myselection,
6488
- unknown, toshow=False, figax=figax)
6489
- if figax is not None:
6490
- fig, ax = figax
6491
- fig.show()
6882
+ begin = choice_bes.begin
6883
+ end = choice_bes.end
6884
+ interval = choice_bes.step
6885
+
6886
+ finally:
6887
+ choice_bes.Destroy()
6888
+
6889
+ if begin == -1:
6890
+ logging.info(_('No interval chosen - Aborting !'))
6891
+ return
6892
+
6893
+ ret = self.active_res2d.export_some_values_to_csv(all_selected, which, filename, for_steps= (begin-1, end-1, interval))
6894
+
6895
+ if not ret:
6896
+ logging.error(_('Error in exporting values !'))
6492
6897
 
6493
6898
  elif itemlabel == _("Plot stats unknown (inside active vector)..."):
6494
6899
 
@@ -6500,24 +6905,91 @@ class WolfMapViewer(wx.Frame):
6500
6905
  logging.warning(_('No active vector !'))
6501
6906
  return
6502
6907
 
6503
- dlg = wx.SingleChoiceDialog(None, _('Choose the unknown to plot'), _('Unknown'), [_('Water depth'), ['Water level'], ['Head']])
6908
+ keys = Extractable_results.get_list()
6909
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
6504
6910
 
6505
6911
  ret = dlg.ShowModal()
6506
6912
  if ret == wx.ID_CANCEL:
6913
+ logging.info(_('No unknown chosen - Aborting !'))
6507
6914
  dlg.Destroy()
6508
6915
  return
6509
6916
 
6510
- unknown = dlg.GetStringSelection()
6917
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
6511
6918
  dlg.Destroy()
6512
6919
 
6513
- if unknown == _('Water depth'):
6514
- unknown = 'h'
6515
- elif unknown == _('Water level'):
6516
- unknown = 'z'
6517
- elif unknown == _('Head'):
6518
- unknown = 'head'
6920
+ try:
6921
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
6922
+ ret = choice_bes.ShowModal()
6923
+
6924
+ begin = choice_bes.begin
6925
+ end = choice_bes.end
6926
+ interval = choice_bes.step
6927
+ violin = choice_bes.check_violin
6928
+
6929
+ finally:
6930
+ choice_bes.Destroy()
6931
+
6932
+ if begin == -1:
6933
+ logging.info(_('No interval chosen - Aborting !'))
6934
+ return
6935
+
6936
+ newfig = self.new_fig(_('Series of {} - {} (polygon)').format(which.value[0], self.active_res2d.idx), 'series_'+self.active_res2d.idx, show=False, size= (800,600))
6937
+
6938
+ if violin:
6939
+ figax = self.active_res2d.plot_violin_values(self.active_vector, which, toshow=False, figax=newfig, for_steps= (begin-1, end-1, interval))
6940
+ else:
6941
+ figax = self.active_res2d.plot_some_values(self.active_vector, which, toshow=False, figax=newfig, for_steps= (begin-1, end-1, interval))
6942
+
6943
+ newfig.Show()
6944
+
6945
+ elif itemlabel == _("Export stats unknown (inside active vector)..."):
6946
+
6947
+ if self.active_res2d is None:
6948
+ logging.warning(_('No active 2D result !'))
6949
+ return
6950
+
6951
+ if self.active_vector is None:
6952
+ logging.warning(_('No active vector !'))
6953
+ return
6519
6954
 
6520
- fig, ax = self.active_res2d.plot_h(self.active_vector, unknown, toshow=True)
6955
+ keys = Extractable_results.get_list()
6956
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
6957
+
6958
+ ret = dlg.ShowModal()
6959
+ if ret == wx.ID_CANCEL:
6960
+ logging.info(_('No unknown chosen - Aborting !'))
6961
+ dlg.Destroy()
6962
+ return
6963
+
6964
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
6965
+ dlg.Destroy()
6966
+
6967
+ dlg = wx.FileDialog(None, _('Choose the file to export'), wildcard='csv (*.csv)|*.csv', style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
6968
+ ret = dlg.ShowModal()
6969
+ if ret == wx.ID_CANCEL:
6970
+ logging.info(_('No file chosen - Aborting !'))
6971
+ dlg.Destroy()
6972
+ return
6973
+
6974
+ filename = Path(dlg.GetPath())
6975
+ dlg.Destroy()
6976
+
6977
+ try:
6978
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
6979
+ ret = choice_bes.ShowModal()
6980
+
6981
+ begin = choice_bes.begin
6982
+ end = choice_bes.end
6983
+ interval = choice_bes.step
6984
+
6985
+ finally:
6986
+ choice_bes.Destroy()
6987
+
6988
+ if begin == -1:
6989
+ logging.info(_('No interval chosen - Aborting !'))
6990
+ return
6991
+
6992
+ ret = self.active_res2d.export_some_values_to_csv(self.active_vector, which, filename=filename, for_steps= (begin-1, end-1, interval))
6521
6993
 
6522
6994
  elif itemlabel == _("Plot stats unknown (inside active zone)..."):
6523
6995
 
@@ -6529,30 +7001,108 @@ class WolfMapViewer(wx.Frame):
6529
7001
  logging.warning(_('No active zone !'))
6530
7002
  return
6531
7003
 
6532
- dlg = wx.SingleChoiceDialog(None, _('Choose the unknown to plot'), _('Unknown'), [_('Water depth'), ['Water level'], ['Head']])
7004
+ keys = Extractable_results.get_list()
7005
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
6533
7006
 
6534
7007
  ret = dlg.ShowModal()
6535
7008
  if ret == wx.ID_CANCEL:
7009
+ logging.info(_('No unknown chosen - Aborting !'))
6536
7010
  dlg.Destroy()
6537
7011
  return
6538
7012
 
6539
- unknown = dlg.GetStringSelection()
7013
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
6540
7014
  dlg.Destroy()
6541
7015
 
6542
- if unknown == _('Water depth'):
6543
- unknown = 'h'
6544
- elif unknown == _('Water level'):
6545
- unknown = 'z'
6546
- elif unknown == _('Head'):
6547
- unknown = 'head'
7016
+ try:
7017
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
7018
+ ret = choice_bes.ShowModal()
7019
+
7020
+ begin = choice_bes.begin
7021
+ end = choice_bes.end
7022
+ interval = choice_bes.step
7023
+ violin = choice_bes.check_violin
7024
+
7025
+ finally:
7026
+ choice_bes.Destroy()
7027
+
7028
+ if begin == -1:
7029
+ logging.info(_('No interval chosen - Aborting !'))
7030
+ return
6548
7031
 
6549
7032
  for idx, curvect in enumerate(self.active_zone.myvectors):
7033
+ logging.info(_('Plotting {} / {}'.format(idx, self.active_zone.nbvectors)))
6550
7034
  if idx ==0:
6551
- fig, ax = self.active_res2d.plot_h(curvect, unknown, toshow=False)
7035
+ newfig = self.new_fig(_('Series of {} - {} (zone)').format(which.value[0], self.active_res2d.idx), 'series_'+self.active_res2d.idx, show=False, size= (800,600))
7036
+
7037
+ if violin:
7038
+ figax = self.active_res2d.plot_violin_values(curvect, which, toshow=False, figax=newfig, for_steps= (begin-1, end-1, interval))
6552
7039
  else:
6553
- self.active_res2d.plot_h(curvect, unknown, toshow=False, figax = (fig, ax))
7040
+ figax = self.active_res2d.plot_some_values(curvect, which, toshow=False, figax=newfig, for_steps= (begin-1, end-1, interval))
6554
7041
 
6555
- fig.show()
7042
+ newfig.Show()
7043
+
7044
+ elif itemlabel == _("Export stats unknown (inside active zone)..."):
7045
+
7046
+ if self.active_res2d is None:
7047
+ logging.warning(_('No active 2D result !'))
7048
+ return
7049
+
7050
+ if self.active_zone is None:
7051
+ logging.warning(_('No active zone !'))
7052
+ return
7053
+
7054
+ keys = Extractable_results.get_list()
7055
+ dlg = wx.SingleChoiceDialog(None, _('Choose the unknown/variable to plot'), _('Unknown'), keys)
7056
+
7057
+ ret = dlg.ShowModal()
7058
+ if ret == wx.ID_CANCEL:
7059
+ logging.info(_('No unknown chosen - Aborting !'))
7060
+ dlg.Destroy()
7061
+ return
7062
+
7063
+ which = Extractable_results.get_from_key(dlg.GetStringSelection())
7064
+ dlg.Destroy()
7065
+
7066
+ dlg = wx.DirDialog(None, _('Choose the directory where to export'), style= wx.DD_DEFAULT_STYLE)
7067
+ ret = dlg.ShowModal()
7068
+ if ret == wx.ID_CANCEL:
7069
+ logging.info(_('No file chosen - Aborting !'))
7070
+ dlg.Destroy()
7071
+ return
7072
+
7073
+ directory = Path(dlg.GetPath())
7074
+ dlg.Destroy()
7075
+
7076
+ try:
7077
+ choice_bes = Select_Begin_end_interval_step(self, _('Choose the interval and step'), self.active_res2d, checkbox=True)
7078
+ ret = choice_bes.ShowModal()
7079
+
7080
+ begin = choice_bes.begin
7081
+ end = choice_bes.end
7082
+ interval = choice_bes.step
7083
+
7084
+ finally:
7085
+ choice_bes.Destroy()
7086
+
7087
+ if begin == -1:
7088
+ logging.info(_('No interval chosen - Aborting !'))
7089
+ return
7090
+
7091
+ allnames = [curvect.myname for curvect in self.active_zone.myvectors]
7092
+ if len(set(allnames)) != len(allnames):
7093
+ logging.warning(_('Some vectors have the same name !'))
7094
+
7095
+ # create new unique names
7096
+ unique_name = []
7097
+ for curvect in self.active_zone.myvectors:
7098
+ if curvect.myname in unique_name:
7099
+ unique_name.append(curvect.myname + '_' + str(unique_name.count(curvect.myname)))
7100
+ else:
7101
+ unique_name.append(curvect.myname)
7102
+
7103
+
7104
+ for idx, (curvect, name) in enumerate(zip(self.active_zone.myvectors, unique_name)):
7105
+ self.active_res2d.export_some_values_to_csv(curvect, which, filename=directory / name, for_steps= (begin-1, end-1, interval))
6556
7106
 
6557
7107
  elif itemlabel == _("Plot active vector..."):
6558
7108
  """ Plot data along active vector """
@@ -6597,11 +7147,14 @@ class WolfMapViewer(wx.Frame):
6597
7147
 
6598
7148
  dlg.Destroy()
6599
7149
 
6600
- fig, ax = self.active_vector.plot_mpl(True, False)
7150
+ # Création d'un graphique matplotlib sous wx
7151
+ lab = _('Plot of active vector') + ' - ' + self.active_vector.myname
7152
+ figmpl = self.new_fig(lab, lab, show=False, size= (800,600))
6601
7153
 
6602
7154
  linkedarrays = self.get_linked_arrays()
6603
7155
 
6604
7156
  with wx.MultiChoiceDialog(None, _('Choose the arrays to plot'), _('Arrays'), [curarray for curarray in list(linkedarrays.keys())]) as dlg:
7157
+ dlg:wx.MultiChoiceDialog
6605
7158
  dlg.SetSelections(range(len(linkedarrays)))
6606
7159
 
6607
7160
  if dlg.ShowModal() == wx.ID_CANCEL:
@@ -6615,20 +7168,19 @@ class WolfMapViewer(wx.Frame):
6615
7168
 
6616
7169
  linkedarrays = {curkey:curval for curkey, curval in linkedarrays.items() if curkey in selected}
6617
7170
 
6618
- self.active_vector.plot_linked(fig, ax, linkedarrays)
7171
+ self.active_vector.plot_linked_wx(figmpl, linkedarrays)
6619
7172
 
6620
7173
  if add_cloud:
6621
7174
  s, z = self.active_cloud.projectontrace(self.active_vector, return_cloud=False, proximity= proxval)
6622
7175
 
6623
- ax.scatter( s, z, c='black', s=1.0)
7176
+ figmpl.plot( s, z, c='black', s=1.0, marker='x')
6624
7177
 
6625
7178
  for curs, curz in zip(s,z):
6626
- ax.plot([curs, curs], [curz-tolval, curz+tolval], 'k--', linewidth=0.5)
6627
- ax.plot([curs-.1, curs+.1], [curz+tolval, curz+tolval], c='black', linewidth=0.5)
6628
- ax.plot([curs-.1, curs+.1], [curz-tolval, curz-tolval], c='black', linewidth=0.5)
7179
+ figmpl.plot([curs, curs], [curz-tolval, curz+tolval], 'k--', linewidth=0.5)
7180
+ figmpl.plot([curs-.1, curs+.1], [curz+tolval, curz+tolval], c='black', linewidth=0.5)
7181
+ figmpl.plot([curs-.1, curs+.1], [curz-tolval, curz-tolval], c='black', linewidth=0.5)
6629
7182
 
6630
- fig.canvas.draw()
6631
- fig.canvas.flush_events()
7183
+ figmpl.Show()
6632
7184
 
6633
7185
  elif itemlabel == _("Compute and apply unique colormap on all..."):
6634
7186
  self.uniquecolormap()
@@ -6649,79 +7201,84 @@ class WolfMapViewer(wx.Frame):
6649
7201
  self.filter_inundation()
6650
7202
 
6651
7203
  elif itemlabel == _("Plot active polygons..."):
7204
+
6652
7205
  if self.active_zone is None:
6653
7206
  logging.warning(_('No active zone ! -- please select a zone containing polygons !'))
6654
7207
  return
6655
7208
 
6656
- plotzone:list[zone]
6657
- plotzone = []
6658
- zonename = self.active_zone.myname
6659
- if '_left_' in zonename or '_right_' in zonename:
6660
-
6661
- logging.info(_('Left and Right polygons are detected'))
6662
-
6663
- testname = zonename.replace('_left_', '')
6664
- testname = testname.replace('_right_', '')
6665
-
6666
- for curzone in self.active_zones.myzones:
6667
- if testname == curzone.myname.replace('_left_', '').replace('_right_', ''):
6668
- plotzone.append(curzone)
6669
-
6670
- msg = wx.MessageDialog(self,
6671
- _('Left and Right polygons are detected \nDo you want like to plot left and right polygons on the same plot ?'),
6672
- style=wx.YES_NO | wx.YES_DEFAULT)
6673
- ret = msg.ShowModal()
6674
- msg.Destroy()
6675
- if ret == wx.ID_NO:
7209
+ try:
7210
+ plotzone:list[zone]
7211
+ plotzone = []
7212
+ zonename = self.active_zone.myname
7213
+ if '_left_' in zonename or '_right_' in zonename:
7214
+
7215
+ logging.info(_('Left and Right polygons are detected'))
7216
+
7217
+ testname = zonename.replace('_left_', '')
7218
+ testname = testname.replace('_right_', '')
7219
+
7220
+ for curzone in self.active_zones.myzones:
7221
+ if testname == curzone.myname.replace('_left_', '').replace('_right_', ''):
7222
+ plotzone.append(curzone)
7223
+
7224
+ msg = wx.MessageDialog(self,
7225
+ _('Left and Right polygons are detected \nDo you want like to plot left and right polygons on the same plot ?'),
7226
+ style=wx.YES_NO | wx.YES_DEFAULT)
7227
+ ret = msg.ShowModal()
7228
+ msg.Destroy()
7229
+ if ret == wx.ID_NO:
7230
+ plotzone = [self.active_zone]
7231
+ else:
7232
+ logging.info(_('Sole polygon detected'))
6676
7233
  plotzone = [self.active_zone]
6677
- else:
6678
- logging.info(_('Sole polygon detected'))
6679
- plotzone = [self.active_zone]
6680
7234
 
6681
- fig, ax = plt.subplots(1, 1)
6682
-
6683
- linkedarrays = {}
7235
+ # Création d'un graphique matplotlib sous wx
7236
+ figmpl = self.new_fig(_('Plot of active polygons'), 'plot_active_polygons', show=False, size= (800,600))
7237
+
7238
+ linkedarrays = {}
7239
+
7240
+ # Matrices 2D
7241
+ for curarray in self.iterator_over_objects(draw_type.ARRAYS):
7242
+ curarray: WolfArray
7243
+ logging.info(_('Plotting array {}').format(curarray.idx))
7244
+ linkedarrays[curarray.idx] = curarray
7245
+
7246
+ # Résultats 2D
7247
+ for curarray in self.iterator_over_objects(draw_type.RES2D):
7248
+ curarray: Wolfresults_2D
7249
+ logging.info(_('Plotting results {}').format(curarray.idx))
7250
+ linkedarrays[curarray.idx] = curarray
7251
+
7252
+ linkedvecs={}
7253
+ for curvect in self.iterator_over_objects(draw_type.VECTORS):
7254
+ curvect: Zones
7255
+ logging.info(_('Plotting vector {}').format(curvect.idx))
7256
+ linkedvecs[curvect.idx] = curvect
7257
+
7258
+ if len(plotzone) > 1:
7259
+ # left and right polygons
7260
+ for curzone in plotzone:
7261
+ if '_left_' in curzone.myname:
7262
+ locarrays = {}
7263
+ for curkey, curarray in linkedarrays.items():
7264
+ locarrays[curkey+ '_left'] = curarray
7265
+
7266
+ curzone.plot_linked_polygons_wx(figmpl, locarrays, linked_vec=linkedvecs, linestyle= '--')
7267
+ elif '_right_' in curzone.myname:
7268
+ locarrays = {}
7269
+ for curkey, curarray in linkedarrays.items():
7270
+ locarrays[curkey+ '_right'] = curarray
7271
+
7272
+ curzone.plot_linked_polygons_wx(figmpl, locarrays, linked_vec=linkedvecs, linestyle= '-.')
7273
+ else:
7274
+ # sole polygon
7275
+ plotzone[0].plot_linked_polygons_wx(figmpl, linkedarrays, linked_vec=linkedvecs)
6684
7276
 
6685
- # Matrices 2D
6686
- for curarray in self.iterator_over_objects(draw_type.ARRAYS):
6687
- curarray: WolfArray
6688
- logging.info(_('Plotting array {}').format(curarray.idx))
6689
- linkedarrays[curarray.idx] = curarray
6690
-
6691
- # Résultats 2D
6692
- for curarray in self.iterator_over_objects(draw_type.RES2D):
6693
- curarray: Wolfresults_2D
6694
- logging.info(_('Plotting results {}').format(curarray.idx))
6695
- linkedarrays[curarray.idx] = curarray
6696
-
6697
- linkedvecs={}
6698
- for curvect in self.iterator_over_objects(draw_type.VECTORS):
6699
- curvect: Zones
6700
- logging.info(_('Plotting vector {}').format(curvect.idx))
6701
- linkedvecs[curvect.idx] = curvect
6702
-
6703
- if len(plotzone) > 1:
6704
- # left and right polygons
6705
- for curzone in plotzone:
6706
- if '_left_' in curzone.myname:
6707
- locarrays = {}
6708
- for curkey, curarray in linkedarrays.items():
6709
- locarrays[curkey+ '_left'] = curarray
6710
-
6711
- curzone.plot_linked_polygons(fig, ax, locarrays, linked_vec=linkedvecs, linestyle= '--')
6712
- elif '_right_' in curzone.myname:
6713
- locarrays = {}
6714
- for curkey, curarray in linkedarrays.items():
6715
- locarrays[curkey+ '_right'] = curarray
6716
-
6717
- curzone.plot_linked_polygons(fig, ax, locarrays, linked_vec=linkedvecs, linestyle= '-.')
6718
- else:
6719
- # sole polygon
6720
- plotzone[0].plot_linked_polygons(fig, ax, linkedarrays, linked_vec=linkedvecs)
7277
+ figmpl.Show()
6721
7278
 
6722
- ax.grid()
6723
- ax.legend()
6724
- fig.show()
7279
+ except Exception as e:
7280
+ logging.error(_('Error in plotting active polygons\n{}'.format(e)))
7281
+ logging.warning(_('Are you sure the active zone contains polygons ?'))
6725
7282
 
6726
7283
  elif itemlabel == _("Manage banks..."):
6727
7284
 
@@ -6906,6 +7463,23 @@ class WolfMapViewer(wx.Frame):
6906
7463
  elif itemlabel == _('Initialize from directory'):
6907
7464
  self.init_laz_from_gridinfos()
6908
7465
 
7466
+ elif itemlabel == _('Copy from current zoom'):
7467
+
7468
+ if self.mylazgrid is None:
7469
+ logging.warning(_('No gridded LAZ data loaded !'))
7470
+ return
7471
+
7472
+ dlg = wx.DirDialog(None, _('Choose a directory to copy the files'), _('Copy files'), style=wx.DD_DEFAULT_STYLE)
7473
+ if dlg.ShowModal() == wx.ID_CANCEL:
7474
+ dlg.Destroy()
7475
+
7476
+ dirout = dlg.GetPath()
7477
+ dlg.Destroy()
7478
+
7479
+ curbounds = [[self.xmin, self.xmin + self.width], [self.ymin, self.ymin + self.height]]
7480
+
7481
+ self.mylazgrid.copy_files_in_bounds(curbounds, dirout)
7482
+
6909
7483
  elif itemlabel == _('Create cloud points from bridges'):
6910
7484
 
6911
7485
  if self.active_laz is None:
@@ -6946,12 +7520,39 @@ class WolfMapViewer(wx.Frame):
6946
7520
  self.add_object('cloud', newobj=mycloud, ToCheck=True, id='Buildings')
6947
7521
 
6948
7522
  elif itemlabel == _('Create cloud points from specified classes'):
6949
- pass
7523
+
7524
+ if self.active_laz is None:
7525
+ self.init_laz_from_lazlasnpz()
7526
+
7527
+ codes = self.active_laz.codes_unique
7528
+
7529
+ dlg = wx.MultiChoiceDialog(None, _('Choose the classes to plot'), _('Classes'), codes)
7530
+ if dlg.ShowModal() == wx.ID_CANCEL:
7531
+ dlg.Destroy()
7532
+
7533
+ selected = dlg.GetSelections()
7534
+ selected = [codes[cur] for cur in selected]
7535
+ dlg.Destroy()
7536
+
7537
+ for curcode in selected:
7538
+ mycloud = cloud_vertices()
7539
+ mydata = self.active_laz.get_data_class(curcode)
7540
+ mycloud.init_from_nparray(mydata)
7541
+ mycloud.myprop.style = 2
7542
+ mycloud.myprop.color = getIfromRGB([102, 102, 102])
7543
+ mycloud.myprop.width = .5
7544
+ if self.linked:
7545
+ if len(self.linkedList) > 0:
7546
+ for curframe in self.linkedList:
7547
+ curframe.add_object('cloud', newobj=mycloud, ToCheck=True, id='Class {}'.format(curcode))
7548
+ else:
7549
+ self.add_object('cloud', newobj=mycloud, ToCheck=True, id='Class {}'.format(curcode))
6950
7550
 
6951
7551
  elif itemlabel == _('Create LAZ viewer'):
6952
7552
 
6953
7553
  laz_source = self._select_laz_source()
6954
7554
  if laz_source is None:
7555
+ logging.warning(_('No LAZ data loaded !'))
6955
7556
  return
6956
7557
 
6957
7558
  if laz_source is self.mylazgrid:
@@ -6983,7 +7584,7 @@ class WolfMapViewer(wx.Frame):
6983
7584
  return
6984
7585
 
6985
7586
  # 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),
7587
+ dlg = wx.NumberEntryDialog(None, _('Your dataset contains {} points.\nWould you like to descimate?').format(self.active_laz.num_points),
6987
7588
  _('Decaimate factor'), _('Decimation'), 0, 0, 100)
6988
7589
 
6989
7590
  ret = dlg.ShowModal()
@@ -6992,11 +7593,11 @@ class WolfMapViewer(wx.Frame):
6992
7593
  dlg.Destroy()
6993
7594
  return
6994
7595
 
6995
- decimate_fact = dlg.GetValue()
7596
+ descimate_fact = dlg.GetValue()
6996
7597
  dlg.Destroy()
6997
7598
 
6998
- if decimate_fact > 0:
6999
- self.active_laz.decimate(decimate_fact)
7599
+ if descimate_fact > 0:
7600
+ self.active_laz.descimate(descimate_fact)
7000
7601
  logging.info(_('New count : {}').format(self.active_laz.num_points))
7001
7602
 
7002
7603
  elif itemlabel == _('Clip LAZ grid on current zoom'):
@@ -7014,8 +7615,8 @@ class WolfMapViewer(wx.Frame):
7014
7615
  if self.active_laz.data.shape[0] > 100_000_000:
7015
7616
 
7016
7617
  # Choose a decimation factor - integer
7017
- dlg = wx.NumberEntryDialog(None, _('Your data selection is very large (>100 M)\nWould you like to decimate?'),
7018
- _('Decaimate factor'), _('Decimation'), 0, 0, 100)
7618
+ dlg = wx.NumberEntryDialog(None, _('Your data selection is very large (>100 M)\nWould you like to descimate?\n\n{} points').format(self.active_laz.data.shape[0]),
7619
+ _('Descimate factor'), _('Decimation'), 0, 0, 100)
7019
7620
 
7020
7621
  ret = dlg.ShowModal()
7021
7622
 
@@ -7023,11 +7624,11 @@ class WolfMapViewer(wx.Frame):
7023
7624
  dlg.Destroy()
7024
7625
  return
7025
7626
 
7026
- decimate_fact = dlg.GetValue()
7627
+ descimate_fact = dlg.GetValue()
7027
7628
  dlg.Destroy()
7028
7629
 
7029
- if decimate_fact > 0:
7030
- self.decimate_laz_data(decimate_fact)
7630
+ if descimate_fact > 0:
7631
+ self.descimate_laz_data(descimate_fact)
7031
7632
 
7032
7633
  elif itemlabel == _('Fill active array from LAZ data'):
7033
7634
 
@@ -7198,7 +7799,7 @@ class WolfMapViewer(wx.Frame):
7198
7799
  self.menu_particlesystem()
7199
7800
 
7200
7801
  elif itemlabel == _('Create particle system...'):
7201
- self.active_particlesystem = newpart = Particle_system()
7802
+ self.active_particle_system = newpart = Particle_system()
7202
7803
  self.add_object(which='particlesystem', newobj=newpart, ToCheck=True)
7203
7804
  self.menu_particlesystem()
7204
7805
 
@@ -8680,7 +9281,7 @@ class WolfMapViewer(wx.Frame):
8680
9281
  curtree = self.myitemslaz
8681
9282
 
8682
9283
  if newobj is None:
8683
- newobj = Base_LAZ_Data(mapviewer=self)
9284
+ newobj = Wolf_LAZ_Data(mapviewer=self)
8684
9285
  newobj.from_file(filename)
8685
9286
 
8686
9287
  self.mylazdata.append(newobj)
@@ -9361,10 +9962,20 @@ class WolfMapViewer(wx.Frame):
9361
9962
 
9362
9963
  fdlg.Destroy()
9363
9964
 
9965
+ elif isinstance(self.selected_object, Wolf_LAZ_Data):
9966
+ filterArray = "Dump (*.dump)|*.dmp|all (*.*)|*.*"
9967
+ fdlg = wx.FileDialog(self, "Choose file name for LAZ data :" + self.selected_object.idx, wildcard=filterArray,
9968
+ style=wx.FD_SAVE)
9969
+ ret = fdlg.ShowModal()
9970
+ if ret == wx.ID_OK:
9971
+ self.selected_object.saveas(fdlg.GetPath())
9972
+
9973
+ fdlg.Destroy()
9974
+
9364
9975
  elif text == _('Properties'):
9365
9976
 
9366
9977
  myobj = self.selected_object
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]:
9978
+ if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir, Wolf_LAZ_Data]:
9368
9979
  myobj.show_properties()
9369
9980
 
9370
9981
  elif isinstance(myobj, cloud_vertices):
@@ -9514,22 +10125,27 @@ class WolfMapViewer(wx.Frame):
9514
10125
 
9515
10126
  elif _('Set colormap') in text:
9516
10127
 
9517
- if isinstance(self.selected_object, Base_LAZ_Data):
10128
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9518
10129
  self.selected_object.associated_color = self._choice_laz_colormap()
9519
10130
 
9520
10131
  elif _('Edit colormap') in text:
9521
10132
 
9522
- if isinstance(self.selected_object, Base_LAZ_Data):
10133
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9523
10134
  self.selected_object.interactive_update_colors()
9524
10135
 
9525
10136
  elif _('Set classification') in text:
9526
10137
 
9527
- if isinstance(self.selected_object, Base_LAZ_Data):
10138
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9528
10139
  self.selected_object.set_classification(self._choice_laz_classification())
9529
10140
 
10141
+ elif _('Edit selection') in text:
10142
+
10143
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
10144
+ self.selected_object._edit_selection()
10145
+
9530
10146
  elif _('All to cloud') in text:
9531
10147
 
9532
- if isinstance(self.selected_object, Base_LAZ_Data):
10148
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9533
10149
 
9534
10150
  if self.selected_object.num_points > 100000:
9535
10151
  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)
@@ -9546,7 +10162,7 @@ class WolfMapViewer(wx.Frame):
9546
10162
 
9547
10163
  elif _('Selection to cloud') in text:
9548
10164
 
9549
- if isinstance(self.selected_object, Base_LAZ_Data):
10165
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9550
10166
 
9551
10167
  xyz = self.selected_object.xyz_selected
9552
10168
  if xyz.shape[0] ==0:
@@ -9566,14 +10182,75 @@ class WolfMapViewer(wx.Frame):
9566
10182
  newcloud.init_from_nparray(xyz)
9567
10183
  self.add_object('cloud', newobj=newcloud, id=self.selected_object.idx + '_cloud_sel')
9568
10184
 
10185
+ elif _('Selection to vector') in text:
10186
+
10187
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
10188
+
10189
+ if self.active_zone is None:
10190
+ logging.warning(_('No active zone selected'))
10191
+ return
10192
+
10193
+ xyz = self.selected_object.xyz_selected
10194
+ if xyz.shape[0] ==0:
10195
+ logging.warning('No points selected')
10196
+ return
10197
+
10198
+ if xyz.shape[0] > 100000:
10199
+ 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)
10200
+ ret = dlg.ShowModal()
10201
+
10202
+ if ret != wx.ID_YES:
10203
+ dlg.Destroy()
10204
+
10205
+ return
10206
+
10207
+ def approximate_vector(xyz):
10208
+ """ Get a cloud of points and return a vector
10209
+ based on the best approximated segment
10210
+ and points projected on its trace
10211
+ """
10212
+
10213
+ # best approximation of the segment
10214
+ # based on the RANSAC algorithm from scikit-learn
10215
+ model = linear_model.RANSACRegressor()
10216
+ model.fit(xyz[:,0].reshape(-1,1), xyz[:,1])
10217
+
10218
+ # get the points projected on the segment
10219
+ proj = model.predict(xyz[:,0].reshape(-1,1))
10220
+
10221
+ # get the coordinates of the projected points
10222
+ xyz_proj = np.zeros((xyz.shape[0],3))
10223
+ xyz_proj[:,0] = xyz[:,0]
10224
+ xyz_proj[:,1] = proj
10225
+ xyz_proj[:,2] = xyz[:,2]
10226
+
10227
+ #Sort the points
10228
+ idx = np.argsort(xyz_proj[:,0])
10229
+ xyz_proj = xyz_proj[idx]
10230
+
10231
+ return xyz_proj
10232
+
10233
+ newvector = vector(name = self.selected_object.idx + '_vector_sel', fromnumpy= approximate_vector(xyz))
10234
+ self.active_zone.add_vector(newvector, forceparent=True)
10235
+ self.active_zone.parent.find_minmax(True)
10236
+ self.active_zone.parent.reset_listogl()
10237
+
10238
+ self.active_zone.parent.fill_structure()
10239
+ self.Refresh()
10240
+
9569
10241
  elif _('Play') in text:
9570
10242
 
9571
- if isinstance(self.selected_object, Base_LAZ_Data):
10243
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9572
10244
  self.selected_object.play_flight()
9573
10245
 
10246
+ elif _('Add point') in text:
10247
+
10248
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
10249
+ self.selected_object.add_pose_in_memory()
10250
+
9574
10251
  elif _('Record') in text:
9575
10252
 
9576
- if isinstance(self.selected_object, Base_LAZ_Data):
10253
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9577
10254
 
9578
10255
  dlg = wx.DirDialog(self, _('Choose a directory to save the video'), style=wx.DD_DEFAULT_STYLE)
9579
10256
  if dlg.ShowModal() == wx.ID_OK:
@@ -9583,7 +10260,7 @@ class WolfMapViewer(wx.Frame):
9583
10260
 
9584
10261
  elif _('Load flight') in text:
9585
10262
 
9586
- if isinstance(self.selected_object, Base_LAZ_Data):
10263
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9587
10264
  dlg = wx.FileDialog(self, _('Choose a file to load the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_OPEN)
9588
10265
  if dlg.ShowModal() == wx.ID_OK:
9589
10266
  self.selected_object.load_flight(dlg.GetPath())
@@ -9592,7 +10269,7 @@ class WolfMapViewer(wx.Frame):
9592
10269
 
9593
10270
  elif _('Save flight') in text:
9594
10271
 
9595
- if isinstance(self.selected_object, Base_LAZ_Data):
10272
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
9596
10273
  dlg = wx.FileDialog(self, _('Choose a file to save the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_SAVE)
9597
10274
  if dlg.ShowModal() == wx.ID_OK:
9598
10275
  self.selected_object.save_flight(dlg.GetPath())
@@ -10311,14 +10988,27 @@ class WolfMapViewer(wx.Frame):
10311
10988
 
10312
10989
  self.mousex = self.mousedown[0]
10313
10990
  self.mousey = self.mousedown[1]
10314
- self.mousedown = (0., 0.)
10991
+ # self.mousedown = (0., 0.)
10315
10992
  self.oneclick = False
10316
10993
  self.setbounds()
10317
10994
 
10318
10995
  if ctrldown:
10319
- if self.active_viewer3d is not None:
10320
- self.active_viewer3d.force_view(self.mousex, self.mousey, self.active_array.get_value(self.mousex, self.mousey))
10321
- self.Refresh()
10996
+ if self.active_array is not None:
10997
+ if self.active_viewer3d is not None:
10998
+ self.active_viewer3d.force_view(self.mousex, self.mousey, self.active_array.get_value(self.mousex, self.mousey))
10999
+ self.Refresh()
11000
+
11001
+ if self.active_laz is not None:
11002
+ if self.active_laz.viewer is not None:
11003
+ self.active_laz.force_view(self.mousex, self.mousey, self.active_array.get_value(self.mousex, self.mousey))
11004
+ else:
11005
+ if self.active_viewer3d is not None:
11006
+ self.active_viewer3d.force_view(self.mousex, self.mousey)
11007
+ self.Refresh()
11008
+
11009
+ if self.active_laz is not None:
11010
+ if self.active_laz.viewer is not None:
11011
+ self.active_laz.force_view(self.mousex, self.mousey)
10322
11012
 
10323
11013
  def OnLDown(self, e):
10324
11014
 
@@ -10384,7 +11074,7 @@ class WolfMapViewer(wx.Frame):
10384
11074
  if ctrl:
10385
11075
  myobj.show_properties()
10386
11076
 
10387
- elif type(myobj) == Base_LAZ_Data:
11077
+ elif type(myobj) == Wolf_LAZ_Data:
10388
11078
 
10389
11079
  self.active_laz = myobj
10390
11080
 
@@ -11857,6 +12547,19 @@ class WolfMapViewer(wx.Frame):
11857
12547
  self.active_vertex = None
11858
12548
  self.active_cloud = None
11859
12549
 
12550
+ self.active_laz = None
12551
+
12552
+ self.active_fig = None
12553
+ self.active_bridge = None
12554
+ self.active_bridges = None
12555
+ self.active_bc = None
12556
+ self.active_cs = None
12557
+ self.active_imagestiles = None
12558
+ self.active_landmap = None
12559
+ self.active_profile = None
12560
+ self.active_tri = None
12561
+ self.active_viewer3d = None
12562
+
11860
12563
  self.set_statusbar_text(_('Esc pressed - No more action in progress - No more active object'))
11861
12564
  self.set_label_selecteditem('')
11862
12565
 
@@ -12021,11 +12724,19 @@ class WolfMapViewer(wx.Frame):
12021
12724
  self.active_array.myops.reset_all_selection()
12022
12725
  self.Refresh()
12023
12726
 
12727
+ if self.active_res2d is not None:
12728
+ self.active_res2d.SelectionData.reset_all()
12729
+ self.Refresh()
12730
+
12024
12731
  elif key == ord('R'): # r
12025
12732
  if self.active_array is not None:
12026
12733
  self.active_array.myops.reset_selection()
12027
12734
  self.Refresh()
12028
12735
 
12736
+ if self.active_res2d is not None:
12737
+ self.active_res2d.SelectionData.reset()
12738
+ self.Refresh()
12739
+
12029
12740
  elif key == ord('O'):
12030
12741
  # Active Opacity for the active array
12031
12742
 
@@ -12123,6 +12834,7 @@ class WolfMapViewer(wx.Frame):
12123
12834
  tracks.append(_('Edit colormap'))
12124
12835
  tracks.append(_('Set classification'))
12125
12836
  tracks.append(_('Convert to...'))
12837
+ tracks.append(_('Edit selection'))
12126
12838
  tracks.append(_('All to cloud'))
12127
12839
  tracks.append(_('Selection to cloud'))
12128
12840
 
@@ -12174,7 +12886,7 @@ class WolfMapViewer(wx.Frame):
12174
12886
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
12175
12887
  self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
12176
12888
 
12177
- if isinstance(self.selected_object, Base_LAZ_Data):
12889
+ if isinstance(self.selected_object, Wolf_LAZ_Data):
12178
12890
 
12179
12891
  colrmapmenu = wx.Menu()
12180
12892
  self.popupmenu.AppendSubMenu(colrmapmenu, _('Colormap'))
@@ -12188,12 +12900,16 @@ class WolfMapViewer(wx.Frame):
12188
12900
 
12189
12901
  converttomenu.Append(wx.ID_ANY, _('All to cloud'), _('Convert all to cloud'))
12190
12902
  converttomenu.Append(wx.ID_ANY, _('Selection to cloud'), _('Convert selection to cloud'))
12903
+ converttomenu.Append(wx.ID_ANY, _('Selection to vector'), _('Convert selection to vector'))
12904
+
12905
+ self.popupmenu.Append(wx.ID_ANY, _('Edit selection'), _('Edit selection'))
12191
12906
 
12192
12907
  moviemenu = wx.Menu()
12193
12908
  self.popupmenu.AppendSubMenu(moviemenu, _('Movie'))
12194
12909
 
12910
+ moviemenu.Append(wx.ID_ANY, _('Add point'), _('Add point passage'))
12195
12911
  moviemenu.Append(wx.ID_ANY, _('Play'), _('Play'))
12196
- moviemenu.Append(wx.ID_ANY, _('Record'), _('Record'))
12912
+ # moviemenu.Append(wx.ID_ANY, _('Record'), _('Record'))
12197
12913
  moviemenu.Append(wx.ID_ANY, _('Load flight'), _('Load flight'))
12198
12914
  moviemenu.Append(wx.ID_ANY, _('Save flight'), _('Save flight'))
12199
12915