wolfhece 2.2.8__py3-none-any.whl → 2.2.10__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 +94 -24
- wolfhece/PyGui.py +1 -0
- wolfhece/PyVertex.py +127 -19
- wolfhece/PyVertexvectors.py +73 -21
- wolfhece/__init__.py +5 -2
- wolfhece/apps/version.py +1 -1
- wolfhece/hydrology/Internal_variables.py +283 -0
- wolfhece/hydrology/Models_characteristics.py +223 -0
- wolfhece/hydrology/Optimisation.py +324 -14
- wolfhece/hydrology/SubBasin.py +112 -28
- wolfhece/hydrology/cst_exchanges.py +1 -0
- wolfhece/hydrometry/kiwis.py +8 -3
- wolfhece/lagrangian/particle_system_ui.py +1 -1
- wolfhece/lazviewer/processing/estimate_normals/estimate_normals.cp311-win_amd64.pyd +0 -0
- wolfhece/lazviewer/vfuncsdir/vfuncs.cp311-win_amd64.pyd +0 -0
- wolfhece/lazviewer/viewer/viewer.exe +0 -0
- wolfhece/lazviewer/viewer/viewer_310.exe +0 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/libs/get_infos.cp311-win_amd64.pyd +0 -0
- wolfhece/libs/verify_wolf.cp311-win_amd64.pyd +0 -0
- wolfhece/libs/wolfogl.cp311-win_amd64.pyd +0 -0
- wolfhece/pydike.py +1 -1
- wolfhece/pyviews.py +1 -1
- wolfhece/wolf_array.py +28 -6
- wolfhece-2.2.10.dist-info/METADATA +90 -0
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.10.dist-info}/RECORD +33 -21
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.10.dist-info}/WHEEL +1 -1
- {wolfhece-2.2.8.dist-info → wolfhece-2.3.0.dist-info}/METADATA +3 -3
- wolfhece-2.3.0.dist-info/WHEEL +5 -0
- wolfhece-2.3.0.dist-info/entry_points.txt +17 -0
- wolfhece-2.3.0.dist-info/top_level.txt +1 -0
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.10.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.10.dist-info}/top_level.txt +0 -0
wolfhece/PyDraw.py
CHANGED
@@ -2008,6 +2008,8 @@ class WolfMapViewer(wx.Frame):
|
|
2008
2008
|
self.treewidth = treewidth
|
2009
2009
|
super(WolfMapViewer, self).__init__(wxparent, title=title, size=(w + self.treewidth, h))
|
2010
2010
|
|
2011
|
+
self._tmp_vector_distance = None # distance computation the vector
|
2012
|
+
|
2011
2013
|
self._wxlogging = wxlogging
|
2012
2014
|
self.action = None # Action à entreprendre
|
2013
2015
|
self.update_absolute_minmax = False # Force la MAJ de la palette
|
@@ -4086,7 +4088,7 @@ class WolfMapViewer(wx.Frame):
|
|
4086
4088
|
if ret == wx.ID_NO:
|
4087
4089
|
return
|
4088
4090
|
|
4089
|
-
with wx.
|
4091
|
+
with wx.BusyInfo(_('Updating 2D model')):
|
4090
4092
|
wait = wx.BusyCursor()
|
4091
4093
|
|
4092
4094
|
sux,suy,cont,interior = self.active_array.suxsuy_contour(self.wolfparent.filenamegen,True)
|
@@ -4305,7 +4307,7 @@ class WolfMapViewer(wx.Frame):
|
|
4305
4307
|
if self.active_cloud is not None and self.active_array is not None:
|
4306
4308
|
|
4307
4309
|
keyvalue='z'
|
4308
|
-
if self.active_cloud.
|
4310
|
+
if self.active_cloud.has_values:
|
4309
4311
|
choices = list(self.active_cloud.myvertices[0].keys())
|
4310
4312
|
dlg = wx.SingleChoiceDialog(None, "Pick the value to interpolate", "Choices", choices)
|
4311
4313
|
ret = dlg.ShowModal()
|
@@ -5734,12 +5736,12 @@ class WolfMapViewer(wx.Frame):
|
|
5734
5736
|
fnpos = self.link_params['gltf pos']
|
5735
5737
|
break
|
5736
5738
|
|
5737
|
-
with wx.
|
5739
|
+
with wx.BusyInfo(_('Importing gltf/glb')):
|
5738
5740
|
wait = wx.BusyCursor()
|
5739
5741
|
sourcenew.import_from_gltf(fn, fnpos, 'scipy')
|
5740
5742
|
del wait
|
5741
5743
|
|
5742
|
-
with wx.
|
5744
|
+
with wx.BusyInfo(_('Update plots')):
|
5743
5745
|
# Création du différentiel -- Les opérateurs mathématiques sont surchargés
|
5744
5746
|
diff.array = (sourcenew - source).array
|
5745
5747
|
grad.array = sourcenew.get_gradient_norm().array
|
@@ -8986,7 +8988,7 @@ class WolfMapViewer(wx.Frame):
|
|
8986
8988
|
fn = dlg.GetPath()
|
8987
8989
|
dlg.Destroy()
|
8988
8990
|
|
8989
|
-
with wx.
|
8991
|
+
with wx.BusyInfo(_('Export to gltf/glb')):
|
8990
8992
|
wait = wx.BusyCursor()
|
8991
8993
|
curarray.export_to_gltf(mybounds, fn)
|
8992
8994
|
del wait
|
@@ -9037,7 +9039,7 @@ class WolfMapViewer(wx.Frame):
|
|
9037
9039
|
method = dlg.GetStringSelection()
|
9038
9040
|
dlg.Destroy()
|
9039
9041
|
|
9040
|
-
with wx.
|
9042
|
+
with wx.BusyInfo(_('Importing gltf/glb')):
|
9041
9043
|
wait = wx.BusyCursor()
|
9042
9044
|
try:
|
9043
9045
|
curarray.import_from_gltf(fn, fnpos, method)
|
@@ -9199,7 +9201,7 @@ class WolfMapViewer(wx.Frame):
|
|
9199
9201
|
dlg.Destroy()
|
9200
9202
|
return
|
9201
9203
|
|
9202
|
-
with wx.
|
9204
|
+
with wx.BusyInfo(_('Loading masks')):
|
9203
9205
|
wait = wx.BusyCursor()
|
9204
9206
|
curarray:WolfArray
|
9205
9207
|
for curarray in self.myarrays:
|
@@ -9830,7 +9832,7 @@ class WolfMapViewer(wx.Frame):
|
|
9830
9832
|
testobj.read_txt_header()
|
9831
9833
|
|
9832
9834
|
if testobj.wolftype in WOLF_ARRAY_MB:
|
9833
|
-
# with wx.
|
9835
|
+
# with wx.BusyInfo(_('Importing array')):
|
9834
9836
|
# wait = wx.BusyCursor()
|
9835
9837
|
# newobj = WolfArrayMB(filename, mapviewer=self)
|
9836
9838
|
# del wait
|
@@ -9839,7 +9841,7 @@ class WolfMapViewer(wx.Frame):
|
|
9839
9841
|
if which.lower() == 'array_crop':
|
9840
9842
|
newobj = WolfArray(filename, mapviewer=self, crop='newcrop')
|
9841
9843
|
else:
|
9842
|
-
# with wx.
|
9844
|
+
# with wx.BusyInfo(_('Importing array')):
|
9843
9845
|
# wait = wx.BusyCursor()
|
9844
9846
|
# newobj = WolfArray(filename, mapviewer=self)
|
9845
9847
|
# del wait
|
@@ -9945,7 +9947,7 @@ class WolfMapViewer(wx.Frame):
|
|
9945
9947
|
curtree = self.myitemsvector
|
9946
9948
|
|
9947
9949
|
if newobj is None:
|
9948
|
-
with wx.
|
9950
|
+
with wx.BusyInfo(_('Importing files')):
|
9949
9951
|
wait = wx.BusyCursor()
|
9950
9952
|
newobj = Bridges(filename, mapviewer=self)
|
9951
9953
|
del wait
|
@@ -9961,7 +9963,7 @@ class WolfMapViewer(wx.Frame):
|
|
9961
9963
|
curtree = self.myitemsvector
|
9962
9964
|
|
9963
9965
|
if newobj is None:
|
9964
|
-
with wx.
|
9966
|
+
with wx.BusyInfo(_('Importing files')):
|
9965
9967
|
wait = wx.BusyCursor()
|
9966
9968
|
newobj = Weirs(filename, mapviewer=self)
|
9967
9969
|
del wait
|
@@ -9996,7 +9998,7 @@ class WolfMapViewer(wx.Frame):
|
|
9996
9998
|
dirname_comp = file.GetPath()
|
9997
9999
|
file.Destroy()
|
9998
10000
|
|
9999
|
-
with wx.
|
10001
|
+
with wx.BusyInfo(_('Importing files')):
|
10000
10002
|
wait = wx.BusyCursor()
|
10001
10003
|
newobj = Tiles(filename, parent=self, linked_data_dir=dirname, mapviewer=self)
|
10002
10004
|
del wait
|
@@ -10152,7 +10154,7 @@ class WolfMapViewer(wx.Frame):
|
|
10152
10154
|
curtree = self.myitemsres2d
|
10153
10155
|
|
10154
10156
|
if newobj is None:
|
10155
|
-
with wx.
|
10157
|
+
with wx.BusyInfo(_('Importing 2D model')):
|
10156
10158
|
wait = wx.BusyCursor()
|
10157
10159
|
newobj = Wolfresults_2D(filename, mapviewer=self)
|
10158
10160
|
del wait
|
@@ -10168,7 +10170,7 @@ class WolfMapViewer(wx.Frame):
|
|
10168
10170
|
curtree = self.myitemsres2d
|
10169
10171
|
|
10170
10172
|
if newobj is None:
|
10171
|
-
with wx.
|
10173
|
+
with wx.BusyInfo(_('Importing 2D GPU model')):
|
10172
10174
|
wait = wx.BusyCursor()
|
10173
10175
|
newobj = wolfres2DGPU(filename, mapviewer=self)
|
10174
10176
|
del wait
|
@@ -10183,7 +10185,7 @@ class WolfMapViewer(wx.Frame):
|
|
10183
10185
|
curdict = self.myvectors
|
10184
10186
|
curtree = self.myitemsvector
|
10185
10187
|
if newobj is None:
|
10186
|
-
with wx.
|
10188
|
+
with wx.BusyInfo(_('Importing file')):
|
10187
10189
|
wait = wx.BusyCursor()
|
10188
10190
|
newobj = Zones(filename, parent=self)
|
10189
10191
|
del wait
|
@@ -10220,7 +10222,7 @@ class WolfMapViewer(wx.Frame):
|
|
10220
10222
|
if ret == wx.ID_OK:
|
10221
10223
|
dirlaz = dlg.GetPath()
|
10222
10224
|
|
10223
|
-
with wx.
|
10225
|
+
with wx.BusyInfo(_('Importing cross sections')):
|
10224
10226
|
wait = wx.BusyCursor()
|
10225
10227
|
if curfilter == 1: # txt 2022
|
10226
10228
|
newobj = crosssections(filename, format='2022', dirlaz=dirlaz, mapviewer=self)
|
@@ -10346,7 +10348,7 @@ class WolfMapViewer(wx.Frame):
|
|
10346
10348
|
curdict = self.mytri
|
10347
10349
|
curtree = self.myitemstri
|
10348
10350
|
if newobj is None:
|
10349
|
-
with wx.
|
10351
|
+
with wx.BusyInfo(_('Importing triangulation')):
|
10350
10352
|
wait = wx.BusyCursor()
|
10351
10353
|
newobj = Triangulation(filename, mapviewer=self)
|
10352
10354
|
del wait
|
@@ -11584,6 +11586,11 @@ class WolfMapViewer(wx.Frame):
|
|
11584
11586
|
|
11585
11587
|
self.rightdown = (x, y)
|
11586
11588
|
|
11589
|
+
elif self.action == 'distance along vector':
|
11590
|
+
|
11591
|
+
# add a vertex to the vector
|
11592
|
+
self._tmp_vector_distance.add_vertex(wolfvertex(x, y))
|
11593
|
+
|
11587
11594
|
elif self.action == 'move triangles':
|
11588
11595
|
|
11589
11596
|
if self.active_tri is None:
|
@@ -12342,6 +12349,39 @@ class WolfMapViewer(wx.Frame):
|
|
12342
12349
|
type = Type_Param.String,
|
12343
12350
|
comment = '')
|
12344
12351
|
|
12352
|
+
if self._tmp_vector_distance is not None:
|
12353
|
+
curgroup = _('Temporary vector')
|
12354
|
+
self.mytooltip.myparams[curgroup] = {}
|
12355
|
+
curpar = _('Length [m]')
|
12356
|
+
self._tmp_vector_distance.update_lengths()
|
12357
|
+
self.mytooltip.add_param(groupname = curgroup,
|
12358
|
+
name = curpar,
|
12359
|
+
value = '{:3f}'.format(self._tmp_vector_distance.length2D),
|
12360
|
+
type = Type_Param.Float,
|
12361
|
+
comment = '')
|
12362
|
+
|
12363
|
+
if self._tmp_vector_distance.nbvertices > 4:
|
12364
|
+
_polygon = self._tmp_vector_distance.asshapely_pol()
|
12365
|
+
_area = _polygon.area
|
12366
|
+
curpar = _('Area [m2]')
|
12367
|
+
self.mytooltip.add_param(groupname = curgroup,
|
12368
|
+
name = curpar,
|
12369
|
+
value = '{:3f}'.format(_area),
|
12370
|
+
type = Type_Param.Float,
|
12371
|
+
comment = '')
|
12372
|
+
curpar = _('Area [ha]')
|
12373
|
+
self.mytooltip.add_param(groupname = curgroup,
|
12374
|
+
name = curpar,
|
12375
|
+
value = '{:3f}'.format(_area / 10000.),
|
12376
|
+
type = Type_Param.Float,
|
12377
|
+
comment = '')
|
12378
|
+
curpar = _('Area [km2]')
|
12379
|
+
self.mytooltip.add_param(groupname = curgroup,
|
12380
|
+
name = curpar,
|
12381
|
+
value = '{:3f}'.format(_area / 1e6),
|
12382
|
+
type = Type_Param.Float,
|
12383
|
+
comment = '')
|
12384
|
+
|
12345
12385
|
for locarray in self.myres2D:
|
12346
12386
|
locarray:Wolfresults_2D
|
12347
12387
|
curgroup = locarray.idx
|
@@ -12735,10 +12775,10 @@ class WolfMapViewer(wx.Frame):
|
|
12735
12775
|
|
12736
12776
|
self.active_vertex.limit2bounds(self.active_vector.mylimits)
|
12737
12777
|
|
12738
|
-
|
12778
|
+
elif self.action == 'dynamic parallel':
|
12739
12779
|
self.active_zone.parallel_active(self.dynapar_dist)
|
12740
12780
|
|
12741
|
-
|
12781
|
+
elif self.action == 'move vector':
|
12742
12782
|
if self.active_vector is not None:
|
12743
12783
|
if self.active_vector._move_start is not None:
|
12744
12784
|
|
@@ -12753,7 +12793,7 @@ class WolfMapViewer(wx.Frame):
|
|
12753
12793
|
|
12754
12794
|
self.active_vector.move(delta_x, delta_y)
|
12755
12795
|
|
12756
|
-
|
12796
|
+
elif self.action == 'move triangles':
|
12757
12797
|
if self.active_tri is not None:
|
12758
12798
|
if self.active_tri._move_start is not None:
|
12759
12799
|
|
@@ -12770,18 +12810,18 @@ class WolfMapViewer(wx.Frame):
|
|
12770
12810
|
|
12771
12811
|
self.active_tri.reset_plot()
|
12772
12812
|
|
12773
|
-
|
12813
|
+
elif self.action == 'rotate vector':
|
12774
12814
|
if self.active_vector is not None:
|
12775
12815
|
if self.active_vector._rotation_center is not None:
|
12776
12816
|
self.active_vector.rotate_xy(x, y)
|
12777
12817
|
|
12778
|
-
|
12818
|
+
elif self.action == 'rotate triangles':
|
12779
12819
|
if self.active_tri is not None:
|
12780
12820
|
if self.active_tri._rotation_center is not None:
|
12781
12821
|
self.active_tri.rotate_xy(x, y)
|
12782
12822
|
self.active_tri.reset_plot()
|
12783
12823
|
|
12784
|
-
|
12824
|
+
elif self.action == 'move zone':
|
12785
12825
|
if self.active_zone is not None:
|
12786
12826
|
if self.active_zone._move_start is not None:
|
12787
12827
|
delta_x = x - self.active_zone._move_start[0]
|
@@ -12795,11 +12835,20 @@ class WolfMapViewer(wx.Frame):
|
|
12795
12835
|
|
12796
12836
|
self.active_zone.move(delta_x, delta_y)
|
12797
12837
|
|
12798
|
-
|
12838
|
+
elif self.action == 'rotate zone':
|
12799
12839
|
if self.active_zone is not None:
|
12800
12840
|
if self.active_zone._rotation_center is not None:
|
12801
12841
|
self.active_zone.rotate_xy(x, y)
|
12802
12842
|
|
12843
|
+
elif self.action == 'distance along vector':
|
12844
|
+
if self._tmp_vector_distance is not None:
|
12845
|
+
self._tmp_vector_distance.myvertices[-1].x = x
|
12846
|
+
self._tmp_vector_distance.myvertices[-1].y = y
|
12847
|
+
|
12848
|
+
if self._tmp_vector_distance.nbvertices ==2:
|
12849
|
+
self._tmp_vector_distance.myvertices[0].x = x
|
12850
|
+
self._tmp_vector_distance.myvertices[0].y = y
|
12851
|
+
|
12803
12852
|
self.Paint()
|
12804
12853
|
|
12805
12854
|
# Store the position of the mouse as last known position
|
@@ -12943,6 +12992,10 @@ class WolfMapViewer(wx.Frame):
|
|
12943
12992
|
# we must reset the temporary vector
|
12944
12993
|
self.active_vector.reset()
|
12945
12994
|
|
12995
|
+
if self.action == 'distance along vector':
|
12996
|
+
|
12997
|
+
self._tmp_vector_distance = None
|
12998
|
+
|
12946
12999
|
elif self.action == 'pick landmap':
|
12947
13000
|
|
12948
13001
|
self.end_action(_('End of landmap picking'))
|
@@ -13172,6 +13225,7 @@ class WolfMapViewer(wx.Frame):
|
|
13172
13225
|
# r : reset de la sélection de la matrice courante\n \
|
13173
13226
|
# R : reset de toutes les sélections de la matrice courante\n \
|
13174
13227
|
# P : sélection de la section transversale par click souris\n \
|
13228
|
+
# D : calcule de distance le long d'un vecteur temporaire\n \
|
13175
13229
|
# \n \
|
13176
13230
|
# RETURN : end current action (cf aussi double clicks droit 'OnRDClick')\n \
|
13177
13231
|
# DELETE : remove item\n \
|
@@ -13220,6 +13274,7 @@ class WolfMapViewer(wx.Frame):
|
|
13220
13274
|
'ALT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
|
13221
13275
|
'ALT+SHIFT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image with axes - multiviewers'),
|
13222
13276
|
'CTRL+ALT+SHIFT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image with axes - all arrays one by one'),
|
13277
|
+
'd or D': _('Drawing : calculate distance along a temporary vector'),
|
13223
13278
|
|
13224
13279
|
'CTRL+o': _('Results : increase transparency of the current result'),
|
13225
13280
|
'CTRL+O': _('Results : decrease transparency of the current result'),
|
@@ -13326,6 +13381,14 @@ class WolfMapViewer(wx.Frame):
|
|
13326
13381
|
logging.info(_('ACTION : ') + _(message) if message != '' else _('ACTION : End of action') )
|
13327
13382
|
self.msg_action(1)
|
13328
13383
|
|
13384
|
+
def distance_by_multiple_clicks(self):
|
13385
|
+
""" Distance between multiple clicks """
|
13386
|
+
|
13387
|
+
self.start_action('distance along vector', _('Distance by multiple clicks -- Select the points'))
|
13388
|
+
self._tmp_vector_distance = vector()
|
13389
|
+
self._tmp_vector_distance.add_vertex([wolfvertex(0., 0.),
|
13390
|
+
wolfvertex(0., 0.)])
|
13391
|
+
|
13329
13392
|
def OnHotKey(self, e: wx.KeyEvent):
|
13330
13393
|
"""
|
13331
13394
|
Gestion des touches clavier -- see print_shortcuts for more details
|
@@ -14001,6 +14064,9 @@ class WolfMapViewer(wx.Frame):
|
|
14001
14064
|
if self.active_laz is not None:
|
14002
14065
|
self.active_laz.add_pose_in_memory()
|
14003
14066
|
|
14067
|
+
elif key == ord('D'):
|
14068
|
+
self.distance_by_multiple_clicks()
|
14069
|
+
|
14004
14070
|
def paste_values(self,fromarray:WolfArray):
|
14005
14071
|
""" Paste selected values from a WolfArray to the active array """
|
14006
14072
|
|
@@ -14309,6 +14375,10 @@ class WolfMapViewer(wx.Frame):
|
|
14309
14375
|
# Gestion des BC (si actif)
|
14310
14376
|
if self.active_bc is not None:
|
14311
14377
|
self.active_bc.plot()
|
14378
|
+
|
14379
|
+
if self._tmp_vector_distance is not None:
|
14380
|
+
self._tmp_vector_distance.plot()
|
14381
|
+
|
14312
14382
|
# try:
|
14313
14383
|
# if self.active_bc is not None:
|
14314
14384
|
# self.active_bc.plot()
|
wolfhece/PyGui.py
CHANGED
wolfhece/PyVertex.py
CHANGED
@@ -549,7 +549,7 @@ class cloud_vertices(Element_To_Draw):
|
|
549
549
|
|
550
550
|
self.loaded = False
|
551
551
|
|
552
|
-
self.
|
552
|
+
self._header = header
|
553
553
|
|
554
554
|
self.gllist = 0
|
555
555
|
self.forceupdategl = False
|
@@ -570,7 +570,7 @@ class cloud_vertices(Element_To_Draw):
|
|
570
570
|
if Path(fname).suffix.lower() == '.dxf':
|
571
571
|
self.import_from_dxf(self.filename, imported_elts=dxf_imported_elts)
|
572
572
|
elif Path(fname).suffix.lower() == '.shp':
|
573
|
-
self.
|
573
|
+
self.import_from_shapefile(self.filename, bbox=bbox)
|
574
574
|
else:
|
575
575
|
self.readfile(self.filename, header)
|
576
576
|
|
@@ -586,24 +586,53 @@ class cloud_vertices(Element_To_Draw):
|
|
586
586
|
xyz = self.get_xyz()
|
587
587
|
self.mytree = KDTree(xyz)
|
588
588
|
|
589
|
-
def find_nearest(self,
|
589
|
+
def find_nearest(self, xyz:np.ndarray | list, nb:int =1):
|
590
590
|
"""
|
591
|
-
Find nearest neighbors from Scipy KDTree structure based on a copy of the vertices
|
591
|
+
Find nearest neighbors from Scipy KDTree structure based on a copy of the vertices.
|
592
592
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
593
|
+
See : https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.KDTree.query.html
|
594
|
+
|
595
|
+
:param xyz: coordinates to find nearest neighbors -- shape (n, m) - where m is the number of coordinates (2 or 3)
|
596
|
+
:param nb: number of nearest neighbors to find
|
597
|
+
:return: list of distances, list of "Wolfvertex", list of elements stored in self.myvertices - or list of lists if xyz is a list of coordinates
|
597
598
|
"""
|
598
599
|
|
599
|
-
|
600
|
-
|
601
|
-
|
600
|
+
if isinstance(xyz, list):
|
601
|
+
if len(xyz) > 0:
|
602
|
+
if isinstance(xyz[0], float | int):
|
603
|
+
logging.warning(_('xyz is a list of floats -- converting to a list of lists'))
|
604
|
+
xyz = [xyz]
|
605
|
+
|
606
|
+
xyz = np.array(xyz)
|
607
|
+
|
608
|
+
try:
|
609
|
+
keys = list(self.myvertices.keys())
|
610
|
+
if self.mytree is None:
|
611
|
+
self.create_kdtree()
|
612
|
+
|
613
|
+
if xyz.shape[1] != self.mytree.m:
|
614
|
+
logging.error(_('Error in find_nearest -- xyz must be a list or 2D array with {} columns').format(self.mytree.m))
|
615
|
+
return None, None, None
|
616
|
+
|
617
|
+
dist, ii = self.mytree.query(xyz, k=nb)
|
618
|
+
|
619
|
+
if xyz.shape[0] == 1:
|
620
|
+
if nb == 1:
|
621
|
+
return dist[0], self.myvertices[keys[ii[0]]]['vertex'], self.myvertices[keys[ii[0]]]
|
622
|
+
else:
|
623
|
+
return dist[0], [self.myvertices[keys[curi]]['vertex'] for curi in ii[0]], [self.myvertices[keys[curi]] for curi in ii[0]]
|
624
|
+
else:
|
625
|
+
if nb == 1:
|
626
|
+
return dist, [self.myvertices[keys[curi]]['vertex'] for curi in ii], [self.myvertices[keys[curi]] for curi in ii]
|
627
|
+
else:
|
628
|
+
return dist, [[self.myvertices[keys[curi]]['vertex'] for curi in curii] for curii in ii], [[self.myvertices[keys[curi]] for curi in curii] for curii in ii]
|
602
629
|
|
603
|
-
|
604
|
-
|
630
|
+
except Exception as e:
|
631
|
+
logging.error(_('Error in find_nearest -- {}').format(e))
|
632
|
+
logging.error(_('Check your input data -- it must be a list or 2D array with 3 columns'))
|
633
|
+
return None, None, None
|
605
634
|
|
606
|
-
def init_from_nparray(self, array):
|
635
|
+
def init_from_nparray(self, array:np.ndarray):
|
607
636
|
"""
|
608
637
|
Fill-in from nparray -- shape (n,3)
|
609
638
|
"""
|
@@ -624,7 +653,7 @@ class cloud_vertices(Element_To_Draw):
|
|
624
653
|
|
625
654
|
self.plotted = True
|
626
655
|
if not self.loaded:
|
627
|
-
self.readfile(self.filename, self.
|
656
|
+
self.readfile(self.filename, self._header)
|
628
657
|
self.loaded = True
|
629
658
|
|
630
659
|
def uncheck_plot(self, unload=True):
|
@@ -703,11 +732,11 @@ class cloud_vertices(Element_To_Draw):
|
|
703
732
|
nbcols = len(curval)
|
704
733
|
|
705
734
|
if nbcols < 2:
|
706
|
-
|
735
|
+
logging.warning(_('Not enough values on one line -- Retry !!'))
|
707
736
|
return
|
708
737
|
elif nbcols > 3:
|
709
738
|
if headers is None:
|
710
|
-
|
739
|
+
logging.warning(_('No headers -- Retry !!'))
|
711
740
|
return
|
712
741
|
else:
|
713
742
|
if headers[2].lower() == 'z':
|
@@ -847,7 +876,7 @@ class cloud_vertices(Element_To_Draw):
|
|
847
876
|
|
848
877
|
return k
|
849
878
|
|
850
|
-
def
|
879
|
+
def import_from_shapefile(self, fn:str='', targetcolumn:str = 'X1_Y1_Z1', bbox:Polygon = None):
|
851
880
|
"""
|
852
881
|
Importing Shapefile using geopandas library
|
853
882
|
|
@@ -1010,6 +1039,8 @@ class cloud_vertices(Element_To_Draw):
|
|
1010
1039
|
Plot OpenGL
|
1011
1040
|
|
1012
1041
|
Legend is an image texture
|
1042
|
+
|
1043
|
+
FIXME : to be improved
|
1013
1044
|
"""
|
1014
1045
|
if self.get_mapviewer() is None:
|
1015
1046
|
logging.warning(_('No mapviewer available for legend plot'))
|
@@ -1235,7 +1266,7 @@ class cloud_vertices(Element_To_Draw):
|
|
1235
1266
|
|
1236
1267
|
"""
|
1237
1268
|
|
1238
|
-
if self.
|
1269
|
+
if self._header:
|
1239
1270
|
if key=='vertex':
|
1240
1271
|
xyz = [[curvert['vertex'].x, curvert['vertex'].y, curvert['vertex'].z] for curvert in self.myvertices.values()]
|
1241
1272
|
else:
|
@@ -1244,6 +1275,63 @@ class cloud_vertices(Element_To_Draw):
|
|
1244
1275
|
xyz = [[curvert['vertex'].x, curvert['vertex'].y, curvert['vertex'].z] for curvert in self.myvertices.values()]
|
1245
1276
|
return np.array(xyz)
|
1246
1277
|
|
1278
|
+
@property
|
1279
|
+
def has_values(self) -> bool:
|
1280
|
+
"""
|
1281
|
+
Check if the cloud has values (other than X,Y,Z)
|
1282
|
+
"""
|
1283
|
+
|
1284
|
+
if self._header:
|
1285
|
+
return len(self.myvertices[0]) > 1
|
1286
|
+
else:
|
1287
|
+
return False
|
1288
|
+
|
1289
|
+
@property
|
1290
|
+
def header(self) -> list[str]:
|
1291
|
+
"""
|
1292
|
+
Return the headers of the cloud
|
1293
|
+
"""
|
1294
|
+
|
1295
|
+
if self._header:
|
1296
|
+
return list(self.myvertices[0].keys())
|
1297
|
+
else:
|
1298
|
+
return []
|
1299
|
+
|
1300
|
+
def add_values_by_id_list(self, id:str, values:list[float]):
|
1301
|
+
"""
|
1302
|
+
Add values to the cloud
|
1303
|
+
|
1304
|
+
:param id: use as key for the values
|
1305
|
+
:param values: list of values to be added - must be the same length as number of vertices
|
1306
|
+
|
1307
|
+
"""
|
1308
|
+
|
1309
|
+
if len(values) != len(self.myvertices):
|
1310
|
+
logging.warning(_('Number of values does not match the number of vertices -- Retry !!'))
|
1311
|
+
logging.info(_(('Number of vertices : ')+str(len(self.myvertices))))
|
1312
|
+
return
|
1313
|
+
|
1314
|
+
for item, val in zip(self.myvertices.values(), values):
|
1315
|
+
item[id] = val
|
1316
|
+
|
1317
|
+
self._header = True
|
1318
|
+
|
1319
|
+
@property
|
1320
|
+
def xyz(self) -> np.ndarray:
|
1321
|
+
"""
|
1322
|
+
Alias for get_xyz method
|
1323
|
+
"""
|
1324
|
+
|
1325
|
+
return self.get_xyz(key='vertex')
|
1326
|
+
|
1327
|
+
@property
|
1328
|
+
def nbvertices(self) -> int:
|
1329
|
+
"""
|
1330
|
+
Number of vertices in the cloud
|
1331
|
+
"""
|
1332
|
+
|
1333
|
+
return len(self.myvertices)
|
1334
|
+
|
1247
1335
|
def interp_on_array(self, myarray, key:str='vertex', method:Literal['linear', 'nearest', 'cubic'] = 'linear'):
|
1248
1336
|
"""
|
1249
1337
|
Interpolation of the cloud on a 2D array
|
@@ -1319,3 +1407,23 @@ class cloud_vertices(Element_To_Draw):
|
|
1319
1407
|
return newcloud
|
1320
1408
|
else:
|
1321
1409
|
return all_s, all_z
|
1410
|
+
|
1411
|
+
def plot_matplotlib(self, ax=None, **kwargs):
|
1412
|
+
"""
|
1413
|
+
Plot the cloud using matplotlib
|
1414
|
+
|
1415
|
+
:param ax: axis to plot on -- if None, a new figure is created
|
1416
|
+
:param kwargs: additional arguments for matplotlib
|
1417
|
+
|
1418
|
+
"""
|
1419
|
+
import matplotlib.pyplot as plt
|
1420
|
+
|
1421
|
+
if ax is None:
|
1422
|
+
fig, ax = plt.subplots()
|
1423
|
+
|
1424
|
+
x = [cur['vertex'].x for cur in self.myvertices.values()]
|
1425
|
+
y = [cur['vertex'].y for cur in self.myvertices.values()]
|
1426
|
+
|
1427
|
+
ax.scatter(x, y, **kwargs)
|
1428
|
+
|
1429
|
+
return fig, ax
|