wolfhece 2.1.99__py3-none-any.whl → 2.1.101__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 +220 -29
- wolfhece/PyGui.py +1039 -53
- wolfhece/PyVertexvectors.py +2 -2
- wolfhece/Results2DGPU.py +37 -13
- wolfhece/acceptability/Parallels.py +2 -2
- wolfhece/acceptability/_add_path.py +23 -0
- wolfhece/acceptability/acceptability.py +594 -563
- wolfhece/acceptability/acceptability_gui.py +564 -331
- wolfhece/acceptability/cli.py +307 -120
- wolfhece/acceptability/func.py +1754 -1597
- wolfhece/apps/version.py +1 -1
- wolfhece/bernoulli/losses.py +76 -23
- wolfhece/bernoulli/losses_jax.py +143 -0
- wolfhece/bernoulli/pipe.py +7 -2
- wolfhece/gpuview.py +4 -1
- wolfhece/libs/__init__.py +11 -10
- wolfhece/libs/wolfogl.cp310-win_amd64.pyd +0 -0
- wolfhece/math_parser/__init__.py +4 -4
- wolfhece/math_parser/calculator.py +51 -9
- wolfhece/mesh2d/bc_manager.py +25 -2
- wolfhece/mesh2d/gpu_2d.py +644 -0
- wolfhece/mesh2d/simple_2d.py +2817 -0
- wolfhece/mesh2d/wolf2dprev.py +5 -2
- wolfhece/pidcontroller.py +131 -0
- wolfhece/pywalous.py +7 -7
- wolfhece/scenario/config_manager.py +98 -21
- wolfhece/wolf_array.py +391 -176
- wolfhece/wolf_vrt.py +108 -7
- wolfhece/wolfresults_2D.py +113 -6
- wolfhece/xyz_file.py +91 -51
- {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/METADATA +3 -1
- {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/RECORD +35 -30
- {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/WHEEL +1 -1
- {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.99.dist-info → wolfhece-2.1.101.dist-info}/top_level.txt +0 -0
wolfhece/wolf_array.py
CHANGED
@@ -22,6 +22,7 @@ import logging
|
|
22
22
|
import json
|
23
23
|
import tempfile
|
24
24
|
from pathlib import Path
|
25
|
+
from tqdm import tqdm
|
25
26
|
|
26
27
|
try:
|
27
28
|
from OpenGL.GL import *
|
@@ -115,6 +116,7 @@ WOLF_ARRAY_CSR_DOUBLE = 5
|
|
115
116
|
WOLF_ARRAY_FULL_INTEGER = 6
|
116
117
|
WOLF_ARRAY_FULL_SINGLE_3D = 7
|
117
118
|
WOLF_ARRAY_FULL_INTEGER8 = 8
|
119
|
+
WOLF_ARRAY_FULL_UINTEGER8 = 88
|
118
120
|
|
119
121
|
WOLF_ARRAY_MB_SINGLE = 3
|
120
122
|
WOLF_ARRAY_MB_INTEGER = 9
|
@@ -277,7 +279,7 @@ class header_wolf():
|
|
277
279
|
ret += _('Spatial extent : \n')
|
278
280
|
ret += _(' - Origin : ({} ; {}) \n').format(self.origx, self.origy)
|
279
281
|
ret += _(' - End : ({} ; {}) \n').format(self.origx + self.nbx * self.dx, self.origy +self.nby * self.dy)
|
280
|
-
ret += _(' -
|
282
|
+
ret += _(' - Width x Height : {} x {} \n').format(self.nbx * self.dx, self.nby * self.dy)
|
281
283
|
ret += _(' - Translation : ({} ; {})\n').format(self.translx, self.transly)
|
282
284
|
ret += _('Null value : {}\n\n'.format(self.nullvalue))
|
283
285
|
|
@@ -344,8 +346,8 @@ class header_wolf():
|
|
344
346
|
"""
|
345
347
|
Return block header
|
346
348
|
|
347
|
-
:param key:
|
348
|
-
:return
|
349
|
+
:param key: block's index (0-based) or key (str)
|
350
|
+
:return: header_wolf instance if key is found, None otherwise
|
349
351
|
"""
|
350
352
|
if key is None:
|
351
353
|
return self
|
@@ -364,7 +366,7 @@ class header_wolf():
|
|
364
366
|
"""
|
365
367
|
Set block header
|
366
368
|
|
367
|
-
:param value
|
369
|
+
:param value: tuple (key, header_wolf)
|
368
370
|
|
369
371
|
'key' can be an int (0-based) or a str
|
370
372
|
If str, please use getkeyblock function to generate the key
|
@@ -381,9 +383,9 @@ class header_wolf():
|
|
381
383
|
"""
|
382
384
|
Set origin
|
383
385
|
|
384
|
-
:param x
|
385
|
-
:param y
|
386
|
-
:param z
|
386
|
+
:param x: origin along X
|
387
|
+
:param y: origin along Y
|
388
|
+
:param z: origin along Z
|
387
389
|
"""
|
388
390
|
self.origx = x
|
389
391
|
self.origy = y
|
@@ -405,8 +407,8 @@ class header_wolf():
|
|
405
407
|
"""
|
406
408
|
Return bounds in coordinates
|
407
409
|
|
408
|
-
:param abs
|
409
|
-
:return
|
410
|
+
:param abs: if True, add translation to (x, y) (coordinate to global space)
|
411
|
+
:return: tuple of two lists of two floats - ([xmin, xmax],[ymin, ymax])
|
410
412
|
"""
|
411
413
|
if abs:
|
412
414
|
return ([self.origx + self.translx, self.origx + self.translx + float(self.nbx) * self.dx],
|
@@ -421,7 +423,7 @@ class header_wolf():
|
|
421
423
|
|
422
424
|
Firstly, get_bounds is called to get bounds in coordinates and then get_ij_from_xy is called to get bounds in indices.
|
423
425
|
|
424
|
-
:param abs
|
426
|
+
:param abs: if True, add translation to (x, y) (coordinate to global space)
|
425
427
|
"""
|
426
428
|
mybounds = self.get_bounds(abs)
|
427
429
|
|
@@ -433,13 +435,13 @@ class header_wolf():
|
|
433
435
|
"""
|
434
436
|
Get indices from coordinates
|
435
437
|
|
436
|
-
:param x
|
437
|
-
:param y
|
438
|
-
:param z
|
439
|
-
:param scale
|
440
|
-
:param aswolf
|
441
|
-
:param abs
|
442
|
-
:param forcedims2
|
438
|
+
:param x: X coordinate
|
439
|
+
:param y: Y coordinate
|
440
|
+
:param z: Z coordinate (optional)
|
441
|
+
:param scale: scaling of the spatial resolution (dx,dy,[dz])
|
442
|
+
:param aswolf: if True, return if one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
443
|
+
:param abs: if True, remove translation from (x, y, [z]) (coordinate from global space)
|
444
|
+
:param forcedims2: if True, force to return only 2 indices even if z is supplied
|
443
445
|
"""
|
444
446
|
|
445
447
|
locx = np.float64(x) - self.origx
|
@@ -475,7 +477,7 @@ class header_wolf():
|
|
475
477
|
:param abs = if True, remove translation from (x, y, [z]) (coordinate from global space)
|
476
478
|
:param forcedims2 = if True, force to return only 2 indices even if z is supplied
|
477
479
|
|
478
|
-
:return
|
480
|
+
:return: numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
|
479
481
|
"""
|
480
482
|
|
481
483
|
if isinstance(xy,tuple):
|
@@ -642,17 +644,17 @@ class header_wolf():
|
|
642
644
|
def ij2xy_np(self, ij:np.ndarray, scale:float=1., aswolf:bool=False, abs:bool=True) -> np.ndarray:
|
643
645
|
""" alias for get_xy_from_ij_array
|
644
646
|
|
645
|
-
:param ij
|
646
|
-
:param scale
|
647
|
-
:param aswolf
|
648
|
-
:param abs
|
647
|
+
:param ij: numpy array containing (i, j, [k]) indices
|
648
|
+
:param scale: scaling of the spatial resolution (dx,dy,[dz])
|
649
|
+
:param aswolf: if True, input is one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
650
|
+
:param abs: if True, add translation to results (x, y, [z]) (coordinate to global space)
|
649
651
|
|
650
652
|
..warning: 'ij' is not the result of np.where() but if you want to use np.where() you can use the following code:
|
651
653
|
```
|
652
654
|
np.vstack((ij[0], ij[1])).T
|
653
655
|
```
|
654
656
|
|
655
|
-
:return
|
657
|
+
:return: numpy array containing (x, y, [z]) coordinates - shape (n, 2) or (n, 3)
|
656
658
|
"""
|
657
659
|
return self.get_xy_from_ij_array(ij, scale, aswolf, abs)
|
658
660
|
|
@@ -664,11 +666,11 @@ class header_wolf():
|
|
664
666
|
"""
|
665
667
|
alias for get_ij_from_xy_array
|
666
668
|
|
667
|
-
:param xy
|
668
|
-
:param scale
|
669
|
-
:param aswolf
|
670
|
-
:param abs
|
671
|
-
:param forcedims2
|
669
|
+
:param xy: numpy array containing (x, y, [z]) coordinates - shape (n, 2) or (n, 3)
|
670
|
+
:param scale: scaling of the spatial resolution (dx,dy,[dz])
|
671
|
+
:param aswolf: if True, return if one-based (as Wolf VB6 or Fortran), otherwise 0-based (default Python standard)
|
672
|
+
:param abs: if True, remove translation from (x, y, [z]) (coordinate from global space)
|
673
|
+
:param forcedims2: if True, force to return only 2 indices even if z is supplied
|
672
674
|
|
673
675
|
:return : numpy array containing (i, j, [k]) indices - shape (n, 2) or (n, 3)
|
674
676
|
"""
|
@@ -689,8 +691,8 @@ class header_wolf():
|
|
689
691
|
"""
|
690
692
|
Find the intersection of two header
|
691
693
|
|
692
|
-
|
693
|
-
|
694
|
+
:param other: other header
|
695
|
+
:param ij: if True, return indices instead of coordinates
|
694
696
|
|
695
697
|
:return: None or tuple of two lists of two floats - ([xmin, xmax],[ymin, ymax]) or indices in each header (if ij=True) [[imin1, imax1], [jmin1, jmax1]], [[imin2, imax2], [jmin2, jmax2]]
|
696
698
|
"""
|
@@ -759,7 +761,7 @@ class header_wolf():
|
|
759
761
|
"""
|
760
762
|
Read informations from header .txt
|
761
763
|
|
762
|
-
:param filename
|
764
|
+
:param filename: path and filename of the basefile
|
763
765
|
|
764
766
|
If filename is a Path object, it is converted to a string
|
765
767
|
If filename ends with '.tif', nothing is done because infos are in the .tif file
|
@@ -866,7 +868,7 @@ class header_wolf():
|
|
866
868
|
elif dtype == np.int16:
|
867
869
|
self.wolftype = WOLF_ARRAY_FULL_INTEGER16
|
868
870
|
elif dtype == np.uint8:
|
869
|
-
self.wolftype =
|
871
|
+
self.wolftype = WOLF_ARRAY_FULL_UINTEGER8
|
870
872
|
elif dtype == np.int8:
|
871
873
|
self.wolftype = WOLF_ARRAY_FULL_INTEGER8
|
872
874
|
else:
|
@@ -994,12 +996,14 @@ class header_wolf():
|
|
994
996
|
|
995
997
|
Nullvalue is not written
|
996
998
|
|
997
|
-
:param filename
|
998
|
-
:param wolftype
|
999
|
-
:param forceupdate
|
999
|
+
:param filename: path and filename with '.txt' extension, which will NOT be automatically added
|
1000
|
+
:param wolftype: type of the WOLF_ARRAY_* array
|
1001
|
+
:param forceupdate: if True, the file is rewritten even if it already exists
|
1000
1002
|
"""
|
1001
1003
|
|
1002
|
-
assert wolftype in [WOLF_ARRAY_CSR_DOUBLE, WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_SYM_DOUBLE, WOLF_ARRAY_FULL_LOGICAL,
|
1004
|
+
assert wolftype in [WOLF_ARRAY_CSR_DOUBLE, WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_SYM_DOUBLE, WOLF_ARRAY_FULL_LOGICAL,
|
1005
|
+
WOLF_ARRAY_CSR_DOUBLE, WOLF_ARRAY_FULL_INTEGER, WOLF_ARRAY_FULL_SINGLE_3D, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8,
|
1006
|
+
WOLF_ARRAY_MB_SINGLE, WOLF_ARRAY_MB_INTEGER, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_MNAP_INTEGER, WOLF_ARRAY_FULL_INTEGER16_2], _('The type of array is not correct')
|
1003
1007
|
|
1004
1008
|
if not os.path.exists(filename) or forceupdate:
|
1005
1009
|
with open(filename,'w') as f:
|
@@ -1035,8 +1039,8 @@ class header_wolf():
|
|
1035
1039
|
"""
|
1036
1040
|
Comparison of two headers
|
1037
1041
|
|
1038
|
-
:param other
|
1039
|
-
:param check_mb
|
1042
|
+
:param other: other header to compare
|
1043
|
+
:param check_mb: if True, the comparison is done on the blocks too
|
1040
1044
|
|
1041
1045
|
The nullvalue is not taken into account
|
1042
1046
|
"""
|
@@ -1173,8 +1177,9 @@ class header_wolf():
|
|
1173
1177
|
"""
|
1174
1178
|
Return the coordinates of the cells in the footprint of a vector
|
1175
1179
|
|
1176
|
-
:param myvect
|
1180
|
+
:param myvect: target vector
|
1177
1181
|
:return: tuple of two numpy arrays - (coordinates, indices)
|
1182
|
+
:param eps: epsilon to avoid rounding errors
|
1178
1183
|
|
1179
1184
|
"""
|
1180
1185
|
|
@@ -1190,8 +1195,9 @@ class header_wolf():
|
|
1190
1195
|
"""
|
1191
1196
|
Return the indices of the cells in the footprint of a vector
|
1192
1197
|
|
1193
|
-
:param myvect
|
1194
|
-
:return
|
1198
|
+
:param myvect: target vector
|
1199
|
+
:return: numpy array of indices
|
1200
|
+
:param eps: epsilon to avoid rounding errors
|
1195
1201
|
"""
|
1196
1202
|
|
1197
1203
|
if isinstance(myvect, Polygon):
|
@@ -1219,7 +1225,7 @@ class header_wolf():
|
|
1219
1225
|
"""
|
1220
1226
|
Convert XY coordinates to IJ indices **(0-based)** with Numpy without any check/options
|
1221
1227
|
|
1222
|
-
:param xy = numpy array of shape (n,2) with XY coordinates
|
1228
|
+
:param xy: = numpy array of shape (n,2) with XY coordinates
|
1223
1229
|
|
1224
1230
|
"""
|
1225
1231
|
|
@@ -1230,7 +1236,7 @@ class header_wolf():
|
|
1230
1236
|
"""
|
1231
1237
|
Convert IJ indices **(0-based)** to XY coordinates with Numpy without any check/options
|
1232
1238
|
|
1233
|
-
:param ij = numpy array of shape (n,2) with IJ indices
|
1239
|
+
:param ij: = numpy array of shape (n,2) with IJ indices
|
1234
1240
|
|
1235
1241
|
"""
|
1236
1242
|
|
@@ -1683,11 +1689,11 @@ class Ops_Array(wx.Frame):
|
|
1683
1689
|
|
1684
1690
|
self.m_button7 = wx.Button(self.Interpolation, wx.ID_ANY, _("Stage/Volume/Surface evaluation"), wx.DefaultPosition,
|
1685
1691
|
wx.DefaultSize, 0)
|
1686
|
-
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship
|
1692
|
+
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship.\nResults : csv and array saved on disk\n\n CAUTION : This function will be applied only on the selected area except if you select "all".\nIn the latter case, the computation time could be long if the array are very large.'))
|
1687
1693
|
|
1688
1694
|
if self.parentarray.nb_blocks>0:
|
1689
1695
|
self.m_button7.Disable()
|
1690
|
-
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship
|
1696
|
+
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship.\nResults : arrays and csv file saved on disk\n\nThis function is not available for multi-block arrays.'))
|
1691
1697
|
|
1692
1698
|
gSizer1.Add(self.m_button7, 0, wx.EXPAND)
|
1693
1699
|
self.m_button7.Bind(wx.EVT_BUTTON, self.volumesurface)
|
@@ -4462,8 +4468,10 @@ class SelectionData():
|
|
4462
4468
|
if self.nb == 0:
|
4463
4469
|
return None
|
4464
4470
|
|
4465
|
-
|
4471
|
+
if self.myselection == 'all':
|
4472
|
+
return WolfArray(mold=self.parent)
|
4466
4473
|
|
4474
|
+
newarray = WolfArray()
|
4467
4475
|
lochead = self._get_header()
|
4468
4476
|
if lochead is None:
|
4469
4477
|
logging.error(_('Error in get_newarray !'))
|
@@ -4586,33 +4594,35 @@ class SelectionData():
|
|
4586
4594
|
|
4587
4595
|
if self.nb == 0 or self.myselection == 'all':
|
4588
4596
|
myarray = array1
|
4589
|
-
axs = myarray.volume_estimation()
|
4597
|
+
fig, axs = myarray.volume_estimation()
|
4590
4598
|
|
4591
4599
|
myarray = array2
|
4592
|
-
axs = myarray.volume_estimation(axs)
|
4600
|
+
fig, axs = myarray.volume_estimation(axs)
|
4593
4601
|
else:
|
4594
4602
|
myarray = array1.mngselection.get_newarray()
|
4595
|
-
axs = myarray.volume_estimation()
|
4603
|
+
fig, axs = myarray.volume_estimation()
|
4596
4604
|
|
4597
4605
|
myarray = array2.mngselection.get_newarray()
|
4598
|
-
axs = myarray.volume_estimation(axs)
|
4606
|
+
fig, axs = myarray.volume_estimation(axs)
|
4599
4607
|
else:
|
4600
4608
|
if len(self.parent.mngselection.myselection) == 0 or self.parent.mngselection.myselection == 'all':
|
4601
4609
|
myarray = self.parent
|
4602
4610
|
else:
|
4603
4611
|
myarray = self.parent.mngselection.get_newarray()
|
4612
|
+
myarray.SelectionData.selections = self.parent.mngselection.selections.copy()
|
4604
4613
|
|
4605
|
-
myarray.volume_estimation()
|
4614
|
+
fig, axs = myarray.volume_estimation()
|
4606
4615
|
else:
|
4607
4616
|
if self.nb == 0 or self.myselection == 'all':
|
4608
4617
|
myarray = self.parent
|
4609
4618
|
else:
|
4610
4619
|
myarray = self.get_newarray()
|
4620
|
+
myarray.SelectionData.selections = self.selections.copy()
|
4611
4621
|
|
4612
|
-
myarray.volume_estimation()
|
4622
|
+
fig, axs = myarray.volume_estimation()
|
4613
4623
|
|
4614
4624
|
if show:
|
4615
|
-
|
4625
|
+
fig.show()
|
4616
4626
|
|
4617
4627
|
class SelectionDataMB(SelectionData):
|
4618
4628
|
""" Extension of SelectionData to manage multiple blocks """
|
@@ -4875,6 +4885,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4875
4885
|
plotted:bool = False,
|
4876
4886
|
need_for_wx:bool = False,
|
4877
4887
|
mask_source:np.ndarray = None,
|
4888
|
+
np_source:np.ndarray = None,
|
4878
4889
|
) -> None:
|
4879
4890
|
"""
|
4880
4891
|
Constructor of the WolfArray class
|
@@ -4893,6 +4904,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4893
4904
|
:param plotted: True = will be plotted if required by the mapviewer
|
4894
4905
|
:param need_for_wx: True = a wxApp is required (if no application is underway --> Error)
|
4895
4906
|
:param mask_source: mask to link to the data
|
4907
|
+
:param np_source: numpy array to link to the data
|
4896
4908
|
|
4897
4909
|
"""
|
4898
4910
|
try:
|
@@ -4980,7 +4992,16 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4980
4992
|
if self.nb_blocks>0:
|
4981
4993
|
self.myblocks = {}
|
4982
4994
|
|
4983
|
-
|
4995
|
+
if np_source is None:
|
4996
|
+
self.allocate_ressources()
|
4997
|
+
else:
|
4998
|
+
assert np_source.shape == (self.nbx, self.nby), _('Shape of np_source is not compatible with header')
|
4999
|
+
|
5000
|
+
if self.dtype != np_source.dtype:
|
5001
|
+
logging.warning(_('dtype of np_source is not compatible with header -- Conversion will be done'))
|
5002
|
+
np_source = np_source.astype(self.dtype)
|
5003
|
+
|
5004
|
+
self.array = ma.MaskedArray(np_source, mask= np_source[:,:] == self.nullvalue, copy=False, order='C')
|
4984
5005
|
|
4985
5006
|
# # FIXME Why not initialize with nullvalue ?
|
4986
5007
|
# self.array = ma.MaskedArray(np.ones((self.nbx, self.nby), order='F', dtype=self.dtype))
|
@@ -5052,6 +5073,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5052
5073
|
else:
|
5053
5074
|
self.init_from_new(new)
|
5054
5075
|
|
5076
|
+
|
5055
5077
|
self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
|
5056
5078
|
|
5057
5079
|
def set_opacity(self, alpha:float):
|
@@ -5092,7 +5114,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5092
5114
|
return size * 4
|
5093
5115
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2]:
|
5094
5116
|
return size * 2
|
5095
|
-
elif self.wolftype
|
5117
|
+
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
|
5096
5118
|
return size
|
5097
5119
|
else:
|
5098
5120
|
return size * 4
|
@@ -5353,6 +5375,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5353
5375
|
dtype = np.int16
|
5354
5376
|
elif self.wolftype == WOLF_ARRAY_FULL_INTEGER8:
|
5355
5377
|
dtype = np.int8
|
5378
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
5379
|
+
dtype = np.uint8
|
5356
5380
|
elif self.wolftype == WOLF_ARRAY_FULL_LOGICAL:
|
5357
5381
|
dtype = np.int16
|
5358
5382
|
|
@@ -5372,6 +5396,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5372
5396
|
dtype = gdal.GDT_Int16
|
5373
5397
|
elif self.wolftype == WOLF_ARRAY_FULL_INTEGER8:
|
5374
5398
|
dtype = gdal.GDT_Byte
|
5399
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
5400
|
+
dtype = gdal.GDT_Byte
|
5375
5401
|
elif self.wolftype == WOLF_ARRAY_FULL_LOGICAL:
|
5376
5402
|
dtype = gdal.GDT_Int16
|
5377
5403
|
|
@@ -5402,6 +5428,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5402
5428
|
dtype = _('int16 - 2 bytes per values')
|
5403
5429
|
elif self.wolftype == WOLF_ARRAY_FULL_INTEGER8:
|
5404
5430
|
dtype = _('int8 - 1 byte per values')
|
5431
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
5432
|
+
dtype = _('uint8 - 1 byte per values')
|
5405
5433
|
elif self.wolftype == WOLF_ARRAY_FULL_LOGICAL:
|
5406
5434
|
dtype = _('int16 - 2 bytes per values')
|
5407
5435
|
|
@@ -6060,7 +6088,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6060
6088
|
- uniquement dans les mailles sélectionnées si elles existent
|
6061
6089
|
- dans les mailles contenues dans le polygone sinon
|
6062
6090
|
|
6063
|
-
On utilise ensuite "griddata" pour interpoler les altitudes des mailles
|
6091
|
+
On utilise ensuite "griddata" de Scipy pour interpoler les altitudes des mailles
|
6064
6092
|
depuis les vertices 3D du polygone
|
6065
6093
|
"""
|
6066
6094
|
|
@@ -6123,17 +6151,27 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6123
6151
|
self.array.data[allij[:, 0], allij[:, 1]] = newz
|
6124
6152
|
|
6125
6153
|
def interpolate_on_polylines(self, working_zone:zone, usemask=True):
|
6154
|
+
""" Interpolation sous toutes les polylignes d'une même zone """
|
6126
6155
|
|
6127
6156
|
for curvec in working_zone.myvectors:
|
6128
6157
|
self.interpolate_on_polyline(curvec, usemask)
|
6129
6158
|
|
6130
6159
|
|
6131
|
-
def interpolate_on_cloud(self, xy:np.ndarray, z:np.ndarray, method='linear'):
|
6160
|
+
def interpolate_on_cloud(self, xy:np.ndarray, z:np.ndarray, method:Literal['linear', 'nearest', 'cubic']= 'linear'):
|
6132
6161
|
"""
|
6133
|
-
|
6162
|
+
Interpolation sur un nuage de points.
|
6134
6163
|
|
6135
|
-
|
6164
|
+
L'interpolation a lieu :
|
6165
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
6166
|
+
- dans les mailles contenues dans le polygone convexe contenant les points sinon
|
6136
6167
|
|
6168
|
+
Using griddata from Scipy.
|
6169
|
+
|
6170
|
+
:param xy: numpy.array of vertices - shape (n,2)
|
6171
|
+
:param z: numpy.array of values - shape (n,)
|
6172
|
+
:param method: method for the interpolation -- 'nearest', 'linear' or 'cubic'
|
6173
|
+
|
6174
|
+
See : https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
|
6137
6175
|
"""
|
6138
6176
|
|
6139
6177
|
if self.mngselection.myselection == [] or self.mngselection.myselection == 'all':
|
@@ -6157,18 +6195,36 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6157
6195
|
|
6158
6196
|
self.reset_plot()
|
6159
6197
|
|
6160
|
-
def interpolate_on_triangulation(self, coords, triangles,
|
6161
|
-
|
6198
|
+
def interpolate_on_triangulation(self, coords, triangles,
|
6199
|
+
grid_x=None, grid_y = None,
|
6200
|
+
mask_tri=None, interp_method:Literal['matplotlib','scipy'] = 'matplotlib'):
|
6162
6201
|
"""
|
6163
|
-
|
6202
|
+
Interpolation sur une triangulation.
|
6164
6203
|
|
6165
|
-
|
6204
|
+
L'interpolation a lieu :
|
6205
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
6206
|
+
- dans les mailles contenues dans la triangulation sinon
|
6207
|
+
|
6208
|
+
Matplotlib is used by default, but Scipy(griddata) can be used as well. If Matplotlib crashes, try with Scipy.
|
6209
|
+
Matplotlib is more strict on the quality of the triangulation.
|
6210
|
+
|
6211
|
+
:param coords: numpy.array of vertices - shape (n,3)
|
6212
|
+
:param triangles: numpy.array of triangles - shape (m,3)
|
6213
|
+
:param grid_x: numpy.array of x values where the interpolation will be done -- if None, the grid is created from the array
|
6214
|
+
:param grid_y: numpy.array of y values where the interpolation will be done -- if None, the grid is created from the array
|
6215
|
+
:param mask_tri: numpy.array of mask for the triangles
|
6216
|
+
:param interp_method: method for the interpolation -- 'matplotlib' or 'scipy'
|
6217
|
+
|
6218
|
+
For matplotlib algo, see : https://matplotlib.org/stable/gallery/images_contours_and_fields/triinterp_demo.html
|
6219
|
+
For scipy algo, see : https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
|
6166
6220
|
|
6167
6221
|
"""
|
6168
6222
|
|
6169
6223
|
|
6170
6224
|
if interp_method =='matplotlib':
|
6171
6225
|
|
6226
|
+
import matplotlib.tri as mtri
|
6227
|
+
|
6172
6228
|
use_scipy=False
|
6173
6229
|
|
6174
6230
|
try:
|
@@ -6289,10 +6345,16 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6289
6345
|
self.reset_plot()
|
6290
6346
|
return
|
6291
6347
|
|
6292
|
-
def import_from_gltf(self, fn:str='', fnpos:str='', interp_method:Literal['matplotlib','
|
6348
|
+
def import_from_gltf(self, fn:str='', fnpos:str='', interp_method:Literal['matplotlib','scipy'] = 'matplotlib'):
|
6293
6349
|
"""
|
6294
|
-
|
6350
|
+
Import from GLTF/GLB format
|
6351
|
+
|
6352
|
+
:param fn: filename
|
6353
|
+
:param fnpos: filename for the position's information
|
6354
|
+
:param interp_method: method for the interpolation -- 'matplotlib' or 'scipy'
|
6355
|
+
|
6295
6356
|
"""
|
6357
|
+
#FIXME : add the possibility to use PyVista
|
6296
6358
|
|
6297
6359
|
if fn == '' or fnpos == '':
|
6298
6360
|
logging.info(_('Retry !! -- Bad files'))
|
@@ -6457,7 +6519,6 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6457
6519
|
triangles.append([[i + decal, i + decal + 1, i + decal + nby] for i in range(nby - 1)])
|
6458
6520
|
triangles.append([[i + decal + nby, i + decal + 1, i + decal + nby + 1] for i in range(nby - 1)])
|
6459
6521
|
|
6460
|
-
from tqdm import tqdm
|
6461
6522
|
for k in tqdm(range(1, nbx - 1)):
|
6462
6523
|
decal = k * nby
|
6463
6524
|
triangles.append([[i + decal, i + decal + 1, i + decal + nby] for i in range(nby - 1)])
|
@@ -6497,7 +6558,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6497
6558
|
|
6498
6559
|
return mylap
|
6499
6560
|
|
6500
|
-
def volume_estimation(self, axs=None):
|
6561
|
+
def volume_estimation(self, axs:plt.Axes= None):
|
6501
6562
|
""" Estimation of the volume of the selected zone """
|
6502
6563
|
|
6503
6564
|
vect = self.array[np.logical_not(self.array.mask)].flatten()
|
@@ -6527,58 +6588,125 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6527
6588
|
deltaz = (zmax - zmin) / nb
|
6528
6589
|
curz = zmin
|
6529
6590
|
nbgroupement = []
|
6530
|
-
|
6591
|
+
labeled_areas = []
|
6531
6592
|
stockage = []
|
6532
6593
|
z = []
|
6533
6594
|
|
6534
|
-
|
6595
|
+
methods = [_("All cells below the elevation (even if cells are disconnected)"),
|
6596
|
+
_("Only the largest connected area below the elevation (not necessarily the same for each elevation)"),
|
6597
|
+
_("Only the area below the elevation (if containing the cells stored in memory selection)")]
|
6598
|
+
|
6599
|
+
keys_select = list(self.SelectionData.selections.keys())
|
6600
|
+
if len(keys_select) == 0:
|
6601
|
+
methods = methods[:2]
|
6602
|
+
use_memory = False
|
6603
|
+
|
6604
|
+
dlg = wx.SingleChoiceDialog(None, _("Choose a method for selecting the area to integrate"), _("Labeling?"), methods)
|
6535
6605
|
ret = dlg.ShowModal()
|
6536
|
-
|
6537
|
-
|
6538
|
-
|
6606
|
+
|
6607
|
+
if ret == wx.ID_CANCEL:
|
6608
|
+
dlg.Destroy()
|
6609
|
+
return
|
6610
|
+
|
6611
|
+
if dlg.GetSelection() == 0:
|
6612
|
+
labeled = False
|
6613
|
+
else:
|
6614
|
+
labeled = True
|
6615
|
+
if dlg.GetSelection() == 1:
|
6616
|
+
use_memory = False
|
6617
|
+
else:
|
6618
|
+
if len(keys_select) >1:
|
6619
|
+
dlg = wx.SingleChoiceDialog(None, _("Choose a memory selection"), _("Memory selection?"), keys_select)
|
6620
|
+
ret = dlg.ShowModal()
|
6621
|
+
|
6622
|
+
if ret == wx.ID_CANCEL:
|
6623
|
+
dlg.Destroy()
|
6624
|
+
return
|
6625
|
+
|
6626
|
+
key = keys_select[dlg.GetSelection()]
|
6627
|
+
else:
|
6628
|
+
key = keys_select[0]
|
6629
|
+
|
6630
|
+
xy_key = self.SelectionData.selections[key]['select']
|
6631
|
+
if len(xy_key) == 0:
|
6632
|
+
logging.error(_('Empty selection'))
|
6633
|
+
return
|
6634
|
+
|
6635
|
+
ij_key = self.xy2ij_np(xy_key)
|
6636
|
+
|
6637
|
+
use_memory = True
|
6539
6638
|
|
6540
6639
|
extensionmax = WolfArray(mold=self)
|
6541
6640
|
extensionmax.array[:, :] = 0.
|
6542
6641
|
|
6543
6642
|
if labeled:
|
6544
|
-
for i in range(nb + 1):
|
6545
|
-
logging.info(_(' Step ') +str(i))
|
6643
|
+
for i in tqdm(range(nb + 1)):
|
6546
6644
|
z.append(curz)
|
6547
6645
|
|
6646
|
+
# Compute difference between the array and the current elevation
|
6548
6647
|
if i == 0:
|
6549
6648
|
diff = self.array - (curz + 1.e-3)
|
6550
6649
|
else:
|
6551
6650
|
diff = self.array - curz
|
6552
6651
|
|
6652
|
+
# Keep only the negative values
|
6553
6653
|
diff[diff > 0] = 0.
|
6554
6654
|
diff.data[diff.mask] = 0.
|
6555
|
-
labeled_array, num_features = label(diff.data)
|
6556
|
-
labeled_array = ma.asarray(labeled_array)
|
6557
|
-
labeled_array.mask = self.array.mask
|
6558
|
-
|
6559
|
-
# groupement = labeled_array
|
6560
|
-
# groupement[labeled_array.mask] = 0
|
6561
|
-
# nbgroupement.append(num_features)
|
6562
|
-
# for j in range(1, nbgroupement[i] + 1):
|
6563
|
-
# taille = (np.sum(groupement[groupement == j]) // j)
|
6564
|
-
# longueur.append([taille, j])
|
6565
|
-
|
6566
6655
|
|
6567
|
-
|
6656
|
+
if np.count_nonzero(diff < 0.) > 1:
|
6657
|
+
# More than one cell below the elevation
|
6658
|
+
|
6659
|
+
# Labeling of the cells below the elevation
|
6660
|
+
labeled_array, num_features = label(diff.data)
|
6661
|
+
# Applying the same mask as the original array
|
6662
|
+
labeled_array = ma.asarray(labeled_array)
|
6663
|
+
labeled_array.mask = self.array.mask
|
6664
|
+
|
6665
|
+
if use_memory:
|
6666
|
+
# Use only the labeled areas containing the cells stored in memory selection
|
6667
|
+
labeled_areas = []
|
6668
|
+
for curij in ij_key:
|
6669
|
+
labeled_areas.append(labeled_array[curij[0], curij[1]])
|
6670
|
+
|
6671
|
+
# Remove masked value
|
6672
|
+
labeled_areas = [x for x in labeled_areas if x is not ma.masked]
|
6673
|
+
# Remove duplicates
|
6674
|
+
labeled_areas = list(set(labeled_areas))
|
6675
|
+
|
6676
|
+
for curarea in labeled_areas:
|
6677
|
+
if curarea ==0:
|
6678
|
+
volume = 0.
|
6679
|
+
surface = 0.
|
6680
|
+
continue
|
6681
|
+
|
6682
|
+
# Search
|
6683
|
+
mask = labeled_array == curarea
|
6684
|
+
area = np.where(mask)
|
6685
|
+
volume = -self.dx * self.dy * np.sum(diff[area])
|
6686
|
+
surface = self.dx * self.dy * len(area[0])
|
6687
|
+
extensionmax.array[np.logical_and(mask, extensionmax.array[:, :] == 0.)] = float(i + 1)
|
6568
6688
|
|
6569
|
-
|
6689
|
+
else:
|
6690
|
+
labeled_areas = list(sum_labels(np.ones(labeled_array.shape, dtype=np.int32), labeled_array, range(1, num_features+1)))
|
6691
|
+
labeled_areas = [[x, y] for x, y in zip(labeled_areas, range(1, num_features+1))]
|
6692
|
+
labeled_areas.sort(key=lambda x: x[0], reverse=True)
|
6693
|
+
jmax = labeled_areas[0][1]
|
6694
|
+
nbmax = labeled_areas[0][0]
|
6695
|
+
|
6696
|
+
volume = -self.dx * self.dy * np.sum(diff[labeled_array == jmax])
|
6697
|
+
surface = self.dx * self.dy * nbmax
|
6698
|
+
extensionmax.array[np.logical_and(labeled_array == jmax, extensionmax.array[:, :] == 0.)] = float(i + 1)
|
6699
|
+
else:
|
6700
|
+
# Only one cell below the elevation
|
6701
|
+
volume = -self.dx * self.dy * np.sum(diff)
|
6702
|
+
surface = self.dx * self.dy * np.count_nonzero(diff<0.)
|
6703
|
+
extensionmax.array[np.logical_and(diff[:,:]<0., extensionmax.array[:, :] == 0.)] = float(i + 1)
|
6570
6704
|
|
6571
|
-
jmax = longueur[0][1]
|
6572
|
-
nbmax = longueur[0][0]
|
6573
|
-
volume = -self.dx * self.dy * np.sum(diff[labeled_array == jmax])
|
6574
|
-
surface = self.dx * self.dy * nbmax
|
6575
6705
|
stockage.append([volume, surface])
|
6576
6706
|
curz += deltaz
|
6577
6707
|
|
6578
|
-
extensionmax.array[np.logical_and(labeled_array == jmax, extensionmax.array[:, :] == 0.)] = float(i + 1)
|
6579
6708
|
else:
|
6580
|
-
for i in range(nb + 1):
|
6581
|
-
logging.info(_(' Step ') +str(i))
|
6709
|
+
for i in tqdm(range(nb + 1)):
|
6582
6710
|
z.append(curz)
|
6583
6711
|
|
6584
6712
|
if i == 0:
|
@@ -6595,7 +6723,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6595
6723
|
|
6596
6724
|
extensionmax.array[np.logical_and(diff[:,:]<0., extensionmax.array[:, :] == 0.)] = float(i + 1)
|
6597
6725
|
|
6598
|
-
dlg = wx.FileDialog(None, _('Choose filename'), wildcard='bin (*.bin)|*.bin|All (*.*)|*.*', style=wx.FD_SAVE)
|
6726
|
+
dlg = wx.FileDialog(None, _('Choose filename for zoning result'), wildcard='bin (*.bin)|*.bin|tif (*.tif)|*.tif|All (*.*)|*.*', style=wx.FD_SAVE)
|
6599
6727
|
ret = dlg.ShowModal()
|
6600
6728
|
if ret == wx.ID_CANCEL:
|
6601
6729
|
dlg.Destroy()
|
@@ -6609,22 +6737,25 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6609
6737
|
|
6610
6738
|
if axs is None:
|
6611
6739
|
fig, axs = plt.subplots(1, 2, tight_layout=True)
|
6740
|
+
else:
|
6741
|
+
fig = axs[0].get_figure()
|
6742
|
+
|
6612
6743
|
axs[0].plot(z, [x[0] for x in stockage])
|
6613
6744
|
axs[0].scatter(z, [x[0] for x in stockage])
|
6614
6745
|
axs[0].set_xlabel(_("Elevation [m]"), size=15)
|
6615
|
-
axs[0].set_ylabel(_("Volume [m^3]"), size=15)
|
6746
|
+
axs[0].set_ylabel(_("Volume [$m^3$]"), size=15)
|
6616
6747
|
axs[1].step(z, [x[1] for x in stockage], where='post')
|
6617
6748
|
axs[1].scatter(z, [x[1] for x in stockage])
|
6618
6749
|
axs[1].set_xlabel(_("Elevation [m]"), size=15)
|
6619
|
-
axs[1].set_ylabel(_("Surface [m^2]"), size=15)
|
6620
|
-
|
6750
|
+
axs[1].set_ylabel(_("Surface [$m^2$]"), size=15)
|
6751
|
+
fig.suptitle(_("Retention capacity of the selected zone"), fontsize=20)
|
6621
6752
|
|
6622
6753
|
with open(fn[:-4] + '_hvs.txt', 'w') as f:
|
6623
|
-
f.write('H [m]\tZ [m DNG]\tVolume [m^3]\tSurface [m^2]\n')
|
6754
|
+
f.write('H [m]\tZ [m DNG]\tVolume [$m^3$]\tSurface [$m^2$]\n')
|
6624
6755
|
for curz, (curv, curs) in zip(z, stockage):
|
6625
6756
|
f.write('{}\t{}\t{}\t{}\n'.format(curz - zmin, curz, curv, curs))
|
6626
6757
|
|
6627
|
-
return axs
|
6758
|
+
return fig, axs
|
6628
6759
|
|
6629
6760
|
def paste_all(self, fromarray:"WolfArray", mask_after:bool=True):
|
6630
6761
|
""" Paste all the values from another WolfArray """
|
@@ -6735,6 +6866,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6735
6866
|
dtype = np.int16
|
6736
6867
|
elif self.wolftype == WOLF_ARRAY_FULL_INTEGER8:
|
6737
6868
|
dtype = np.int8
|
6869
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
6870
|
+
dtype = np.uint8
|
6738
6871
|
|
6739
6872
|
self.dx = myhead.dx
|
6740
6873
|
self.dy = myhead.dy
|
@@ -6905,20 +7038,24 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6905
7038
|
self.plotted = False
|
6906
7039
|
|
6907
7040
|
if unload and self.filename != '':
|
6908
|
-
if
|
6909
|
-
|
6910
|
-
|
6911
|
-
style=wx.YES_NO)
|
6912
|
-
ret = dlg.ShowModal()
|
6913
|
-
if ret == wx.ID_YES:
|
6914
|
-
unload=True
|
7041
|
+
if Path(self.filename).exists():
|
7042
|
+
# An array can exists with a filename but no written data on disk
|
7043
|
+
# In this case, we don't want to delete the data in memory
|
6915
7044
|
|
6916
|
-
|
6917
|
-
|
6918
|
-
|
6919
|
-
|
6920
|
-
|
6921
|
-
|
7045
|
+
if askquestion and self.wx_exists:
|
7046
|
+
dlg = wx.MessageDialog(None,
|
7047
|
+
_('Do you want to unload data? \n If YES, the data will be reloaded from file once checekd \n If not saved, modifications will be lost !!'),
|
7048
|
+
style=wx.YES_NO)
|
7049
|
+
ret = dlg.ShowModal()
|
7050
|
+
if ret == wx.ID_YES:
|
7051
|
+
unload=True
|
7052
|
+
|
7053
|
+
if unload:
|
7054
|
+
self.delete_lists()
|
7055
|
+
self.array = np.zeros([1])
|
7056
|
+
if VERSION_RGB==1 : self.rgb = None
|
7057
|
+
self.loaded = False
|
7058
|
+
return
|
6922
7059
|
|
6923
7060
|
if not forceresetOGL:
|
6924
7061
|
if askquestion and self.wx_exists:
|
@@ -7186,7 +7323,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7186
7323
|
|
7187
7324
|
return newArray
|
7188
7325
|
|
7189
|
-
def mask_outsidepoly(self, myvect: vector, eps:float = 0
|
7326
|
+
def mask_outsidepoly(self, myvect: vector, eps:float = 0., set_nullvalue:bool=True):
|
7190
7327
|
"""
|
7191
7328
|
Mask nodes outside a polygon and set values to nullvalue
|
7192
7329
|
|
@@ -7196,31 +7333,21 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7196
7333
|
# (coord will be converted back with translation, origin and dx/dy)
|
7197
7334
|
# (mesh coord, 0-based)
|
7198
7335
|
|
7199
|
-
mask = self.array.mask
|
7200
|
-
mask[:,:] = True # Mask everything
|
7201
|
-
|
7202
7336
|
# trouve les indices dans le polygone
|
7203
|
-
myij = self.get_ij_inside_polygon(myvect, usemask=
|
7337
|
+
myij = self.get_ij_inside_polygon(myvect, usemask=True, eps=eps)
|
7204
7338
|
|
7205
|
-
#
|
7206
|
-
mask[myij[:,0],myij[:,1]] = False
|
7339
|
+
self.array.mask.fill(True) # Mask everything
|
7207
7340
|
|
7208
|
-
#
|
7209
|
-
self.array.
|
7210
|
-
|
7211
|
-
# recherche du nouveau masque, sinon les valeurs no_data à
|
7212
|
-
# l'intérieur du polygone vont pollluer la matrice
|
7341
|
+
# démasquage des mailles contenues
|
7342
|
+
self.array.mask[myij[:,0],myij[:,1]] = False
|
7213
7343
|
|
7214
|
-
|
7215
|
-
|
7216
|
-
|
7217
|
-
# FIXME Why simply not use the previous mask value ?
|
7218
|
-
# FIXME This operation seems to contradict mask[:,:] = True
|
7219
|
-
self.mask_data(self.nullvalue)
|
7344
|
+
if set_nullvalue:
|
7345
|
+
# annulation des valeurs en dehors du polygone
|
7346
|
+
self.set_nullvalue_in_mask()
|
7220
7347
|
|
7221
7348
|
self.count()
|
7222
7349
|
|
7223
|
-
def mask_insidepoly(self, myvect: vector, eps:float = 0
|
7350
|
+
def mask_insidepoly(self, myvect: vector, eps:float = 0., set_nullvalue:bool=True):
|
7224
7351
|
"""
|
7225
7352
|
Mask nodes inside a polygon and set values to nullvalue
|
7226
7353
|
|
@@ -7233,8 +7360,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7233
7360
|
# trouve les indices dans le polygone
|
7234
7361
|
myij = self.get_ij_inside_polygon(myvect, usemask=False, eps=eps)
|
7235
7362
|
|
7236
|
-
|
7237
|
-
|
7363
|
+
if set_nullvalue:
|
7364
|
+
# annulation des valeurs en dehors du polygone
|
7365
|
+
self.array.data[myij[:,0],myij[:,1]] = self.nullvalue
|
7238
7366
|
|
7239
7367
|
# masquage des mailles contenues
|
7240
7368
|
self.array.mask[myij[:,0],myij[:,1]] = True
|
@@ -7250,8 +7378,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7250
7378
|
"""
|
7251
7379
|
Return the coordinates inside a polygon
|
7252
7380
|
|
7253
|
-
:param myvect
|
7254
|
-
:param usemask
|
7381
|
+
:param myvect: target vector
|
7382
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7255
7383
|
"""
|
7256
7384
|
|
7257
7385
|
if isinstance(myvect, vector):
|
@@ -7279,8 +7407,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7279
7407
|
"""
|
7280
7408
|
Return the coordinates inside a polygon
|
7281
7409
|
|
7282
|
-
:param myvect
|
7283
|
-
:param usemask
|
7410
|
+
:param myvect: target vector
|
7411
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7284
7412
|
"""
|
7285
7413
|
|
7286
7414
|
if isinstance(myvect, vector):
|
@@ -7307,8 +7435,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7307
7435
|
"""
|
7308
7436
|
Return the coordinates along a polyline
|
7309
7437
|
|
7310
|
-
:param myvect
|
7311
|
-
:param usemask
|
7438
|
+
:param myvect: target vector
|
7439
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7312
7440
|
"""
|
7313
7441
|
|
7314
7442
|
allij = self.get_ij_under_polyline(myvect, usemask)
|
@@ -7320,8 +7448,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7320
7448
|
"""
|
7321
7449
|
Return the indices inside a polygon
|
7322
7450
|
|
7323
|
-
:param myvect
|
7324
|
-
:param usemask
|
7451
|
+
:param myvect: target vector
|
7452
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7453
|
+
:param eps: epsilon for the intersection
|
7325
7454
|
"""
|
7326
7455
|
|
7327
7456
|
# force la mise à jour des min/max
|
@@ -7346,8 +7475,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7346
7475
|
def intersects_polygon(self, myvect: vector | Polygon, usemask:bool=True):
|
7347
7476
|
""" Return True if the array intersects the polygon
|
7348
7477
|
|
7349
|
-
:param myvect
|
7350
|
-
:param usemask
|
7478
|
+
:param myvect: target vector
|
7479
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7351
7480
|
"""
|
7352
7481
|
|
7353
7482
|
return self.get_xy_inside_polygon(myvect, usemask).shape[0] > 0
|
@@ -7355,8 +7484,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7355
7484
|
def intersects_polygon_shapely(self, myvect: vector | Polygon, eps:float = 0., usemask:bool=True):
|
7356
7485
|
""" Return True if the array intersects the polygon
|
7357
7486
|
|
7358
|
-
:param myvect
|
7359
|
-
:param usemask
|
7487
|
+
:param myvect: target vector
|
7488
|
+
:param usemask: limit potential nodes to unmaksed nodes
|
7360
7489
|
"""
|
7361
7490
|
return self.get_xy_inside_polygon_shapely(myvect, usemask).shape[0] > 0
|
7362
7491
|
|
@@ -7364,8 +7493,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7364
7493
|
"""
|
7365
7494
|
Return the indices along a polyline
|
7366
7495
|
|
7367
|
-
:param myvect
|
7368
|
-
:param usedmask
|
7496
|
+
:param myvect: target vector
|
7497
|
+
:param usedmask: limit potential nodes to unmaksed nodes
|
7369
7498
|
"""
|
7370
7499
|
|
7371
7500
|
ds = min(self.dx, self.dy)
|
@@ -7388,8 +7517,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7388
7517
|
"""
|
7389
7518
|
Récupération des valeurs contenues dans un polygone
|
7390
7519
|
|
7391
|
-
:param usemask
|
7392
|
-
:param getxy
|
7520
|
+
:param usemask: (optional) restreint les éléments aux éléments non masqués de la matrice
|
7521
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
7393
7522
|
"""
|
7394
7523
|
mypoints = self.get_xy_inside_polygon(myvect, usemask)
|
7395
7524
|
myvalues = np.asarray([self.get_value(cur[0], cur[1]) for cur in mypoints])
|
@@ -7403,8 +7532,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7403
7532
|
"""
|
7404
7533
|
Récupération des valeurs contenues sous une polyligne
|
7405
7534
|
|
7406
|
-
:param usemask
|
7407
|
-
:param getxy
|
7535
|
+
:param usemask: (optional) restreint les éléments aux éléments non masqués de la matrice
|
7536
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
7408
7537
|
"""
|
7409
7538
|
mypoints = self.get_xy_under_polyline(myvect, usemask)
|
7410
7539
|
|
@@ -7419,8 +7548,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7419
7548
|
"""
|
7420
7549
|
Récupération de toutes les valeurs contenues dans un polygone
|
7421
7550
|
|
7422
|
-
:param usemask
|
7423
|
-
:param getxy
|
7551
|
+
:param usemask: (optional) restreint les éléments aux éléments non masqués de la matrice
|
7552
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
7424
7553
|
|
7425
7554
|
ICI on retourne le résultat de get_values_insidepoly, car une seule matrice, mais une autre classe pourrait vouloir faure autre chose
|
7426
7555
|
C'est le cas notamment de Wolfresults_2D
|
@@ -7432,8 +7561,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7432
7561
|
"""
|
7433
7562
|
Récupération de toutes les valeurs sous la polyligne
|
7434
7563
|
|
7435
|
-
:param usemask
|
7436
|
-
:param getxy
|
7564
|
+
:param usemask: (optional) restreint les éléments aux éléments non masqués de la matrice
|
7565
|
+
:param getxy: (optional) retourne en plus les coordonnées des points
|
7437
7566
|
|
7438
7567
|
ICI on retourne le résultat de get_values_underpoly, car une seule matrice, mais une autre classe pourrait vouloir faure autre chose
|
7439
7568
|
C'est le cas notamment de Wolfresults_2D
|
@@ -7562,6 +7691,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7562
7691
|
elif locarray.dtype == np.int8:
|
7563
7692
|
self.wolftype = WOLF_ARRAY_FULL_INTEGER8
|
7564
7693
|
logging.warning(_('Data type changed to int8'))
|
7694
|
+
elif locarray.dtype == np.uint8:
|
7695
|
+
self.wolftype = WOLF_ARRAY_FULL_UINTEGER8
|
7696
|
+
logging.warning(_('Data type changed to uint8'))
|
7565
7697
|
else:
|
7566
7698
|
logging.error(_('Unsupported type in numpy file -- Abort wrting header file'))
|
7567
7699
|
writing_header = False
|
@@ -7586,7 +7718,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7586
7718
|
:param factor: factor of resolution change -- > 1.0 : decrease resolution, < 1.0 : increase resolution
|
7587
7719
|
:type factor: float
|
7588
7720
|
:return: new shape
|
7589
|
-
:rtype: Tuple[int, int]
|
7721
|
+
:rtype: Tuple[int, int], Tuple[float, float]
|
7590
7722
|
"""
|
7591
7723
|
|
7592
7724
|
newdx = self.dx * float(factor)
|
@@ -7869,6 +8001,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7869
8001
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER8]:
|
7870
8002
|
locarray = np.frombuffer(f.read(self.nbx * self.nby * 2), dtype=np.int8)
|
7871
8003
|
self.array = ma.masked_array(locarray.copy(), dtype=np.int8)
|
8004
|
+
elif self.wolftype in [WOLF_ARRAY_FULL_UINTEGER8]:
|
8005
|
+
locarray = np.frombuffer(f.read(self.nbx * self.nby * 2), dtype=np.uint8)
|
8006
|
+
self.array = ma.masked_array(locarray.copy(), dtype=np.uint8)
|
7872
8007
|
|
7873
8008
|
if self.nbdims == 2:
|
7874
8009
|
self.array = self.array.reshape(self.nbx, self.nby, order='F')
|
@@ -7903,7 +8038,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7903
8038
|
|
7904
8039
|
return xyz[filter]
|
7905
8040
|
|
7906
|
-
|
8041
|
+
@classmethod
|
8042
|
+
def set_general_frame_from_xyz(cls, fname:str, dx:float, dy:float, border_size:int=5, delimiter:str=',', fillin:bool=False):
|
7907
8043
|
"""
|
7908
8044
|
Lecture d'un fichier texte xyz et initialisation des données de base
|
7909
8045
|
|
@@ -7913,19 +8049,72 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
7913
8049
|
:param border_size: nombre de mailles de bordure en plus de l'extension spatiale du fichier
|
7914
8050
|
"""
|
7915
8051
|
|
7916
|
-
my_file = XYZFile(fname)
|
8052
|
+
my_file = XYZFile(fname, delimiter=delimiter)
|
7917
8053
|
my_file.read_from_file()
|
7918
8054
|
(xlim, ylim) = my_file.get_extent()
|
7919
8055
|
|
7920
|
-
|
7921
|
-
|
7922
|
-
|
7923
|
-
|
7924
|
-
|
7925
|
-
|
8056
|
+
Array = WolfArray()
|
8057
|
+
Array.dx = dx
|
8058
|
+
Array.dy = dy
|
8059
|
+
Array.origx = m.floor(xlim[0]) - dx/2. - float(border_size) * Array.dx
|
8060
|
+
Array.origy = m.floor(ylim[0]) - dy/2. - float(border_size) * Array.dy
|
8061
|
+
Array.nbx = int((m.floor(xlim[1]) - m.ceil(xlim[0])) / Array.dx) + 1 + 2*border_size
|
8062
|
+
Array.nby = int((m.floor(ylim[1]) - m.ceil(ylim[0])) / Array.dy) + 1 + 2*border_size
|
8063
|
+
|
8064
|
+
Array.array = np.ma.zeros((Array.nbx, Array.nby), dtype=np.float32)
|
7926
8065
|
|
7927
|
-
|
7928
|
-
|
8066
|
+
if fillin:
|
8067
|
+
Array.fillin_from_xyz(my_file.xyz)
|
8068
|
+
|
8069
|
+
return Array
|
8070
|
+
|
8071
|
+
@classmethod
|
8072
|
+
def set_general_frame_from_xyz_dir(cls, path:str, bounds:list, delimiter:str=',', dxdy:tuple[float, float]= None, border_size:int=5, fillin:bool=True):
|
8073
|
+
"""
|
8074
|
+
Lecture d'un dossier contenant des fichiers texte xyz, initialisation des données de base et chargement de la matrice
|
8075
|
+
Renvoie un WolfArray or False si le fichier n'est pas dans les limites
|
8076
|
+
|
8077
|
+
:param path: chemin du dossier avec les fichier xyz
|
8078
|
+
:dtype path: str
|
8079
|
+
:param bounds: limites de l'extension spatiale
|
8080
|
+
:dtype bounds: list
|
8081
|
+
:param delimiter: délimiteur des fichiers xyz
|
8082
|
+
:dtype delimiter: str
|
8083
|
+
:param border_size: nombre de mailles de bordure en plus de l'extension spatiale du fichier
|
8084
|
+
:dtype border_size: int
|
8085
|
+
"""
|
8086
|
+
|
8087
|
+
Data_xyz = XYZFile('nothing.xyz', folder=path, bounds=bounds, delimiter=delimiter)
|
8088
|
+
|
8089
|
+
if Data_xyz.nblines == 0:
|
8090
|
+
logging.info(f"File not in the boundaries for {path.split(os.sep)[-1]}")
|
8091
|
+
return False
|
8092
|
+
|
8093
|
+
xlim, ylim = Data_xyz.get_extent()
|
8094
|
+
|
8095
|
+
if dxdy is None:
|
8096
|
+
# We assume dx and dy are equals within xyz file
|
8097
|
+
dx = np.diff(Data_xyz.xyz[0:2,0])[0]
|
8098
|
+
logging.info(f"dx = {dx} ; dy = {dx}")
|
8099
|
+
dy = dx
|
8100
|
+
else:
|
8101
|
+
dx,dy = dxdy
|
8102
|
+
assert dx is not None and dy is not None, _('dx and dy must be defined')
|
8103
|
+
|
8104
|
+
Array = WolfArray()
|
8105
|
+
Array.dx = dx
|
8106
|
+
Array.dy = dy
|
8107
|
+
Array.origx = m.floor(xlim[0]) -dx/2. - float(border_size) * Array.dx
|
8108
|
+
Array.origy = m.floor(ylim[0]) -dy/2. - float(border_size) * Array.dy
|
8109
|
+
Array.nbx = int((m.floor(xlim[1]) - m.ceil(xlim[0])) / Array.dx) +1 + 2*border_size
|
8110
|
+
Array.nby = int((m.floor(ylim[1]) - m.ceil(ylim[0])) / Array.dy) +1 + 2*border_size
|
8111
|
+
|
8112
|
+
Array.array = np.ma.zeros((Array.nbx, Array.nby))
|
8113
|
+
|
8114
|
+
if fillin:
|
8115
|
+
Array.fillin_from_xyz(Data_xyz.xyz)
|
8116
|
+
|
8117
|
+
return Array
|
7929
8118
|
|
7930
8119
|
def fillin_from_xyz(self, xyz:np.ndarray):
|
7931
8120
|
""" Remplissage du tableau à partir d'un tableau xyz """
|
@@ -8027,6 +8216,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8027
8216
|
value=np.int16(value)
|
8028
8217
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER8]:
|
8029
8218
|
value=np.int8(value)
|
8219
|
+
elif self.wolftype in [WOLF_ARRAY_FULL_UINTEGER8]:
|
8220
|
+
value=np.uint8(value)
|
8030
8221
|
except:
|
8031
8222
|
logging.error(_('Type not supported : {} - {}'.format(value, type(value))))
|
8032
8223
|
logging.warning(_('Masking operation compromised'))
|
@@ -8190,7 +8381,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8190
8381
|
assert type(k_start) == int, "k_start must be an integer"
|
8191
8382
|
assert type(nbz) == int, "nbz must be an integer"
|
8192
8383
|
|
8193
|
-
newWolfArray = WolfArray()
|
8384
|
+
newWolfArray = WolfArray(nullvalue=self.nullvalue)
|
8194
8385
|
newWolfArray.nbx = nbx
|
8195
8386
|
newWolfArray.nby = nby
|
8196
8387
|
newWolfArray.dx = self.dx
|
@@ -8383,7 +8574,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8383
8574
|
|
8384
8575
|
if VERSION_RGB==1 :
|
8385
8576
|
if self.nbx * self.nby > 1_000_000 : logging.info(_('Computing colors'))
|
8386
|
-
if self.wolftype not in [WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_INTEGER8]:
|
8577
|
+
if self.wolftype not in [WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_UINTEGER8]:
|
8387
8578
|
# FIXME: Currently, only some types are supported in Cython/OpenGL library
|
8388
8579
|
self._tmp_float32 = self.array.astype(dtype=np.float32)
|
8389
8580
|
self.rgb = self.mypal.get_rgba(self._tmp_float32)
|
@@ -8394,6 +8585,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8394
8585
|
elif VERSION_RGB in [2 ,3]:
|
8395
8586
|
if self.wolftype not in [WOLF_ARRAY_FULL_SINGLE,
|
8396
8587
|
WOLF_ARRAY_FULL_INTEGER8,
|
8588
|
+
WOLF_ARRAY_FULL_UINTEGER8,
|
8397
8589
|
WOLF_ARRAY_FULL_INTEGER16,
|
8398
8590
|
WOLF_ARRAY_FULL_INTEGER16_2,
|
8399
8591
|
WOLF_ARRAY_FULL_INTEGER,
|
@@ -8561,7 +8753,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8561
8753
|
self.mygrid = {}
|
8562
8754
|
self.gridmaxscales = -1
|
8563
8755
|
|
8564
|
-
def plot_matplotlib(self):
|
8756
|
+
def plot_matplotlib(self, figax:tuple=None, getdata_im:bool=False):
|
8565
8757
|
"""
|
8566
8758
|
Plot the array - Matplotlib version
|
8567
8759
|
|
@@ -8570,14 +8762,19 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8570
8762
|
|
8571
8763
|
self.mask_data(self.nullvalue)
|
8572
8764
|
self.updatepalette(0)
|
8765
|
+
if figax is None:
|
8766
|
+
fig, ax = plt.subplots()
|
8767
|
+
else:
|
8768
|
+
fig, ax = figax
|
8573
8769
|
|
8574
|
-
|
8575
|
-
|
8576
|
-
ax.imshow(self.array.transpose(), origin='lower', cmap=self.mypal,
|
8770
|
+
im = ax.imshow(self.array.transpose(), origin='lower', cmap=self.mypal,
|
8577
8771
|
extent=(self.origx, self.origx + self.dx * self.nbx, self.origy, self.origy + self.dy * self.nby))
|
8578
8772
|
ax.set_aspect('equal')
|
8579
8773
|
|
8580
|
-
|
8774
|
+
if getdata_im:
|
8775
|
+
return fig, ax, im
|
8776
|
+
else:
|
8777
|
+
return fig, ax
|
8581
8778
|
|
8582
8779
|
def fillonecellgrid(self, curscale, loci, locj, force=False):
|
8583
8780
|
""" Fill one cell of the plotted grid """
|
@@ -8638,6 +8835,14 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8638
8835
|
elif self.nbnotnull > 0:
|
8639
8836
|
wolfogl.addmeall_int8_pal(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8640
8837
|
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst))
|
8838
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
8839
|
+
if self.nbnotnull != self.nbx * self.nby:
|
8840
|
+
if self.nbnotnull > 0:
|
8841
|
+
wolfogl.addme_uint8_pal(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8842
|
+
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst))
|
8843
|
+
elif self.nbnotnull > 0:
|
8844
|
+
wolfogl.addmeall_uint8_pal(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8845
|
+
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst))
|
8641
8846
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2]:
|
8642
8847
|
if self.nbnotnull != self.nbx * self.nby:
|
8643
8848
|
if self.nbnotnull > 0:
|
@@ -8694,6 +8899,14 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8694
8899
|
elif self.nbnotnull > 0:
|
8695
8900
|
wolfogl.addmeall_int8_pal_mask(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8696
8901
|
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst), self.array.mask)
|
8902
|
+
elif self.wolftype == WOLF_ARRAY_FULL_UINTEGER8:
|
8903
|
+
if self.nbnotnull != self.nbx * self.nby:
|
8904
|
+
if self.nbnotnull > 0:
|
8905
|
+
wolfogl.addme_uint8_pal_mask(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8906
|
+
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst), self.array.mask)
|
8907
|
+
elif self.nbnotnull > 0:
|
8908
|
+
wolfogl.addmeall_uint8_pal_mask(self.array, self.mypal.colorsflt, self.mypal.values, ox, oy, dx, dy, jstart,
|
8909
|
+
jend, istart, iend, cursize, self.nullvalue, self.alpha, int(self.mypal.interval_cst), self.array.mask)
|
8697
8910
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2]:
|
8698
8911
|
if self.nbnotnull != self.nbx * self.nby:
|
8699
8912
|
if self.nbnotnull > 0:
|
@@ -8764,8 +8977,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8764
8977
|
"""
|
8765
8978
|
The borders are computed on basis of the current *mask*
|
8766
8979
|
|
8767
|
-
:param filename
|
8768
|
-
:param abs
|
8980
|
+
:param filename: if provided, write 'sux', 'sux' and 'xy' files
|
8981
|
+
:param abs: add translation coordinates (Global World Coordinates)
|
8769
8982
|
|
8770
8983
|
:return indicesX, indicesY, contourgen, interior
|
8771
8984
|
|
@@ -8961,6 +9174,8 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
8961
9174
|
return WOLF_ARRAY_FULL_INTEGER
|
8962
9175
|
elif curarray.dtype == np.int8:
|
8963
9176
|
return WOLF_ARRAY_FULL_INTEGER8
|
9177
|
+
elif curarray.dtype == np.uint8:
|
9178
|
+
return WOLF_ARRAY_FULL_UINTEGER8
|
8964
9179
|
|
8965
9180
|
self.array = np.ma.array(array.copy())
|
8966
9181
|
self.wolftype = wolftype_from_npz(array)
|