wolfhece 2.1.117__py3-none-any.whl → 2.1.119__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/CpGrid.py +1 -1
- wolfhece/PyDraw.py +519 -101
- wolfhece/PyVertexvectors.py +5 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/laz_viewer.py +884 -12
- wolfhece/lazviewer/viewer/viewer.py +14 -4
- wolfhece/opengl/py3d.py +10 -4
- wolfhece/wolf_array.py +278 -5
- wolfhece/wolf_vrt.py +18 -17
- {wolfhece-2.1.117.dist-info → wolfhece-2.1.119.dist-info}/METADATA +1 -1
- {wolfhece-2.1.117.dist-info → wolfhece-2.1.119.dist-info}/RECORD +14 -14
- {wolfhece-2.1.117.dist-info → wolfhece-2.1.119.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.117.dist-info → wolfhece-2.1.119.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.117.dist-info → wolfhece-2.1.119.dist-info}/top_level.txt +0 -0
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
|
@@ -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
|
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
|
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.")
|
@@ -557,6 +560,7 @@ class draw_type(Enum):
|
|
557
560
|
WMSFORE = 'wms-foreground'
|
558
561
|
TILES = 'tiles'
|
559
562
|
IMAGESTILES = 'imagestiles'
|
563
|
+
LAZ = 'laz'
|
560
564
|
|
561
565
|
class Colors_1to9(wx.Frame):
|
562
566
|
|
@@ -1171,6 +1175,8 @@ class WolfMapViewer(wx.Frame):
|
|
1171
1175
|
myimagestiles: list[ImagesTiles]
|
1172
1176
|
mypartsystems: list[Particle_system]
|
1173
1177
|
myviewers3d:list[Wolf_Viewer3D]
|
1178
|
+
mylazdata:list[Wolf_LAZ_Data]
|
1179
|
+
|
1174
1180
|
sim_explorers: dict[Wolfresults_2D:Sim_Explorer]
|
1175
1181
|
|
1176
1182
|
canvas: GLCanvas # canvas OpenGL
|
@@ -1196,10 +1202,12 @@ class WolfMapViewer(wx.Frame):
|
|
1196
1202
|
active_imagestiles: ImagesTiles
|
1197
1203
|
active_particle_system: Particle_system
|
1198
1204
|
active_viewer3d: Wolf_Viewer3D
|
1205
|
+
active_viewerlaz: viewerlaz
|
1199
1206
|
active_bridges: Bridges
|
1200
1207
|
active_bridge: Bridge
|
1201
1208
|
active_weirs : Weirs
|
1202
1209
|
active_weir : Weir
|
1210
|
+
active_laz : Wolf_LAZ_Data
|
1203
1211
|
|
1204
1212
|
def __init__(self,
|
1205
1213
|
wxparent = None,
|
@@ -1275,9 +1283,7 @@ class WolfMapViewer(wx.Frame):
|
|
1275
1283
|
self.forcemimic = True
|
1276
1284
|
self.currently_readresults = False
|
1277
1285
|
|
1278
|
-
self.
|
1279
|
-
# self.mylazdata_colors = None
|
1280
|
-
self.mylazgrid = None
|
1286
|
+
self.mylazgrid:xyz_laz_grids = None # LAZ grid preprocessed by Numpy
|
1281
1287
|
|
1282
1288
|
self.colors1to9 = Colors_1to9(self)
|
1283
1289
|
|
@@ -1309,7 +1315,7 @@ class WolfMapViewer(wx.Frame):
|
|
1309
1315
|
self.menuimagestiles = None
|
1310
1316
|
|
1311
1317
|
self.filemenu = wx.Menu()
|
1312
|
-
openitem = self.filemenu.Append(wx.ID_OPEN, _('Open/Add project'), _('Open a
|
1318
|
+
openitem = self.filemenu.Append(wx.ID_OPEN, _('Open/Add project'), _('Open a full project from file'))
|
1313
1319
|
saveproject = self.filemenu.Append(wx.ID_ANY, _('Save project as...'), _('Save the current project to file'))
|
1314
1320
|
self.filemenu.AppendSeparator()
|
1315
1321
|
saveitem = self.filemenu.Append(wx.ID_SAVE, _('Save'), _('Save all checked arrays or vectors to files'))
|
@@ -1535,6 +1541,7 @@ class WolfMapViewer(wx.Frame):
|
|
1535
1541
|
self.active_res2d = None
|
1536
1542
|
self.active_particle_system = None
|
1537
1543
|
self.active_viewer3d = None
|
1544
|
+
self.active_viewerlaz = None
|
1538
1545
|
self.active_landmap:PlansTerrier = None
|
1539
1546
|
self.active_tile = None
|
1540
1547
|
self.selected_treeitem = None
|
@@ -1543,6 +1550,7 @@ class WolfMapViewer(wx.Frame):
|
|
1543
1550
|
self.active_bridge = None
|
1544
1551
|
self.active_weirs = None
|
1545
1552
|
self.active_weir = None
|
1553
|
+
self.active_laz = None
|
1546
1554
|
|
1547
1555
|
curtool = self.tools[ID_SORTALONG] = {}
|
1548
1556
|
curtool['menu'] = self.sortalong
|
@@ -1591,14 +1599,15 @@ class WolfMapViewer(wx.Frame):
|
|
1591
1599
|
|
1592
1600
|
self.root = self.treelist.GetRootItem()
|
1593
1601
|
self.treelist.AppendColumn(_('Objects to plot'))
|
1594
|
-
self.myitemsarray
|
1602
|
+
self.myitemsarray = self.treelist.AppendItem(self.root, _("Arrays"))
|
1595
1603
|
self.myitemsvector = self.treelist.AppendItem(self.root, _("Vectors"))
|
1596
|
-
self.myitemscloud
|
1597
|
-
self.
|
1598
|
-
self.
|
1599
|
-
self.
|
1604
|
+
self.myitemscloud = self.treelist.AppendItem(self.root, _("Clouds"))
|
1605
|
+
self.myitemslaz = self.treelist.AppendItem(self.root, _("Laz"))
|
1606
|
+
self.myitemstri = self.treelist.AppendItem(self.root, _("Triangulations"))
|
1607
|
+
self.myitemsres2d = self.treelist.AppendItem(self.root, _("Wolf2D"))
|
1608
|
+
self.myitemsps = self.treelist.AppendItem(self.root, _("Particle systems"))
|
1600
1609
|
self.myitemsothers = self.treelist.AppendItem(self.root, _("Others"))
|
1601
|
-
self.myitemsviews
|
1610
|
+
self.myitemsviews = self.treelist.AppendItem(self.root, _("Views"))
|
1602
1611
|
self.myitemswmsback = self.treelist.AppendItem(self.root, _("WMS-background"))
|
1603
1612
|
self.myitemswmsfore = self.treelist.AppendItem(self.root, _("WMS-foreground"))
|
1604
1613
|
|
@@ -1922,17 +1931,20 @@ class WolfMapViewer(wx.Frame):
|
|
1922
1931
|
self.menulaz.AppendSubMenu(self.menulazdata, _('LAZ data'))
|
1923
1932
|
self.menulaz.AppendSubMenu(self.menulazgrid, _('LAZ grid'))
|
1924
1933
|
|
1925
|
-
readlaz = self.menulazdata.Append(wx.ID_ANY, _('Initialize from npz'), _('LAZ from
|
1926
|
-
readlaz_gridinfo = self.menulazgrid.Append(wx.ID_ANY, _('Initialize from
|
1934
|
+
readlaz = self.menulazdata.Append(wx.ID_ANY, _('Initialize from laz, las or npz'), _('LAZ data from one specific file (type laz, las or npz)'))
|
1935
|
+
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)
|
1936
|
+
updatecolors_laz = self.menulazgrid.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
|
1927
1937
|
|
1928
|
-
bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('LAZ
|
1929
|
-
buildinglaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from buildings'), _('LAZ
|
1938
|
+
bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('Extract bridge from LAZ data as cloud points (class 10)'))
|
1939
|
+
buildinglaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from buildings'), _('Extract buildings from LAZ data as cloud points (class 1)'))
|
1940
|
+
classlaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from specified classes'), _('Extract cloud points from LAZ data (class to specify)'))
|
1930
1941
|
|
1931
1942
|
croplaz = self.menulaz.Append(wx.ID_ANY, _('Clip LAZ grid on current zoom'), _('Select LAZ data based on the visible screen extent'),)
|
1932
1943
|
viewlaz = self.menulaz.Append(wx.ID_ANY, _('Create LAZ viewer'), _('Create a LAZ Viewer based on loaded data'))
|
1944
|
+
filterlaz = self.menulaz.Append(wx.ID_ANY, _('Filter data based on codes'), _('Filter LAZ data based on codes'),)
|
1945
|
+
descimate_laz = self.menulaz.Append(wx.ID_ANY, _('Descimate LAZ data'), _('Descimate LAZ data'),)
|
1933
1946
|
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'),)
|
1934
1947
|
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'),)
|
1935
|
-
updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
|
1936
1948
|
fillarray_laz = self.menulaz.Append(wx.ID_ANY, _('Fill active array from LAZ data'), _('Fill an array from the LAZ data'),)
|
1937
1949
|
selectarray_laz = self.menulaz.Append(wx.ID_ANY, _('Select cells in array from LAZ data'), _('Select nodes in active array from the LAZ data'),)
|
1938
1950
|
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'),)
|
@@ -3890,10 +3902,13 @@ class WolfMapViewer(wx.Frame):
|
|
3890
3902
|
self.mywmsfore = []
|
3891
3903
|
self.myres2D = []
|
3892
3904
|
self.myviewers3d = []
|
3905
|
+
self.myviewerslaz = []
|
3906
|
+
self.mylazdata = []
|
3907
|
+
|
3893
3908
|
self.sim_explorers = {}
|
3894
3909
|
|
3895
3910
|
# liste des éléments modifiable dans l'arbre
|
3896
|
-
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]
|
3911
|
+
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]
|
3897
3912
|
|
3898
3913
|
self.menu_options = wx.Menu()
|
3899
3914
|
self._change_title = self.menu_options.Append(wx.ID_ANY, _('Change title'), _('Change title of the window'))
|
@@ -3995,7 +4010,7 @@ class WolfMapViewer(wx.Frame):
|
|
3995
4010
|
self.ymin = self.mousey - height / 2.
|
3996
4011
|
self.ymax = self.ymin + height
|
3997
4012
|
|
3998
|
-
def setbounds(self,updatescale=True):
|
4013
|
+
def setbounds(self, updatescale=True):
|
3999
4014
|
"""
|
4000
4015
|
Calcule les limites visibles de la fenêtrte graphique sur base des
|
4001
4016
|
facteurs d'échelle courants
|
@@ -5524,22 +5539,66 @@ class WolfMapViewer(wx.Frame):
|
|
5524
5539
|
""" Clip laz grid on current zoom """
|
5525
5540
|
|
5526
5541
|
if self.mylazgrid is None:
|
5542
|
+
logging.warning(_('No laz grid -- Please initialize it !'))
|
5527
5543
|
return
|
5528
5544
|
|
5529
5545
|
curbounds = [[self.xmin, self.xmin + self.width], [self.ymin, self.ymin + self.height]]
|
5530
5546
|
|
5531
|
-
self.
|
5547
|
+
if self.active_laz is None:
|
5548
|
+
newobj = Wolf_LAZ_Data()
|
5549
|
+
newobj.classification = self.mylazgrid.colors
|
5550
|
+
newobj.from_grid(self.mylazgrid, curbounds)
|
5551
|
+
|
5552
|
+
self.add_object('laz', newobj= newobj)
|
5553
|
+
|
5554
|
+
else:
|
5555
|
+
dlg = wx.MessageDialog(None, _('Do you want to keep the current data ?'), _('Keep data ?'), wx.YES_NO | wx.ICON_QUESTION)
|
5556
|
+
ret = dlg.ShowModal()
|
5557
|
+
|
5558
|
+
if ret == wx.ID_YES:
|
5559
|
+
newobj = Wolf_LAZ_Data()
|
5560
|
+
newobj.classification = self.mylazgrid.colors
|
5561
|
+
newobj.from_grid(self.mylazgrid, curbounds)
|
5562
|
+
|
5563
|
+
self.add_object('laz', newobj= newobj)
|
5564
|
+
|
5565
|
+
else:
|
5566
|
+
|
5567
|
+
self.active_laz.from_grid(self.mylazgrid, curbounds)
|
5532
5568
|
|
5533
|
-
logging.info(_('Clip LAZ grid on current zoom
|
5569
|
+
logging.info(_('Clip LAZ grid on current zoom'))
|
5570
|
+
logging.info(_('Bounds {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
|
5571
|
+
logging.info(_('Nb points : {}').format(self.active_laz.num_points))
|
5534
5572
|
|
5535
|
-
def
|
5536
|
-
"""
|
5573
|
+
def filter_active_laz(self):
|
5574
|
+
""" Filter active laz data """
|
5537
5575
|
|
5538
|
-
if self.
|
5576
|
+
if self.active_laz is None:
|
5539
5577
|
logging.warning(_('No laz data'))
|
5540
5578
|
return
|
5541
5579
|
|
5542
|
-
|
5580
|
+
codes = self.active_laz.codes_unique()
|
5581
|
+
|
5582
|
+
names = [self.active_laz.classification.classification[curcode][0] for curcode in codes]
|
5583
|
+
|
5584
|
+
with wx.MultiChoiceDialog(None, _('Choose the codes to keep'), _('Codes'), names) as dlg:
|
5585
|
+
if dlg.ShowModal() == wx.ID_OK:
|
5586
|
+
used_codes = dlg.GetSelections()
|
5587
|
+
used_codes = [codes[cur] for cur in used_codes]
|
5588
|
+
self.active_laz.filter_data(used_codes)
|
5589
|
+
|
5590
|
+
logging.info(_('Filter done - Nb points : {}').format(self.active_laz.num_points))
|
5591
|
+
else:
|
5592
|
+
logging.info(_('Filter cancelled'))
|
5593
|
+
|
5594
|
+
def descimate_laz_data(self, factor:int = 10):
|
5595
|
+
""" Descimate data """
|
5596
|
+
|
5597
|
+
if self.active_laz is None:
|
5598
|
+
logging.warning(_('No laz data'))
|
5599
|
+
return
|
5600
|
+
|
5601
|
+
self.active_laz.descimate(factor)
|
5543
5602
|
|
5544
5603
|
def select_active_array_from_laz(self, array:WolfArray = None, used_codes:list = None, chunk_size:float = 500.):
|
5545
5604
|
""" select some nodes from laz data
|
@@ -5548,6 +5607,7 @@ class WolfMapViewer(wx.Frame):
|
|
5548
5607
|
:param used_codes: codes to use
|
5549
5608
|
"""
|
5550
5609
|
if self.mylazgrid is None:
|
5610
|
+
logging.info(_('No laz grid - Aborting !'))
|
5551
5611
|
return
|
5552
5612
|
|
5553
5613
|
if array is None:
|
@@ -5581,19 +5641,19 @@ class WolfMapViewer(wx.Frame):
|
|
5581
5641
|
curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
|
5582
5642
|
|
5583
5643
|
logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
|
5584
|
-
|
5644
|
+
mylazdata = self.mylazgrid.scan(curbounds)
|
5585
5645
|
# logging.info(_('Scan done'))
|
5586
5646
|
|
5587
5647
|
data = {}
|
5588
5648
|
for curcode in used_codes:
|
5589
|
-
data[curcode] =
|
5649
|
+
data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
|
5590
5650
|
|
5591
5651
|
for curdata in data.values():
|
5592
5652
|
|
5593
5653
|
if curdata.shape[0] == 0:
|
5594
5654
|
continue
|
5595
5655
|
|
5596
|
-
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5656
|
+
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5597
5657
|
|
5598
5658
|
keys = np.vstack((i,j)).T
|
5599
5659
|
|
@@ -5616,6 +5676,7 @@ class WolfMapViewer(wx.Frame):
|
|
5616
5676
|
"""
|
5617
5677
|
|
5618
5678
|
if self.mylazgrid is None:
|
5679
|
+
logging.info(_('No laz grid - Aborting !'))
|
5619
5680
|
return
|
5620
5681
|
|
5621
5682
|
if array is None:
|
@@ -5679,16 +5740,16 @@ class WolfMapViewer(wx.Frame):
|
|
5679
5740
|
curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
|
5680
5741
|
|
5681
5742
|
logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
|
5682
|
-
|
5743
|
+
mylazdata = self.mylazgrid.scan(curbounds)
|
5683
5744
|
# logging.info(_('Scan done'))
|
5684
5745
|
|
5685
|
-
if len(
|
5746
|
+
if len(mylazdata) == 0:
|
5686
5747
|
continue
|
5687
5748
|
|
5688
5749
|
# Test codes
|
5689
5750
|
data = {}
|
5690
5751
|
for curcode in used_codes:
|
5691
|
-
data[curcode] =
|
5752
|
+
data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
|
5692
5753
|
|
5693
5754
|
# Treat data for each code
|
5694
5755
|
for curdata in data.values():
|
@@ -5699,7 +5760,7 @@ class WolfMapViewer(wx.Frame):
|
|
5699
5760
|
logging.info(_('Code {} : {} points'.format(curdata[0,3], curdata.shape[0])))
|
5700
5761
|
|
5701
5762
|
# get i,j from x,y
|
5702
|
-
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5763
|
+
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5703
5764
|
|
5704
5765
|
# keep only valid points -- inside the array
|
5705
5766
|
used = np.where((i >=0) & (i < array.nbx) & (j >=0) & (j < array.nby))[0]
|
@@ -5766,6 +5827,7 @@ class WolfMapViewer(wx.Frame):
|
|
5766
5827
|
"""
|
5767
5828
|
|
5768
5829
|
if self.mylazgrid is None:
|
5830
|
+
logging.info(_('No laz grid - Aborting !'))
|
5769
5831
|
return
|
5770
5832
|
|
5771
5833
|
if array is None:
|
@@ -5801,15 +5863,15 @@ class WolfMapViewer(wx.Frame):
|
|
5801
5863
|
curbounds = [[curx, curx + chunk_size], [cury, cury + chunk_size]]
|
5802
5864
|
|
5803
5865
|
logging.info(_('Scan {}-{} {}-{}').format(curbounds[0][0],curbounds[0][1],curbounds[1][0],curbounds[1][1]))
|
5804
|
-
|
5866
|
+
mylazdata = self.mylazgrid.scan(curbounds)
|
5805
5867
|
|
5806
|
-
if len(
|
5868
|
+
if len(mylazdata) == 0:
|
5807
5869
|
continue
|
5808
5870
|
|
5809
5871
|
# Test codes
|
5810
5872
|
data = {}
|
5811
5873
|
for curcode in used_codes:
|
5812
|
-
data[curcode] =
|
5874
|
+
data[curcode] = mylazdata[mylazdata[:, 3] == curcode]
|
5813
5875
|
|
5814
5876
|
# Treat data for each code
|
5815
5877
|
for curdata in data.values():
|
@@ -5820,7 +5882,7 @@ class WolfMapViewer(wx.Frame):
|
|
5820
5882
|
logging.info(_('Code {} : {} points'.format(curdata[0,3], curdata.shape[0])))
|
5821
5883
|
|
5822
5884
|
# get i,j from x,y
|
5823
|
-
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5885
|
+
i,j = array.get_ij_from_xy(curdata[:, 0], curdata[:, 1])
|
5824
5886
|
|
5825
5887
|
# keep only valid points -- inside the array
|
5826
5888
|
used = np.where((i >=0) & (i < array.nbx) & (j >=0) & (j < array.nby))[0]
|
@@ -5877,26 +5939,48 @@ class WolfMapViewer(wx.Frame):
|
|
5877
5939
|
|
5878
5940
|
logging.info(_('Counting done'))
|
5879
5941
|
|
5880
|
-
def
|
5881
|
-
""" Read LAZ data stored in
|
5942
|
+
def init_laz_from_lazlasnpz(self, fn=None):
|
5943
|
+
""" Read LAZ data stored in one file
|
5944
|
+
|
5945
|
+
:param fn: filename (extension .laz, .las, .npz)
|
5946
|
+
"""
|
5882
5947
|
|
5883
5948
|
if fn is None:
|
5884
5949
|
filternpz = "npz (*.npz)|*.npz|LAZ (*.laz)|*.laz|LAS (*.las)|*.las|all (*.*)|*.*"
|
5885
|
-
dlg = wx.FileDialog(None, _('Choose LAS
|
5950
|
+
dlg = wx.FileDialog(None, _('Choose a file containing LAS data'), wildcard=filternpz)
|
5886
5951
|
ret = dlg.ShowModal()
|
5887
5952
|
if ret != wx.ID_OK:
|
5953
|
+
dlg.Destroy()
|
5888
5954
|
return
|
5889
5955
|
|
5890
5956
|
fn = dlg.GetPath()
|
5957
|
+
dlg.Destroy()
|
5958
|
+
|
5959
|
+
self.mylazdata.append(Wolf_LAZ_Data())
|
5960
|
+
self.active_laz = self.mylazdata[-1]
|
5961
|
+
self.active_laz.from_file(fn)
|
5891
5962
|
|
5892
|
-
|
5893
|
-
|
5894
|
-
# self.mylazdata_colors.init_2023()
|
5963
|
+
logging.info(_('LAZ data read from file : ')+ fn)
|
5964
|
+
logging.info(_('Stored in internal variable'))
|
5895
5965
|
|
5896
5966
|
if self.linked:
|
5897
5967
|
if len(self.linkedList) > 0:
|
5898
5968
|
for curframe in self.linkedList:
|
5899
|
-
curframe
|
5969
|
+
if not curframe is self:
|
5970
|
+
curframe.mylazdata.append(self.active_laz)
|
5971
|
+
|
5972
|
+
def _choice_laz_classification(self):
|
5973
|
+
|
5974
|
+
dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
|
5975
|
+
ret = dlg.ShowModal()
|
5976
|
+
if ret != wx.ID_OK:
|
5977
|
+
dlg.Destroy()
|
5978
|
+
return None
|
5979
|
+
|
5980
|
+
classification = dlg.GetStringSelection()
|
5981
|
+
dlg.Destroy()
|
5982
|
+
|
5983
|
+
return classification
|
5900
5984
|
|
5901
5985
|
def init_laz_from_gridinfos(self, dirlaz:str = None, classification:Literal['SPW-Geofit 2023', 'SPW 2013-2014'] = 'SPW-Geofit 2023'):
|
5902
5986
|
|
@@ -5911,15 +5995,13 @@ class WolfMapViewer(wx.Frame):
|
|
5911
5995
|
self.mylazgrid = xyz_laz_grids(dirlaz)
|
5912
5996
|
|
5913
5997
|
if classification not in ['SPW-Geofit 2023', 'SPW 2013-2014']:
|
5914
|
-
dlg = wx.SingleChoiceDialog(None, _('Choose the classification'), _('Classification'), ['SPW-Geofit 2023', 'SPW 2013-2014'], wx.CHOICEDLG_STYLE)
|
5915
|
-
ret = dlg.ShowModal()
|
5916
|
-
if ret != wx.ID_OK:
|
5917
|
-
dlg.Destroy()
|
5918
|
-
return
|
5919
|
-
classification = dlg.GetStringSelection()
|
5920
|
-
dlg.Destroy()
|
5921
5998
|
|
5922
|
-
|
5999
|
+
classification = self._choice_laz_classification()
|
6000
|
+
|
6001
|
+
if classification is None:
|
6002
|
+
logging.warning(_('No classification chosen - Abort !'))
|
6003
|
+
return
|
6004
|
+
elif classification == 'SPW 2013-2014':
|
5923
6005
|
self.mylazgrid.colors.init_2013()
|
5924
6006
|
else:
|
5925
6007
|
self.mylazgrid.colors.init_2023()
|
@@ -6129,15 +6211,23 @@ class WolfMapViewer(wx.Frame):
|
|
6129
6211
|
def _select_laz_source(self):
|
6130
6212
|
""" Select laz source """
|
6131
6213
|
|
6132
|
-
if self.
|
6133
|
-
logging.warning(_('No LAZ data loaded !'))
|
6214
|
+
if self.active_laz is None and self.mylazgrid is None:
|
6215
|
+
logging.warning(_('No LAZ data loaded/initialized !'))
|
6134
6216
|
return None
|
6135
|
-
elif self.
|
6217
|
+
elif self.active_laz is None:
|
6218
|
+
# No active laz data
|
6136
6219
|
laz_source = self.mylazgrid
|
6137
6220
|
elif self.mylazgrid is None:
|
6138
|
-
|
6221
|
+
# No laz grid
|
6222
|
+
laz_source = self.active_laz
|
6139
6223
|
else:
|
6140
|
-
|
6224
|
+
# We have both
|
6225
|
+
choices = [_('From active LAZ data'), _('From newly extracted data')]
|
6226
|
+
|
6227
|
+
keys = self.get_list_keys(draw_type.LAZ, None)
|
6228
|
+
if len(keys) > 1:
|
6229
|
+
choices.append(_('From multiple LAZ data'))
|
6230
|
+
|
6141
6231
|
dlg = wx.SingleChoiceDialog(None, _("Pick a data source"), "Choices", choices)
|
6142
6232
|
ret = dlg.ShowModal()
|
6143
6233
|
if ret == wx.ID_CANCEL:
|
@@ -6149,12 +6239,46 @@ class WolfMapViewer(wx.Frame):
|
|
6149
6239
|
dlg.Destroy()
|
6150
6240
|
|
6151
6241
|
if idx == 0:
|
6152
|
-
laz_source = self.
|
6153
|
-
|
6242
|
+
laz_source = self.active_laz
|
6243
|
+
elif idx == 1:
|
6154
6244
|
laz_source = self.mylazgrid
|
6245
|
+
else:
|
6246
|
+
dlg = wx.MultiChoiceDialog(None, _('Choose the LAZ data to use\n\nIf multiple, a new one will be created !'), _('LAZ data'), keys)
|
6247
|
+
if dlg.ShowModal() == wx.ID_OK:
|
6248
|
+
used_keys = dlg.GetSelections()
|
6249
|
+
used_keys = [keys[cur] for cur in used_keys]
|
6250
|
+
laz_source = Wolf_LAZ_Data()
|
6251
|
+
for curkey in used_keys:
|
6252
|
+
laz_source.merge(self.get_obj_from_id(curkey, draw_type.LAZ))
|
6253
|
+
|
6254
|
+
self.add_object('laz', newobj=laz_source, id = 'Merged LAZ data')
|
6255
|
+
dlg.Destroy()
|
6256
|
+
else:
|
6257
|
+
dlg.Destroy()
|
6258
|
+
return None
|
6155
6259
|
|
6156
6260
|
return laz_source
|
6157
6261
|
|
6262
|
+
def _choice_laz_colormap(self) -> int:
|
6263
|
+
|
6264
|
+
choices, ass_values = choices_laz_colormap()
|
6265
|
+
dlg = wx.SingleChoiceDialog(None, _("Pick a colormap"), "Choices", choices)
|
6266
|
+
|
6267
|
+
if self.active_laz is not None:
|
6268
|
+
dlg.SetSelection(ass_values.index(self.active_laz.associated_color))
|
6269
|
+
|
6270
|
+
ret = dlg.ShowModal()
|
6271
|
+
if ret == wx.ID_CANCEL:
|
6272
|
+
dlg.Destroy()
|
6273
|
+
return
|
6274
|
+
|
6275
|
+
colormap = dlg.GetStringSelection()
|
6276
|
+
idx = choices.index(colormap)
|
6277
|
+
dlg.Destroy()
|
6278
|
+
|
6279
|
+
return ass_values[idx]
|
6280
|
+
|
6281
|
+
|
6158
6282
|
def OnMenubar(self, event: wx.MenuEvent):
|
6159
6283
|
"""
|
6160
6284
|
Gestion des clicks sur le menu quel que soit le niveau
|
@@ -6498,7 +6622,13 @@ class WolfMapViewer(wx.Frame):
|
|
6498
6622
|
|
6499
6623
|
dlg.Destroy()
|
6500
6624
|
|
6501
|
-
|
6625
|
+
# Création d'un graphique matplotlib sous wx
|
6626
|
+
figmpl = MplFig()
|
6627
|
+
figmpl.presets()
|
6628
|
+
figmpl.Hide()
|
6629
|
+
fig, ax = figmpl.get_figax()
|
6630
|
+
|
6631
|
+
# fig, ax = self.active_vector.plot_mpl(True, False)
|
6502
6632
|
|
6503
6633
|
linkedarrays = self.get_linked_arrays()
|
6504
6634
|
|
@@ -6528,8 +6658,10 @@ class WolfMapViewer(wx.Frame):
|
|
6528
6658
|
ax.plot([curs-.1, curs+.1], [curz+tolval, curz+tolval], c='black', linewidth=0.5)
|
6529
6659
|
ax.plot([curs-.1, curs+.1], [curz-tolval, curz-tolval], c='black', linewidth=0.5)
|
6530
6660
|
|
6531
|
-
fig.canvas.draw()
|
6532
|
-
fig.canvas.flush_events()
|
6661
|
+
# fig.canvas.draw()
|
6662
|
+
# fig.canvas.flush_events()
|
6663
|
+
|
6664
|
+
figmpl.Show()
|
6533
6665
|
|
6534
6666
|
elif itemlabel == _("Compute and apply unique colormap on all..."):
|
6535
6667
|
self.uniquecolormap()
|
@@ -6550,6 +6682,7 @@ class WolfMapViewer(wx.Frame):
|
|
6550
6682
|
self.filter_inundation()
|
6551
6683
|
|
6552
6684
|
elif itemlabel == _("Plot active polygons..."):
|
6685
|
+
|
6553
6686
|
if self.active_zone is None:
|
6554
6687
|
logging.warning(_('No active zone ! -- please select a zone containing polygons !'))
|
6555
6688
|
return
|
@@ -6579,7 +6712,14 @@ class WolfMapViewer(wx.Frame):
|
|
6579
6712
|
logging.info(_('Sole polygon detected'))
|
6580
6713
|
plotzone = [self.active_zone]
|
6581
6714
|
|
6582
|
-
|
6715
|
+
# Création d'un graphique matplotlib sous wx
|
6716
|
+
figmpl = MplFig()
|
6717
|
+
figmpl.presets()
|
6718
|
+
figmpl.Hide()
|
6719
|
+
|
6720
|
+
fig, ax = figmpl.get_figax()
|
6721
|
+
|
6722
|
+
# fig, ax = plt.subplots(1, 1)
|
6583
6723
|
|
6584
6724
|
linkedarrays = {}
|
6585
6725
|
|
@@ -6620,9 +6760,12 @@ class WolfMapViewer(wx.Frame):
|
|
6620
6760
|
# sole polygon
|
6621
6761
|
plotzone[0].plot_linked_polygons(fig, ax, linkedarrays, linked_vec=linkedvecs)
|
6622
6762
|
|
6623
|
-
ax.grid()
|
6624
|
-
ax.legend()
|
6625
|
-
fig.show()
|
6763
|
+
# ax.grid()
|
6764
|
+
# ax.legend()
|
6765
|
+
# fig.show()
|
6766
|
+
|
6767
|
+
figmpl.Show()
|
6768
|
+
figmpl.CenterOnScreen()
|
6626
6769
|
|
6627
6770
|
elif itemlabel == _("Manage banks..."):
|
6628
6771
|
|
@@ -6801,18 +6944,20 @@ class WolfMapViewer(wx.Frame):
|
|
6801
6944
|
|
6802
6945
|
self.save_project(filename, absolute= abspath)
|
6803
6946
|
|
6804
|
-
elif itemlabel == _('Initialize from npz'):
|
6805
|
-
self.
|
6947
|
+
elif itemlabel == _('Initialize from laz, las or npz'):
|
6948
|
+
self.init_laz_from_lazlasnpz()
|
6806
6949
|
|
6807
|
-
elif itemlabel == _('Initialize from
|
6950
|
+
elif itemlabel == _('Initialize from directory'):
|
6808
6951
|
self.init_laz_from_gridinfos()
|
6809
6952
|
|
6810
6953
|
elif itemlabel == _('Create cloud points from bridges'):
|
6811
|
-
if self.mylazdata is None:
|
6812
|
-
self.init_laz_from_numpy()
|
6813
6954
|
|
6814
|
-
|
6955
|
+
if self.active_laz is None:
|
6956
|
+
self.init_laz_from_lazlasnpz()
|
6957
|
+
|
6958
|
+
mybridges = self.active_laz.get_data_class(10)
|
6815
6959
|
mycloud = cloud_vertices()
|
6960
|
+
|
6816
6961
|
mycloud.init_from_nparray(mybridges)
|
6817
6962
|
mycloud.myprop.style = 2
|
6818
6963
|
mycloud.myprop.color = getIfromRGB([255, 102, 102])
|
@@ -6827,11 +6972,12 @@ class WolfMapViewer(wx.Frame):
|
|
6827
6972
|
|
6828
6973
|
elif itemlabel == _('Create cloud points from buildings'):
|
6829
6974
|
|
6830
|
-
if self.
|
6831
|
-
self.
|
6975
|
+
if self.active_laz is None:
|
6976
|
+
self.init_laz_from_lazlasnpz()
|
6832
6977
|
|
6833
|
-
mybuildings = self.
|
6978
|
+
mybuildings = self.active_laz.get_data_class(1)
|
6834
6979
|
mycloud = cloud_vertices()
|
6980
|
+
|
6835
6981
|
mycloud.init_from_nparray(mybuildings)
|
6836
6982
|
mycloud.myprop.style = 2
|
6837
6983
|
mycloud.myprop.color = getIfromRGB([102, 102, 102])
|
@@ -6843,23 +6989,15 @@ class WolfMapViewer(wx.Frame):
|
|
6843
6989
|
else:
|
6844
6990
|
self.add_object('cloud', newobj=mycloud, ToCheck=True, id='Buildings')
|
6845
6991
|
|
6992
|
+
elif itemlabel == _('Create cloud points from specified classes'):
|
6993
|
+
pass
|
6994
|
+
|
6846
6995
|
elif itemlabel == _('Create LAZ viewer'):
|
6847
6996
|
|
6848
6997
|
laz_source = self._select_laz_source()
|
6849
6998
|
if laz_source is None:
|
6850
6999
|
return
|
6851
7000
|
|
6852
|
-
choices, ass_values = choices_laz_colormap()
|
6853
|
-
dlg = wx.SingleChoiceDialog(None, _("Pick a colormap"), "Choices", choices)
|
6854
|
-
ret = dlg.ShowModal()
|
6855
|
-
if ret == wx.ID_CANCEL:
|
6856
|
-
dlg.Destroy()
|
6857
|
-
return
|
6858
|
-
|
6859
|
-
colormap = dlg.GetStringSelection()
|
6860
|
-
idx = choices.index(colormap)
|
6861
|
-
dlg.Destroy()
|
6862
|
-
|
6863
7001
|
if laz_source is self.mylazgrid:
|
6864
7002
|
if self.mylazgrid is None:
|
6865
7003
|
logging.warning(_('No gridded LAZ data loaded !'))
|
@@ -6867,9 +7005,43 @@ class WolfMapViewer(wx.Frame):
|
|
6867
7005
|
autoscale=False
|
6868
7006
|
self.clip_laz_gridded()
|
6869
7007
|
|
6870
|
-
self.
|
7008
|
+
self.active_laz.create_viewer(self._choice_laz_colormap(), self.mylazgrid.colors)
|
7009
|
+
self.myviewerslaz.append(self.active_laz.viewer)
|
7010
|
+
self.active_viewerlaz = self.myviewerslaz[-1]
|
7011
|
+
|
7012
|
+
# self.myviewer = myviewer(self.active_laz.data, ass_values[idx], palette_classif = self.mylazgrid.colors)
|
6871
7013
|
else:
|
6872
|
-
self.
|
7014
|
+
self.active_laz.create_viewer(classification= self.mylazgrid.colors)
|
7015
|
+
self.myviewerslaz.append(self.active_laz.viewer)
|
7016
|
+
self.active_viewerlaz = self.myviewerslaz[-1]
|
7017
|
+
|
7018
|
+
# self.myviewer = myviewer(laz_source.data, ass_values[idx], palette_classif= laz_source.classification)
|
7019
|
+
|
7020
|
+
elif itemlabel == _('Filter data based on codes'):
|
7021
|
+
|
7022
|
+
self.filter_active_laz()
|
7023
|
+
|
7024
|
+
elif itemlabel == _('Descimate LAZ data'):
|
7025
|
+
|
7026
|
+
if self.active_laz is None:
|
7027
|
+
return
|
7028
|
+
|
7029
|
+
# Choose a decimation factor - integer
|
7030
|
+
dlg = wx.NumberEntryDialog(None, _('Your dataset contains {} points.\nWould you like to descimate?').format(self.active_laz.num_points),
|
7031
|
+
_('Decaimate factor'), _('Decimation'), 0, 0, 100)
|
7032
|
+
|
7033
|
+
ret = dlg.ShowModal()
|
7034
|
+
|
7035
|
+
if ret == wx.ID_CANCEL:
|
7036
|
+
dlg.Destroy()
|
7037
|
+
return
|
7038
|
+
|
7039
|
+
descimate_fact = dlg.GetValue()
|
7040
|
+
dlg.Destroy()
|
7041
|
+
|
7042
|
+
if descimate_fact > 0:
|
7043
|
+
self.active_laz.descimate(descimate_fact)
|
7044
|
+
logging.info(_('New count : {}').format(self.active_laz.num_points))
|
6873
7045
|
|
6874
7046
|
elif itemlabel == _('Clip LAZ grid on current zoom'):
|
6875
7047
|
|
@@ -6879,14 +7051,15 @@ class WolfMapViewer(wx.Frame):
|
|
6879
7051
|
|
6880
7052
|
self.clip_laz_gridded()
|
6881
7053
|
|
6882
|
-
if self.
|
7054
|
+
if self.active_laz is None:
|
7055
|
+
logging.error(_('No data found'))
|
6883
7056
|
return
|
6884
7057
|
|
6885
|
-
if self.
|
7058
|
+
if self.active_laz.data.shape[0] > 100_000_000:
|
6886
7059
|
|
6887
7060
|
# Choose a decimation factor - integer
|
6888
|
-
dlg = wx.NumberEntryDialog(None, _('Your data selection is very large (>100 M)\nWould you like to
|
6889
|
-
_('
|
7061
|
+
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]),
|
7062
|
+
_('Descimate factor'), _('Decimation'), 0, 0, 100)
|
6890
7063
|
|
6891
7064
|
ret = dlg.ShowModal()
|
6892
7065
|
|
@@ -6894,11 +7067,11 @@ class WolfMapViewer(wx.Frame):
|
|
6894
7067
|
dlg.Destroy()
|
6895
7068
|
return
|
6896
7069
|
|
6897
|
-
|
7070
|
+
descimate_fact = dlg.GetValue()
|
6898
7071
|
dlg.Destroy()
|
6899
7072
|
|
6900
|
-
if
|
6901
|
-
self.
|
7073
|
+
if descimate_fact > 0:
|
7074
|
+
self.descimate_laz_data(descimate_fact)
|
6902
7075
|
|
6903
7076
|
elif itemlabel == _('Fill active array from LAZ data'):
|
6904
7077
|
|
@@ -7991,7 +8164,7 @@ class WolfMapViewer(wx.Frame):
|
|
7991
8164
|
'weirs',
|
7992
8165
|
'vector',
|
7993
8166
|
'tiles', 'tilescomp'
|
7994
|
-
'cloud',
|
8167
|
+
'cloud', 'laz',
|
7995
8168
|
'triangulation',
|
7996
8169
|
'cross_sections',
|
7997
8170
|
'other',
|
@@ -8011,12 +8184,13 @@ class WolfMapViewer(wx.Frame):
|
|
8011
8184
|
Add object to current Frame/Drawing area
|
8012
8185
|
"""
|
8013
8186
|
|
8014
|
-
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 (*.*)|*.*"
|
8187
|
+
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 (*.*)|*.*"
|
8015
8188
|
filterjson = "json (*.json)|*.json|all (*.*)|*.*"
|
8016
8189
|
filterall = "all (*.*)|*.*"
|
8017
8190
|
filterres2d = "all (*.*)|*.*"
|
8018
8191
|
filterVector = "All supported formats|*.vec;*.vecz;*.dxf;*.shp|vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|dxf (*.dxf)|*.dxf|shp (*.shp)|*.shp|all (*.*)|*.*"
|
8019
8192
|
filterCloud = "xyz (*.xyz)|*.xyz|dxf (*.dxf)|*.dxf|text (*.txt)|*.txt|shp (*.shp)|*.shp|all (*.*)|*.*"
|
8193
|
+
filterlaz = "laz (*.laz)|*.laz|las (*.las)|*.las|Numpy (*.npz)|*.npz|all (*.*)|*.*"
|
8020
8194
|
filtertri = "tri (*.tri)|*.tri|text (*.txt)|*.txt|dxf (*.dxf)|*.dxf|gltf (*.gltf)|*.gltf|gltf binary (*.glb)|*.glb|*.*'all (*.*)|*.*"
|
8021
8195
|
filterCs = "vecz WOLF (*.vecz)|*.vecz|txt 2022 (*.txt)|*.txt|WOLF (*.sxy)|*.sxy|text 2000 (*.txt)|*.txt|all (*.*)|*.*"
|
8022
8196
|
filterimage = "Geotif (*.tif)|*.tif|all (*.*)|*.*"
|
@@ -8043,6 +8217,8 @@ class WolfMapViewer(wx.Frame):
|
|
8043
8217
|
file = wx.FileDialog(self, "Choose file", wildcard=filterVector)
|
8044
8218
|
elif which.lower() == 'cloud':
|
8045
8219
|
file = wx.FileDialog(self, "Choose file", wildcard=filterCloud)
|
8220
|
+
elif which.lower() == 'laz':
|
8221
|
+
file = wx.FileDialog(self, "Choose file", wildcard=filterlaz)
|
8046
8222
|
elif which.lower() == 'triangulation':
|
8047
8223
|
file = wx.FileDialog(self, "Choose file", wildcard=filtertri)
|
8048
8224
|
elif which.lower() == 'cross_sections':
|
@@ -8543,6 +8719,19 @@ class WolfMapViewer(wx.Frame):
|
|
8543
8719
|
self.myvectors.append(newobj)
|
8544
8720
|
newobj.mapviewer = self
|
8545
8721
|
|
8722
|
+
elif which.lower() =='laz':
|
8723
|
+
curdict = self.mylazdata
|
8724
|
+
curtree = self.myitemslaz
|
8725
|
+
|
8726
|
+
if newobj is None:
|
8727
|
+
newobj = Wolf_LAZ_Data(mapviewer=self)
|
8728
|
+
newobj.from_file(filename)
|
8729
|
+
|
8730
|
+
self.mylazdata.append(newobj)
|
8731
|
+
self.active_laz = newobj
|
8732
|
+
|
8733
|
+
newobj.set_mapviewer(self)
|
8734
|
+
|
8546
8735
|
elif which.lower() == 'cloud':
|
8547
8736
|
|
8548
8737
|
curdict = self.myclouds
|
@@ -8784,6 +8973,8 @@ class WolfMapViewer(wx.Frame):
|
|
8784
8973
|
return self.mywmsfore
|
8785
8974
|
elif drawing_type == draw_type.IMAGESTILES:
|
8786
8975
|
return self.myimagestiles
|
8976
|
+
elif drawing_type == draw_type.LAZ:
|
8977
|
+
return self.mylazdata
|
8787
8978
|
else:
|
8788
8979
|
logging.error('Unknown drawing type : ' + drawing_type)
|
8789
8980
|
return None
|
@@ -9214,10 +9405,20 @@ class WolfMapViewer(wx.Frame):
|
|
9214
9405
|
|
9215
9406
|
fdlg.Destroy()
|
9216
9407
|
|
9408
|
+
elif isinstance(self.selected_object, Wolf_LAZ_Data):
|
9409
|
+
filterArray = "Dump (*.dump)|*.dmp|all (*.*)|*.*"
|
9410
|
+
fdlg = wx.FileDialog(self, "Choose file name for LAZ data :" + self.selected_object.idx, wildcard=filterArray,
|
9411
|
+
style=wx.FD_SAVE)
|
9412
|
+
ret = fdlg.ShowModal()
|
9413
|
+
if ret == wx.ID_OK:
|
9414
|
+
self.selected_object.saveas(fdlg.GetPath())
|
9415
|
+
|
9416
|
+
fdlg.Destroy()
|
9417
|
+
|
9217
9418
|
elif text == _('Properties'):
|
9218
9419
|
|
9219
9420
|
myobj = self.selected_object
|
9220
|
-
if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir]:
|
9421
|
+
if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir, Wolf_LAZ_Data]:
|
9221
9422
|
myobj.show_properties()
|
9222
9423
|
|
9223
9424
|
elif isinstance(myobj, cloud_vertices):
|
@@ -9365,6 +9566,158 @@ class WolfMapViewer(wx.Frame):
|
|
9365
9566
|
self.selected_object.export_active_zone_to_shapefile(fdlg.GetPath())
|
9366
9567
|
fdlg.Destroy()
|
9367
9568
|
|
9569
|
+
elif _('Set colormap') in text:
|
9570
|
+
|
9571
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9572
|
+
self.selected_object.associated_color = self._choice_laz_colormap()
|
9573
|
+
|
9574
|
+
elif _('Edit colormap') in text:
|
9575
|
+
|
9576
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9577
|
+
self.selected_object.interactive_update_colors()
|
9578
|
+
|
9579
|
+
elif _('Set classification') in text:
|
9580
|
+
|
9581
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9582
|
+
self.selected_object.set_classification(self._choice_laz_classification())
|
9583
|
+
|
9584
|
+
elif _('Edit selection') in text:
|
9585
|
+
|
9586
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9587
|
+
self.selected_object._edit_selection()
|
9588
|
+
|
9589
|
+
elif _('All to cloud') in text:
|
9590
|
+
|
9591
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9592
|
+
|
9593
|
+
if self.selected_object.num_points > 100000:
|
9594
|
+
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)
|
9595
|
+
ret = dlg.ShowModal()
|
9596
|
+
|
9597
|
+
if ret != wx.ID_YES:
|
9598
|
+
dlg.Destroy()
|
9599
|
+
|
9600
|
+
return
|
9601
|
+
|
9602
|
+
newcloud = cloud_vertices()
|
9603
|
+
newcloud.init_from_nparray(self.selected_object.xyz)
|
9604
|
+
self.add_object('cloud', newobj=newcloud, id=self.selected_object.idx + '_cloud')
|
9605
|
+
|
9606
|
+
elif _('Selection to cloud') in text:
|
9607
|
+
|
9608
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9609
|
+
|
9610
|
+
xyz = self.selected_object.xyz_selected
|
9611
|
+
if xyz.shape[0] ==0:
|
9612
|
+
logging.warning('No points selected')
|
9613
|
+
return
|
9614
|
+
|
9615
|
+
if xyz.shape[0] > 100000:
|
9616
|
+
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)
|
9617
|
+
ret = dlg.ShowModal()
|
9618
|
+
|
9619
|
+
if ret != wx.ID_YES:
|
9620
|
+
dlg.Destroy()
|
9621
|
+
|
9622
|
+
return
|
9623
|
+
|
9624
|
+
newcloud = cloud_vertices()
|
9625
|
+
newcloud.init_from_nparray(xyz)
|
9626
|
+
self.add_object('cloud', newobj=newcloud, id=self.selected_object.idx + '_cloud_sel')
|
9627
|
+
|
9628
|
+
elif _('Selection to vector') in text:
|
9629
|
+
|
9630
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9631
|
+
|
9632
|
+
if self.active_zone is None:
|
9633
|
+
logging.warning(_('No active zone selected'))
|
9634
|
+
return
|
9635
|
+
|
9636
|
+
xyz = self.selected_object.xyz_selected
|
9637
|
+
if xyz.shape[0] ==0:
|
9638
|
+
logging.warning('No points selected')
|
9639
|
+
return
|
9640
|
+
|
9641
|
+
if xyz.shape[0] > 100000:
|
9642
|
+
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)
|
9643
|
+
ret = dlg.ShowModal()
|
9644
|
+
|
9645
|
+
if ret != wx.ID_YES:
|
9646
|
+
dlg.Destroy()
|
9647
|
+
|
9648
|
+
return
|
9649
|
+
|
9650
|
+
def approximate_vector(xyz):
|
9651
|
+
""" Get a cloud of points and return a vector
|
9652
|
+
based on the best approximated segment
|
9653
|
+
and points projected on its trace
|
9654
|
+
"""
|
9655
|
+
|
9656
|
+
# best approximation of the segment
|
9657
|
+
# based on the RANSAC algorithm from scikit-learn
|
9658
|
+
model = linear_model.RANSACRegressor()
|
9659
|
+
model.fit(xyz[:,0].reshape(-1,1), xyz[:,1])
|
9660
|
+
|
9661
|
+
# get the points projected on the segment
|
9662
|
+
proj = model.predict(xyz[:,0].reshape(-1,1))
|
9663
|
+
|
9664
|
+
# get the coordinates of the projected points
|
9665
|
+
xyz_proj = np.zeros((xyz.shape[0],3))
|
9666
|
+
xyz_proj[:,0] = xyz[:,0]
|
9667
|
+
xyz_proj[:,1] = proj
|
9668
|
+
xyz_proj[:,2] = xyz[:,2]
|
9669
|
+
|
9670
|
+
#Sort the points
|
9671
|
+
idx = np.argsort(xyz_proj[:,0])
|
9672
|
+
xyz_proj = xyz_proj[idx]
|
9673
|
+
|
9674
|
+
return xyz_proj
|
9675
|
+
|
9676
|
+
newvector = vector(name = self.selected_object.idx + '_vector_sel', fromnumpy= approximate_vector(xyz))
|
9677
|
+
self.active_zone.add_vector(newvector, forceparent=True)
|
9678
|
+
self.active_zone.parent.find_minmax(True)
|
9679
|
+
self.active_zone.parent.reset_listogl()
|
9680
|
+
|
9681
|
+
self.active_zone.parent.fill_structure()
|
9682
|
+
self.Refresh()
|
9683
|
+
|
9684
|
+
elif _('Play') in text:
|
9685
|
+
|
9686
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9687
|
+
self.selected_object.play_flight()
|
9688
|
+
|
9689
|
+
elif _('Add point') in text:
|
9690
|
+
|
9691
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9692
|
+
self.selected_object.add_pose_in_memory()
|
9693
|
+
|
9694
|
+
elif _('Record') in text:
|
9695
|
+
|
9696
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9697
|
+
|
9698
|
+
dlg = wx.DirDialog(self, _('Choose a directory to save the video'), style=wx.DD_DEFAULT_STYLE)
|
9699
|
+
if dlg.ShowModal() == wx.ID_OK:
|
9700
|
+
self.selected_object.record_flight(dlg.GetPath())
|
9701
|
+
|
9702
|
+
dlg.Destroy()
|
9703
|
+
|
9704
|
+
elif _('Load flight') in text:
|
9705
|
+
|
9706
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9707
|
+
dlg = wx.FileDialog(self, _('Choose a file to load the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_OPEN)
|
9708
|
+
if dlg.ShowModal() == wx.ID_OK:
|
9709
|
+
self.selected_object.load_flight(dlg.GetPath())
|
9710
|
+
|
9711
|
+
dlg.Destroy()
|
9712
|
+
|
9713
|
+
elif _('Save flight') in text:
|
9714
|
+
|
9715
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
9716
|
+
dlg = wx.FileDialog(self, _('Choose a file to save the flight'), wildcard='JSON (*.json)|*.json|All (*.*)|*.*', style=wx.FD_SAVE)
|
9717
|
+
if dlg.ShowModal() == wx.ID_OK:
|
9718
|
+
self.selected_object.save_flight(dlg.GetPath())
|
9719
|
+
|
9720
|
+
dlg.Destroy()
|
9368
9721
|
|
9369
9722
|
def OnClose(self, event):
|
9370
9723
|
""" Close the application """
|
@@ -10078,14 +10431,27 @@ class WolfMapViewer(wx.Frame):
|
|
10078
10431
|
|
10079
10432
|
self.mousex = self.mousedown[0]
|
10080
10433
|
self.mousey = self.mousedown[1]
|
10081
|
-
self.mousedown = (0., 0.)
|
10434
|
+
# self.mousedown = (0., 0.)
|
10082
10435
|
self.oneclick = False
|
10083
10436
|
self.setbounds()
|
10084
10437
|
|
10085
10438
|
if ctrldown:
|
10086
|
-
if self.
|
10087
|
-
self.active_viewer3d
|
10088
|
-
|
10439
|
+
if self.active_array is not None:
|
10440
|
+
if self.active_viewer3d is not None:
|
10441
|
+
self.active_viewer3d.force_view(self.mousex, self.mousey, self.active_array.get_value(self.mousex, self.mousey))
|
10442
|
+
self.Refresh()
|
10443
|
+
|
10444
|
+
if self.active_laz is not None:
|
10445
|
+
if self.active_laz.viewer is not None:
|
10446
|
+
self.active_laz.force_view(self.mousex, self.mousey, self.active_array.get_value(self.mousex, self.mousey))
|
10447
|
+
else:
|
10448
|
+
if self.active_viewer3d is not None:
|
10449
|
+
self.active_viewer3d.force_view(self.mousex, self.mousey)
|
10450
|
+
self.Refresh()
|
10451
|
+
|
10452
|
+
if self.active_laz is not None:
|
10453
|
+
if self.active_laz.viewer is not None:
|
10454
|
+
self.active_laz.force_view(self.mousex, self.mousey)
|
10089
10455
|
|
10090
10456
|
def OnLDown(self, e):
|
10091
10457
|
|
@@ -10151,6 +10517,13 @@ class WolfMapViewer(wx.Frame):
|
|
10151
10517
|
if ctrl:
|
10152
10518
|
myobj.show_properties()
|
10153
10519
|
|
10520
|
+
elif type(myobj) == Wolf_LAZ_Data:
|
10521
|
+
|
10522
|
+
self.active_laz = myobj
|
10523
|
+
|
10524
|
+
if ctrl:
|
10525
|
+
myobj.show_properties()
|
10526
|
+
|
10154
10527
|
elif type(myobj) == Bridge:
|
10155
10528
|
self.active_bridge = myobj
|
10156
10529
|
|
@@ -11825,6 +12198,10 @@ class WolfMapViewer(wx.Frame):
|
|
11825
12198
|
self.mousex = self.mousex + self.width / 10.
|
11826
12199
|
self.setbounds()
|
11827
12200
|
|
12201
|
+
elif key == ord('A'):
|
12202
|
+
if self.active_laz is not None:
|
12203
|
+
self.active_laz.add_pose_in_memory()
|
12204
|
+
|
11828
12205
|
def paste_values(self,fromarray:WolfArray):
|
11829
12206
|
""" Paste selected values from a WolfArray to the active array """
|
11830
12207
|
|
@@ -11875,6 +12252,20 @@ class WolfMapViewer(wx.Frame):
|
|
11875
12252
|
tracks.append(_('Export active zone to Shape file'))
|
11876
12253
|
tracks.append(_('Rebin'))
|
11877
12254
|
tracks.append(_('Set NullValue'))
|
12255
|
+
tracks.append(_('Set colormap'))
|
12256
|
+
tracks.append(_('Edit colormap'))
|
12257
|
+
tracks.append(_('Set classification'))
|
12258
|
+
tracks.append(_('Convert to...'))
|
12259
|
+
tracks.append(_('Edit selection'))
|
12260
|
+
tracks.append(_('All to cloud'))
|
12261
|
+
tracks.append(_('Selection to cloud'))
|
12262
|
+
|
12263
|
+
tracks.append(_('Colormap'))
|
12264
|
+
tracks.append(_('Movie'))
|
12265
|
+
tracks.append(_('Play'))
|
12266
|
+
tracks.append(_('Record'))
|
12267
|
+
tracks.append(_('Load flight'))
|
12268
|
+
tracks.append(_('Save flight'))
|
11878
12269
|
|
11879
12270
|
# Récupération des items du menu contextuel
|
11880
12271
|
menuitems = self.popupmenu.GetMenuItems()
|
@@ -11917,6 +12308,33 @@ class WolfMapViewer(wx.Frame):
|
|
11917
12308
|
self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
|
11918
12309
|
self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
|
11919
12310
|
|
12311
|
+
if isinstance(self.selected_object, Wolf_LAZ_Data):
|
12312
|
+
|
12313
|
+
colrmapmenu = wx.Menu()
|
12314
|
+
self.popupmenu.AppendSubMenu(colrmapmenu, _('Colormap'))
|
12315
|
+
|
12316
|
+
colrmapmenu.Append(wx.ID_ANY, _('Set colormap'), _('Change colormap'))
|
12317
|
+
colrmapmenu.Append(wx.ID_ANY, _('Edit colormap'), _('Edit colormap'))
|
12318
|
+
colrmapmenu.Append(wx.ID_ANY, _('Set classification'), _('Change classification'))
|
12319
|
+
|
12320
|
+
converttomenu = wx.Menu()
|
12321
|
+
self.popupmenu.AppendSubMenu(converttomenu, _('Convert to...'))
|
12322
|
+
|
12323
|
+
converttomenu.Append(wx.ID_ANY, _('All to cloud'), _('Convert all to cloud'))
|
12324
|
+
converttomenu.Append(wx.ID_ANY, _('Selection to cloud'), _('Convert selection to cloud'))
|
12325
|
+
converttomenu.Append(wx.ID_ANY, _('Selection to vector'), _('Convert selection to vector'))
|
12326
|
+
|
12327
|
+
self.popupmenu.Append(wx.ID_ANY, _('Edit selection'), _('Edit selection'))
|
12328
|
+
|
12329
|
+
moviemenu = wx.Menu()
|
12330
|
+
self.popupmenu.AppendSubMenu(moviemenu, _('Movie'))
|
12331
|
+
|
12332
|
+
moviemenu.Append(wx.ID_ANY, _('Add point'), _('Add point passage'))
|
12333
|
+
moviemenu.Append(wx.ID_ANY, _('Play'), _('Play'))
|
12334
|
+
# moviemenu.Append(wx.ID_ANY, _('Record'), _('Record'))
|
12335
|
+
moviemenu.Append(wx.ID_ANY, _('Load flight'), _('Load flight'))
|
12336
|
+
moviemenu.Append(wx.ID_ANY, _('Save flight'), _('Save flight'))
|
12337
|
+
|
11920
12338
|
self.treelist.PopupMenu(self.popupmenu)
|
11921
12339
|
|
11922
12340
|
def update(self):
|