wolfhece 2.0.55__py3-none-any.whl → 2.1.1__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/GraphProfile.py +1 -1
- wolfhece/PyDraw.py +1197 -361
- wolfhece/PyGui.py +1924 -661
- wolfhece/PyPalette.py +47 -0
- wolfhece/PyParams.py +377 -76
- wolfhece/PyVertex.py +14 -1
- wolfhece/PyVertexvectors.py +171 -22
- wolfhece/Results2DGPU.py +1 -2
- wolfhece/apps/version.py +2 -2
- wolfhece/bernoulli/__init__.py +0 -0
- wolfhece/bernoulli/chamber.py +93 -0
- wolfhece/bernoulli/fluids.py +10 -0
- wolfhece/bernoulli/losses.py +100 -0
- wolfhece/bernoulli/network.py +128 -0
- wolfhece/bernoulli/pipe.py +194 -0
- wolfhece/lagrangian/example_domain.py +1 -1
- wolfhece/mesh2d/bc_manager.py +66 -5
- wolfhece/mesh2d/config_manager.py +1 -1
- wolfhece/mesh2d/cst_2D_boundary_conditions.py +59 -2
- wolfhece/mesh2d/wolf2dprev.py +11606 -2678
- wolfhece/models/walous_niv1.pal +29 -0
- wolfhece/models/walous_niv2.pal +77 -0
- wolfhece/pywalous.py +400 -46
- wolfhece/scenario/config_manager.py +14 -5
- wolfhece/wolf_array.py +1487 -458
- wolfhece/wolf_vrt.py +31 -8
- wolfhece/wolfresults_2D.py +230 -91
- {wolfhece-2.0.55.dist-info → wolfhece-2.1.1.dist-info}/METADATA +3 -2
- {wolfhece-2.0.55.dist-info → wolfhece-2.1.1.dist-info}/RECORD +32 -24
- {wolfhece-2.0.55.dist-info → wolfhece-2.1.1.dist-info}/WHEEL +0 -0
- {wolfhece-2.0.55.dist-info → wolfhece-2.1.1.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.0.55.dist-info → wolfhece-2.1.1.dist-info}/top_level.txt +0 -0
wolfhece/wolf_array.py
CHANGED
@@ -61,7 +61,7 @@ from .opengl.py3d import Cache_WolfArray_plot3D, WolfArray_plot3D
|
|
61
61
|
WOLF_ARRAY_HILLSHAPE = -1
|
62
62
|
WOLF_ARRAY_FULL_SINGLE = 1
|
63
63
|
WOLF_ARRAY_FULL_DOUBLE = 2
|
64
|
-
WOLF_ARRAY_SYM_DOUBLE =
|
64
|
+
WOLF_ARRAY_SYM_DOUBLE = 12
|
65
65
|
WOLF_ARRAY_FULL_LOGICAL = 4
|
66
66
|
WOLF_ARRAY_CSR_DOUBLE = 5
|
67
67
|
WOLF_ARRAY_FULL_INTEGER = 6
|
@@ -146,7 +146,7 @@ class header_wolf():
|
|
146
146
|
|
147
147
|
self.head_blocks = {}
|
148
148
|
|
149
|
-
self.
|
149
|
+
self._nullvalue = 0.
|
150
150
|
|
151
151
|
def __str__(self) -> str:
|
152
152
|
""" Return a string representation of the header """
|
@@ -168,6 +168,14 @@ class header_wolf():
|
|
168
168
|
|
169
169
|
return ret
|
170
170
|
|
171
|
+
@property
|
172
|
+
def nullvalue(self):
|
173
|
+
return self._nullvalue
|
174
|
+
|
175
|
+
@nullvalue.setter
|
176
|
+
def nullvalue(self, value:float):
|
177
|
+
self._nullvalue = value
|
178
|
+
|
171
179
|
@property
|
172
180
|
def nbdims(self):
|
173
181
|
if self.nbz == 0:
|
@@ -527,7 +535,7 @@ class header_wolf():
|
|
527
535
|
return None
|
528
536
|
elif otherbounds[0][1] < mybounds[0][0]:
|
529
537
|
return None
|
530
|
-
elif otherbounds[1][1] < mybounds[
|
538
|
+
elif otherbounds[1][1] < mybounds[1][0]:
|
531
539
|
return None
|
532
540
|
else:
|
533
541
|
ox = max(mybounds[0][0], otherbounds[0][0])
|
@@ -545,20 +553,37 @@ class header_wolf():
|
|
545
553
|
else:
|
546
554
|
return ([ox, ex], [oy, ey])
|
547
555
|
|
548
|
-
def find_union(self, other:"header_wolf") -> tuple[list[float],list[float]]:
|
556
|
+
def find_union(self, other:Union["header_wolf", list["header_wolf"]]) -> tuple[list[float],list[float]]:
|
549
557
|
"""
|
550
558
|
Find the union of two header
|
551
559
|
|
552
560
|
:return: tuple of two lists of two floats - ([xmin, xmax],[ymin, ymax])
|
553
561
|
"""
|
554
562
|
|
555
|
-
|
556
|
-
|
563
|
+
if isinstance(other, list):
|
564
|
+
|
565
|
+
for cur in other:
|
566
|
+
assert isinstance(cur, header_wolf), _('All elements in the list must be header_wolf instances')
|
567
|
+
|
568
|
+
[ox,ex], [oy,ey] = self.get_bounds()
|
569
|
+
|
570
|
+
for cur in other:
|
571
|
+
otherbounds = cur.get_bounds()
|
557
572
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
573
|
+
ox = min(ox, otherbounds[0][0])
|
574
|
+
oy = min(oy, otherbounds[1][0])
|
575
|
+
ex = max(ex, otherbounds[0][1])
|
576
|
+
ey = max(ey, otherbounds[1][1])
|
577
|
+
|
578
|
+
else:
|
579
|
+
|
580
|
+
mybounds = self.get_bounds()
|
581
|
+
otherbounds = other.get_bounds()
|
582
|
+
|
583
|
+
ox = min(mybounds[0][0], otherbounds[0][0])
|
584
|
+
oy = min(mybounds[1][0], otherbounds[1][0])
|
585
|
+
ex = max(mybounds[0][1], otherbounds[0][1])
|
586
|
+
ey = max(mybounds[1][1], otherbounds[1][1])
|
562
587
|
|
563
588
|
return ([ox, ex], [oy, ey])
|
564
589
|
|
@@ -773,7 +798,11 @@ class header_wolf():
|
|
773
798
|
return test
|
774
799
|
|
775
800
|
def align2grid(self, x1:float, y1:float, eps:float=0.0001) -> tuple[float,float]:
|
776
|
-
"""
|
801
|
+
"""
|
802
|
+
Align coordinates to nearest grid point
|
803
|
+
where the grid is defined by the borders of the array.
|
804
|
+
|
805
|
+
"""
|
777
806
|
|
778
807
|
if x1-self.origx < 0:
|
779
808
|
x2 = np.round((x1 - self.origx + eps) / self.dx) * self.dx + self.origx
|
@@ -793,6 +822,7 @@ class header_wolf():
|
|
793
822
|
xstart:float=None, ystart:float=None) -> list[list[float]]:
|
794
823
|
"""
|
795
824
|
Rasterize a segment according to the grid
|
825
|
+
where the grid is defined by the borders of the array.
|
796
826
|
|
797
827
|
:param x1: x coordinate of the first point
|
798
828
|
:param y1: y coordinate of the first point
|
@@ -870,47 +900,65 @@ class header_wolf():
|
|
870
900
|
|
871
901
|
return newvector
|
872
902
|
|
873
|
-
def get_xy_infootprint_vect(self, myvect: vector) -> np.ndarray:
|
903
|
+
def get_xy_infootprint_vect(self, myvect: vector, eps:float = 0.) -> tuple[np.ndarray,np.ndarray]:
|
874
904
|
"""
|
875
905
|
Return the coordinates of the cells in the footprint of a vector
|
876
906
|
|
877
907
|
:param myvect = target vector
|
908
|
+
:return: tuple of two numpy arrays - (coordinates, indices)
|
909
|
+
|
878
910
|
"""
|
879
911
|
|
880
|
-
myptsij = self.get_ij_infootprint_vect(myvect)
|
912
|
+
myptsij = self.get_ij_infootprint_vect(myvect, eps=eps)
|
881
913
|
mypts=np.asarray(myptsij.copy(),dtype=np.float64)
|
914
|
+
|
882
915
|
mypts[:,0] = (mypts[:,0]+.5)*self.dx +self.origx +self.translx
|
883
916
|
mypts[:,1] = (mypts[:,1]+.5)*self.dy +self.origy +self.transly
|
884
917
|
|
885
918
|
return mypts,myptsij
|
886
919
|
|
887
|
-
def get_ij_infootprint_vect(self, myvect: vector) -> np.ndarray:
|
920
|
+
def get_ij_infootprint_vect(self, myvect: vector, eps:float = 0.) -> np.ndarray:
|
888
921
|
"""
|
889
922
|
Return the indices of the cells in the footprint of a vector
|
890
923
|
|
891
924
|
:param myvect = target vector
|
925
|
+
:return : numpy array of indices
|
892
926
|
"""
|
893
927
|
|
894
|
-
i1, j1 = self.get_ij_from_xy(myvect.xmin, myvect.ymin)
|
895
|
-
i2, j2 = self.get_ij_from_xy(myvect.xmax, myvect.ymax)
|
928
|
+
i1, j1 = self.get_ij_from_xy(myvect.xmin+eps, myvect.ymin+eps)
|
929
|
+
i2, j2 = self.get_ij_from_xy(myvect.xmax-eps, myvect.ymax-eps)
|
930
|
+
|
896
931
|
i1 = max(i1,0) # FIXME Why ??? How could i,j be negative ? --> because this fucntion can be called with a vector that is not in the array (e.g. a vector defined by clicks in the UI)
|
897
932
|
j1 = max(j1,0)
|
898
933
|
i2 = min(i2,self.nbx-1)
|
899
934
|
j2 = min(j2,self.nby-1)
|
935
|
+
|
900
936
|
xv,yv = np.meshgrid(np.arange(i1,i2+1),np.arange(j1,j2+1))
|
901
937
|
mypts = np.hstack((xv.flatten()[:,np.newaxis],yv.flatten()[:,np.newaxis]))
|
902
938
|
|
903
939
|
return mypts
|
904
940
|
|
905
941
|
def convert_xy2ij_np(self,xy):
|
906
|
-
"""
|
942
|
+
"""
|
943
|
+
Convert XY coordinates to IJ indices **(0-based)** with Numpy without any check/options
|
944
|
+
|
945
|
+
:param xy = numpy array of shape (n,2) with XY coordinates
|
946
|
+
|
947
|
+
"""
|
948
|
+
|
907
949
|
return np.asarray((xy[:,0]-self.origx -self.translx)/self.dx-.5,dtype=np.int32), \
|
908
950
|
np.asarray((xy[:,1]-self.origy -self.transly)/self.dy-.5,dtype=np.int32)
|
909
951
|
|
910
|
-
def convert_ij2xy_np(self,
|
911
|
-
"""
|
912
|
-
|
913
|
-
|
952
|
+
def convert_ij2xy_np(self,ij):
|
953
|
+
"""
|
954
|
+
Convert IJ indices **(0-based)** to XY coordinates with Numpy without any check/options
|
955
|
+
|
956
|
+
:param ij = numpy array of shape (n,2) with IJ indices
|
957
|
+
|
958
|
+
"""
|
959
|
+
|
960
|
+
return np.asarray((ij[:,0]+.5)*self.dx+self.origx +self.translx ,dtype=np.float64), \
|
961
|
+
np.asarray((ij[:,1]+.5)*self.dy+self.origy +self.transly ,dtype=np.float64)
|
914
962
|
|
915
963
|
class NewArray(wx.Dialog):
|
916
964
|
"""
|
@@ -1149,26 +1197,41 @@ class Ops_Array(wx.Frame):
|
|
1149
1197
|
self.array_ops = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize)
|
1150
1198
|
|
1151
1199
|
# panel Selection
|
1200
|
+
# -----------------
|
1201
|
+
|
1152
1202
|
self.selection = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1153
1203
|
self.array_ops.AddPage(self.selection, _("Selection"), True)
|
1154
1204
|
|
1155
1205
|
# panel Operations
|
1206
|
+
# -----------------
|
1207
|
+
|
1156
1208
|
self.operation = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1157
1209
|
self.array_ops.AddPage(self.operation, _("Operators"), False)
|
1158
1210
|
|
1159
1211
|
# panel Mask
|
1212
|
+
# -----------------
|
1213
|
+
|
1160
1214
|
self.mask = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1161
1215
|
self.array_ops.AddPage(self.mask, _("Mask"), False)
|
1162
1216
|
|
1163
1217
|
# panel Interpolation
|
1218
|
+
# ---------------------
|
1219
|
+
|
1220
|
+
# if self.parentarray.nb_blocks>0:
|
1221
|
+
# self.Interpolation = None
|
1222
|
+
# else:
|
1164
1223
|
self.Interpolation = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1165
1224
|
self.array_ops.AddPage(self.Interpolation, _("Interpolation"), False)
|
1166
1225
|
|
1167
1226
|
# panel Tools/Misc
|
1227
|
+
# -----------------
|
1228
|
+
|
1168
1229
|
self.tools = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1169
1230
|
self.array_ops.AddPage(self.tools, _("Miscellaneous"), False)
|
1170
1231
|
|
1171
|
-
#
|
1232
|
+
# panel PALETTE de couleurs
|
1233
|
+
# -------------------------
|
1234
|
+
|
1172
1235
|
self.Palette = PlotPanel(self.array_ops, wx.ID_ANY, toolbar=False)
|
1173
1236
|
self.palgrid = CpGrid(self.Palette, wx.ID_ANY, style=wx.WANTS_CHARS | wx.TE_CENTER)
|
1174
1237
|
self.palapply = wx.Button(self.Palette, wx.ID_ANY, _("Apply"), wx.DefaultPosition, wx.DefaultSize, 0)
|
@@ -1205,8 +1268,18 @@ class Ops_Array(wx.Frame):
|
|
1205
1268
|
|
1206
1269
|
self.palsave = wx.Button(self.Palette, wx.ID_ANY, _("Save to file"), wx.DefaultPosition, wx.DefaultSize, 0)
|
1207
1270
|
self.palsave.SetToolTip(_('Save colormap on .pal file'))
|
1271
|
+
|
1272
|
+
sizer_loadpal = wx.BoxSizer(wx.HORIZONTAL)
|
1273
|
+
|
1208
1274
|
self.palload = wx.Button(self.Palette, wx.ID_ANY, _("Load from file"), wx.DefaultPosition, wx.DefaultSize, 0)
|
1209
1275
|
self.palload.SetToolTip(_('Load colormap from .pal file'))
|
1276
|
+
|
1277
|
+
self._default_pal = wx.Button(self.Palette, wx.ID_ANY, _("Load precomputed"), wx.DefaultPosition, wx.DefaultSize, 0)
|
1278
|
+
self._default_pal.SetToolTip(_('Load a default colormap available in the software'))
|
1279
|
+
|
1280
|
+
sizer_loadpal.Add(self.palload, 1, wx.EXPAND)
|
1281
|
+
sizer_loadpal.Add(self._default_pal, 1, wx.EXPAND)
|
1282
|
+
|
1210
1283
|
self.palimage = wx.Button(self.Palette, wx.ID_ANY, _("Create image"), wx.DefaultPosition, wx.DefaultSize, 0)
|
1211
1284
|
self.palimage.SetToolTip(_('Generate colormap image (horizontal, vertical or both) and save to disk'))
|
1212
1285
|
self.paldistribute = wx.Button(self.Palette, wx.ID_ANY, _("Distribute"), wx.DefaultPosition, wx.DefaultSize, 0)
|
@@ -1240,7 +1313,7 @@ class Ops_Array(wx.Frame):
|
|
1240
1313
|
|
1241
1314
|
self.Palette.sizer.Add(self.palchoosecolor, 1, wx.EXPAND)
|
1242
1315
|
self.Palette.sizer.Add(self.palapply, 1, wx.EXPAND)
|
1243
|
-
self.Palette.sizer.Add(
|
1316
|
+
self.Palette.sizer.Add(sizer_loadpal, 1, wx.EXPAND)
|
1244
1317
|
self.Palette.sizer.Add(self.palsave, 1, wx.EXPAND)
|
1245
1318
|
self.Palette.sizer.Add(self.palimage, 1, wx.EXPAND)
|
1246
1319
|
self.Palette.sizer.Add(self.paldistribute, 1 , wx.EXPAND)
|
@@ -1248,6 +1321,8 @@ class Ops_Array(wx.Frame):
|
|
1248
1321
|
self.array_ops.AddPage(self.Palette, _("Palette"), False)
|
1249
1322
|
|
1250
1323
|
# HISTOGRAMMES
|
1324
|
+
# ----------------
|
1325
|
+
|
1251
1326
|
self.histo = PlotPanel(self.array_ops, wx.ID_ANY, toolbar=True)
|
1252
1327
|
self.histoupdate = wx.Button(self.histo, wx.ID_ANY, _("All data..."), wx.DefaultPosition, wx.DefaultSize, 0)
|
1253
1328
|
self.histoupdatezoom = wx.Button(self.histo, wx.ID_ANY, _("On zoom..."), wx.DefaultPosition, wx.DefaultSize, 0)
|
@@ -1260,58 +1335,70 @@ class Ops_Array(wx.Frame):
|
|
1260
1335
|
self.array_ops.AddPage(self.histo, _("Histogram"), False)
|
1261
1336
|
|
1262
1337
|
# LINKS
|
1338
|
+
# ----------------
|
1339
|
+
|
1263
1340
|
self.links = wx.Panel(self.array_ops, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
|
1264
1341
|
self.array_ops.AddPage(self.links, _("Links"), False)
|
1265
1342
|
|
1266
1343
|
# Interpolation
|
1267
|
-
|
1268
|
-
|
1269
|
-
self.interp2D = wx.Button(self.Interpolation, wx.ID_ANY, _("2D Interpolation on selection"), wx.DefaultPosition,
|
1270
|
-
wx.DefaultSize, 0)
|
1271
|
-
self.interp2D.SetToolTip(_('Spatial interpolation based on nodes stored in named groups. \n The interpolation apply only on the current selection.'))
|
1272
|
-
gSizer1.Add(self.interp2D, 0, wx.EXPAND)
|
1273
|
-
self.interp2D.Bind(wx.EVT_BUTTON, self.interpolation2D)
|
1344
|
+
# ----------------
|
1274
1345
|
|
1275
|
-
|
1276
|
-
wx.DefaultSize, 0)
|
1277
|
-
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship. \n Results : plots and arrays saved on disk'))
|
1346
|
+
if self.Interpolation is not None:
|
1278
1347
|
|
1279
|
-
|
1280
|
-
self.m_button7.Bind(wx.EVT_BUTTON, self.volumesurface)
|
1348
|
+
gSizer1 = wx.GridSizer(0, 2, 0, 0)
|
1281
1349
|
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1350
|
+
self.interp2D = wx.Button(self.Interpolation, wx.ID_ANY, _("2D Interpolation on selection"), wx.DefaultPosition,
|
1351
|
+
wx.DefaultSize, 0)
|
1352
|
+
self.interp2D.SetToolTip(_('Spatial interpolation based on nodes stored in named groups. \n The interpolation apply only on the current selection.'))
|
1353
|
+
gSizer1.Add(self.interp2D, 0, wx.EXPAND)
|
1354
|
+
self.interp2D.Bind(wx.EVT_BUTTON, self.interpolation2D)
|
1285
1355
|
|
1286
|
-
|
1287
|
-
|
1356
|
+
self.m_button7 = wx.Button(self.Interpolation, wx.ID_ANY, _("Stage/Volume/Surface evaluation"), wx.DefaultPosition,
|
1357
|
+
wx.DefaultSize, 0)
|
1358
|
+
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship. \n Results : plots and arrays saved on disk'))
|
1288
1359
|
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1360
|
+
if self.parentarray.nb_blocks>0:
|
1361
|
+
self.m_button7.Disable()
|
1362
|
+
self.m_button7.SetToolTip(_('Evaluate stage-volume-surface relationship. \n Results : plots and arrays saved on disk\n\nThis function is not available for multi-block arrays.'))
|
1292
1363
|
|
1293
|
-
|
1294
|
-
|
1364
|
+
gSizer1.Add(self.m_button7, 0, wx.EXPAND)
|
1365
|
+
self.m_button7.Bind(wx.EVT_BUTTON, self.volumesurface)
|
1295
1366
|
|
1296
|
-
|
1367
|
+
self.m_button8 = wx.Button(self.Interpolation, wx.ID_ANY, _("Interpolation on active zone \n polygons"),
|
1297
1368
|
wx.DefaultPosition, wx.DefaultSize, 0)
|
1298
|
-
|
1369
|
+
self.m_button8.SetToolTip(_('Spatial interpolation based on all polygons in active zone'))
|
1299
1370
|
|
1300
|
-
|
1301
|
-
|
1371
|
+
gSizer1.Add(self.m_button8, 0, wx.EXPAND)
|
1372
|
+
self.m_button8.Bind(wx.EVT_BUTTON, self.interp2Dpolygons)
|
1302
1373
|
|
1303
|
-
|
1374
|
+
self.m_button9 = wx.Button(self.Interpolation, wx.ID_ANY, _("Interpolation on active zone \n 3D polylines"),
|
1304
1375
|
wx.DefaultPosition, wx.DefaultSize, 0)
|
1305
|
-
|
1376
|
+
self.m_button9.SetToolTip(_('Spatial interpolation based on all polylines in active zone'))
|
1377
|
+
|
1378
|
+
gSizer1.Add(self.m_button9, 0, wx.EXPAND)
|
1379
|
+
self.m_button9.Bind(wx.EVT_BUTTON, self.interp2Dpolylines)
|
1380
|
+
|
1381
|
+
self.m_button10 = wx.Button(self.Interpolation, wx.ID_ANY, _("Interpolation on active vector \n polygon"),
|
1382
|
+
wx.DefaultPosition, wx.DefaultSize, 0)
|
1383
|
+
self.m_button10.SetToolTip(_('Spatial interpolation based on active polygon'))
|
1306
1384
|
|
1307
|
-
|
1308
|
-
|
1385
|
+
gSizer1.Add(self.m_button10, 0, wx.EXPAND)
|
1386
|
+
self.m_button10.Bind(wx.EVT_BUTTON, self.interp2Dpolygon)
|
1309
1387
|
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1388
|
+
self.m_button11 = wx.Button(self.Interpolation, wx.ID_ANY, _("Interpolation on active vector \n 3D polyline"),
|
1389
|
+
wx.DefaultPosition, wx.DefaultSize, 0)
|
1390
|
+
self.m_button11.SetToolTip(_('Spatial interpolation based on active polyline'))
|
1391
|
+
|
1392
|
+
gSizer1.Add(self.m_button11, 0, wx.EXPAND)
|
1393
|
+
self.m_button11.Bind(wx.EVT_BUTTON, self.interp2Dpolyline)
|
1394
|
+
|
1395
|
+
self.Interpolation.SetSizer(gSizer1)
|
1396
|
+
self.Interpolation.Layout()
|
1397
|
+
gSizer1.Fit(self.Interpolation)
|
1313
1398
|
|
1314
1399
|
# Tools
|
1400
|
+
# ----------------
|
1401
|
+
|
1315
1402
|
Toolssizer = wx.BoxSizer(wx.VERTICAL)
|
1316
1403
|
|
1317
1404
|
hbox = wx.BoxSizer(wx.HORIZONTAL)
|
@@ -1322,30 +1409,36 @@ class Ops_Array(wx.Frame):
|
|
1322
1409
|
hbox.Add(self.lbl_nullval, 0, wx.EXPAND|wx.ALL)
|
1323
1410
|
hbox.Add(self.txt_nullval, 1, wx.EXPAND|wx.ALL)
|
1324
1411
|
|
1325
|
-
self.ApplyTools = wx.Button(self.tools, wx.ID_ANY, _("Apply null value"), wx.DefaultPosition,
|
1326
|
-
wx.DefaultSize, 0)
|
1412
|
+
self.ApplyTools = wx.Button(self.tools, wx.ID_ANY, _("Apply null value"), wx.DefaultPosition,wx.DefaultSize, 0)
|
1327
1413
|
|
1328
1414
|
|
1329
|
-
self.nullborder = wx.Button(self.tools, wx.ID_ANY, _("Null border"), wx.DefaultPosition,
|
1330
|
-
wx.DefaultSize, 0)
|
1415
|
+
self.nullborder = wx.Button(self.tools, wx.ID_ANY, _("Null border"), wx.DefaultPosition,wx.DefaultSize, 0)
|
1331
1416
|
|
1332
|
-
self.filter_zone = wx.Button(self.tools, wx.ID_ANY, _("Filter zone"), wx.DefaultPosition,
|
1333
|
-
|
1417
|
+
self.filter_zone = wx.Button(self.tools, wx.ID_ANY, _("Filter zone"), wx.DefaultPosition,wx.DefaultSize, 0)
|
1418
|
+
|
1419
|
+
self.labelling = wx.Button(self.tools, wx.ID_ANY, _("Labelling"), wx.DefaultPosition,wx.DefaultSize, 0)
|
1420
|
+
|
1421
|
+
self.extract_selection = wx.Button(self.tools, wx.ID_ANY, _("Extract selection"), wx.DefaultPosition,wx.DefaultSize, 0)
|
1334
1422
|
|
1335
1423
|
Toolssizer.Add(hbox, 0, wx.EXPAND)
|
1336
1424
|
Toolssizer.Add(self.ApplyTools, 1, wx.EXPAND)
|
1337
1425
|
Toolssizer.Add(self.nullborder, 1, wx.EXPAND)
|
1338
1426
|
Toolssizer.Add(self.filter_zone, 1, wx.EXPAND)
|
1427
|
+
Toolssizer.Add(self.labelling, 1, wx.EXPAND)
|
1428
|
+
Toolssizer.Add(self.extract_selection, 1, wx.EXPAND)
|
1339
1429
|
|
1340
|
-
self.ApplyTools.SetToolTip(_("
|
1341
|
-
self.nullborder.SetToolTip(_("Set null value on the border of the array"))
|
1342
|
-
self.filter_zone.SetToolTip(_("Filter the array based on
|
1430
|
+
self.ApplyTools.SetToolTip(_("Apply Nullvalue into memmory/object"))
|
1431
|
+
self.nullborder.SetToolTip(_("Set null value on the border of the array\n\nYou will be asked for the width of the border (in cells)"))
|
1432
|
+
self.filter_zone.SetToolTip(_("Filter the array based on contiguous zones\n\nConservation of the ones which contain selected nodes"))
|
1433
|
+
self.labelling.SetToolTip(_("Labelling of contiguous zones using Scipy.label function\n\nReplacing the current values by the labels"))
|
1434
|
+
self.extract_selection.SetToolTip(_("Extract the current selection"))
|
1343
1435
|
|
1344
1436
|
self.tools.SetSizer(Toolssizer)
|
1345
1437
|
self.tools.Layout()
|
1346
1438
|
Toolssizer.Fit(self.tools)
|
1347
1439
|
|
1348
1440
|
# Selection
|
1441
|
+
# ----------------
|
1349
1442
|
|
1350
1443
|
bSizer15 = wx.BoxSizer(wx.VERTICAL)
|
1351
1444
|
|
@@ -1372,7 +1465,7 @@ class Ops_Array(wx.Frame):
|
|
1372
1465
|
self.LaunchSelection = wx.Button(self.selection, wx.ID_ANY,
|
1373
1466
|
_("Action !"), wx.DefaultPosition,
|
1374
1467
|
wx.DefaultSize, 0)
|
1375
|
-
self.LaunchSelection.SetBackgroundColour((0,128,64,255))
|
1468
|
+
# self.LaunchSelection.SetBackgroundColour((0,128,64,255))
|
1376
1469
|
self.LaunchSelection.SetDefault()
|
1377
1470
|
# self.LaunchSelection.SetForegroundColour((255,255,255,255))
|
1378
1471
|
font = wx.Font(12, wx.FONTFAMILY_DECORATIVE, 0, 90, underline = False,faceName ="")
|
@@ -1413,9 +1506,35 @@ class Ops_Array(wx.Frame):
|
|
1413
1506
|
bSizer16.Add(self.to_clipboard_str, 0, wx.EXPAND)
|
1414
1507
|
bSizer16.Add(self.to_clipboard_script, 0, wx.EXPAND)
|
1415
1508
|
|
1416
|
-
|
1509
|
+
# MultiBlocks
|
1510
|
+
# ----------------
|
1511
|
+
# Add a listbox to define the active blocks
|
1512
|
+
|
1513
|
+
if self.parentarray.nb_blocks>0:
|
1514
|
+
self._list = wx.ListBox(self.selection,
|
1515
|
+
wx.ID_ANY,
|
1516
|
+
wx.DefaultPosition,
|
1517
|
+
wx.DefaultSize,
|
1518
|
+
[_('All')] + [str(i) for i in range(1, self.parentarray.nb_blocks+1)],
|
1519
|
+
style = wx.LB_MULTIPLE | wx.LB_NEEDED_SB)
|
1520
|
+
self._list.SetToolTip(_("Active block"))
|
1521
|
+
bSizer16.Add(self._list, 1, wx.EXPAND)
|
1522
|
+
|
1523
|
+
self._list.Bind(wx.EVT_LISTBOX, self.OnBlockSelect)
|
1524
|
+
|
1525
|
+
# self._open_block = wx.Button(self.selection, wx.ID_ANY, _("Open block"), wx.DefaultPosition,
|
1526
|
+
# wx.DefaultSize, 0)
|
1417
1527
|
|
1528
|
+
# self._open_block.SetToolTip(_("Open the Operation manager for the selected block"))
|
1529
|
+
# self._open_block.Bind(wx.EVT_BUTTON, self.OnOpenBlock)
|
1530
|
+
|
1531
|
+
# bSizer16.Add(self._open_block, 0, wx.EXPAND)
|
1532
|
+
|
1533
|
+
|
1534
|
+
bSizer21.Add(bSizer16, 1, wx.EXPAND, 5)
|
1418
1535
|
|
1536
|
+
# VECTORS Manager
|
1537
|
+
# ----------------
|
1419
1538
|
|
1420
1539
|
bSizer17 = wx.BoxSizer(wx.VERTICAL)
|
1421
1540
|
|
@@ -1594,11 +1713,14 @@ class Ops_Array(wx.Frame):
|
|
1594
1713
|
self.ApplyTools.Bind(wx.EVT_BUTTON, self.OnApplyNullvalue)
|
1595
1714
|
self.nullborder.Bind(wx.EVT_BUTTON, self.OnNullBorder)
|
1596
1715
|
self.filter_zone.Bind(wx.EVT_BUTTON, self.OnFilterZone)
|
1716
|
+
self.labelling.Bind(wx.EVT_BUTTON, self.OnLabelling)
|
1717
|
+
self.extract_selection.Bind(wx.EVT_BUTTON, self.OnExtractSelection)
|
1597
1718
|
|
1598
1719
|
self.SelectOp.Bind(wx.EVT_BUTTON, self.OnApplyOpSelect)
|
1599
1720
|
self.palapply.Bind(wx.EVT_BUTTON, self.Onupdatepal)
|
1600
1721
|
self.palsave.Bind(wx.EVT_BUTTON, self.Onsavepal)
|
1601
1722
|
self.palload.Bind(wx.EVT_BUTTON, self.Onloadpal)
|
1723
|
+
self._default_pal.Bind(wx.EVT_BUTTON, self.Onloaddefaultpal)
|
1602
1724
|
self.palimage.Bind(wx.EVT_BUTTON, self.Onpalimage)
|
1603
1725
|
self.paldistribute.Bind(wx.EVT_BUTTON, self.Onpaldistribute)
|
1604
1726
|
self.palchoosecolor.Bind(wx.EVT_BUTTON, self.OnClickColorPal)
|
@@ -1606,8 +1728,36 @@ class Ops_Array(wx.Frame):
|
|
1606
1728
|
self.histoupdatezoom.Bind(wx.EVT_BUTTON, self.OnClickHistoUpdate)
|
1607
1729
|
self.histoupdateerase.Bind(wx.EVT_BUTTON, self.OnClickHistoUpdate)
|
1608
1730
|
|
1731
|
+
def OnBlockSelect(self, event):
|
1732
|
+
""" Select block """
|
1733
|
+
|
1734
|
+
self.parentarray.active_blocks = self._list.GetSelections()
|
1735
|
+
|
1736
|
+
# def OnOpenBlock(self, event):
|
1737
|
+
# """ Open block """
|
1738
|
+
|
1739
|
+
# sel = self._list.GetSelections()
|
1740
|
+
|
1741
|
+
# if len(sel)==0:
|
1742
|
+
# logging.info('No block selected')
|
1743
|
+
# return
|
1744
|
+
# elif len(sel)>1:
|
1745
|
+
# logging.info('Only one block can be selected')
|
1746
|
+
# return
|
1747
|
+
# elif sel[0]==0:
|
1748
|
+
# logging.info('All blocks selected -- Choose only one specific block')
|
1749
|
+
# return
|
1750
|
+
# else:
|
1751
|
+
# keyblock = getkeyblock(sel[0], addone=False)
|
1752
|
+
|
1753
|
+
# ops = self.parentarray.myblocks[keyblock].myops
|
1754
|
+
|
1755
|
+
# if ops is not None:
|
1756
|
+
# ops.Show()
|
1757
|
+
|
1609
1758
|
def interpolation2D(self, event: wx.MouseEvent):
|
1610
1759
|
""" calling Interpolation 2D """
|
1760
|
+
|
1611
1761
|
self.parentarray.interpolation2D()
|
1612
1762
|
|
1613
1763
|
def Unmaskall(self, event: wx.MouseEvent):
|
@@ -1615,6 +1765,7 @@ class Ops_Array(wx.Frame):
|
|
1615
1765
|
Unmask all values in the current array
|
1616
1766
|
@author Pierre Archambeau
|
1617
1767
|
"""
|
1768
|
+
|
1618
1769
|
self.parentarray.mask_reset()
|
1619
1770
|
self.refresh_array()
|
1620
1771
|
|
@@ -1623,201 +1774,109 @@ class Ops_Array(wx.Frame):
|
|
1623
1774
|
Enlève le masque des éléments sélectionnés
|
1624
1775
|
@author Pierre Archambeau
|
1625
1776
|
"""
|
1626
|
-
curarray: WolfArray
|
1627
|
-
curarray = self.parentarray
|
1628
|
-
|
1629
|
-
if len(curarray.mngselection.myselection) == 0:
|
1630
|
-
return
|
1631
|
-
else:
|
1632
|
-
destxy = curarray.mngselection.myselection
|
1633
|
-
|
1634
|
-
destij = np.asarray([list(curarray.get_ij_from_xy(x, y)) for x, y in destxy])
|
1635
1777
|
|
1636
|
-
|
1778
|
+
self.parentarray.SelectionData.Unmasksel()
|
1637
1779
|
|
1638
|
-
self.refresh_array()
|
1639
1780
|
|
1640
1781
|
def InvertMask(self, event: wx.MouseEvent):
|
1641
1782
|
""" Invert mask """
|
1783
|
+
|
1642
1784
|
self.parentarray.mask_invert()
|
1643
1785
|
self.refresh_array()
|
1644
1786
|
|
1645
1787
|
def interp2Dpolygons(self, event: wx.MouseEvent):
|
1646
1788
|
"""
|
1647
1789
|
Bouton d'interpolation sous tous les polygones d'une zone
|
1648
|
-
cf
|
1790
|
+
cf WolfArray.interp2Dpolygon
|
1649
1791
|
"""
|
1650
|
-
choices = ["nearest", "linear", "cubic"]
|
1651
|
-
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
1652
|
-
ret = dlg.ShowModal()
|
1653
|
-
if ret == wx.ID_CANCEL:
|
1654
|
-
dlg.Destroy()
|
1655
|
-
return
|
1656
|
-
|
1657
|
-
method = dlg.GetStringSelection()
|
1658
|
-
dlg.Destroy()
|
1659
|
-
|
1660
|
-
actzone = self.active_zone
|
1661
1792
|
|
1662
|
-
|
1663
|
-
curvec: vector
|
1664
|
-
self._interp2Dpolygon(curvec, method)
|
1665
|
-
|
1666
|
-
self.refresh_array()
|
1793
|
+
self.parentarray.SelectionData.interp2Dpolygons(self.active_zone)
|
1667
1794
|
|
1668
1795
|
def interp2Dpolygon(self, event: wx.MouseEvent):
|
1669
1796
|
"""
|
1670
1797
|
Bouton d'interpolation sous un polygone
|
1671
|
-
cf
|
1672
|
-
"""
|
1673
|
-
choices = ["nearest", "linear", "cubic"]
|
1674
|
-
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
1675
|
-
ret = dlg.ShowModal()
|
1676
|
-
if ret == wx.ID_CANCEL:
|
1677
|
-
dlg.Destroy()
|
1678
|
-
return
|
1679
|
-
|
1680
|
-
method = dlg.GetStringSelection()
|
1681
|
-
dlg.Destroy()
|
1682
|
-
|
1683
|
-
self._interp2Dpolygon(self.active_vector, method)
|
1684
|
-
|
1685
|
-
self.refresh_array()
|
1686
|
-
|
1687
|
-
def _interp2Dpolygon(self, vect: vector, method):
|
1688
|
-
"""
|
1689
|
-
Interpolation sous un polygone
|
1690
|
-
|
1691
|
-
L'interpolation a lieu :
|
1692
|
-
- uniquement dans les mailles sélectionnées si elles existent
|
1693
|
-
- dans les mailles contenues dans le polygone sinon
|
1694
|
-
|
1695
|
-
On utilise ensuite "griddata" pour interpoler les altitudes des mailles
|
1696
|
-
depuis les vertices 3D du polygone
|
1798
|
+
cf WolfArray.interp2Dpolygon
|
1697
1799
|
"""
|
1698
|
-
curarray: WolfArray
|
1699
|
-
curarray = self.parentarray
|
1700
|
-
|
1701
|
-
if len(curarray.mngselection.myselection) == 0:
|
1702
|
-
destxy = curarray.get_xy_inside_polygon(vect)
|
1703
|
-
else:
|
1704
|
-
destxy = curarray.mngselection.myselection
|
1705
|
-
|
1706
|
-
if len(destxy)==0:
|
1707
|
-
return
|
1708
|
-
|
1709
|
-
destij = np.asarray([list(curarray.get_ij_from_xy(x, y)) for x, y in destxy])
|
1710
|
-
|
1711
|
-
xyz = vect.asnparray3d()
|
1712
|
-
|
1713
|
-
newvalues = griddata(xyz[:, :2], xyz[:, 2], destxy, method=method, fill_value=-99999.)
|
1714
1800
|
|
1715
|
-
|
1716
|
-
curarray.array.data[destij[locmask][:, 0], destij[locmask][:, 1]] = newvalues[locmask]
|
1801
|
+
self.parentarray.SelectionData.interp2Dpolygon(self.active_vector)
|
1717
1802
|
|
1718
1803
|
def interp2Dpolylines(self, event: wx.MouseEvent):
|
1719
1804
|
"""
|
1720
1805
|
Bouton d'interpolation sous toutes les polylignes de la zone
|
1721
|
-
cf
|
1806
|
+
cf parent.interp2Dpolyline
|
1722
1807
|
"""
|
1723
|
-
actzone = self.active_zone
|
1724
1808
|
|
1725
|
-
|
1726
|
-
curvec: vector
|
1727
|
-
self._interp2Dpolyline(curvec)
|
1809
|
+
self.parentarray.SelectionData.interp2Dpolylines(self.active_zone)
|
1728
1810
|
|
1729
|
-
self.refresh_array()
|
1730
1811
|
|
1731
1812
|
def interp2Dpolyline(self, event: wx.MouseEvent):
|
1732
1813
|
"""
|
1733
1814
|
Bouton d'interpolation sous la polyligne active
|
1734
|
-
cf
|
1735
|
-
"""
|
1736
|
-
self._interp2Dpolyline(self.active_vector)
|
1737
|
-
|
1738
|
-
self.refresh_array()
|
1739
|
-
|
1740
|
-
def _interp2Dpolyline(self, vect: vector, usemask=True):
|
1741
|
-
"""
|
1742
|
-
Interpolation sous une polyligne
|
1743
|
-
|
1744
|
-
L'interpolation a lieu :
|
1745
|
-
- uniquement dans les mailles sélectionnées si elles existent
|
1746
|
-
- dans les mailles sous la polyligne sinon
|
1747
|
-
|
1748
|
-
On utilise ensuite "interpolate" de shapely pour interpoler les altitudes des mailles
|
1749
|
-
depuis les vertices 3D de la polyligne
|
1815
|
+
cf parent.interp2Dpolyline
|
1750
1816
|
"""
|
1751
|
-
curarray: WolfArray
|
1752
|
-
curarray = self.parentarray
|
1753
|
-
|
1754
|
-
vecls = vect.asshapely_ls()
|
1755
|
-
if len(curarray.mngselection.myselection) == 0:
|
1756
|
-
allij = curarray.get_ij_under_polyline(vect, usemask)
|
1757
|
-
allxy = [curarray.get_xy_from_ij(cur[0], cur[1]) for cur in allij]
|
1758
|
-
else:
|
1759
|
-
allxy = curarray.mngselection.myselection
|
1760
|
-
allij = np.asarray([curarray.get_ij_from_xy(x,y) for x,y in allxy])
|
1761
1817
|
|
1762
|
-
|
1763
|
-
curarray.array.data[allij[:, 0], allij[:, 1]] = newz
|
1818
|
+
self.parentarray.SelectionData.interp2Dpolyline(self.active_vector)
|
1764
1819
|
|
1765
1820
|
def volumesurface(self, event):
|
1766
1821
|
"""
|
1767
1822
|
Click on evaluation of stage-storage-surface relation
|
1768
1823
|
"""
|
1769
|
-
self._volumesurface()
|
1770
|
-
|
1771
|
-
def _volumesurface(self, show=True):
|
1772
|
-
"""
|
1773
|
-
Evaluation of stage-storage-surface relation
|
1774
|
-
"""
|
1775
|
-
if self.mapviewer is not None:
|
1776
|
-
if self.mapviewer.linked:
|
1777
|
-
array1 = self.mapviewer.linkedList[0].active_array
|
1778
|
-
array2 = self.mapviewer.linkedList[1].active_array
|
1779
|
-
|
1780
|
-
# transfert des mailles sélectionnées dans l'autre matrice
|
1781
|
-
if array1 is self.parentarray:
|
1782
|
-
array2.mngselection.myselection = array1.mngselection.myselection.copy()
|
1783
|
-
if array2 is self.parentarray:
|
1784
|
-
array1.mngselection.myselection = array2.mngselection.myselection.copy()
|
1785
|
-
|
1786
|
-
if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1787
|
-
myarray = array1
|
1788
|
-
axs = myarray.volume_estimation()
|
1789
|
-
myarray = array2
|
1790
|
-
axs = myarray.volume_estimation(axs)
|
1791
|
-
else:
|
1792
|
-
myarray = array1.mngselection.get_newarray()
|
1793
|
-
axs = myarray.volume_estimation()
|
1794
|
-
myarray = array2.mngselection.get_newarray()
|
1795
|
-
axs = myarray.volume_estimation(axs)
|
1796
|
-
else:
|
1797
|
-
if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1798
|
-
myarray = self.parentarray
|
1799
|
-
else:
|
1800
|
-
myarray = self.parentarray.mngselection.get_newarray()
|
1801
|
-
myarray.volume_estimation()
|
1802
|
-
else:
|
1803
|
-
if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1804
|
-
myarray = self.parentarray
|
1805
|
-
else:
|
1806
|
-
myarray = self.parentarray.mngselection.get_newarray()
|
1807
|
-
myarray.volume_estimation()
|
1808
1824
|
|
1809
|
-
|
1810
|
-
|
1825
|
+
self.parentarray.SelectionData.volumesurface()
|
1826
|
+
|
1827
|
+
# def _volumesurface(self, show=True):
|
1828
|
+
# """
|
1829
|
+
# Evaluation of stage-storage-surface relation
|
1830
|
+
# """
|
1831
|
+
|
1832
|
+
# if self.mapviewer is not None:
|
1833
|
+
# if self.mapviewer.linked:
|
1834
|
+
# array1 = self.mapviewer.linkedList[0].active_array
|
1835
|
+
# array2 = self.mapviewer.linkedList[1].active_array
|
1836
|
+
|
1837
|
+
# # transfert des mailles sélectionnées dans l'autre matrice
|
1838
|
+
# if array1 is self.parentarray:
|
1839
|
+
# array2.mngselection.myselection = array1.mngselection.myselection.copy()
|
1840
|
+
# if array2 is self.parentarray:
|
1841
|
+
# array1.mngselection.myselection = array2.mngselection.myselection.copy()
|
1842
|
+
|
1843
|
+
# if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1844
|
+
# myarray = array1
|
1845
|
+
# axs = myarray.volume_estimation()
|
1846
|
+
# myarray = array2
|
1847
|
+
# axs = myarray.volume_estimation(axs)
|
1848
|
+
# else:
|
1849
|
+
# myarray = array1.mngselection.get_newarray()
|
1850
|
+
# axs = myarray.volume_estimation()
|
1851
|
+
# myarray = array2.mngselection.get_newarray()
|
1852
|
+
# axs = myarray.volume_estimation(axs)
|
1853
|
+
# else:
|
1854
|
+
# if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1855
|
+
# myarray = self.parentarray
|
1856
|
+
# else:
|
1857
|
+
# myarray = self.parentarray.mngselection.get_newarray()
|
1858
|
+
# myarray.volume_estimation()
|
1859
|
+
# else:
|
1860
|
+
# if len(self.parentarray.mngselection.myselection) == 0 or self.parentarray.mngselection.myselection == 'all':
|
1861
|
+
# myarray = self.parentarray
|
1862
|
+
# else:
|
1863
|
+
# myarray = self.parentarray.mngselection.get_newarray()
|
1864
|
+
# myarray.volume_estimation()
|
1865
|
+
|
1866
|
+
# if show:
|
1867
|
+
# plt.show()
|
1811
1868
|
|
1812
1869
|
def OnAllSelect(self, event):
|
1813
1870
|
"""
|
1814
1871
|
Select all --> just put "all" in "myselection"
|
1815
1872
|
"""
|
1816
|
-
|
1873
|
+
|
1874
|
+
self.parentarray.SelectionData.select_all()
|
1817
1875
|
self.parentarray.myops.nbselect.SetLabelText('All')
|
1818
1876
|
|
1819
1877
|
def OnMoveSelect(self, event):
|
1820
1878
|
"""Transfert de la sélection courante dans un dictionnaire"""
|
1879
|
+
|
1821
1880
|
dlg = wx.TextEntryDialog(self, 'Choose id', 'id?')
|
1822
1881
|
ret = dlg.ShowModal()
|
1823
1882
|
idtxt = dlg.GetValue()
|
@@ -1826,13 +1885,15 @@ class Ops_Array(wx.Frame):
|
|
1826
1885
|
ret = dlg.ShowModal()
|
1827
1886
|
color = dlg.GetColourData()
|
1828
1887
|
|
1829
|
-
self.parentarray.
|
1888
|
+
self.parentarray.SelectionData.move_selectionto(idtxt, color.GetColour())
|
1830
1889
|
|
1831
1890
|
def reset_selection(self):
|
1832
1891
|
"""
|
1833
1892
|
Reset of current selection
|
1834
1893
|
"""
|
1835
|
-
|
1894
|
+
|
1895
|
+
self.parentarray.SelectionData.reset()
|
1896
|
+
|
1836
1897
|
self.nbselect.SetLabelText('0')
|
1837
1898
|
self.minx.SetLabelText('0')
|
1838
1899
|
self.miny.SetLabelText('0')
|
@@ -1843,13 +1904,15 @@ class Ops_Array(wx.Frame):
|
|
1843
1904
|
"""
|
1844
1905
|
Reset of current selection and stored ones
|
1845
1906
|
"""
|
1907
|
+
|
1846
1908
|
self.reset_selection()
|
1847
|
-
self.parentarray.
|
1909
|
+
self.parentarray.SelectionData.reset_all()
|
1848
1910
|
|
1849
1911
|
def OnResetSelect(self, event):
|
1850
1912
|
"""
|
1851
1913
|
Click on Reset of current selection
|
1852
1914
|
"""
|
1915
|
+
|
1853
1916
|
self.reset_selection()
|
1854
1917
|
self.refresh_array()
|
1855
1918
|
|
@@ -1857,6 +1920,7 @@ class Ops_Array(wx.Frame):
|
|
1857
1920
|
"""
|
1858
1921
|
Click on reset all
|
1859
1922
|
"""
|
1923
|
+
|
1860
1924
|
self.reset_all_selection()
|
1861
1925
|
self.refresh_array()
|
1862
1926
|
|
@@ -1874,7 +1938,7 @@ class Ops_Array(wx.Frame):
|
|
1874
1938
|
|
1875
1939
|
selectobj = self.parentarray.mngselection
|
1876
1940
|
|
1877
|
-
if
|
1941
|
+
if selectobj.nb > 0:
|
1878
1942
|
choices = [_("Current selection")]
|
1879
1943
|
for cur in selectobj.selections.items():
|
1880
1944
|
choices.append(cur[0])
|
@@ -1934,10 +1998,11 @@ class Ops_Array(wx.Frame):
|
|
1934
1998
|
# condition value
|
1935
1999
|
curcondvalue = float(self.condvalue.GetValue())
|
1936
2000
|
|
1937
|
-
self.parentarray.
|
2001
|
+
self.parentarray.SelectionData.condition_select(curcond, curcondvalue)
|
1938
2002
|
|
1939
2003
|
def OnApplyNullvalue(self, event:wx.MouseEvent):
|
1940
2004
|
""" Apply null value to the array """
|
2005
|
+
|
1941
2006
|
newnull = self.txt_nullval.Value
|
1942
2007
|
if newnull.lower() == 'nan':
|
1943
2008
|
newnull = np.nan
|
@@ -1945,12 +2010,14 @@ class Ops_Array(wx.Frame):
|
|
1945
2010
|
newnull = float(newnull)
|
1946
2011
|
|
1947
2012
|
if self.parentarray.nullvalue!= newnull:
|
2013
|
+
|
1948
2014
|
self.parentarray.nullvalue = newnull
|
1949
2015
|
self.parentarray.mask_data(newnull)
|
1950
2016
|
self.refresh_array()
|
1951
2017
|
|
1952
2018
|
def refresh_array(self):
|
1953
2019
|
""" Force refresh of the parent array """
|
2020
|
+
|
1954
2021
|
if self.parentarray is not None:
|
1955
2022
|
self.parentarray.reset_plot()
|
1956
2023
|
|
@@ -1971,8 +2038,19 @@ class Ops_Array(wx.Frame):
|
|
1971
2038
|
def OnFilterZone(self, event:wx.MouseEvent):
|
1972
2039
|
""" Filter the array based on contiguous zones """
|
1973
2040
|
|
2041
|
+
pass
|
1974
2042
|
self.parentarray.filter_zone()
|
1975
2043
|
|
2044
|
+
def OnLabelling(self, event:wx.MouseEvent):
|
2045
|
+
""" Labelling of contiguous zones """
|
2046
|
+
|
2047
|
+
self.parentarray.labelling()
|
2048
|
+
|
2049
|
+
def OnExtractSelection(self, event:wx.MouseEvent):
|
2050
|
+
""" Extract the current selection """
|
2051
|
+
|
2052
|
+
self.parentarray.extract_selection()
|
2053
|
+
|
1976
2054
|
def OnApplyOpMath(self, event:wx.MouseEvent):
|
1977
2055
|
""" Apply math operator to the array """
|
1978
2056
|
|
@@ -1995,7 +2073,7 @@ class Ops_Array(wx.Frame):
|
|
1995
2073
|
else:
|
1996
2074
|
curcondvalue = float(curcondvalue)
|
1997
2075
|
|
1998
|
-
self.parentarray.
|
2076
|
+
self.parentarray.SelectionData.treat_select(curop, curcond, curopvalue, curcondvalue)
|
1999
2077
|
|
2000
2078
|
def Onmask(self, event:wx.MouseEvent):
|
2001
2079
|
""" Mask nodes based on condition """
|
@@ -2006,7 +2084,7 @@ class Ops_Array(wx.Frame):
|
|
2006
2084
|
curopvalue = float(self.opvalue.GetValue())
|
2007
2085
|
curcondvalue = float(self.condvalue.GetValue())
|
2008
2086
|
|
2009
|
-
self.parentarray.
|
2087
|
+
self.parentarray.SelectionData.mask_condition(curop, curcond, curopvalue, curcondvalue)
|
2010
2088
|
self.refresh_array()
|
2011
2089
|
|
2012
2090
|
def OnManageVectors(self, event:wx.MouseEvent):
|
@@ -2122,7 +2200,7 @@ class Ops_Array(wx.Frame):
|
|
2122
2200
|
""" Select nodes inside a vector or set action to add vertices to a vector by clicks"""
|
2123
2201
|
|
2124
2202
|
if vect.nbvertices > 2:
|
2125
|
-
self.parentarray.
|
2203
|
+
self.parentarray.SelectionData.select_insidepoly(vect)
|
2126
2204
|
|
2127
2205
|
elif self.mapviewer is not None:
|
2128
2206
|
if vect.nbvertices < 3:
|
@@ -2160,7 +2238,7 @@ class Ops_Array(wx.Frame):
|
|
2160
2238
|
""" Select nodes along a vector or set action to add vertices to a vector by clicks """
|
2161
2239
|
|
2162
2240
|
if vect.nbvertices > 1:
|
2163
|
-
self.parentarray.
|
2241
|
+
self.parentarray.SelectionData.select_underpoly(vect)
|
2164
2242
|
|
2165
2243
|
elif self.mapviewer is not None:
|
2166
2244
|
if vect.nbvertices < 2:
|
@@ -2239,6 +2317,7 @@ class Ops_Array(wx.Frame):
|
|
2239
2317
|
|
2240
2318
|
def onclose(self, event:wx.MouseEvent):
|
2241
2319
|
""" Hide the window """
|
2320
|
+
|
2242
2321
|
self.Hide()
|
2243
2322
|
|
2244
2323
|
def onshow(self, event:wx.MouseEvent):
|
@@ -2291,6 +2370,7 @@ class Ops_Array(wx.Frame):
|
|
2291
2370
|
|
2292
2371
|
def Onloadpal(self, event:wx.MouseEvent):
|
2293
2372
|
""" Load palette from file """
|
2373
|
+
|
2294
2374
|
myarray: WolfArray
|
2295
2375
|
myarray = self.parentarray
|
2296
2376
|
myarray.mypal.readfile()
|
@@ -2300,6 +2380,36 @@ class Ops_Array(wx.Frame):
|
|
2300
2380
|
|
2301
2381
|
self.refresh_array()
|
2302
2382
|
|
2383
|
+
def Onloaddefaultpal(self, event:wx.MouseEvent):
|
2384
|
+
""" Load default palette """
|
2385
|
+
|
2386
|
+
import glob
|
2387
|
+
|
2388
|
+
# list of all .pal file in model directory
|
2389
|
+
|
2390
|
+
dirpal = os.path.join(os.path.dirname(__file__), 'models')
|
2391
|
+
|
2392
|
+
listpal = glob.glob(dirpal + '/*.pal')
|
2393
|
+
|
2394
|
+
if len(listpal) == 0:
|
2395
|
+
logging.info('No default palette found')
|
2396
|
+
return
|
2397
|
+
|
2398
|
+
listpal = [os.path.basename(i) for i in listpal]
|
2399
|
+
|
2400
|
+
dlg = wx.SingleChoiceDialog(None, 'Choose the default palette', 'Default palette', listpal)
|
2401
|
+
ret = dlg.ShowModal()
|
2402
|
+
|
2403
|
+
if ret == wx.ID_CANCEL:
|
2404
|
+
dlg.Destroy()
|
2405
|
+
|
2406
|
+
self.parentarray.mypal.readfile(dirpal + '/' + dlg.GetStringSelection())
|
2407
|
+
|
2408
|
+
self.parentarray.mypal.automatic = False
|
2409
|
+
self.palauto.SetValue(0)
|
2410
|
+
|
2411
|
+
self.refresh_array()
|
2412
|
+
|
2303
2413
|
def Onpalimage(self, event:wx.MouseEvent):
|
2304
2414
|
""" Create image from palette """
|
2305
2415
|
myarray: WolfArray
|
@@ -2432,19 +2542,17 @@ class SelectionData():
|
|
2432
2542
|
|
2433
2543
|
The selected nodes are stored using their "world" spatial coordinates so that they can be easily transferred to other objects.
|
2434
2544
|
"""
|
2545
|
+
|
2435
2546
|
myselection:list[tuple[float, float]]
|
2436
2547
|
selections: dict[str:dict['select':list[tuple[float, float]], 'idgllist':int, 'color':list[float]]]
|
2437
2548
|
|
2438
2549
|
def __init__(self, parent:"WolfArray") -> None:
|
2550
|
+
|
2439
2551
|
self.parent: WolfArray
|
2440
2552
|
self.parent = parent
|
2441
2553
|
|
2442
2554
|
self.wx_exists = wx.GetApp() is not None
|
2443
2555
|
|
2444
|
-
#copy of the resolution
|
2445
|
-
self.dx = parent.dx
|
2446
|
-
self.dy = parent.dy
|
2447
|
-
|
2448
2556
|
self.myselection = []
|
2449
2557
|
self.selections = {}
|
2450
2558
|
|
@@ -2452,6 +2560,59 @@ class SelectionData():
|
|
2452
2560
|
self.hideselection = False
|
2453
2561
|
self.numlist_select = 0 # OpenGL list index
|
2454
2562
|
|
2563
|
+
@property
|
2564
|
+
def dx(self) -> float:
|
2565
|
+
""" Resolution in x """
|
2566
|
+
|
2567
|
+
if self.parent is None:
|
2568
|
+
return 0.
|
2569
|
+
else:
|
2570
|
+
return self.parent.dx
|
2571
|
+
|
2572
|
+
@property
|
2573
|
+
def dy(self) -> float:
|
2574
|
+
""" Resolution in y """
|
2575
|
+
|
2576
|
+
if self.parent is None:
|
2577
|
+
return 0.
|
2578
|
+
else:
|
2579
|
+
return self.parent.dy
|
2580
|
+
|
2581
|
+
@property
|
2582
|
+
def nb(self) -> int:
|
2583
|
+
""" Number of selected nodes """
|
2584
|
+
|
2585
|
+
return len(self.myselection)
|
2586
|
+
|
2587
|
+
def Unmasksel(self, resetplot:bool=True):
|
2588
|
+
""" Unmask selection """
|
2589
|
+
|
2590
|
+
curarray: WolfArray
|
2591
|
+
curarray = self.parent
|
2592
|
+
|
2593
|
+
if self.nb == 0:
|
2594
|
+
return
|
2595
|
+
else:
|
2596
|
+
destxy = self.myselection
|
2597
|
+
|
2598
|
+
destij = np.asarray([list(curarray.get_ij_from_xy(x, y)) for x, y in destxy])
|
2599
|
+
|
2600
|
+
curarray.array.mask[destij[:, 0], destij[:, 1]] = False
|
2601
|
+
|
2602
|
+
if resetplot:
|
2603
|
+
curarray.reset_plot()
|
2604
|
+
|
2605
|
+
def reset(self):
|
2606
|
+
""" Reset the selection """
|
2607
|
+
|
2608
|
+
self.myselection = []
|
2609
|
+
|
2610
|
+
def reset_all(self):
|
2611
|
+
""" Reset the selection """
|
2612
|
+
|
2613
|
+
self.myselection = []
|
2614
|
+
self.selections = {}
|
2615
|
+
|
2455
2616
|
def get_string(self, which:str = None) -> str:
|
2456
2617
|
""" Get string of the current selection or of a stored one """
|
2457
2618
|
|
@@ -2536,7 +2697,7 @@ class SelectionData():
|
|
2536
2697
|
logging.warning(_('Cannot open the clipboard'))
|
2537
2698
|
|
2538
2699
|
|
2539
|
-
def move_selectionto(self, idx:str, color:list[float]):
|
2700
|
+
def move_selectionto(self, idx:str, color:list[float], resetplot:bool=True):
|
2540
2701
|
"""
|
2541
2702
|
Transfer current selection to dictionary
|
2542
2703
|
|
@@ -2556,7 +2717,10 @@ class SelectionData():
|
|
2556
2717
|
curdict['color'] = color
|
2557
2718
|
|
2558
2719
|
self.myselection = [] # reset current selection
|
2559
|
-
self.
|
2720
|
+
self.update_nb_nodes_selection()
|
2721
|
+
|
2722
|
+
if resetplot:
|
2723
|
+
self.parent.reset_plot()
|
2560
2724
|
|
2561
2725
|
def plot_selection(self):
|
2562
2726
|
""" Plot current selection and stored selections """
|
@@ -2594,6 +2758,10 @@ class SelectionData():
|
|
2594
2758
|
|
2595
2759
|
#FIXME : Is it a good idea to use SHADER rather than list ?
|
2596
2760
|
if self.update_plot_selection:
|
2761
|
+
|
2762
|
+
dx = self.dx
|
2763
|
+
dy = self.dy
|
2764
|
+
|
2597
2765
|
if loclist != 0:
|
2598
2766
|
glDeleteLists(loclist, 1)
|
2599
2767
|
|
@@ -2603,10 +2771,10 @@ class SelectionData():
|
|
2603
2771
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
|
2604
2772
|
glBegin(GL_QUADS)
|
2605
2773
|
for cursel in curlist:
|
2606
|
-
x1 = cursel[0] -
|
2607
|
-
x2 = cursel[0] +
|
2608
|
-
y1 = cursel[1] -
|
2609
|
-
y2 = cursel[1] +
|
2774
|
+
x1 = cursel[0] - dx / 2.
|
2775
|
+
x2 = cursel[0] + dx / 2.
|
2776
|
+
y1 = cursel[1] - dy / 2.
|
2777
|
+
y2 = cursel[1] + dy / 2.
|
2610
2778
|
glColor3f(color[0], color[1], color[2])
|
2611
2779
|
glVertex2f(x1, y1)
|
2612
2780
|
glVertex2f(x2, y1)
|
@@ -2617,10 +2785,10 @@ class SelectionData():
|
|
2617
2785
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
|
2618
2786
|
for cursel in curlist:
|
2619
2787
|
glBegin(GL_LINE_STRIP)
|
2620
|
-
x1 = cursel[0] -
|
2621
|
-
x2 = cursel[0] +
|
2622
|
-
y1 = cursel[1] -
|
2623
|
-
y2 = cursel[1] +
|
2788
|
+
x1 = cursel[0] - dx / 2.
|
2789
|
+
x2 = cursel[0] + dx / 2.
|
2790
|
+
y1 = cursel[1] - dy / 2.
|
2791
|
+
y2 = cursel[1] + dy / 2.
|
2624
2792
|
glColor3f(0., 1., 0.)
|
2625
2793
|
glVertex2f(x1, y1)
|
2626
2794
|
glVertex2f(x2, y1)
|
@@ -2653,7 +2821,10 @@ class SelectionData():
|
|
2653
2821
|
|
2654
2822
|
if self.parent.check_bounds_ij(i, j):
|
2655
2823
|
# if i>=0 and j>=0 and i<self.parent.nbx and j<self.parent.nby:
|
2656
|
-
self.
|
2824
|
+
self._add_node_to_selectionij(i, j, verif)
|
2825
|
+
return 0 # useful for MB
|
2826
|
+
else:
|
2827
|
+
return -1 # useful for MB
|
2657
2828
|
|
2658
2829
|
def add_nodes_to_selection(self, xy:list[float], verif:bool=True):
|
2659
2830
|
"""
|
@@ -2666,9 +2837,9 @@ class SelectionData():
|
|
2666
2837
|
# on repasse par les i,j car les coordonnées transférées peuvent venir d'un click souris
|
2667
2838
|
# le but est de ne conserver que les coordonnées des CG de mailles
|
2668
2839
|
ij = [self.parent.get_ij_from_xy(x, y) for x, y in xy]
|
2669
|
-
self.
|
2840
|
+
self._add_nodes_to_selectionij(ij, verif)
|
2670
2841
|
|
2671
|
-
def
|
2842
|
+
def _add_node_to_selectionij(self, i:int, j:int, verif=True):
|
2672
2843
|
"""
|
2673
2844
|
Add one ij coordinate to the selection
|
2674
2845
|
|
@@ -2676,6 +2847,7 @@ class SelectionData():
|
|
2676
2847
|
:param j: j coordinate
|
2677
2848
|
:param verif: if True, the coordinates are checked to avoid duplicates
|
2678
2849
|
"""
|
2850
|
+
|
2679
2851
|
x1, y1 = self.parent.get_xy_from_ij(i, j)
|
2680
2852
|
|
2681
2853
|
if isinstance(self.myselection, str):
|
@@ -2688,12 +2860,16 @@ class SelectionData():
|
|
2688
2860
|
ret = -1
|
2689
2861
|
if ret >= 0:
|
2690
2862
|
self.myselection.pop(ret)
|
2863
|
+
|
2864
|
+
return 0
|
2691
2865
|
else:
|
2692
2866
|
self.myselection.append((x1, y1))
|
2867
|
+
return 0
|
2693
2868
|
else:
|
2694
2869
|
self.myselection.append((x1, y1))
|
2870
|
+
return 0
|
2695
2871
|
|
2696
|
-
def
|
2872
|
+
def _add_nodes_to_selectionij(self, ij:list[tuple[float, float]], verif:bool=True):
|
2697
2873
|
"""
|
2698
2874
|
Add multiple ij coordinates to the selection
|
2699
2875
|
|
@@ -2742,7 +2918,7 @@ class SelectionData():
|
|
2742
2918
|
nbini = len(self.myselection)
|
2743
2919
|
|
2744
2920
|
myvect.find_minmax()
|
2745
|
-
mypoints,
|
2921
|
+
mypoints, _tmpij = self.parent.get_xy_infootprint_vect(myvect)
|
2746
2922
|
path = mpltPath.Path(myvect.asnparray())
|
2747
2923
|
inside = path.contains_points(mypoints)
|
2748
2924
|
|
@@ -2759,7 +2935,7 @@ class SelectionData():
|
|
2759
2935
|
self.condition_select('Mask',0)
|
2760
2936
|
|
2761
2937
|
self.hideselection=False
|
2762
|
-
self.
|
2938
|
+
self.update_nb_nodes_selection()
|
2763
2939
|
|
2764
2940
|
def select_underpoly(self, myvect: vector):
|
2765
2941
|
""" Select nodes along a polyline """
|
@@ -2769,16 +2945,17 @@ class SelectionData():
|
|
2769
2945
|
myvect.find_minmax()
|
2770
2946
|
mypoints = self.parent.get_ij_under_polyline(myvect)
|
2771
2947
|
|
2772
|
-
self.
|
2948
|
+
self._add_nodes_to_selectionij(mypoints, verif=nbini != 0)
|
2773
2949
|
|
2774
2950
|
if self.parent.myops is not None:
|
2775
2951
|
if self.parent.myops.selectrestricttomask.IsChecked():
|
2776
2952
|
self.condition_select('Mask',0)
|
2777
2953
|
|
2778
|
-
self.
|
2954
|
+
self.update_nb_nodes_selection()
|
2779
2955
|
|
2780
|
-
def
|
2956
|
+
def update_nb_nodes_selection(self):
|
2781
2957
|
""" Update the number of selected nodes """
|
2958
|
+
|
2782
2959
|
if self.myselection=='all':
|
2783
2960
|
nb = self.parent.nbnotnull
|
2784
2961
|
else:
|
@@ -2800,13 +2977,31 @@ class SelectionData():
|
|
2800
2977
|
else:
|
2801
2978
|
self.update_plot_selection = True
|
2802
2979
|
|
2980
|
+
if nb>0:
|
2981
|
+
if self.myselection=='all':
|
2982
|
+
[xmin, xmax], [ymin, ymax] = self.parent.get_bounds()
|
2983
|
+
else:
|
2984
|
+
xmin = np.min(np.asarray(self.myselection)[:, 0])
|
2985
|
+
ymin = np.min(np.asarray(self.myselection)[:, 1])
|
2986
|
+
xmax = np.max(np.asarray(self.myselection)[:, 0])
|
2987
|
+
ymax = np.max(np.asarray(self.myselection)[:, 1])
|
2988
|
+
else:
|
2989
|
+
xmin = -99999.
|
2990
|
+
ymin = -99999.
|
2991
|
+
xmax = -99999.
|
2992
|
+
ymax = -99999.
|
2993
|
+
|
2803
2994
|
if self.parent.myops is not None:
|
2995
|
+
|
2804
2996
|
self.parent.myops.nbselect.SetLabelText(str(nb))
|
2805
2997
|
if nb>0:
|
2806
|
-
|
2807
|
-
self.parent.myops.
|
2808
|
-
self.parent.myops.
|
2809
|
-
self.parent.myops.
|
2998
|
+
|
2999
|
+
self.parent.myops.minx.SetLabelText('{:.3f}'.format(xmin))
|
3000
|
+
self.parent.myops.miny.SetLabelText('{:.3f}'.format(ymin))
|
3001
|
+
self.parent.myops.maxx.SetLabelText('{:.3f}'.format(xmax))
|
3002
|
+
self.parent.myops.maxy.SetLabelText('{:.3f}'.format(ymax))
|
3003
|
+
|
3004
|
+
return nb, xmin, xmax, ymin, ymax
|
2810
3005
|
|
2811
3006
|
def condition_select(self, cond, condval, condval2=0, usemask=False):
|
2812
3007
|
array = self.parent.array
|
@@ -2867,7 +3062,7 @@ class SelectionData():
|
|
2867
3062
|
# interval without equality
|
2868
3063
|
ij = np.argwhere(((array<condval) | (array>condval2)) & mask)
|
2869
3064
|
|
2870
|
-
self.
|
3065
|
+
self._add_nodes_to_selectionij(ij, nbini != 0)
|
2871
3066
|
except:
|
2872
3067
|
logging.error(_('Error in condition_select -- nbini == 0 ! -- Please report this bug, specifying the context'))
|
2873
3068
|
return
|
@@ -2904,7 +3099,7 @@ class SelectionData():
|
|
2904
3099
|
ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]<condval) | (array[ijall[:, 0], ijall[:, 1]]>condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
|
2905
3100
|
|
2906
3101
|
ij = ij.flatten()
|
2907
|
-
self.
|
3102
|
+
self._add_nodes_to_selectionij(ijall[ij], nbini != 0)
|
2908
3103
|
except:
|
2909
3104
|
logging.error(_('Error in condition_select ! -- Please report this bug, specifying the context'))
|
2910
3105
|
return
|
@@ -2945,7 +3140,7 @@ class SelectionData():
|
|
2945
3140
|
# Mask
|
2946
3141
|
ij = np.argwhere(np.logical_not(array.mask))
|
2947
3142
|
|
2948
|
-
self.
|
3143
|
+
self._add_nodes_to_selectionij(ij, nbini != 0)
|
2949
3144
|
except:
|
2950
3145
|
logging.error(_('Error in condition_select -- nbini == 0 ! -- Please report this bug, specifying the context'))
|
2951
3146
|
return
|
@@ -2989,12 +3184,12 @@ class SelectionData():
|
|
2989
3184
|
ij = np.argwhere(np.logical_not(array.mask[ijall[:, 0], ijall[:, 1]]))
|
2990
3185
|
|
2991
3186
|
ij = ij.flatten()
|
2992
|
-
self.
|
3187
|
+
self._add_nodes_to_selectionij(ijall[ij], nbini != 0)
|
2993
3188
|
except:
|
2994
3189
|
logging.error(_('Error in condition_select ! -- Please report this bug, specifying the context'))
|
2995
3190
|
return
|
2996
3191
|
|
2997
|
-
self.
|
3192
|
+
self.update_nb_nodes_selection()
|
2998
3193
|
|
2999
3194
|
def treat_select(self, op, cond, opval, condval):
|
3000
3195
|
# operationChoices = [ u"+", u"-", u"*", u"/", u"replace'" ]
|
@@ -3289,34 +3484,48 @@ class SelectionData():
|
|
3289
3484
|
|
3290
3485
|
return z
|
3291
3486
|
|
3292
|
-
def
|
3293
|
-
|
3487
|
+
def _get_header(self):
|
3488
|
+
""" Header corresponding to the selection """
|
3294
3489
|
|
3295
3490
|
array = self.parent
|
3296
3491
|
sel = np.asarray(self.myselection)
|
3297
3492
|
|
3298
3493
|
myhead = header_wolf()
|
3299
3494
|
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
|
3495
|
+
if self.dx == 0. or self.dy == 0.:
|
3496
|
+
logging.error(_('dx or dy is null in get_header - Abort !'))
|
3497
|
+
return None
|
3498
|
+
|
3499
|
+
myhead.dx = self.dx
|
3500
|
+
myhead.dy = self.dy
|
3501
|
+
myhead.translx = 0.
|
3502
|
+
myhead.transly = 0.
|
3304
3503
|
|
3305
|
-
myhead.origx = np.amin(sel[:, 0]) -
|
3306
|
-
myhead.origy = np.amin(sel[:, 1]) -
|
3504
|
+
myhead.origx = np.amin(sel[:, 0]) - self.dx / 2.
|
3505
|
+
myhead.origy = np.amin(sel[:, 1]) - self.dy / 2.
|
3307
3506
|
|
3308
|
-
ex = np.amax(sel[:, 0]) +
|
3309
|
-
ey = np.amax(sel[:, 1]) +
|
3507
|
+
ex = np.amax(sel[:, 0]) + self.dx / 2.
|
3508
|
+
ey = np.amax(sel[:, 1]) + self.dy / 2.
|
3310
3509
|
|
3311
|
-
myhead.nbx = int((ex - myhead.origx) /
|
3312
|
-
myhead.nby = int((ey - myhead.origy) /
|
3510
|
+
myhead.nbx = int((ex - myhead.origx) / self.dx)
|
3511
|
+
myhead.nby = int((ey - myhead.origy) / self.dy)
|
3313
3512
|
|
3314
3513
|
return myhead
|
3315
3514
|
|
3316
3515
|
def get_newarray(self):
|
3516
|
+
""" Create a new array from the selection """
|
3517
|
+
|
3518
|
+
if self.nb == 0:
|
3519
|
+
return None
|
3317
3520
|
|
3318
3521
|
newarray = WolfArray()
|
3319
|
-
|
3522
|
+
|
3523
|
+
lochead = self._get_header()
|
3524
|
+
if lochead is None:
|
3525
|
+
logging.error(_('Error in get_newarray !'))
|
3526
|
+
return
|
3527
|
+
|
3528
|
+
newarray.init_from_header(self._get_header())
|
3320
3529
|
|
3321
3530
|
sel = np.asarray(self.myselection)
|
3322
3531
|
if len(sel) == 1:
|
@@ -3333,6 +3542,325 @@ class SelectionData():
|
|
3333
3542
|
|
3334
3543
|
return newarray
|
3335
3544
|
|
3545
|
+
def select_all(self):
|
3546
|
+
""" Select all nodes """
|
3547
|
+
|
3548
|
+
self.myselection = 'all'
|
3549
|
+
self.update_nb_nodes_selection()
|
3550
|
+
|
3551
|
+
def interp2Dpolygons(self, working_zone:zone, method:Literal["nearest", "linear", "cubic"] = None, resetplot:bool = True):
|
3552
|
+
"""
|
3553
|
+
Interpolation sous tous les polygones d'une zone
|
3554
|
+
cf parent.interp2Dpolygon
|
3555
|
+
"""
|
3556
|
+
|
3557
|
+
if method is None:
|
3558
|
+
choices = ["nearest", "linear", "cubic"]
|
3559
|
+
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
3560
|
+
ret = dlg.ShowModal()
|
3561
|
+
if ret == wx.ID_CANCEL:
|
3562
|
+
dlg.Destroy()
|
3563
|
+
return
|
3564
|
+
|
3565
|
+
method = dlg.GetStringSelection()
|
3566
|
+
dlg.Destroy()
|
3567
|
+
|
3568
|
+
self.parent.interpolate_on_polygons(working_zone, method)
|
3569
|
+
|
3570
|
+
if resetplot:
|
3571
|
+
self.parent.reset_plot()
|
3572
|
+
|
3573
|
+
def interp2Dpolygon(self, working_vector:vector, method:Literal["nearest", "linear", "cubic"] = None, resetplot:bool = True):
|
3574
|
+
"""
|
3575
|
+
Interpolation sous un polygone
|
3576
|
+
cf parent.interp2Dpolygon
|
3577
|
+
"""
|
3578
|
+
|
3579
|
+
if method is None:
|
3580
|
+
choices = ["nearest", "linear", "cubic"]
|
3581
|
+
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
3582
|
+
ret = dlg.ShowModal()
|
3583
|
+
if ret == wx.ID_CANCEL:
|
3584
|
+
dlg.Destroy()
|
3585
|
+
return
|
3586
|
+
|
3587
|
+
method = dlg.GetStringSelection()
|
3588
|
+
dlg.Destroy()
|
3589
|
+
|
3590
|
+
self.parent.interpolate_on_polygon(working_vector, method)
|
3591
|
+
|
3592
|
+
if resetplot:
|
3593
|
+
self.parent.reset_plot()
|
3594
|
+
|
3595
|
+
def interp2Dpolylines(self, working_zone:zone, resetplot:bool = True):
|
3596
|
+
"""
|
3597
|
+
Interpolation sous toutes les polylignes de la zone
|
3598
|
+
cf parent.interp2Dpolyline
|
3599
|
+
"""
|
3600
|
+
|
3601
|
+
self.parent.interpolate_on_polylines(working_zone)
|
3602
|
+
|
3603
|
+
if resetplot:
|
3604
|
+
self.parent.reset_plot()
|
3605
|
+
|
3606
|
+
def interp2Dpolyline(self, working_vector:vector, resetplot:bool = True):
|
3607
|
+
"""
|
3608
|
+
Interpolation sous la polyligne active
|
3609
|
+
cf parent.interp2Dpolyline
|
3610
|
+
"""
|
3611
|
+
|
3612
|
+
self.parent.interpolate_on_polyline(working_vector)
|
3613
|
+
|
3614
|
+
if resetplot:
|
3615
|
+
self.parent.reset_plot()
|
3616
|
+
|
3617
|
+
|
3618
|
+
def copy(self, source:"SelectionData"):
|
3619
|
+
|
3620
|
+
self.myselection = source.myselection.copy()
|
3621
|
+
|
3622
|
+
def volumesurface(self, show=True):
|
3623
|
+
"""
|
3624
|
+
Evaluation of stage-storage-surface relation
|
3625
|
+
"""
|
3626
|
+
|
3627
|
+
if self.parent.get_mapviewer() is not None:
|
3628
|
+
|
3629
|
+
mapviewer = self.parent.get_mapviewer()
|
3630
|
+
|
3631
|
+
if mapviewer.linked:
|
3632
|
+
|
3633
|
+
array1:WolfArray = mapviewer.linkedList[0].active_array
|
3634
|
+
array2:WolfArray = mapviewer.linkedList[1].active_array
|
3635
|
+
|
3636
|
+
# transfert des mailles sélectionnées dans l'autre matrice
|
3637
|
+
if array1 is self.parent:
|
3638
|
+
array2.SelectionData.copy(array1.SelectionData)
|
3639
|
+
|
3640
|
+
if array2 is self.parent:
|
3641
|
+
array1.SelectionData.copy(array2.SelectionData)
|
3642
|
+
|
3643
|
+
if self.nb == 0 or self.myselection == 'all':
|
3644
|
+
myarray = array1
|
3645
|
+
axs = myarray.volume_estimation()
|
3646
|
+
|
3647
|
+
myarray = array2
|
3648
|
+
axs = myarray.volume_estimation(axs)
|
3649
|
+
else:
|
3650
|
+
myarray = array1.mngselection.get_newarray()
|
3651
|
+
axs = myarray.volume_estimation()
|
3652
|
+
|
3653
|
+
myarray = array2.mngselection.get_newarray()
|
3654
|
+
axs = myarray.volume_estimation(axs)
|
3655
|
+
else:
|
3656
|
+
if len(self.parent.mngselection.myselection) == 0 or self.parent.mngselection.myselection == 'all':
|
3657
|
+
myarray = self.parent
|
3658
|
+
else:
|
3659
|
+
myarray = self.parent.mngselection.get_newarray()
|
3660
|
+
|
3661
|
+
myarray.volume_estimation()
|
3662
|
+
else:
|
3663
|
+
if self.nb == 0 or self.myselection == 'all':
|
3664
|
+
myarray = self.parent
|
3665
|
+
else:
|
3666
|
+
myarray = self.get_newarray()
|
3667
|
+
|
3668
|
+
myarray.volume_estimation()
|
3669
|
+
|
3670
|
+
if show:
|
3671
|
+
plt.show()
|
3672
|
+
|
3673
|
+
class SelectionDataMB(SelectionData):
|
3674
|
+
""" Extension of SelectionData to manage multiple blocks """
|
3675
|
+
|
3676
|
+
def __init__(self, parent:"WolfArrayMB"):
|
3677
|
+
SelectionData.__init__(self, parent)
|
3678
|
+
|
3679
|
+
self.parent:"WolfArrayMB" = parent
|
3680
|
+
|
3681
|
+
@property
|
3682
|
+
def nb(self):
|
3683
|
+
|
3684
|
+
return np.sum([cur.SelectionData.nb for cur in self.parent.active_blocks])
|
3685
|
+
|
3686
|
+
def Unmasksel(self):
|
3687
|
+
|
3688
|
+
for curblock in self.parent.active_blocks:
|
3689
|
+
curblock.SelectionData.Unmasksel(resetplot=False)
|
3690
|
+
|
3691
|
+
self.parent.reset_plot()
|
3692
|
+
|
3693
|
+
def reset(self):
|
3694
|
+
|
3695
|
+
for curblock in self.parent.active_blocks:
|
3696
|
+
curblock.SelectionData.reset()
|
3697
|
+
|
3698
|
+
def select_all(self):
|
3699
|
+
|
3700
|
+
for curblock in self.parent.active_blocks:
|
3701
|
+
curblock.SelectionData.select_all()
|
3702
|
+
|
3703
|
+
def reset_all(self):
|
3704
|
+
""" Reset the selection """
|
3705
|
+
|
3706
|
+
for curblock in self.parent.active_blocks:
|
3707
|
+
curblock.SelectionData.reset_all()
|
3708
|
+
|
3709
|
+
def get_string(self, which:str = None) -> str:
|
3710
|
+
|
3711
|
+
logging.error(_('Not yet implemented for Multi-Blocks'))
|
3712
|
+
|
3713
|
+
def get_script(self, which:int = None) -> str:
|
3714
|
+
|
3715
|
+
logging.error(_('Not yet implemented for Multi-Blocks'))
|
3716
|
+
|
3717
|
+
def get_newarray(self):
|
3718
|
+
|
3719
|
+
logging.error(_('Not yet implemented for Multi-Blocks'))
|
3720
|
+
|
3721
|
+
def add_node_to_selection(self, x:float, y:float, verif:bool=True):
|
3722
|
+
""" Add a node to the selection """
|
3723
|
+
|
3724
|
+
for curblock in self.parent.active_blocks:
|
3725
|
+
ret = curblock.SelectionData.add_node_to_selection(x, y, verif)
|
3726
|
+
|
3727
|
+
def add_nodes_to_selection(self, xy:list[float], verif:bool=True):
|
3728
|
+
""" Add nodes to the selection """
|
3729
|
+
|
3730
|
+
for curblock in self.parent.active_blocks:
|
3731
|
+
curblock.SelectionData.add_nodes_to_selection(xy, verif)
|
3732
|
+
|
3733
|
+
def select_insidepoly(self, myvect: vector):
|
3734
|
+
|
3735
|
+
for curblock in self.parent.active_blocks:
|
3736
|
+
curblock.SelectionData.select_insidepoly(myvect)
|
3737
|
+
|
3738
|
+
def select_underpoly(self, myvect: vector):
|
3739
|
+
|
3740
|
+
for curblock in self.parent.active_blocks:
|
3741
|
+
curblock.SelectionData.select_underpoly(myvect)
|
3742
|
+
|
3743
|
+
def update_nb_nodes_selection(self):
|
3744
|
+
|
3745
|
+
ret = []
|
3746
|
+
for curblock in self.parent.active_blocks:
|
3747
|
+
ret.append(curblock.SelectionData.update_nb_nodes_selection())
|
3748
|
+
|
3749
|
+
nb = np.sum([cur[0] for cur in ret])
|
3750
|
+
xmin = np.min([cur[1] for cur in ret if cur[1] != -99999.])
|
3751
|
+
ymin = np.min([cur[3] for cur in ret if cur[3] != -99999.])
|
3752
|
+
xmax = np.max([cur[2] for cur in ret if cur[2] != -99999.])
|
3753
|
+
ymax = np.max([cur[4] for cur in ret if cur[4] != -99999.])
|
3754
|
+
|
3755
|
+
if self.parent.myops is not None:
|
3756
|
+
|
3757
|
+
self.parent.myops.nbselect.SetLabelText(str(nb))
|
3758
|
+
if nb>0:
|
3759
|
+
self.parent.myops.minx.SetLabelText('{:.3f}'.format(xmin))
|
3760
|
+
self.parent.myops.miny.SetLabelText('{:.3f}'.format(ymin))
|
3761
|
+
self.parent.myops.maxx.SetLabelText('{:.3f}'.format(xmax))
|
3762
|
+
self.parent.myops.maxy.SetLabelText('{:.3f}'.format(ymax))
|
3763
|
+
|
3764
|
+
|
3765
|
+
def condition_select(self, cond, condval, condval2=0, usemask=False):
|
3766
|
+
|
3767
|
+
for curblock in self.parent.active_blocks:
|
3768
|
+
curblock.SelectionData.condition_select(cond, condval, condval2, usemask)
|
3769
|
+
|
3770
|
+
def treat_select(self, op, cond, opval, condval):
|
3771
|
+
|
3772
|
+
for curblock in self.parent.active_blocks:
|
3773
|
+
curblock.SelectionData.treat_select(op, cond, opval, condval)
|
3774
|
+
|
3775
|
+
def mask_condition(self, op, cond, opval, condval):
|
3776
|
+
|
3777
|
+
for curblock in self.parent.active_blocks:
|
3778
|
+
curblock.SelectionData.mask_condition(op, cond, opval, condval)
|
3779
|
+
|
3780
|
+
def plot_selection(self):
|
3781
|
+
|
3782
|
+
for curblock in self.parent.active_blocks:
|
3783
|
+
curblock.SelectionData.plot_selection()
|
3784
|
+
|
3785
|
+
def move_selectionto(self, idx:str, color:list[float]):
|
3786
|
+
|
3787
|
+
for curblock in self.parent.active_blocks:
|
3788
|
+
curblock.SelectionData.move_selectionto(idx, color, resetplot=False)
|
3789
|
+
|
3790
|
+
self.parent.reset_plot()
|
3791
|
+
|
3792
|
+
def copy_to_clipboard(self, which:int = None, typestr:Literal['string', 'script'] = 'string'):
|
3793
|
+
|
3794
|
+
logging.error(_('Not yet implemented for Multi-Blocks'))
|
3795
|
+
|
3796
|
+
def interp2Dpolygons(self, working_zone:zone, method:Literal["nearest", "linear", "cubic"] = None):
|
3797
|
+
"""
|
3798
|
+
Interpolation sous tous les polygones d'une zone
|
3799
|
+
cf parent.interp2Dpolygon
|
3800
|
+
"""
|
3801
|
+
|
3802
|
+
if method is None:
|
3803
|
+
choices = ["nearest", "linear", "cubic"]
|
3804
|
+
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
3805
|
+
ret = dlg.ShowModal()
|
3806
|
+
if ret == wx.ID_CANCEL:
|
3807
|
+
dlg.Destroy()
|
3808
|
+
return
|
3809
|
+
|
3810
|
+
method = dlg.GetStringSelection()
|
3811
|
+
dlg.Destroy()
|
3812
|
+
|
3813
|
+
self.parent.interpolate_on_polygons(working_zone, method)
|
3814
|
+
|
3815
|
+
self.parent.reset_plot()
|
3816
|
+
|
3817
|
+
def interp2Dpolygon(self, working_vector:vector, method:Literal["nearest", "linear", "cubic"] = None):
|
3818
|
+
"""
|
3819
|
+
Interpolation sous un polygone
|
3820
|
+
cf parent.interp2Dpolygon
|
3821
|
+
"""
|
3822
|
+
|
3823
|
+
if method is None:
|
3824
|
+
choices = ["nearest", "linear", "cubic"]
|
3825
|
+
dlg = wx.SingleChoiceDialog(None, "Pick an interpolate method", "Choices", choices)
|
3826
|
+
ret = dlg.ShowModal()
|
3827
|
+
if ret == wx.ID_CANCEL:
|
3828
|
+
dlg.Destroy()
|
3829
|
+
return
|
3830
|
+
|
3831
|
+
method = dlg.GetStringSelection()
|
3832
|
+
dlg.Destroy()
|
3833
|
+
|
3834
|
+
self.parent.interpolate_on_polygon(working_vector, method)
|
3835
|
+
|
3836
|
+
self.parent.reset_plot()
|
3837
|
+
|
3838
|
+
def interp2Dpolylines(self, working_zone:zone, resetplot:bool = True):
|
3839
|
+
"""
|
3840
|
+
Interpolation sous toutes les polylignes de la zone
|
3841
|
+
cf parent.interp2Dpolyline
|
3842
|
+
"""
|
3843
|
+
|
3844
|
+
self.parent.interpolate_on_polylines(working_zone)
|
3845
|
+
|
3846
|
+
self.parent.reset_plot()
|
3847
|
+
|
3848
|
+
def interp2Dpolyline(self, working_vector:vector, resetplot:bool = True):
|
3849
|
+
"""
|
3850
|
+
Interpolation sous la polyligne active
|
3851
|
+
cf parent.interp2Dpolyline
|
3852
|
+
"""
|
3853
|
+
|
3854
|
+
self.parent.interpolate_on_polyline(working_vector)
|
3855
|
+
|
3856
|
+
self.parent.reset_plot()
|
3857
|
+
|
3858
|
+
def volumesurface(self, show=True):
|
3859
|
+
"""
|
3860
|
+
Evaluation of stage-storage-surface relation
|
3861
|
+
"""
|
3862
|
+
|
3863
|
+
logging.error(_('Not yet implemented for Multi-Blocks'))
|
3336
3864
|
|
3337
3865
|
class WolfArray(Element_To_Draw, header_wolf):
|
3338
3866
|
"""
|
@@ -3398,6 +3926,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3398
3926
|
|
3399
3927
|
self.mngselection = None
|
3400
3928
|
|
3929
|
+
self.myblocks = None
|
3930
|
+
self._active_blocks = None
|
3931
|
+
|
3401
3932
|
self.flipupd=False
|
3402
3933
|
self.array:ma.masked_array = None # numpy masked array to stored numerical data
|
3403
3934
|
|
@@ -3425,7 +3956,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3425
3956
|
self.shaded.mypal.defaultgray()
|
3426
3957
|
self.shaded.mypal.automatic = False
|
3427
3958
|
|
3428
|
-
self.
|
3959
|
+
self._nullvalue = nullvalue
|
3429
3960
|
self.nbnotnull = 99999 # number of non-null values in the entire aray
|
3430
3961
|
self.nbnotnullzoom = 99999 # number of non-null values in the current visible part in mapviwer
|
3431
3962
|
self.nbtoplot = 0
|
@@ -3464,6 +3995,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3464
3995
|
|
3465
3996
|
self.head_blocks = header.head_blocks.copy()
|
3466
3997
|
|
3998
|
+
if self.nb_blocks>0:
|
3999
|
+
self.myblocks = {}
|
4000
|
+
|
3467
4001
|
self.allocate_ressources()
|
3468
4002
|
|
3469
4003
|
# # FIXME Why not initialize with nullvalue ?
|
@@ -3532,6 +4066,16 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3532
4066
|
|
3533
4067
|
self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
|
3534
4068
|
|
4069
|
+
def extract_selection(self):
|
4070
|
+
""" Extract the current selection """
|
4071
|
+
|
4072
|
+
newarray = self.SelectionData.get_newarray()
|
4073
|
+
|
4074
|
+
mapviewer = self.get_mapviewer()
|
4075
|
+
|
4076
|
+
if mapviewer is not None:
|
4077
|
+
mapviewer.add_object('array', newobj = newarray, ToCheck = True, id = self.idx + '_extracted')
|
4078
|
+
|
3535
4079
|
def crop_array(self, bbox:list[list[float],list[float]]) -> "WolfArray":
|
3536
4080
|
""" Crop the data based on the bounding box """
|
3537
4081
|
imin, jmin = self.get_ij_from_xy(bbox[0][0], bbox[1][0])
|
@@ -3605,6 +4149,93 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3605
4149
|
self.myops.SetTitle(_('Operations on array: ') + self.idx)
|
3606
4150
|
self.myops.Show()
|
3607
4151
|
|
4152
|
+
@property
|
4153
|
+
def nullvalue(self) -> float:
|
4154
|
+
""" Return the null value """
|
4155
|
+
|
4156
|
+
return self._nullvalue
|
4157
|
+
|
4158
|
+
@nullvalue.setter
|
4159
|
+
def nullvalue(self, value:float):
|
4160
|
+
""" Set the null value """
|
4161
|
+
|
4162
|
+
self._nullvalue = value
|
4163
|
+
|
4164
|
+
@property
|
4165
|
+
def SelectionData(self) -> SelectionData:
|
4166
|
+
""" Return the data of the selection """
|
4167
|
+
|
4168
|
+
return self.mngselection
|
4169
|
+
|
4170
|
+
@property
|
4171
|
+
def active_blocks(self) -> list["WolfArray"]:
|
4172
|
+
""" Return the active blocks """
|
4173
|
+
|
4174
|
+
if self.nb_blocks>0 and self._active_blocks is not None:
|
4175
|
+
|
4176
|
+
if isinstance(self._active_blocks, list):
|
4177
|
+
return [self.myblocks[cur] for cur in self._active_blocks]
|
4178
|
+
elif self._active_blocks == 0:
|
4179
|
+
return [k for k in self.myblocks.values()]
|
4180
|
+
elif self._active_blocks in self.myblocks:
|
4181
|
+
return [self.myblocks[self._active_blocks]]
|
4182
|
+
else:
|
4183
|
+
return None
|
4184
|
+
|
4185
|
+
else:
|
4186
|
+
return [self]
|
4187
|
+
|
4188
|
+
@active_blocks.setter
|
4189
|
+
def active_blocks(self, value:Union[str, int, list[int]]):
|
4190
|
+
"""
|
4191
|
+
Set the active blocks
|
4192
|
+
|
4193
|
+
:param value: name of the block or index 1-based or list of index 1-based
|
4194
|
+
|
4195
|
+
"""
|
4196
|
+
|
4197
|
+
if isinstance(value, str):
|
4198
|
+
if value in self.myblocks:
|
4199
|
+
self._active_blocks = value
|
4200
|
+
logging.info(_(f'Block found - {value}'))
|
4201
|
+
else:
|
4202
|
+
self._active_blocks = None
|
4203
|
+
logging.info(_('Block not found'))
|
4204
|
+
|
4205
|
+
elif isinstance(value, int):
|
4206
|
+
|
4207
|
+
if value == 0:
|
4208
|
+
self._active_blocks = 0
|
4209
|
+
logging.info(_('All blocks selected'))
|
4210
|
+
else:
|
4211
|
+
value = getkeyblock(value, addone=False)
|
4212
|
+
|
4213
|
+
if value in self.myblocks:
|
4214
|
+
self._active_blocks = value
|
4215
|
+
logging.info(_(f'Block found - {value}'))
|
4216
|
+
else:
|
4217
|
+
self._active_blocks = None
|
4218
|
+
logging.info(_('Block not found'))
|
4219
|
+
|
4220
|
+
elif isinstance(value, list):
|
4221
|
+
|
4222
|
+
if 0 in value:
|
4223
|
+
self._active_blocks = 0
|
4224
|
+
logging.info(_('All blocks selected'))
|
4225
|
+
else:
|
4226
|
+
value = [getkeyblock(cur, addone=False) for cur in value]
|
4227
|
+
value = [cur for cur in value if cur in self.myblocks]
|
4228
|
+
|
4229
|
+
if len(value)>0:
|
4230
|
+
self._active_blocks = value
|
4231
|
+
logging.info(_('List of blocks selected'))
|
4232
|
+
else:
|
4233
|
+
self._active_blocks = None
|
4234
|
+
logging.info(_('No block found'))
|
4235
|
+
|
4236
|
+
else:
|
4237
|
+
logging.error(_('Unknown type for active_blocks'))
|
4238
|
+
|
3608
4239
|
@property
|
3609
4240
|
def dtype(self):
|
3610
4241
|
"""
|
@@ -3707,7 +4338,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3707
4338
|
|
3708
4339
|
self.reset_plot()
|
3709
4340
|
|
3710
|
-
def filter_independent_zones(self, n_largest:int = 1):
|
4341
|
+
def filter_independent_zones(self, n_largest:int = 1, reset_plot:bool = True):
|
3711
4342
|
"""
|
3712
4343
|
Filtre des zones indépendantes et conservation des n plus grandes
|
3713
4344
|
|
@@ -3721,7 +4352,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3721
4352
|
# convertion en masked array
|
3722
4353
|
labeled_array = ma.asarray(labeled_array)
|
3723
4354
|
# application du masque
|
3724
|
-
labeled_array.mask = self.array.mask
|
4355
|
+
labeled_array.mask[:,:] = self.array.mask[:,:]
|
3725
4356
|
|
3726
4357
|
longueur = []
|
3727
4358
|
labeled_array[labeled_array.mask] = 0
|
@@ -3737,8 +4368,61 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3737
4368
|
|
3738
4369
|
self.set_nullvalue_in_mask()
|
3739
4370
|
|
3740
|
-
|
4371
|
+
if reset_plot:
|
4372
|
+
self.reset_plot()
|
3741
4373
|
|
4374
|
+
def filter_zone(self, set_null:bool = False, reset_plot:bool = True):
|
4375
|
+
"""
|
4376
|
+
Filtre des zones et conservation de celles pour lesquelles des
|
4377
|
+
mailles sont sélectionnées
|
4378
|
+
|
4379
|
+
"""
|
4380
|
+
|
4381
|
+
if self.SelectionData.nb == 0:
|
4382
|
+
logging.info(_('No selection -- no filtering'))
|
4383
|
+
return
|
4384
|
+
|
4385
|
+
if self.SelectionData.myselection == 'all':
|
4386
|
+
logging.info(_('All nodes selected -- no filtering'))
|
4387
|
+
return
|
4388
|
+
|
4389
|
+
# labellisation
|
4390
|
+
labeled_array = self.array.data.copy()
|
4391
|
+
labeled_array[np.where(self.array.mask)] = 0
|
4392
|
+
|
4393
|
+
labeled_array, num_features = label(labeled_array)
|
4394
|
+
|
4395
|
+
# récupération des zones utiles
|
4396
|
+
vals_ij = [self.get_ij_from_xy(cur[0], cur[1]) for cur in self.SelectionData.myselection]
|
4397
|
+
vals = list(set([labeled_array[int(cur[0]), int(cur[1])] for cur in vals_ij]))
|
4398
|
+
|
4399
|
+
self.array.mask[:,:] = True
|
4400
|
+
|
4401
|
+
for j in vals:
|
4402
|
+
self.array.mask[labeled_array == j] = False
|
4403
|
+
|
4404
|
+
if set_null:
|
4405
|
+
self.set_nullvalue_in_mask()
|
4406
|
+
|
4407
|
+
if reset_plot:
|
4408
|
+
self.reset_plot()
|
4409
|
+
|
4410
|
+
def labelling(self, reset_plot:bool = True):
|
4411
|
+
"""
|
4412
|
+
Labelling of the array using Scipy
|
4413
|
+
|
4414
|
+
"""
|
4415
|
+
|
4416
|
+
# labellisation
|
4417
|
+
labeled_array = self.array.data.copy()
|
4418
|
+
labeled_array[np.where(self.array.mask)] = 0
|
4419
|
+
|
4420
|
+
labeled_array, num_features = label(labeled_array)
|
4421
|
+
|
4422
|
+
self.array.data[:,:] = labeled_array[:,:].astype(self.dtype)
|
4423
|
+
|
4424
|
+
if reset_plot:
|
4425
|
+
self.reset_plot()
|
3742
4426
|
|
3743
4427
|
def export_geotif(self, outdir='', extent = ''):
|
3744
4428
|
"""
|
@@ -3902,10 +4586,12 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3902
4586
|
|
3903
4587
|
def add_ops_sel(self):
|
3904
4588
|
"""
|
3905
|
-
|
3906
|
-
|
3907
|
-
|
4589
|
+
Adding selection manager and operations array
|
4590
|
+
|
4591
|
+
- Ops_Array (GUI) if mapviewer is not None
|
4592
|
+
- create SelectionData (Selection manager) if None
|
3908
4593
|
"""
|
4594
|
+
|
3909
4595
|
if self.wx_exists and self.mapviewer is not None:
|
3910
4596
|
self.myops = Ops_Array(self, self.mapviewer)
|
3911
4597
|
self.myops.Hide()
|
@@ -3913,7 +4599,11 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
3913
4599
|
self.myops = None
|
3914
4600
|
|
3915
4601
|
if self.mngselection is None:
|
3916
|
-
|
4602
|
+
|
4603
|
+
if self.nb_blocks>0:
|
4604
|
+
self.mngselection = SelectionDataMB(self)
|
4605
|
+
else:
|
4606
|
+
self.mngselection = SelectionData(self)
|
3917
4607
|
|
3918
4608
|
def change_gui(self, newparentgui):
|
3919
4609
|
"""
|
@@ -4039,6 +4729,82 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4039
4729
|
|
4040
4730
|
plt.show()
|
4041
4731
|
|
4732
|
+
def interpolate_on_polygon(self, working_vector: vector, method:Literal["nearest", "linear", "cubic"]="linear"):
|
4733
|
+
"""
|
4734
|
+
Interpolation sous un polygone
|
4735
|
+
|
4736
|
+
L'interpolation a lieu :
|
4737
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
4738
|
+
- dans les mailles contenues dans le polygone sinon
|
4739
|
+
|
4740
|
+
On utilise ensuite "griddata" pour interpoler les altitudes des mailles
|
4741
|
+
depuis les vertices 3D du polygone
|
4742
|
+
"""
|
4743
|
+
|
4744
|
+
if self.mngselection is None:
|
4745
|
+
destxy = self.get_xy_inside_polygon(working_vector)
|
4746
|
+
else:
|
4747
|
+
if self.SelectionData.nb == 0:
|
4748
|
+
destxy = self.get_xy_inside_polygon(working_vector)
|
4749
|
+
else:
|
4750
|
+
destxy = self.SelectionData.myselection
|
4751
|
+
|
4752
|
+
if len(destxy)==0:
|
4753
|
+
logging.debug(_('No points to interpolate'))
|
4754
|
+
return
|
4755
|
+
|
4756
|
+
destij = np.asarray([list(self.get_ij_from_xy(x, y)) for x, y in destxy])
|
4757
|
+
|
4758
|
+
xyz = working_vector.asnparray3d()
|
4759
|
+
|
4760
|
+
newvalues = griddata(xyz[:, :2], xyz[:, 2], destxy, method=method, fill_value=-99999.)
|
4761
|
+
|
4762
|
+
locmask = np.where(newvalues != -99999.)
|
4763
|
+
self.array.data[destij[locmask][:, 0], destij[locmask][:, 1]] = newvalues[locmask]
|
4764
|
+
|
4765
|
+
def interpolate_on_polygons(self, working_zone:zone, method:Literal["nearest", "linear", "cubic"]="linear"):
|
4766
|
+
"""
|
4767
|
+
Interpolation sous plusieurs polygones d'une même zone
|
4768
|
+
|
4769
|
+
"""
|
4770
|
+
|
4771
|
+
for curvec in working_zone.myvectors:
|
4772
|
+
self.interpolate_on_polygon(curvec, method)
|
4773
|
+
|
4774
|
+
def interpolate_on_polyline(self, working_vector:vector, usemask=True):
|
4775
|
+
"""
|
4776
|
+
Interpolation sous une polyligne
|
4777
|
+
|
4778
|
+
L'interpolation a lieu :
|
4779
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
4780
|
+
- dans les mailles sous la polyligne sinon
|
4781
|
+
|
4782
|
+
On utilise ensuite "interpolate" de shapely pour interpoler les altitudes des mailles
|
4783
|
+
depuis les vertices 3D de la polyligne
|
4784
|
+
"""
|
4785
|
+
|
4786
|
+
vecls = working_vector.asshapely_ls()
|
4787
|
+
|
4788
|
+
if self.SelectionData is None:
|
4789
|
+
allij = self.get_ij_under_polyline(working_vector, usemask)
|
4790
|
+
allxy = [self.get_xy_from_ij(cur[0], cur[1]) for cur in allij]
|
4791
|
+
else:
|
4792
|
+
if self.SelectionData.nb == 0:
|
4793
|
+
allij = self.get_ij_under_polyline(working_vector, usemask)
|
4794
|
+
allxy = [self.get_xy_from_ij(cur[0], cur[1]) for cur in allij]
|
4795
|
+
else:
|
4796
|
+
allxy = self.SelectionData.myselection
|
4797
|
+
allij = np.asarray([self.get_ij_from_xy(x,y) for x,y in allxy])
|
4798
|
+
|
4799
|
+
newz = np.asarray([vecls.interpolate(vecls.project(Point(x, y))).z for x, y in allxy])
|
4800
|
+
self.array.data[allij[:, 0], allij[:, 1]] = newz
|
4801
|
+
|
4802
|
+
def interpolate_on_polylines(self, working_zone:zone, usemask=True):
|
4803
|
+
|
4804
|
+
for curvec in working_zone.myvectors:
|
4805
|
+
self.interpolate_on_polyline(curvec, usemask)
|
4806
|
+
|
4807
|
+
|
4042
4808
|
def interpolate_on_cloud(self, xy:np.ndarray, z:np.ndarray, method='linear'):
|
4043
4809
|
"""
|
4044
4810
|
See : https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html
|
@@ -4195,7 +4961,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4195
4961
|
curvec.add_vertex(wolfvertex(coords[curpt,0],coords[curpt,1], coords[curpt,2]))
|
4196
4962
|
curvec.close_force()
|
4197
4963
|
|
4198
|
-
self.
|
4964
|
+
self.interpolate_on_polygon(curvec, "linear")
|
4199
4965
|
|
4200
4966
|
self.reset_plot()
|
4201
4967
|
return
|
@@ -4546,7 +5312,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4546
5312
|
|
4547
5313
|
return axs
|
4548
5314
|
|
4549
|
-
def paste_all(self, fromarray:"WolfArray"):
|
5315
|
+
def paste_all(self, fromarray:"WolfArray", mask_after:bool=True):
|
4550
5316
|
""" Paste all the values from another WolfArray """
|
4551
5317
|
|
4552
5318
|
fromarray: WolfArray
|
@@ -4583,8 +5349,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4583
5349
|
|
4584
5350
|
self.array.data[usefulij_dest] = fromarray.array.data[usefulij]
|
4585
5351
|
|
4586
|
-
|
4587
|
-
|
5352
|
+
if mask_after:
|
5353
|
+
self.mask_data(self.nullvalue)
|
5354
|
+
self.reset_plot()
|
4588
5355
|
|
4589
5356
|
def set_values_sel(self, xy:list[float], z:list[float], update:bool=True):
|
4590
5357
|
"""
|
@@ -4594,6 +5361,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4594
5361
|
:param z: [z1,z2,...]
|
4595
5362
|
:param update: update the plot
|
4596
5363
|
"""
|
5364
|
+
|
4597
5365
|
sel = np.asarray(xy)
|
4598
5366
|
|
4599
5367
|
if len(sel) == 1:
|
@@ -4779,6 +5547,10 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
4779
5547
|
"""
|
4780
5548
|
assert self.shape == mask.shape, _('Bad shape')
|
4781
5549
|
|
5550
|
+
if self.array is None:
|
5551
|
+
logging.debug(_('No array !!'))
|
5552
|
+
return
|
5553
|
+
|
4782
5554
|
if link:
|
4783
5555
|
self.array.mask = mask
|
4784
5556
|
else:
|
@@ -5024,7 +5796,60 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5024
5796
|
|
5025
5797
|
return newArray
|
5026
5798
|
|
5027
|
-
def
|
5799
|
+
def concatenate(self, list_arr:list["WolfArray"], nullvalue:float = 0.):
|
5800
|
+
"""
|
5801
|
+
Concatenate the values from another WolfArrays into a new one
|
5802
|
+
|
5803
|
+
:param list_arr: list of WolfArray objects
|
5804
|
+
:return: a new WolfArray
|
5805
|
+
:return_type: WolfArray
|
5806
|
+
"""
|
5807
|
+
|
5808
|
+
list_arr:list[WolfArray]
|
5809
|
+
|
5810
|
+
for curarray in list_arr:
|
5811
|
+
assert isinstance(curarray, WolfArray), "The list must contain WolfArray objects"
|
5812
|
+
assert curarray.nbdims == self.nbdims, "The arrays must have the same number of dimensions"
|
5813
|
+
assert curarray.dx == self.dx and curarray.dy == self.dy, "The arrays must have the same dx and dy"
|
5814
|
+
assert curarray.translx == 0 and curarray.transly == 0, "The translations must be zero"
|
5815
|
+
assert (np.abs(curarray.origx-self.origx)%int(self.dx) == 0)and(np.abs(curarray.origy-self.origy)%int(self.dy) == 0), "The origins are not compatible! You need to do some interpolation stuff"
|
5816
|
+
assert self.translx == 0 and self.transly == 0, "The translations must be zero"
|
5817
|
+
assert self.wolftype == curarray.wolftype, "The arrays must have the same wolftype"
|
5818
|
+
|
5819
|
+
# create an array
|
5820
|
+
newArray = WolfArray(nullvalue=nullvalue, whichtype=self.wolftype)
|
5821
|
+
|
5822
|
+
Xlim,Ylim = self.find_union(list_arr)
|
5823
|
+
|
5824
|
+
newArray.origx = Xlim[0]
|
5825
|
+
newArray.origy = Ylim[0]
|
5826
|
+
newArray.dx = self.dx
|
5827
|
+
newArray.dy = self.dy
|
5828
|
+
|
5829
|
+
newArray.nbx = int(np.diff(Xlim)[0]/newArray.dx)
|
5830
|
+
newArray.nby = int(np.diff(Ylim)[0]/newArray.dy)
|
5831
|
+
|
5832
|
+
newArray.translx = 0.
|
5833
|
+
newArray.transly = 0.
|
5834
|
+
|
5835
|
+
newArray.array = np.ma.masked_array(np.ones((newArray.nbx, newArray.nby), dtype=self.dtype) * nullvalue, mask=True, dtype=self.dtype)
|
5836
|
+
|
5837
|
+
newArray.paste_all(self, mask_after=False)
|
5838
|
+
|
5839
|
+
for curarray in list_arr:
|
5840
|
+
Array_intersect = curarray.find_intersection(self, ij=True)
|
5841
|
+
|
5842
|
+
if Array_intersect is not None:
|
5843
|
+
logging.info(_("There is intersection. By default, the array {} overlaps the first one.".format(curarray.filename)))
|
5844
|
+
|
5845
|
+
newArray.paste_all(curarray, mask_after=False)
|
5846
|
+
|
5847
|
+
newArray.mask_data(nullvalue)
|
5848
|
+
|
5849
|
+
|
5850
|
+
return newArray
|
5851
|
+
|
5852
|
+
def mask_outsidepoly(self, myvect: vector, eps:float = 0.):
|
5028
5853
|
"""
|
5029
5854
|
Mask nodes outside a polygon and set values to nullvalue
|
5030
5855
|
|
@@ -5038,27 +5863,51 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5038
5863
|
mask[:,:] = True # Mask everything
|
5039
5864
|
|
5040
5865
|
# trouve les indices dans le polygone
|
5041
|
-
myij = self.get_ij_inside_polygon(myvect, False)
|
5866
|
+
myij = self.get_ij_inside_polygon(myvect, usemask=False, eps=eps)
|
5867
|
+
|
5042
5868
|
# démasquage des mailles contenues
|
5043
5869
|
mask[myij[:,0],myij[:,1]] = False
|
5870
|
+
|
5044
5871
|
# annulation des valeurs en dehors du polygone
|
5045
5872
|
self.array.data[np.where(mask)] = self.nullvalue
|
5046
5873
|
|
5047
|
-
# recherche du nouveau masque, sinon les valeurs no_data à
|
5048
|
-
# l'intérieur du polygone vont pollluer la matrice
|
5874
|
+
# recherche du nouveau masque, sinon les valeurs no_data à
|
5875
|
+
# l'intérieur du polygone vont pollluer la matrice
|
5876
|
+
|
5877
|
+
# Now we have masked everything outside the polygon,
|
5878
|
+
# we still have to keep into account values that were
|
5879
|
+
# already masked inside the polygon before this operation.
|
5880
|
+
# FIXME Why simply not use the previous mask value ?
|
5881
|
+
# FIXME This operation seems to contradict mask[:,:] = True
|
5882
|
+
self.mask_data(self.nullvalue)
|
5883
|
+
|
5884
|
+
self.count()
|
5885
|
+
|
5886
|
+
def mask_insidepoly(self, myvect: vector, eps:float = 0.):
|
5887
|
+
"""
|
5888
|
+
Mask nodes inside a polygon and set values to nullvalue
|
5889
|
+
|
5890
|
+
:param myvect: target vector in global coordinates
|
5891
|
+
"""
|
5892
|
+
# The polygon here is in world coordinates
|
5893
|
+
# (coord will be converted back with translation, origin and dx/dy)
|
5894
|
+
# (mesh coord, 0-based)
|
5895
|
+
|
5896
|
+
# trouve les indices dans le polygone
|
5897
|
+
myij = self.get_ij_inside_polygon(myvect, usemask=False, eps=eps)
|
5898
|
+
|
5899
|
+
# annulation des valeurs en dehors du polygone
|
5900
|
+
self.array.data[myij[:,0],myij[:,1]] = self.nullvalue
|
5049
5901
|
|
5050
|
-
#
|
5051
|
-
|
5052
|
-
# already masked inside the polygon before this operation.
|
5053
|
-
# FIXME Why simply not use the previous mask value ?
|
5054
|
-
# FIXME This operation seems to contradict mask[:,:] = True
|
5055
|
-
self.mask_data(self.nullvalue)
|
5902
|
+
# masquage des mailles contenues
|
5903
|
+
self.array.mask[myij[:,0],myij[:,1]] = True
|
5056
5904
|
|
5905
|
+
self.count()
|
5057
5906
|
|
5058
5907
|
# *************************************************************************************************************************
|
5059
5908
|
# POSITION and VALUES associated to a vector/polygon/polyline
|
5060
5909
|
# These functions can not be stored in header_wolf, because wa can use the mask of the array to limit the search
|
5061
|
-
# These functions are also present in WolfResults_2D, but they are not exactly the same
|
5910
|
+
# These functions are also present in WolfResults_2D, but they are not exactly the same due to the structure of the results
|
5062
5911
|
# *************************************************************************************************************************
|
5063
5912
|
def get_xy_inside_polygon(self, myvect: vector, usemask:bool=True):
|
5064
5913
|
"""
|
@@ -5069,7 +5918,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5069
5918
|
"""
|
5070
5919
|
|
5071
5920
|
myvect.find_minmax()
|
5072
|
-
mypointsxy,mypointsij = self.get_xy_infootprint_vect(myvect)
|
5921
|
+
mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect)
|
5073
5922
|
myvert = myvect.asnparray()
|
5074
5923
|
path = mpltPath.Path(myvert)
|
5075
5924
|
inside = path.contains_points(mypointsxy)
|
@@ -5096,7 +5945,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5096
5945
|
|
5097
5946
|
return mypoints
|
5098
5947
|
|
5099
|
-
def get_ij_inside_polygon(self, myvect: vector, usemask:bool=True):
|
5948
|
+
def get_ij_inside_polygon(self, myvect: vector, usemask:bool=True, eps:float = 0.):
|
5100
5949
|
"""
|
5101
5950
|
Return the indices inside a polygon
|
5102
5951
|
|
@@ -5104,12 +5953,16 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5104
5953
|
:param usemask : limit potential nodes to unmaksed nodes
|
5105
5954
|
"""
|
5106
5955
|
|
5956
|
+
# force la mise à jour des min/max
|
5107
5957
|
myvect.find_minmax()
|
5108
|
-
|
5958
|
+
|
5959
|
+
mypointsxy, mypointsij = self.get_xy_infootprint_vect(myvect, eps=eps)
|
5960
|
+
|
5961
|
+
# Conversion des coordonnées en numpy pour plus d'efficacité (du moins on espère)
|
5109
5962
|
myvert = myvect.asnparray()
|
5110
|
-
|
5111
|
-
path = mpltPath.Path(
|
5112
|
-
inside = path.contains_points(
|
5963
|
+
|
5964
|
+
path = mpltPath.Path(myvert)
|
5965
|
+
inside = path.contains_points(mypointsxy)
|
5113
5966
|
|
5114
5967
|
mypointsij = mypointsij[np.where(inside)]
|
5115
5968
|
|
@@ -5287,6 +6140,11 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5287
6140
|
|
5288
6141
|
else:
|
5289
6142
|
self.read_txt_header()
|
6143
|
+
|
6144
|
+
if self.nb_blocks > 0:
|
6145
|
+
# At this point, we have the header, we know the number of blocks, if exists
|
6146
|
+
self.myblocks = {}
|
6147
|
+
|
5290
6148
|
if self.preload:
|
5291
6149
|
self.read_data()
|
5292
6150
|
self.loaded = True
|
@@ -5296,7 +6154,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5296
6154
|
"""
|
5297
6155
|
Ecriture de tous les fichiers d'un Wolf array
|
5298
6156
|
|
5299
|
-
:param newpath: path and filename with extension
|
6157
|
+
:param newpath: new path and filename with extension -- if None, use the current filename
|
5300
6158
|
"""
|
5301
6159
|
|
5302
6160
|
if isinstance(newpath, Path):
|
@@ -5308,7 +6166,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5308
6166
|
if self.filename.endswith('.tif'):
|
5309
6167
|
self.export_geotif()
|
5310
6168
|
elif self.filename.endswith('.npy'):
|
5311
|
-
|
6169
|
+
|
5312
6170
|
writing_header = True
|
5313
6171
|
if self.dtype != self.array.data.dtype:
|
5314
6172
|
logging.warning(_('Data type changed -- Force conversion to internal numpy array'))
|
@@ -5510,6 +6368,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5510
6368
|
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_INTEGER16_2]:
|
5511
6369
|
locarray = np.frombuffer(f.read(self.nbx * self.nby * 2), dtype=np.int16)
|
5512
6370
|
self.array = ma.masked_array(locarray.copy(), dtype=np.int16)
|
6371
|
+
elif self.wolftype in [WOLF_ARRAY_FULL_INTEGER8]:
|
6372
|
+
locarray = np.frombuffer(f.read(self.nbx * self.nby * 2), dtype=np.int8)
|
6373
|
+
self.array = ma.masked_array(locarray.copy(), dtype=np.int8)
|
5513
6374
|
|
5514
6375
|
if self.nbdims == 2:
|
5515
6376
|
self.array = self.array.reshape(self.nbx, self.nby, order='F')
|
@@ -5606,7 +6467,7 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5606
6467
|
"""
|
5607
6468
|
|
5608
6469
|
if self.nbdims == 2:
|
5609
|
-
# FIXME if
|
6470
|
+
# FIXME if mask linking should work
|
5610
6471
|
# as expected, then we do: self.array.mask.fill(0.0)
|
5611
6472
|
# to avoid replacing the linked mask by a (non linked) one.
|
5612
6473
|
|
@@ -5677,6 +6538,25 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5677
6538
|
np.copyto(self.array.mask, self.array.data <= value)
|
5678
6539
|
self.count()
|
5679
6540
|
|
6541
|
+
def mask_greater(self, value):
|
6542
|
+
""" Mask cell where values are strictly greater than `value` """
|
6543
|
+
if self.array is None:
|
6544
|
+
return
|
6545
|
+
|
6546
|
+
# Copy to prevent unlinking the mask (see `mask_reset`)
|
6547
|
+
np.copyto(self.array.mask, self.array.data > value)
|
6548
|
+
self.count()
|
6549
|
+
|
6550
|
+
def mask_greaterequal(self, value):
|
6551
|
+
""" Mask cell where values are greater or equal than `value`"""
|
6552
|
+
if self.array is None:
|
6553
|
+
return
|
6554
|
+
|
6555
|
+
# Copy to prevent unlinking the mask (see `mask_reset`)
|
6556
|
+
np.copyto(self.array.mask, self.array.data >= value)
|
6557
|
+
self.count()
|
6558
|
+
|
6559
|
+
|
5680
6560
|
def set_nullvalue_in_mask(self):
|
5681
6561
|
""" Set nullvalue in masked cells """
|
5682
6562
|
if self.array is None:
|
@@ -5736,6 +6616,29 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5736
6616
|
y, x = np.meshgrid(y_discr, x_discr)
|
5737
6617
|
return x, y
|
5738
6618
|
|
6619
|
+
def crop_masked_at_edges(self):
|
6620
|
+
|
6621
|
+
"""
|
6622
|
+
Crop the array to remove masked cells at the edges of the array
|
6623
|
+
:return: cropped array, WolfArray instance
|
6624
|
+
|
6625
|
+
"""
|
6626
|
+
|
6627
|
+
# Get max indexes
|
6628
|
+
Existing_indexes = np.argwhere(self.array.mask!=True)
|
6629
|
+
Max_index = np.max(Existing_indexes, 0)
|
6630
|
+
Min_index = np.min(Existing_indexes, 0)
|
6631
|
+
|
6632
|
+
# convert index in location
|
6633
|
+
xMax, yMax = self.convert_ij2xy_np(Max_index.reshape((1,2)))
|
6634
|
+
xMin, yMin = self.convert_ij2xy_np(Min_index.reshape((1,2)))
|
6635
|
+
|
6636
|
+
# crop
|
6637
|
+
nbx=np.ceil((xMax[0]-xMin[0])/self.dx).astype(int)+1 #+1 otherwise you remove one line
|
6638
|
+
nby=np.ceil((yMax[0]-yMin[0])/self.dy).astype(int)+1 #+1 otherwise you remove one column
|
6639
|
+
return self.crop(int(Min_index[0]),int(Min_index[1]),int(nbx),int(nby))
|
6640
|
+
|
6641
|
+
|
5739
6642
|
def crop(self, i_start:int, j_start:int, nbx:int, nby:int, k_start:int=1, nbz:int=1):
|
5740
6643
|
"""
|
5741
6644
|
Crop the array
|
@@ -5779,6 +6682,44 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
5779
6682
|
|
5780
6683
|
return newWolfArray
|
5781
6684
|
|
6685
|
+
def extend(self, x_ext:int, y_ext:int):
|
6686
|
+
|
6687
|
+
# crop is the opposite
|
6688
|
+
|
6689
|
+
assert x_ext >= 0 and y_ext >= 0
|
6690
|
+
assert self.nbdims == 2, "Only 2D arrays are supported"
|
6691
|
+
|
6692
|
+
# Remember WolfArrays are masked. Therefore
|
6693
|
+
# we need to extend mask. In this case, not specifying
|
6694
|
+
# anything will expand the mask with "dont mask"
|
6695
|
+
# values.
|
6696
|
+
|
6697
|
+
# extend vertically
|
6698
|
+
ex = self.array
|
6699
|
+
|
6700
|
+
if x_ext > 0:
|
6701
|
+
# dtype is important: it allows to keep a Fortran friendly
|
6702
|
+
# type I think.
|
6703
|
+
ex = ma.append(
|
6704
|
+
ex,
|
6705
|
+
np.array([0] * ex.shape[1] * x_ext, dtype=ex.dtype).reshape((x_ext, -1)),
|
6706
|
+
axis=0,
|
6707
|
+
)
|
6708
|
+
self.nbx += x_ext
|
6709
|
+
|
6710
|
+
# extend horizontally
|
6711
|
+
if y_ext > 0:
|
6712
|
+
ex = ma.append(
|
6713
|
+
ex,
|
6714
|
+
np.array([0] * ex.shape[0] * y_ext, dtype=ex.dtype).reshape((-1, y_ext)),
|
6715
|
+
axis=1,
|
6716
|
+
)
|
6717
|
+
self.nby += y_ext
|
6718
|
+
|
6719
|
+
self.array = ex
|
6720
|
+
|
6721
|
+
self.mask_data(self.nullvalue)
|
6722
|
+
|
5782
6723
|
def extremum(self, which:Literal['min','max']='min'):
|
5783
6724
|
""" Return the extremum value """
|
5784
6725
|
|
@@ -6354,6 +7295,55 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6354
7295
|
self.array.mask[:,:width] = True
|
6355
7296
|
self.array.mask[:,-width:] = True
|
6356
7297
|
|
7298
|
+
def as_WolfArray(self, abs:bool=True) -> "WolfArray":
|
7299
|
+
"""
|
7300
|
+
Return a WolfArray object from this WolfArray
|
7301
|
+
"""
|
7302
|
+
|
7303
|
+
NewArray = WolfArray(mold=self)
|
7304
|
+
|
7305
|
+
if abs:
|
7306
|
+
NewArray.origx += self.translx
|
7307
|
+
NewArray.origy += self.transly
|
7308
|
+
NewArray.translx = 0.
|
7309
|
+
NewArray.transly = 0.
|
7310
|
+
|
7311
|
+
return NewArray
|
7312
|
+
|
7313
|
+
def get_unique_values(self):
|
7314
|
+
"""
|
7315
|
+
Return unique values in the array
|
7316
|
+
"""
|
7317
|
+
|
7318
|
+
unique = np.ma.unique(self.array)
|
7319
|
+
|
7320
|
+
while unique[-1] is np.ma.masked and len(unique) > 1:
|
7321
|
+
unique = unique[:-1]
|
7322
|
+
|
7323
|
+
return unique
|
7324
|
+
|
7325
|
+
def map_values(self, keys_vals:dict, default:float=None):
|
7326
|
+
"""
|
7327
|
+
Apply a mapping to the array
|
7328
|
+
"""
|
7329
|
+
|
7330
|
+
vals = self.get_unique_values()
|
7331
|
+
|
7332
|
+
if default is not None:
|
7333
|
+
self.array.data[:,:] = default
|
7334
|
+
|
7335
|
+
for val in vals:
|
7336
|
+
if val not in keys_vals:
|
7337
|
+
logging.warning(f"Value {val} not in keys_vals")
|
7338
|
+
continue
|
7339
|
+
|
7340
|
+
for key, val in keys_vals.items():
|
7341
|
+
self.array.data[self.array.data == key] = val
|
7342
|
+
|
7343
|
+
self.mask_data(self.nullvalue)
|
7344
|
+
|
7345
|
+
self.reset_plot()
|
7346
|
+
|
6357
7347
|
class WolfArrayMB(WolfArray):
|
6358
7348
|
"""
|
6359
7349
|
Matrice multiblocks
|
@@ -6366,12 +7356,133 @@ class WolfArrayMB(WolfArray):
|
|
6366
7356
|
|
6367
7357
|
def __init__(self, fname=None, mold=None, masknull=True, crop=None, whichtype=WOLF_ARRAY_MB_SINGLE, preload=True,
|
6368
7358
|
create=False, mapviewer=None, nullvalue=0, srcheader=None):
|
6369
|
-
|
7359
|
+
|
6370
7360
|
super().__init__(fname, mold, masknull, crop, whichtype, preload, create, mapviewer, nullvalue, srcheader)
|
6371
|
-
|
7361
|
+
|
7362
|
+
self._active_blocks = 0
|
7363
|
+
|
7364
|
+
if self.myblocks is None:
|
7365
|
+
self.myblocks = {}
|
7366
|
+
|
7367
|
+
def extract_selection(self):
|
7368
|
+
""" Extract the current selection """
|
7369
|
+
|
7370
|
+
newarrays = []
|
7371
|
+
|
7372
|
+
for curblock in self.myblocks.values():
|
7373
|
+
newblock = curblock.SelectionData.get_newarray()
|
7374
|
+
|
7375
|
+
if newblock is not None:
|
7376
|
+
newarrays.append(newblock)
|
7377
|
+
|
7378
|
+
if len(newarrays) == 0:
|
7379
|
+
logging.warning(_('No selection to extract'))
|
7380
|
+
return None
|
7381
|
+
|
7382
|
+
newMBarray = WolfArrayMB()
|
7383
|
+
for newarray in newarrays:
|
7384
|
+
newMBarray.add_block(newarray, force_idx=True)
|
7385
|
+
|
7386
|
+
mapviewer = self.get_mapviewer()
|
7387
|
+
|
7388
|
+
if mapviewer is not None:
|
7389
|
+
mapviewer.add_object('array', newobj = newarray, ToCheck = True, id = self.idx + '_extracted')
|
7390
|
+
|
7391
|
+
|
7392
|
+
@property
|
7393
|
+
def nullvalue(self) -> float:
|
7394
|
+
""" Return the null value """
|
7395
|
+
|
7396
|
+
return self._nullvalue
|
7397
|
+
|
7398
|
+
@nullvalue.setter
|
7399
|
+
def nullvalue(self, value:float):
|
7400
|
+
""" Set the null value """
|
7401
|
+
|
7402
|
+
self._nullvalue = value
|
7403
|
+
|
7404
|
+
if self.myblocks is not None:
|
7405
|
+
for curblock in self.myblocks.values():
|
7406
|
+
curblock.nullvalue = value
|
7407
|
+
|
7408
|
+
def add_ops_sel(self):
|
7409
|
+
""" Add operations and selection manager to all blocks """
|
7410
|
+
|
7411
|
+
super().add_ops_sel()
|
7412
|
+
|
7413
|
+
if self.myblocks is None:
|
7414
|
+
self.myblocks = {}
|
7415
|
+
|
7416
|
+
for curblock in self.myblocks.values():
|
7417
|
+
curblock.add_ops_sel()
|
7418
|
+
|
7419
|
+
def filter_zone(self, set_null:bool = False):
|
7420
|
+
"""
|
7421
|
+
Filtre des zones et conservation de celles pour lesquelles des
|
7422
|
+
mailles sont sélectionnées
|
7423
|
+
|
7424
|
+
"""
|
7425
|
+
|
7426
|
+
for curblock in self.myblocks.values():
|
7427
|
+
curblock.filter_zone(set_null, reset_plot=False)
|
7428
|
+
|
7429
|
+
self.reset_plot()
|
7430
|
+
|
7431
|
+
def labelling(self):
|
7432
|
+
"""
|
7433
|
+
Labelling of the array using Scipy
|
7434
|
+
|
7435
|
+
"""
|
7436
|
+
|
7437
|
+
for curblock in self.myblocks.values():
|
7438
|
+
curblock.labelling(reset_plot=False)
|
7439
|
+
|
7440
|
+
self.reset_plot()
|
7441
|
+
|
7442
|
+
def interpolate_on_polygon(self, working_vector: vector, method:Literal["nearest", "linear", "cubic"]="linear"):
|
7443
|
+
"""
|
7444
|
+
Interpolation sous un polygone
|
7445
|
+
|
7446
|
+
L'interpolation a lieu :
|
7447
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
7448
|
+
- dans les mailles contenues dans le polygone sinon
|
7449
|
+
|
7450
|
+
On utilise ensuite "griddata" pour interpoler les altitudes des mailles
|
7451
|
+
depuis les vertices 3D du polygone
|
7452
|
+
"""
|
7453
|
+
|
7454
|
+
for curblock in self.myblocks.values():
|
7455
|
+
curblock.interpolate_on_polygon(working_vector, method)
|
7456
|
+
|
7457
|
+
def interpolate_on_polygons(self, working_zone: zone, method:Literal["nearest", "linear", "cubic"]="linear"):
|
7458
|
+
|
7459
|
+
for curvector in working_zone.myvectors:
|
7460
|
+
self.interpolate_on_polygon(curvector, method)
|
7461
|
+
|
7462
|
+
def interpolate_on_polyline(self, working_vector:vector, usemask=True):
|
7463
|
+
"""
|
7464
|
+
Interpolation sous une polyligne
|
7465
|
+
|
7466
|
+
L'interpolation a lieu :
|
7467
|
+
- uniquement dans les mailles sélectionnées si elles existent
|
7468
|
+
- dans les mailles sous la polyligne sinon
|
7469
|
+
|
7470
|
+
On utilise ensuite "interpolate" de shapely pour interpoler les altitudes des mailles
|
7471
|
+
depuis les vertices 3D de la polyligne
|
7472
|
+
"""
|
7473
|
+
|
7474
|
+
for curblock in self.myblocks.values():
|
7475
|
+
curblock.interpolate_on_polyline(working_vector, usemask)
|
7476
|
+
|
7477
|
+
def interpolate_on_polylines(self, working_zone:zone, usemask=True):
|
7478
|
+
""" Interpolation sous les polylignes d'une même zone """
|
7479
|
+
|
7480
|
+
for curvec in working_zone.myvectors:
|
7481
|
+
self.interpolate_on_polyline(curvec, usemask)
|
6372
7482
|
|
6373
7483
|
def check_bounds_ij(self, i:int, j:int):
|
6374
7484
|
"""Check if i and j are inside the array bounds"""
|
7485
|
+
|
6375
7486
|
x,y = self.get_xy_from_ij(i,j)
|
6376
7487
|
return self.check_bounds_xy(x,y)
|
6377
7488
|
|
@@ -6468,6 +7579,8 @@ class WolfArrayMB(WolfArray):
|
|
6468
7579
|
self.loaded = True
|
6469
7580
|
else:
|
6470
7581
|
raise Exception(_(f"Trying to load an array that doesn't exist ({self.filename})"))
|
7582
|
+
else:
|
7583
|
+
logging.info(_('Array already loaded'))
|
6471
7584
|
|
6472
7585
|
def uncheck_plot(self, unload:bool=True, forceresetOGL:bool=False, askquestion:bool=True):
|
6473
7586
|
""" Uncheck plot and apply to each block """
|
@@ -6491,6 +7604,8 @@ class WolfArrayMB(WolfArray):
|
|
6491
7604
|
|
6492
7605
|
self.myblocks = {}
|
6493
7606
|
self.loaded = False
|
7607
|
+
else:
|
7608
|
+
logging.info(_('Array not unloaded'))
|
6494
7609
|
|
6495
7610
|
def mask_data(self, value):
|
6496
7611
|
""" Mask cells where values are equal to `value`"""
|
@@ -6759,6 +7874,15 @@ class WolfArrayMB(WolfArray):
|
|
6759
7874
|
self.plotting = False
|
6760
7875
|
self.mimic_plotdata()
|
6761
7876
|
|
7877
|
+
# Plot selected nodes
|
7878
|
+
if self.mngselection is not None:
|
7879
|
+
self.mngselection.plot_selection()
|
7880
|
+
|
7881
|
+
# Plot zones attached to array
|
7882
|
+
if self.myops is not None:
|
7883
|
+
self.myops.myzones.plot()
|
7884
|
+
|
7885
|
+
|
6762
7886
|
def fillonecellgrid(self, curscale, loci, locj, force=False):
|
6763
7887
|
for curblock in self.myblocks.values():
|
6764
7888
|
curblock.fillonecellgrid(curscale, loci, locj, force)
|
@@ -7067,16 +8191,20 @@ class WolfArrayMB(WolfArray):
|
|
7067
8191
|
def allocate_ressources(self):
|
7068
8192
|
""" Allocate memory ressources """
|
7069
8193
|
|
7070
|
-
if
|
7071
|
-
|
7072
|
-
|
7073
|
-
self.myblocks[key] = WolfArray(srcheader=curhead, whichtype=WOLF_ARRAY_FULL_SINGLE)
|
7074
|
-
elif self.wolftype == WOLF_ARRAY_MB_INTEGER:
|
7075
|
-
self.myblocks[key] = WolfArray(srcheader=curhead, whichtype=WOLF_ARRAY_FULL_INTEGER)
|
8194
|
+
if self.myblocks is None:
|
8195
|
+
logging.warning("No blocks to allocate")
|
8196
|
+
else:
|
7076
8197
|
|
7077
|
-
|
7078
|
-
self.
|
7079
|
-
|
8198
|
+
if len(self.myblocks)==0:
|
8199
|
+
for id, (key, curhead) in enumerate(self.head_blocks.items()):
|
8200
|
+
if self.wolftype == WOLF_ARRAY_MB_SINGLE:
|
8201
|
+
self.myblocks[key] = WolfArray(srcheader=curhead, whichtype=WOLF_ARRAY_FULL_SINGLE)
|
8202
|
+
elif self.wolftype == WOLF_ARRAY_MB_INTEGER:
|
8203
|
+
self.myblocks[key] = WolfArray(srcheader=curhead, whichtype=WOLF_ARRAY_FULL_INTEGER)
|
8204
|
+
|
8205
|
+
self.myblocks[key].isblock = True
|
8206
|
+
self.myblocks[key].blockindex = id
|
8207
|
+
self.myblocks[key].idx = key
|
7080
8208
|
|
7081
8209
|
def set_header_from_added_blocks(self):
|
7082
8210
|
""" Set header from blocks """
|
@@ -7213,18 +8341,26 @@ class WolfArrayMB(WolfArray):
|
|
7213
8341
|
logging.debug(f"Block {curblock.idx} is empty or totally masked.")
|
7214
8342
|
|
7215
8343
|
return newArray
|
8344
|
+
|
8345
|
+
|
7216
8346
|
class WolfArrayMNAP(WolfArrayMB):
|
7217
8347
|
"""
|
7218
8348
|
Matrice MNAP d'une modélisation WOLF2D
|
7219
8349
|
|
7220
|
-
Elle contient toutes les informations de maillage
|
8350
|
+
Elle contient toutes les informations de maillage en Multi-blocks
|
8351
|
+
ainsi que les relations de voisinage de blocs.
|
8352
|
+
|
8353
|
+
Surcharge de WolfArrayMB avec modification des opérations de lecture/écriture
|
8354
|
+
car le fichier est au format TEXTE/ASCII et d'une structure spécifique.
|
8355
|
+
|
7221
8356
|
"""
|
8357
|
+
|
7222
8358
|
# Each zone will have the contour of one block.
|
7223
8359
|
contour: Zones
|
7224
8360
|
|
7225
8361
|
def __init__(self, fname=None, mold=None, masknull=True, crop=None):
|
7226
8362
|
super().__init__(fname, mold, masknull, crop)
|
7227
|
-
|
8363
|
+
|
7228
8364
|
|
7229
8365
|
def write_all(self):
|
7230
8366
|
|
@@ -7259,23 +8395,38 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7259
8395
|
f.write(padf(v.x) + padf(v.y) + "\n")
|
7260
8396
|
|
7261
8397
|
def read_data(self):
|
7262
|
-
|
8398
|
+
|
8399
|
+
# Vérification de l'existence de certains attributs
|
8400
|
+
if self.myblocks is None:
|
8401
|
+
self.myblocks = {}
|
8402
|
+
|
8403
|
+
# une matrice WolfArrayMB n'a pas de contour -> ajout d'un attribut spécifique
|
8404
|
+
self.contour = Zones()
|
8405
|
+
|
8406
|
+
if Path(self.filename + '.mnap').exists():
|
8407
|
+
|
7263
8408
|
with open(self.filename + '.mnap') as f:
|
8409
|
+
|
8410
|
+
# Lecture au format texte
|
7264
8411
|
lines = f.read().splitlines()
|
7265
8412
|
|
8413
|
+
# nombre de blocks dans la première ligne
|
7266
8414
|
nb_blocks = abs(int(lines[0]))
|
7267
|
-
self.contour = Zones()
|
7268
8415
|
|
7269
8416
|
decal = 1
|
7270
8417
|
for i in range(nb_blocks):
|
8418
|
+
# bouclage sur chque block
|
7271
8419
|
curkey = getkeyblock(i)
|
7272
|
-
|
8420
|
+
|
8421
|
+
curarray = WolfArray(whichtype=WOLF_ARRAY_FULL_INTEGER8)
|
7273
8422
|
self.myblocks[curkey] = curarray
|
7274
8423
|
|
7275
|
-
curarray.wolftype
|
8424
|
+
assert curarray.wolftype == WOLF_ARRAY_FULL_INTEGER8, "Type de block incorrect"
|
8425
|
+
|
7276
8426
|
curarray.isblock = True
|
7277
8427
|
curarray.blockindex = i
|
7278
8428
|
|
8429
|
+
# Recherche des informations de maillage - dx, dy, origx, origy, nbx, nby
|
7279
8430
|
tmp = re.sub('\\s+', ' ', lines[decal].strip()).split(' ')
|
7280
8431
|
curarray.dx = float(tmp[0])
|
7281
8432
|
curarray.dy = float(tmp[1])
|
@@ -7291,6 +8442,8 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7291
8442
|
curarray.nby = int(tmp[1])
|
7292
8443
|
|
7293
8444
|
decal += 4
|
8445
|
+
|
8446
|
+
#Lecture de la matrice de maillage pour le block en cours
|
7294
8447
|
myarray = []
|
7295
8448
|
|
7296
8449
|
for j in range(curarray.nby):
|
@@ -7304,6 +8457,7 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7304
8457
|
|
7305
8458
|
curarray.array = np.flipud(np.ma.asarray(myarray, order='F')).transpose()
|
7306
8459
|
|
8460
|
+
#Lecture du contour de block
|
7307
8461
|
curzone = zone(name=curkey)
|
7308
8462
|
contourblock = vector(name='contour')
|
7309
8463
|
|
@@ -7320,6 +8474,9 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7320
8474
|
curarray.translx = self.translx + self.origx
|
7321
8475
|
curarray.transly = self.transly + self.origy
|
7322
8476
|
|
8477
|
+
# Remplissagze du header
|
8478
|
+
# --> la matrice MNAP est la référence d'une simulation 2D
|
8479
|
+
# pour obtenir les informations de maillage
|
7323
8480
|
curhead = self.head_blocks[getkeyblock(i)] = header_wolf()
|
7324
8481
|
|
7325
8482
|
curhead.nbx = curarray.nbx
|
@@ -7332,6 +8489,17 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7332
8489
|
curhead.transly = curarray.transly
|
7333
8490
|
|
7334
8491
|
def read_txt_header(self):
|
8492
|
+
"""
|
8493
|
+
Surcharge de la lecture du header
|
8494
|
+
|
8495
|
+
Il n'y a pas en tant que tel de header d'un fichier MNAP.
|
8496
|
+
|
8497
|
+
Les informations de translation sont dans le fichier ".trl".
|
8498
|
+
|
8499
|
+
Les informations de tailles de maille 'fines',
|
8500
|
+
Nbx, Nby et coordonnées d'origine sont dans le fichier ".par"
|
8501
|
+
|
8502
|
+
"""
|
7335
8503
|
|
7336
8504
|
if os.path.exists(self.filename + '.trl'):
|
7337
8505
|
with open(self.filename + '.trl') as f:
|
@@ -7349,144 +8517,5 @@ class WolfArrayMNAP(WolfArrayMB):
|
|
7349
8517
|
self.origx = float(lines[11])
|
7350
8518
|
self.origy = float(lines[12])
|
7351
8519
|
|
8520
|
+
# Imposition du type de stockage
|
7352
8521
|
self.wolftype = WOLF_ARRAY_MNAP_INTEGER
|
7353
|
-
|
7354
|
-
|
7355
|
-
class WolfArray_Sim2D(WolfArray):
|
7356
|
-
"""
|
7357
|
-
Surcharge de WolfArray pour les matrices fines de simulation
|
7358
|
-
|
7359
|
-
Objectif : lier la matrice de mask à une source commune
|
7360
|
-
|
7361
|
-
"""
|
7362
|
-
def __init__(self,
|
7363
|
-
fname:str=None,
|
7364
|
-
mold:"WolfArray"=None,
|
7365
|
-
masknull:bool=True,
|
7366
|
-
crop:list[float]=None,
|
7367
|
-
whichtype=WOLF_ARRAY_FULL_SINGLE,
|
7368
|
-
preload:bool=True,
|
7369
|
-
create:bool=False,
|
7370
|
-
mapviewer=None,
|
7371
|
-
nullvalue:float=0,
|
7372
|
-
srcheader:header_wolf=None,
|
7373
|
-
masksrc:np.ndarray=None):
|
7374
|
-
|
7375
|
-
# link to mask source
|
7376
|
-
self.masksrc = masksrc
|
7377
|
-
|
7378
|
-
# FIXME __init__ will initialize a mask of its own and so self.masksrc
|
7379
|
-
# will be ignored at this point. That's misleading, I'd thought
|
7380
|
-
# that passing a mask would wire it to this array, forever.
|
7381
|
-
super().__init__(fname, mold, masknull, crop, whichtype, preload, create, mapviewer, nullvalue, srcheader, mask_source=masksrc)
|
7382
|
-
|
7383
|
-
def check_plot(self):
|
7384
|
-
"""
|
7385
|
-
Surcharge de la fonction de vérification du plot
|
7386
|
-
|
7387
|
-
Utile notamment pour lier le masque
|
7388
|
-
"""
|
7389
|
-
self.plotted = True
|
7390
|
-
|
7391
|
-
if not self.loaded and self.filename != '':
|
7392
|
-
self.read_data()
|
7393
|
-
|
7394
|
-
if self.array is None:
|
7395
|
-
#problème à la lecture
|
7396
|
-
self.plotted=False
|
7397
|
-
return
|
7398
|
-
|
7399
|
-
if self.masksrc is not None:
|
7400
|
-
self.array.mask = self.masksrc
|
7401
|
-
|
7402
|
-
self.loaded = True
|
7403
|
-
|
7404
|
-
if self.rgb is None:
|
7405
|
-
self.updatepalette(0)
|
7406
|
-
|
7407
|
-
def read_all(self):
|
7408
|
-
"""
|
7409
|
-
Surcharge de la fonction de lecture de la matrice
|
7410
|
-
|
7411
|
-
Utile notamment puor le fichier zbin
|
7412
|
-
"""
|
7413
|
-
|
7414
|
-
if self.filename[-4:]=='zbin':
|
7415
|
-
fileold = self.filename
|
7416
|
-
|
7417
|
-
self.filename = fileold[:-4]+'top'
|
7418
|
-
|
7419
|
-
if not os.path.exists(self.filename):
|
7420
|
-
return
|
7421
|
-
|
7422
|
-
self.read_txt_header()
|
7423
|
-
self.filename = fileold
|
7424
|
-
self.read_data()
|
7425
|
-
else:
|
7426
|
-
return super().read_all()
|
7427
|
-
|
7428
|
-
def read_data(self):
|
7429
|
-
"""
|
7430
|
-
Surcharge de la fonction de lecture de la matrice
|
7431
|
-
|
7432
|
-
Utile notamment puor le fichier zbin
|
7433
|
-
"""
|
7434
|
-
|
7435
|
-
if self.filename[-4:]=='zbin':
|
7436
|
-
fileold = self.filename
|
7437
|
-
|
7438
|
-
self.filename = fileold[:-4]+'top'
|
7439
|
-
|
7440
|
-
if not os.path.exists(self.filename):
|
7441
|
-
self.filename = fileold
|
7442
|
-
return
|
7443
|
-
|
7444
|
-
self.read_data()
|
7445
|
-
toparray = self.array.copy()
|
7446
|
-
|
7447
|
-
self.filename = fileold[:-4]+'hbin'
|
7448
|
-
if not os.path.exists(self.filename):
|
7449
|
-
self.filename = fileold
|
7450
|
-
return
|
7451
|
-
|
7452
|
-
self.read_data()
|
7453
|
-
harray = self.array.copy()
|
7454
|
-
|
7455
|
-
self.array = toparray+harray
|
7456
|
-
self.array.mask = self.masksrc
|
7457
|
-
|
7458
|
-
self.filename = fileold
|
7459
|
-
else:
|
7460
|
-
return super().read_data()
|
7461
|
-
|
7462
|
-
def write_all(self):
|
7463
|
-
return super().write_all()
|
7464
|
-
|
7465
|
-
def write_array(self):
|
7466
|
-
"""
|
7467
|
-
Surcharge de la fonction d'écriture de la matrice
|
7468
|
-
|
7469
|
-
Utile notamment puor le fichier zbin
|
7470
|
-
"""
|
7471
|
-
if self.filename[-4:]=='zbin':
|
7472
|
-
fileold = self.filename
|
7473
|
-
|
7474
|
-
self.filename = fileold[:-4]+'top'
|
7475
|
-
if not os.path.exists(self.filename):
|
7476
|
-
self.filename = fileold
|
7477
|
-
return
|
7478
|
-
|
7479
|
-
zarray = self.array.copy()
|
7480
|
-
self.read_data()
|
7481
|
-
toparray = self.array.copy()
|
7482
|
-
|
7483
|
-
self.array = zarray-toparray
|
7484
|
-
self.array[np.where(self.array<0.)]=0.
|
7485
|
-
|
7486
|
-
self.filename = fileold[:-4]+'hbin'
|
7487
|
-
self.write_array()
|
7488
|
-
|
7489
|
-
self.filename = fileold
|
7490
|
-
|
7491
|
-
else:
|
7492
|
-
return super().write_array()
|