wolfhece 2.1.115__py3-none-any.whl → 2.1.116__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/PyConfig.py CHANGED
@@ -26,6 +26,8 @@ class ConfigurationKeys(Enum):
26
26
  PLAY_WELCOME_SOUND = "PlayWelcomeSound"
27
27
  TICKS_SIZE = "TicksSize"
28
28
  TICKS_BOUNDS = "TicksBounds"
29
+ TICKS_XROTATION = "TicksXRotation"
30
+ TICKS_FONTSIZE = "TicksFontSize"
29
31
  COLOR_BACKGROUND = "ColorBackground"
30
32
  ACTIVE_ARRAY_PALETTE_FOR_IMAGE = "Use active array palette for image"
31
33
  ACTIVE_RES2D_PALETTE_FOR_IMAGE = "Use active result palette for image"
@@ -72,7 +74,10 @@ class WolfConfiguration:
72
74
  ConfigurationKeys.ACTIVE_RES2D_PALETTE_FOR_IMAGE.value: False,
73
75
  ConfigurationKeys.TICKS_BOUNDS.value: True,
74
76
  ConfigurationKeys.COLOR_BACKGROUND.value: [255, 255, 255, 255],
75
- ConfigurationKeys.ASSEMBLY_IMAGES.value: 0
77
+ ConfigurationKeys.ASSEMBLY_IMAGES.value: 0,
78
+ ConfigurationKeys.TICKS_XROTATION.value: 30.,
79
+ ConfigurationKeys.TICKS_FONTSIZE.value: 12
80
+
76
81
  }
77
82
  self._types = {
78
83
  ConfigurationKeys.VERSION.value: int,
@@ -82,7 +87,9 @@ class WolfConfiguration:
82
87
  ConfigurationKeys.ACTIVE_RES2D_PALETTE_FOR_IMAGE.value: bool,
83
88
  ConfigurationKeys.TICKS_BOUNDS.value: bool,
84
89
  ConfigurationKeys.COLOR_BACKGROUND.value: list,
85
- ConfigurationKeys.ASSEMBLY_IMAGES.value: int
90
+ ConfigurationKeys.ASSEMBLY_IMAGES.value: int,
91
+ ConfigurationKeys.TICKS_XROTATION.value: float,
92
+ ConfigurationKeys.TICKS_FONTSIZE.value: int
86
93
  }
87
94
 
88
95
  self._check_config()
@@ -140,6 +147,8 @@ class GlobalOptionsDialog(wx.Dialog):
140
147
  self.cfg_active_array_pal.SetValue(configuration[ConfigurationKeys.ACTIVE_ARRAY_PALETTE_FOR_IMAGE])
141
148
  self.cfg_active_res_pal.SetValue(configuration[ConfigurationKeys.ACTIVE_RES2D_PALETTE_FOR_IMAGE])
142
149
  self.cfg_assembly_images.SetSelection(configuration[ConfigurationKeys.ASSEMBLY_IMAGES])
150
+ self.cfg_ticks_xrotation.SetValue(str(configuration[ConfigurationKeys.TICKS_XROTATION]))
151
+ self.cfg_ticks_fontsize.SetValue(str(configuration[ConfigurationKeys.TICKS_FONTSIZE]))
143
152
 
144
153
  def pull_configuration(self, configuration):
145
154
  configuration[ConfigurationKeys.PLAY_WELCOME_SOUND] = self.cfg_welcome_voice.IsChecked()
@@ -149,6 +158,8 @@ class GlobalOptionsDialog(wx.Dialog):
149
158
  configuration[ConfigurationKeys.ACTIVE_ARRAY_PALETTE_FOR_IMAGE] = self.cfg_active_array_pal.IsChecked()
150
159
  configuration[ConfigurationKeys.ACTIVE_RES2D_PALETTE_FOR_IMAGE] = self.cfg_active_res_pal.IsChecked()
151
160
  configuration[ConfigurationKeys.ASSEMBLY_IMAGES] = self.cfg_assembly_images.GetSelection()
161
+ configuration[ConfigurationKeys.TICKS_XROTATION] = float(self.cfg_ticks_xrotation.Value)
162
+ configuration[ConfigurationKeys.TICKS_FONTSIZE] = int(self.cfg_ticks_fontsize.Value)
152
163
 
153
164
  def InitUI(self):
154
165
 
@@ -193,10 +204,26 @@ class GlobalOptionsDialog(wx.Dialog):
193
204
  self.label_ticks_size = wx.StaticText(pnl, label=_('Default ticks size [m]'))
194
205
  self.cfg_ticks_size = wx.TextCtrl(pnl, value='500.',style = wx.TE_CENTRE )
195
206
 
207
+ self.label_ticks_xrotation = wx.StaticText(pnl, label=_('X rotation of ticks [°]'))
208
+ self.cfg_ticks_xrotation = wx.TextCtrl(pnl, value='30.',style = wx.TE_CENTRE )
209
+
210
+ self.label_ticks_fontsize = wx.StaticText(pnl, label=_('Font size of ticks'))
211
+ self.cfg_ticks_fontsize = wx.TextCtrl(pnl, value='12',style = wx.TE_CENTRE )
212
+
196
213
  hboxticks.Add(self.label_ticks_size, 1, wx.EXPAND)
197
214
  hboxticks.Add(self.cfg_ticks_size, 1, wx.EXPAND, 5)
198
215
  sbs.Add(hboxticks, 1, wx.EXPAND,5)
199
216
 
217
+ hboxticksxrotation = wx.BoxSizer(wx.HORIZONTAL)
218
+ hboxticksxrotation.Add(self.label_ticks_xrotation, 1, wx.EXPAND)
219
+ hboxticksxrotation.Add(self.cfg_ticks_xrotation, 1, wx.EXPAND, 5)
220
+ sbs.Add(hboxticksxrotation, 1, wx.EXPAND,5)
221
+
222
+ hboxticksfontsize = wx.BoxSizer(wx.HORIZONTAL)
223
+ hboxticksfontsize.Add(self.label_ticks_fontsize, 1, wx.EXPAND)
224
+ hboxticksfontsize.Add(self.cfg_ticks_fontsize, 1, wx.EXPAND, 5)
225
+ sbs.Add(hboxticksfontsize, 1, wx.EXPAND,5)
226
+
200
227
  self.cfg_ticks_bounds = wx.CheckBox(pnl, label=_('Add bounds to ticks'))
201
228
  self.cfg_ticks_bounds.SetToolTip(_('If not checked, the extreme values of the ticks will not be displayed'))
202
229
  sbs.Add(self.cfg_ticks_bounds, 1, wx.EXPAND, 5)
wolfhece/PyDraw.py CHANGED
@@ -2283,21 +2283,33 @@ class WolfMapViewer(wx.Frame):
2283
2283
  dlg.Destroy()
2284
2284
  return
2285
2285
 
2286
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
2286
+ pgbar = wx.ProgressDialog(_('Setting epsilon'), _('Setting epsilon'), maximum = len(self.myres2D), parent=self, style = wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
2287
+
2288
+ for id, curmodel in enumerate(self.iterator_over_objects(draw_type.RES2D)):
2287
2289
  curmodel: Wolfresults_2D
2288
2290
  curmodel.epsilon = neweps
2289
2291
  curmodel._epsilon_default = neweps
2290
2292
  curmodel.read_oneresult(curmodel.current_result)
2291
2293
  curmodel.set_currentview()
2292
2294
 
2295
+ pgbar.Update(id, _('Setting epsilon for result {}'.format(curmodel.idx)))
2296
+
2297
+ pgbar.Destroy()
2298
+
2293
2299
  elif itemlabel == _("Filter independent"):
2294
2300
 
2295
2301
  self.menu_filter_independent.IsChecked = not self.menu_filter_independent.IsChecked
2296
2302
 
2297
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
2303
+ pgbar = wx.ProgressDialog(_('Filtering independent zones'), _('Filtering independent zones'), maximum = len(self.myres2D), parent=self, style = wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
2304
+
2305
+ for id, curmodel in enumerate(self.iterator_over_objects(draw_type.RES2D)):
2298
2306
  curmodel: Wolfresults_2D
2299
2307
  curmodel.to_filter_independent = not self.menu_filter_independent.IsChecked
2300
2308
 
2309
+ pgbar.Update(id, _('Filtering independent zones for result {}'.format(curmodel.idx)))
2310
+
2311
+ pgbar.Destroy()
2312
+
2301
2313
  # elif itemlabel == _("Manage boundary conditions..."):
2302
2314
 
2303
2315
  # if self.active_res2d is not None:
@@ -2988,6 +3000,26 @@ class WolfMapViewer(wx.Frame):
2988
3000
  else:
2989
3001
  return config[ConfigurationKeys.TICKS_SIZE]
2990
3002
 
3003
+ @property
3004
+ def ticks_xrotation(self) -> float:
3005
+ """ Return the ticks x rotation from configs """
3006
+
3007
+ config = self.get_configuration()
3008
+ if config is None:
3009
+ return 30.
3010
+ else:
3011
+ return config[ConfigurationKeys.TICKS_XROTATION]
3012
+
3013
+ @property
3014
+ def ticks_fontsize(self) -> int:
3015
+ """ Return the ticks font size from configs """
3016
+
3017
+ config = self.get_configuration()
3018
+ if config is None:
3019
+ return 14
3020
+ else:
3021
+ return config[ConfigurationKeys.TICKS_FONTSIZE]
3022
+
2991
3023
  @property
2992
3024
  def assembly_mode(self) -> str:
2993
3025
  """ Return the assembly mode from configs """
@@ -3182,187 +3214,10 @@ class WolfMapViewer(wx.Frame):
3182
3214
  return
3183
3215
  self.start_action('rotate triangles', 'Rotate the current triangulation -- Please select 1 point for the center')
3184
3216
 
3185
- def copy_canvasogl(self, mpl:bool= True, ds:float= 0., figsizes= [10.,10.], palette:wolfpalette = None):
3186
- """
3187
- Generate image based on UI context and copy to the Clipboard
3188
3217
 
3189
- :param mpl: Using Matplolib as renderer. Defaults to True.
3190
- :type mpl: bool, optional
3191
- :parem ds: Ticks size. Defaults to 0..
3192
- :type ds: float, optional
3193
- :parem figsizes: fig size in inches
3194
- :type figsizes: list, optional
3195
- """
3196
-
3197
- if wx.TheClipboard.Open():
3198
- self.Paint()
3199
-
3200
- if self.SetCurrentContext():
3201
-
3202
- myimage = self.get_canvas_as_image()
3203
-
3204
- # # Récupération du buffer OpenGL
3205
- # glPixelStorei(GL_PACK_ALIGNMENT, 1)
3206
- # data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3207
- # # Création d'une image sur base du buffer
3208
- # myimage: Image.Image
3209
- # myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3210
- # # On tranpose car OpenGL travaille avec comme référence le coin inférieur gauche
3211
- # myimage = myimage.transpose(1)
3212
-
3213
- metadata = PngInfo()
3214
- metadata.add_text('xmin', str(self.xmin))
3215
- metadata.add_text('ymin', str(self.ymin))
3216
- metadata.add_text('xmax', str(self.xmax))
3217
- metadata.add_text('ymax', str(self.ymax))
3218
-
3219
- if mpl:
3220
- if ds == 0.:
3221
- ds = self.ticks_size # Global parameters
3222
-
3223
- if ds == 0.:
3224
- ds = 100.
3225
-
3226
- nb_ticks_x = (self.xmax - self.xmin) // ds
3227
- nb_ticks_y = (self.ymax - self.ymin) // ds
3228
-
3229
- if nb_ticks_x > 10 or nb_ticks_y > 10:
3230
- logging.error(_('Too many ticks for the image. Please raise the ticks size in the global options.'))
3231
- return
3232
-
3233
- # Création d'une graphique Matplotlib
3234
- extent = (self.xmin, self.xmax, self.ymin, self.ymax)
3235
- fig, ax = plt.subplots(1, 1)
3236
-
3237
- w, h = [self.width, self.height]
3238
-
3239
- # neww = figsizes[0]/figsizes[1] *h
3240
- neww = figsizes[0]
3241
- newh = h/w * figsizes[0]
3242
-
3243
- fig.set_size_inches(neww, newh)
3244
-
3245
- pos = ax.imshow(myimage,
3246
- origin='upper',
3247
- extent=extent)
3248
-
3249
- x1 = np.ceil((self.xmin // ds) * ds)
3250
- if x1 < self.xmin:
3251
- x1 += ds
3252
- x2 = int((self.xmax // ds) * ds)
3253
- if x2 > self.xmax:
3254
- x2 -= ds
3255
- y1 = np.ceil((self.ymin // ds) * ds)
3256
- if y1 < self.ymin:
3257
- y1 += ds
3258
- y2 = int((self.ymax // ds) * ds)
3259
- if y2 > self.ymax:
3260
- y2 -= ds
3261
-
3262
- x_label_list = np.linspace(x1, x2, int((x2 - x1) / ds) + 1, True)
3263
- if self.ticks_bounds:
3264
- x_label_list = np.insert(x_label_list, 0, self.xmin)
3265
- x_label_list = np.insert(x_label_list, -1, self.xmax)
3266
- x_label_list = np.unique(x_label_list)
3267
-
3268
- y_label_list = np.linspace(y1, y2, int((y2 - y1) / ds) + 1, True)
3269
- if self.ticks_bounds:
3270
- y_label_list = np.insert(y_label_list, 0, self.ymin)
3271
- y_label_list = np.insert(y_label_list, -1, self.ymax)
3272
- y_label_list = np.unique(y_label_list)
3273
-
3274
- ax.set_xticks(x_label_list)
3275
- ax.set_yticks(y_label_list)
3276
-
3277
- ax.set_xticklabels(plt.FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize=14, rotation=30)
3278
- ax.set_yticklabels(plt.FormatStrFormatter('%.1f').format_ticks(y_label_list), fontsize=14)
3279
-
3280
- ax.set_xlabel('X [m]')
3281
- ax.set_ylabel('Y [m]')
3282
-
3283
- #création de 2 buffers
3284
- buf = io.BytesIO()
3285
- #sauvegarde de la figure au format png
3286
- fig.tight_layout()
3287
- fig.savefig(buf, format='png')
3288
-
3289
- #déplacement au début du buffer
3290
- buf.seek(0)
3291
- #lecture du buffer et conversion en image avec PIL
3292
- im = Image.open(buf)
3293
-
3294
- if palette is None:
3295
- palette = self.palette_for_copy
3296
- # if self.active_array is not None:
3297
- # palette = self.active_array.mypal
3298
- # elif self.active_res2d is not None:
3299
- # palette = self.active_res2d.mypal
3300
-
3301
- if palette is not None:
3302
- if palette.values is not None:
3303
- bufpal = io.BytesIO()
3304
- palette.export_image(bufpal,'v')
3305
- bufpal.seek(0)
3306
-
3307
- #lecture du buffer et conversion en image avec PIL
3308
- impal = Image.open(bufpal)
3309
- impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
3310
-
3311
- imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
3312
-
3313
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3314
- imnew.paste(im.convert('RGB'),(0,0))
3315
- imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
3316
- im=imnew
3317
- else:
3318
- imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3319
-
3320
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3321
- imnew.paste(im.convert('RGB'),(0,0))
3322
- im=imnew
3323
- else:
3324
- imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3325
-
3326
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3327
- imnew.paste(im.convert('RGB'),(0,0))
3328
- im=imnew
3329
-
3330
- #création d'un objet bitmap wx
3331
- wxbitmap = wx.Bitmap().FromBuffer(im.width,im.height,im.tobytes())
3332
-
3333
- # objet wx exportable via le clipboard
3334
- dataobj = wx.BitmapDataObject()
3335
- dataobj.SetBitmap(wxbitmap)
3336
-
3337
- wx.TheClipboard.SetData(dataobj)
3338
- wx.TheClipboard.Close()
3339
-
3340
- fig.set_visible(False)
3341
-
3342
- buf.close()
3343
-
3344
- return fig, ax, im
3345
-
3346
- else:
3347
- """ Création d'un objet bitmap wx sur base du canvas
3348
- et copie dans le clipboard
3349
- """
3350
- # wxbitmap = wx.Bitmap().FromBuffer(myimage.width,myimage.height,myimage.tobytes())
3351
- wxbitmap = wx.Bitmap().FromBufferRGBA(myimage.width,myimage.height,myimage.tobytes())
3352
-
3353
- # objet wx exportable via le clipboard
3354
- dataobj = wx.BitmapDataObject()
3355
- dataobj.SetBitmap(wxbitmap)
3356
-
3357
- wx.TheClipboard.SetData(dataobj)
3358
- wx.TheClipboard.Close()
3359
-
3360
- return myimage
3361
-
3362
- else:
3363
- wx.MessageBox("Can't open the clipboard", "Error")
3364
-
3365
- def display_canvasogl(self,mpl =True, ds=0., fig: Figure = None, ax: Axes = None, clear = True, redraw =True, palette=False, title=''):
3218
+ def display_canvasogl(self, mpl =True,
3219
+ ds=0., fig: Figure = None, ax: Axes = None,
3220
+ clear = True, redraw =True, palette=False, title=''):
3366
3221
  """
3367
3222
  This method takes a matplotlib figure and axe and,
3368
3223
  returns a clear screenshot of the information displayed in the wolfpy GUI.
@@ -3418,19 +3273,22 @@ class WolfMapViewer(wx.Frame):
3418
3273
  myax.set_xticks(x_label_list)
3419
3274
  myax.set_yticks(y_label_list)
3420
3275
 
3421
- myax.set_xticklabels(FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize = 'xx-small', rotation = 90)
3422
- myax.set_yticklabels(FormatStrFormatter('%.1f').format_ticks(y_label_list), fontsize='xx-small')
3276
+ myax.set_xticklabels(FormatStrFormatter('%.1f').format_ticks(x_label_list),
3277
+ fontsize = self.ticks_fontsize, rotation = self.ticks_xrotation)
3278
+ myax.set_yticklabels(FormatStrFormatter('%.1f').format_ticks(y_label_list),
3279
+ fontsize = self.ticks_fontsize)
3423
3280
  myax.xaxis.set_ticks_position('top')
3424
3281
  myax.xaxis.set_label_position('top')
3425
3282
 
3426
- myax.set_xlabel('X - coordinates ($m$)')
3427
- myax.set_ylabel('Y - coordinates ($m$)')
3283
+ myax.set_xlabel('X ($m$)')
3284
+ myax.set_ylabel('Y ($m$)')
3428
3285
  myax.xaxis.set_ticks_position('bottom')
3429
3286
  myax.xaxis.set_label_position('bottom')
3430
3287
 
3431
3288
  if title!='':
3432
3289
  myax.set_title(title)
3433
3290
 
3291
+ fig.tight_layout()
3434
3292
  fig.canvas.draw()
3435
3293
  fig.canvas.flush_events()
3436
3294
 
@@ -3605,12 +3463,188 @@ class WolfMapViewer(wx.Frame):
3605
3463
 
3606
3464
  return myimage
3607
3465
 
3466
+ def copy_canvasogl(self, mpl:bool= True, ds:float= 0., figsizes= [10.,10.], palette:wolfpalette = None):
3467
+ """
3468
+ Generate image based on UI context and copy to the Clipboard
3469
+
3470
+ :param mpl: Using Matplolib as renderer. Defaults to True.
3471
+ :type mpl: bool, optional
3472
+ :parem ds: Ticks size. Defaults to 0..
3473
+ :type ds: float, optional
3474
+ :parem figsizes: fig size in inches
3475
+ :type figsizes: list, optional
3476
+ """
3477
+
3478
+ if wx.TheClipboard.Open():
3479
+ self.Paint()
3480
+
3481
+ if self.SetCurrentContext():
3482
+
3483
+ myimage = self.get_canvas_as_image()
3484
+
3485
+ metadata = PngInfo()
3486
+ metadata.add_text('xmin', str(self.xmin))
3487
+ metadata.add_text('ymin', str(self.ymin))
3488
+ metadata.add_text('xmax', str(self.xmax))
3489
+ metadata.add_text('ymax', str(self.ymax))
3490
+
3491
+ if mpl:
3492
+ if ds == 0.:
3493
+ ds = self.ticks_size # Global parameters
3494
+
3495
+ if ds == 0.:
3496
+ ds = 100.
3497
+
3498
+ nb_ticks_x = (self.xmax - self.xmin) // ds
3499
+ nb_ticks_y = (self.ymax - self.ymin) // ds
3500
+
3501
+ if nb_ticks_x > 10 or nb_ticks_y > 10:
3502
+ logging.error(_('Too many ticks for the image. Please raise the ticks size in the global options.'))
3503
+ return
3504
+
3505
+ # Création d'un graphique Matplotlib
3506
+ extent = (self.xmin, self.xmax, self.ymin, self.ymax)
3507
+ fig, ax = plt.subplots(1, 1)
3508
+
3509
+ w, h = [self.width, self.height]
3510
+
3511
+ neww = figsizes[0]
3512
+ newh = h/w * figsizes[0]
3513
+
3514
+ fig.set_size_inches(neww, newh)
3515
+
3516
+ pos = ax.imshow(myimage,
3517
+ origin='upper',
3518
+ extent=extent)
3519
+
3520
+ x1 = np.ceil((self.xmin // ds) * ds)
3521
+ if x1 < self.xmin:
3522
+ x1 += ds
3523
+ x2 = int((self.xmax // ds) * ds)
3524
+ if x2 > self.xmax:
3525
+ x2 -= ds
3526
+ y1 = np.ceil((self.ymin // ds) * ds)
3527
+ if y1 < self.ymin:
3528
+ y1 += ds
3529
+ y2 = int((self.ymax // ds) * ds)
3530
+ if y2 > self.ymax:
3531
+ y2 -= ds
3532
+
3533
+ x_label_list = np.linspace(x1, x2, int((x2 - x1) / ds) + 1, True)
3534
+ if self.ticks_bounds:
3535
+ x_label_list = np.insert(x_label_list, 0, self.xmin)
3536
+ x_label_list = np.insert(x_label_list, -1, self.xmax)
3537
+ x_label_list = np.unique(x_label_list)
3538
+
3539
+ y_label_list = np.linspace(y1, y2, int((y2 - y1) / ds) + 1, True)
3540
+ if self.ticks_bounds:
3541
+ y_label_list = np.insert(y_label_list, 0, self.ymin)
3542
+ y_label_list = np.insert(y_label_list, -1, self.ymax)
3543
+ y_label_list = np.unique(y_label_list)
3544
+
3545
+ ax.set_xticks(x_label_list)
3546
+ ax.set_yticks(y_label_list)
3547
+
3548
+ ax.set_xticklabels(plt.FormatStrFormatter('%.1f').format_ticks(x_label_list),
3549
+ fontsize = self.ticks_fontsize, rotation = self.ticks_xrotation)
3550
+ ax.set_yticklabels(plt.FormatStrFormatter('%.1f').format_ticks(y_label_list),
3551
+ fontsize = self.ticks_fontsize)
3552
+
3553
+ ax.set_xlabel('X ($m$)')
3554
+ ax.set_ylabel('Y ($m$)')
3555
+
3556
+ fig.tight_layout()
3557
+
3558
+ #création d'un'buffers
3559
+ buf = io.BytesIO()
3560
+ #sauvegarde de la figure au format png
3561
+ fig.savefig(buf, format='png')
3562
+
3563
+ #déplacement au début du buffer
3564
+ buf.seek(0)
3565
+ #lecture du buffer et conversion en image avec PIL
3566
+ im = Image.open(buf)
3567
+
3568
+ if palette is None:
3569
+ palette = self.palette_for_copy
3570
+ # if self.active_array is not None:
3571
+ # palette = self.active_array.mypal
3572
+ # elif self.active_res2d is not None:
3573
+ # palette = self.active_res2d.mypal
3574
+
3575
+ if palette is not None:
3576
+ if palette.values is not None:
3577
+ bufpal = io.BytesIO()
3578
+ palette.export_image(bufpal,'v')
3579
+ bufpal.seek(0)
3580
+
3581
+ #lecture du buffer et conversion en image avec PIL
3582
+ impal = Image.open(bufpal)
3583
+ impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
3584
+
3585
+ imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
3586
+
3587
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3588
+ imnew.paste(im.convert('RGB'),(0,0))
3589
+ imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
3590
+ im=imnew
3591
+ bufpal.close()
3592
+ else:
3593
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3594
+
3595
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3596
+ imnew.paste(im.convert('RGB'),(0,0))
3597
+ im=imnew
3598
+ else:
3599
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3600
+
3601
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3602
+ imnew.paste(im.convert('RGB'),(0,0))
3603
+ im=imnew
3604
+
3605
+ #création d'un objet bitmap wx
3606
+ wxbitmap = wx.Bitmap().FromBuffer(im.width,im.height,im.tobytes())
3607
+
3608
+ # objet wx exportable via le clipboard
3609
+ dataobj = wx.BitmapDataObject()
3610
+ dataobj.SetBitmap(wxbitmap)
3611
+
3612
+ wx.TheClipboard.SetData(dataobj)
3613
+ wx.TheClipboard.Close()
3614
+
3615
+ fig.set_visible(False)
3616
+
3617
+ buf.close()
3618
+
3619
+ return fig, ax, im
3620
+
3621
+ else:
3622
+ """ Création d'un objet bitmap wx sur base du canvas
3623
+ et copie dans le clipboard
3624
+ """
3625
+ # wxbitmap = wx.Bitmap().FromBuffer(myimage.width,myimage.height,myimage.tobytes())
3626
+ wxbitmap = wx.Bitmap().FromBufferRGBA(myimage.width,myimage.height,myimage.tobytes())
3627
+
3628
+ # objet wx exportable via le clipboard
3629
+ dataobj = wx.BitmapDataObject()
3630
+ dataobj.SetBitmap(wxbitmap)
3631
+
3632
+ wx.TheClipboard.SetData(dataobj)
3633
+ wx.TheClipboard.Close()
3634
+
3635
+ return myimage
3636
+
3637
+ else:
3638
+ wx.MessageBox("Can't open the clipboard", "Error")
3639
+
3608
3640
  def save_canvasogl(self,
3609
3641
  fn:str='',
3610
3642
  mpl:bool=True,
3611
3643
  ds:float=0.,
3612
3644
  dpi:int= 300,
3613
- add_title:bool = False):
3645
+ add_title:bool = False,
3646
+ figsizes= [10.,10.],
3647
+ arrayid_as_title:bool = False):
3614
3648
  """
3615
3649
  Sauvegarde de la fenêtre d'affichage dans un fichier
3616
3650
 
@@ -3619,6 +3653,7 @@ class WolfMapViewer(wx.Frame):
3619
3653
  :param ds: Ticks interval
3620
3654
  """
3621
3655
 
3656
+ # FIXME : SHOULD BE MERGEd WITH copy_canvasogl
3622
3657
  fn = str(fn)
3623
3658
 
3624
3659
  if fn == '':
@@ -3634,19 +3669,7 @@ class WolfMapViewer(wx.Frame):
3634
3669
  fn += '.png'
3635
3670
 
3636
3671
  if self.SetCurrentContext():
3637
- # glPixelStorei(GL_PACK_ALIGNMENT, 1)
3638
- # data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3639
- # myimage: Image.Image
3640
- # myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3641
- # myimage = myimage.transpose(1)
3642
-
3643
- myimage = self.get_canvas_as_image()
3644
-
3645
- metadata = PngInfo()
3646
- metadata.add_text('xmin', str(self.xmin))
3647
- metadata.add_text('ymin', str(self.ymin))
3648
- metadata.add_text('xmax', str(self.xmax))
3649
- metadata.add_text('ymax', str(self.ymax))
3672
+ self.Paint()
3650
3673
 
3651
3674
  if mpl:
3652
3675
  if ds == 0.:
@@ -3664,69 +3687,70 @@ class WolfMapViewer(wx.Frame):
3664
3687
  ds = float(dlg.GetValue())
3665
3688
  dlg.Destroy()
3666
3689
 
3690
+ # Création d'un graphique Matplotlib
3667
3691
  extent = (self.xmin, self.xmax, self.ymin, self.ymax)
3668
- # fig, ax = plt.subplots(1, 1)
3669
- fig,axes = plt.subplots(1,2, gridspec_kw={'width_ratios': [20, 1]})
3692
+ fig, ax = plt.subplots(1, 1)
3693
+ w, h = [self.width, self.height]
3670
3694
 
3671
- ax = axes[0]
3672
- self.display_canvasogl(fig=fig,ax=axes[0])
3695
+ neww = figsizes[0]
3696
+ newh = h/w * figsizes[0]
3673
3697
 
3674
- # pos = ax.imshow(myimage, origin='upper',
3675
- # extent=extent)
3676
- # fig.colorbar(pos,ax=ax)
3698
+ fig.set_size_inches(neww, newh)
3677
3699
 
3678
- x1 = np.ceil((self.xmin // ds) * ds)
3679
- if x1 < self.xmin:
3680
- x1 += ds
3681
- x2 = int((self.xmax // ds) * ds)
3682
- if x2 > self.xmax:
3683
- x2 -= ds
3684
- y1 = np.ceil((self.ymin // ds) * ds)
3685
- if y1 < self.ymin:
3686
- y1 += ds
3687
- y2 = int((self.ymax // ds) * ds)
3688
- if y2 > self.ymax:
3689
- y2 -= ds
3700
+ pot_title = self.viewer_name
3701
+ if arrayid_as_title:
3702
+ pot_title = self.active_array.idx
3690
3703
 
3691
- x_label_list = np.linspace(x1, x2, int((x2 - x1) / ds) + 1, True)
3692
- x_label_list = np.insert(x_label_list, 0, self.xmin)
3693
- x_label_list = np.insert(x_label_list, -1, self.xmax)
3694
- x_label_list = np.unique(x_label_list)
3704
+ self.display_canvasogl(fig=fig,
3705
+ ax=ax,
3706
+ title=pot_title if add_title else '',
3707
+ ds = ds)
3695
3708
 
3696
- y_label_list = np.linspace(y1, y2, int((y2 - y1) / ds) + 1, True)
3697
- y_label_list = np.insert(y_label_list, 0, self.ymin)
3698
- y_label_list = np.insert(y_label_list, -1, self.ymax)
3699
- y_label_list = np.unique(y_label_list)
3709
+ #création d'un'buffers
3710
+ buf = io.BytesIO()
3711
+ #sauvegarde de la figure au format png
3712
+ fig.savefig(buf, format='png')
3700
3713
 
3701
- ax.set_xticks(x_label_list)
3702
- ax.set_yticks(y_label_list)
3714
+ #déplacement au début du buffer
3715
+ buf.seek(0)
3716
+ #lecture du buffer et conversion en image avec PIL
3717
+ im = Image.open(buf)
3703
3718
 
3704
- ax.set_xticklabels(plt.FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize=8, rotation=30)
3705
- ax.set_yticklabels(plt.FormatStrFormatter('%.1f').format_ticks(y_label_list), fontsize=8)
3719
+ if self.palette_for_copy.values is not None:
3720
+ bufpal = io.BytesIO()
3721
+ self.palette_for_copy.export_image(bufpal,'v')
3722
+ bufpal.seek(0)
3706
3723
 
3707
- ax.set_xlabel('X [m]')
3708
- ax.set_ylabel('Y [m]')
3724
+ #lecture du buffer et conversion en image avec PIL
3725
+ impal = Image.open(bufpal)
3726
+ impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
3709
3727
 
3710
- if self.palette_for_copy.values is not None:
3711
- self.palette_for_copy.export_image(None, h_or_v='v', figax=(fig,axes[1]))
3712
- else:
3713
- axes[1].clear()
3714
- axes[1].axis('off')
3728
+ imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
3715
3729
 
3716
- # if self.active_array is not None:
3717
- # self.active_array.mypal.export_image(None, h_or_v='v', figax=(fig,axes[1]))
3718
- # elif self.active_res2d is not None:
3719
- # self.active_res2d.mypal.export_image(None, h_or_v='v', figax=(fig,axes[1]))
3730
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3731
+ imnew.paste(im.convert('RGB'),(0,0))
3732
+ imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
3733
+ im=imnew
3734
+ bufpal.close()
3735
+ else:
3736
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3720
3737
 
3721
- # self.Paint()
3738
+ # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3739
+ imnew.paste(im.convert('RGB'),(0,0))
3740
+ im=imnew
3722
3741
 
3723
- if add_title:
3724
- ax.set_title(self.viewer_name)
3725
- fig.set_size_inches(12, 10)
3726
- fig.tight_layout()
3742
+ im.save(fn, dpi=(dpi, dpi))
3743
+ fig.set_visible(False)
3744
+ buf.close()
3727
3745
 
3728
- fig.savefig(fn, dpi=dpi)
3729
3746
  else:
3747
+ metadata = PngInfo()
3748
+ metadata.add_text('xmin', str(self.xmin))
3749
+ metadata.add_text('ymin', str(self.ymin))
3750
+ metadata.add_text('xmax', str(self.xmax))
3751
+ metadata.add_text('ymax', str(self.ymax))
3752
+
3753
+ myimage = self.get_canvas_as_image()
3730
3754
  myimage.save(fn, pnginfo=metadata)
3731
3755
 
3732
3756
  return fn, ds
@@ -5622,7 +5646,9 @@ class WolfMapViewer(wx.Frame):
5622
5646
 
5623
5647
  self.currently_readresults = True
5624
5648
 
5625
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
5649
+ pgbar = wx.ProgressDialog(_('Reading results'), _('Reading results'), maximum=len(self.myres2D), parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
5650
+
5651
+ for id, curmodel in enumerate(self.iterator_over_objects(draw_type.RES2D)):
5626
5652
  curmodel: Wolfresults_2D
5627
5653
  logging.info(_('Updating {} - Last result'.format(curmodel.idx)))
5628
5654
 
@@ -5630,6 +5656,10 @@ class WolfMapViewer(wx.Frame):
5630
5656
  curmodel.set_currentview()
5631
5657
  self._update_sim_explorer(curmodel)
5632
5658
 
5659
+ pgbar.Update(id + 1, _('Reading results') + ' - ' + curmodel.idx)
5660
+
5661
+ pgbar.Destroy()
5662
+
5633
5663
  self.Refresh()
5634
5664
  self.currently_readresults = False
5635
5665
  self._update_mytooltip()
@@ -6594,8 +6624,21 @@ class WolfMapViewer(wx.Frame):
6594
6624
 
6595
6625
  nb = dlg.GetValue()
6596
6626
  dlg.Destroy()
6597
- for i in range(nb):
6598
- self.add_viewer_and_link()
6627
+
6628
+ if nb > 0:
6629
+
6630
+ # Renaming the current viewer
6631
+ dlg = wx.TextEntryDialog(None, _('New name for the current viewer'), _('Rename'), self.viewer_name, style=wx.OK | wx.CANCEL)
6632
+ ret = dlg.ShowModal()
6633
+ if ret == wx.ID_OK:
6634
+ self.viewer_name = dlg.GetValue()
6635
+ self.SetName(self.viewer_name)
6636
+ dlg.Destroy()
6637
+
6638
+ for i in range(nb):
6639
+ self.add_viewer_and_link()
6640
+ else:
6641
+ logging.warning(_('No additional viewer !'))
6599
6642
 
6600
6643
  elif itemlabel == _('3D viewer'):
6601
6644
 
@@ -7503,6 +7546,44 @@ class WolfMapViewer(wx.Frame):
7503
7546
 
7504
7547
  return ret
7505
7548
 
7549
+ def save_arrays_indep(self, fn:str, mpl:bool= True, ds:float= 0., add_title:bool= True) -> tuple[(str, float), str]:
7550
+ """ Save each array in a separate file
7551
+
7552
+ :param fn: filename without extension -- '.png' will be added
7553
+ :param mpl: save as matplotlib image
7554
+ :param ds: Ticks size for matplotlib image
7555
+ :return: list of tuple ((filename, ds), viewer_name)
7556
+ """
7557
+
7558
+ # Get all checked arrays
7559
+ checked_arrays = self.get_list_keys(drawing_type= draw_type.ARRAYS, checked_state= True)
7560
+ old_active = self.active_array
7561
+
7562
+ if len(checked_arrays) == 0:
7563
+ logging.warning(_('No arrays checked for export'))
7564
+ return
7565
+
7566
+ def uncheck_all():
7567
+ # uncheck arrays
7568
+ for curarray in checked_arrays:
7569
+ self.uncheck_id(curarray, unload= False, forceresetOGL= False)
7570
+
7571
+ fn = str(fn)
7572
+ ret = []
7573
+ for idx, curel in enumerate(checked_arrays):
7574
+ uncheck_all()
7575
+ self.check_id(curel)
7576
+ self.active_array = self.get_obj_from_id(curel, drawtype= draw_type.ARRAYS)
7577
+ ret.append((self.save_canvasogl(fn + '_' + str(idx) + '.png', mpl, ds, add_title= add_title, arrayid_as_title=True), curel))
7578
+
7579
+ self.active_array = old_active
7580
+ for curarray in checked_arrays:
7581
+ self.check_id(curarray)
7582
+
7583
+ self.Refresh()
7584
+
7585
+ return ret
7586
+
7506
7587
  def assembly_images(self, all_images, mode:Literal['horizontal', 'vertical', 'square']= 'square'):
7507
7588
  """ Assembly images
7508
7589
 
@@ -7518,6 +7599,9 @@ class WolfMapViewer(wx.Frame):
7518
7599
 
7519
7600
  images = [Image.open(fn) for (fn, ds), viewername in all_images]
7520
7601
 
7602
+ if len(images) in [1,2] and (mode == 'square' or mode == 2):
7603
+ mode = 'horizontal'
7604
+
7521
7605
  widths, heights = zip(*(i.size for i in images))
7522
7606
 
7523
7607
  if mode == 'horizontal' or mode==0:
@@ -8858,6 +8942,24 @@ class WolfMapViewer(wx.Frame):
8858
8942
  else:
8859
8943
  logging.warning(_('Rebin not yet implemented for this type of object'))
8860
8944
 
8945
+ elif text == _('Set NullValue'):
8946
+
8947
+ if isinstance(self.selected_object, WolfArray):
8948
+ dlg = wx.TextEntryDialog(self, _('Enter the new null value :'), _('Set NullValue'), str(self.selected_object.array.data[0,0]))
8949
+ if dlg.ShowModal() == wx.ID_OK:
8950
+ res = dlg.GetValue()
8951
+ dlg.Destroy()
8952
+
8953
+ try:
8954
+ res = float(res)
8955
+ self.selected_object.nullvalue = res
8956
+ self.selected_object.mask_data(res)
8957
+ self.selected_object.reset_plot()
8958
+ self.Refresh()
8959
+ except:
8960
+ logging.warning(_('Invalid value for null value'))
8961
+ return
8962
+
8861
8963
  elif _('Convert to mono-block') in text:
8862
8964
 
8863
8965
  if isinstance(self.selected_object, WolfArrayMB):
@@ -8892,6 +8994,30 @@ class WolfMapViewer(wx.Frame):
8892
8994
  else:
8893
8995
  logging.warning(_('Convert to multi-blocks not yet implemented for this type of object'))
8894
8996
 
8997
+ elif _('Extract current step as IC') in text:
8998
+
8999
+ if isinstance(self.selected_object, Wolfresults_2D):
9000
+
9001
+ if self.selected_object.current_result is None or self.selected_object.current_result < 0 :
9002
+ logging.warning(_('No current step defined'))
9003
+ return
9004
+
9005
+ import shutil
9006
+
9007
+ logging.info(_('Extracting current step as IC'))
9008
+
9009
+ dir = Path(self.selected_object.filename).parent
9010
+ files = ['h.npy', 'qx.npy', 'qy.npy']
9011
+ for curfile in files:
9012
+ if (dir / curfile).exists():
9013
+ # prepend the file with __
9014
+ logging.info(f'File {curfile} already exists -- renaming it')
9015
+ shutil.copyfile(dir / curfile, dir / ('__' + curfile))
9016
+
9017
+ logging.info(_('Extracting current step as IC'))
9018
+ self.selected_object.export_as(Path(self.selected_object.filename).parent, [views_2D.WATERDEPTH, views_2D.QX, views_2D.QY], 'numpy', False)
9019
+ logging.info(_('Done !'))
9020
+
8895
9021
  elif _('Export to Shape file') in text:
8896
9022
 
8897
9023
  if isinstance(self.selected_object, Zones | Bridge | Weir):
@@ -10588,6 +10714,8 @@ class WolfMapViewer(wx.Frame):
10588
10714
  # CTRL+L : chargement d'une matrice sur base du nom de fichier de la tile\n \
10589
10715
  # \n \
10590
10716
  # ALT+C : Copy image"
10717
+ # ALT+SHIFT+C : Copy images from multiviewers \
10718
+ # CTRL+ALT+SHIFT+C : Copy images from all arrays as independent image \
10591
10719
 
10592
10720
  groups = ['Results', 'Particle system', 'Drawing', 'Arrays', 'Cross sections', 'Zones', 'Action', 'Tree', 'Tiles', 'GLTF/GLB', 'App']
10593
10721
 
@@ -10619,7 +10747,8 @@ class WolfMapViewer(wx.Frame):
10619
10747
  'Arrows': _('Drawing : lateral movements'),
10620
10748
  'c or C': _('Drawing : copy canvas to Clipboard wo axes'),
10621
10749
  'ALT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
10622
- 'ALT+SHIFT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image with axes - linked arrays'),
10750
+ 'ALT+SHIFT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image with axes - multiviewers'),
10751
+ 'CTRL+ALT+SHIFT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image with axes - all arrays one by one'),
10623
10752
 
10624
10753
  'CTRL+o': _('Results : increase transparency of the current result'),
10625
10754
  'CTRL+O': _('Results : decrease transparency of the current result'),
@@ -10940,12 +11069,20 @@ class WolfMapViewer(wx.Frame):
10940
11069
  # Copie du canvas dans le clipboard pour transfert vers autre application
10941
11070
  # Copie des canvas liés
10942
11071
 
11072
+ if not self.linked:
11073
+ logging.error(_('No linked canvas to copy -- calling ALT+C instead'))
11074
+ self.copy_canvasogl()
11075
+ return
11076
+
10943
11077
  from tempfile import TemporaryDirectory
10944
11078
 
10945
11079
  logging.info(_('Creating images'))
10946
11080
 
10947
11081
  with TemporaryDirectory() as tmpdirname:
10948
11082
  all_images = self.save_linked_canvas(Path(tmpdirname) / 'fig', mpl= True, ds= self.ticks_size, add_title= True)
11083
+ if len(all_images) == 0:
11084
+ logging.error(_('No image to combine -- aborting !'))
11085
+ return
10949
11086
  im_assembly = self.assembly_images(all_images, mode= self.assembly_mode)
10950
11087
 
10951
11088
  logging.info(_('Creating images - done'))
@@ -10998,7 +11135,44 @@ class WolfMapViewer(wx.Frame):
10998
11135
 
10999
11136
  logging.info(_('Values copied to clipboard'))
11000
11137
 
11001
- elif key == ord('C') and ctrldown and altdown:
11138
+ elif key == ord('C') and ctrldown and altdown and shiftdown:
11139
+ # CTRL+ALT+SHIFT+C
11140
+ # Copie du canvas dans le clipboard pour transfert vers autre application
11141
+ # Une matrice est associée à chaque canvas
11142
+
11143
+ from tempfile import TemporaryDirectory
11144
+
11145
+ logging.info(_('Creating images'))
11146
+
11147
+ with TemporaryDirectory() as tmpdirname:
11148
+ all_images = self.save_arrays_indep(Path(tmpdirname) / 'fig', mpl= True, ds= self.ticks_size, add_title= True)
11149
+ if len(all_images) == 0:
11150
+ logging.error(_('No image to combine -- aborting !'))
11151
+ return
11152
+ im_assembly = self.assembly_images(all_images, mode= self.assembly_mode)
11153
+
11154
+ logging.info(_('Creating images - done'))
11155
+
11156
+ # Copy image to clipboard
11157
+ if im_assembly is not None:
11158
+ if wx.TheClipboard.Open():
11159
+
11160
+ #création d'un objet bitmap wx
11161
+ wxbitmap = wx.Bitmap().FromBuffer(im_assembly.width, im_assembly.height, im_assembly.tobytes())
11162
+
11163
+ # objet wx exportable via le clipboard
11164
+ dataobj = wx.BitmapDataObject()
11165
+ dataobj.SetBitmap(wxbitmap)
11166
+
11167
+ wx.TheClipboard.SetData(dataobj)
11168
+ wx.TheClipboard.Close()
11169
+ logging.info(_('Image copied to clipboard'))
11170
+ else:
11171
+ logging.error(_('Cannot open the clipboard'))
11172
+ else:
11173
+ logging.error(_('No image to copy to clipboard'))
11174
+
11175
+ elif key == ord('C') and ctrldown and altdown and not shiftdown:
11002
11176
  if self.active_array is None:
11003
11177
  dlg = wx.MessageDialog(self,
11004
11178
  _('The active array is None - Please active an array from which to copy the selection !'),
@@ -11372,9 +11546,11 @@ class WolfMapViewer(wx.Frame):
11372
11546
  tracks.append(_('Convert to mono-block'))
11373
11547
  tracks.append(_('Convert to mono-block (result)'))
11374
11548
  tracks.append(_('Convert to multi-blocks (result)'))
11549
+ tracks.append(_('Extract current step as IC (result)'))
11375
11550
  tracks.append(_('Export to Shape file'))
11376
11551
  tracks.append(_('Export active zone to Shape file'))
11377
11552
  tracks.append(_('Rebin'))
11553
+ tracks.append(_('Set NullValue'))
11378
11554
 
11379
11555
  # Récupération des items du menu contextuel
11380
11556
  menuitems = self.popupmenu.GetMenuItems()
@@ -11401,6 +11577,7 @@ class WolfMapViewer(wx.Frame):
11401
11577
  self.popupmenu.Append(wx.ID_ANY, _('Boundary conditions'), _('Boundary conditions'))
11402
11578
  self.popupmenu.Append(wx.ID_ANY, _('Contours'))
11403
11579
  self.popupmenu.Append(wx.ID_ANY, _('Rebin'), _('Change the spatial resolution'))
11580
+ self.popupmenu.Append(wx.ID_ANY, _('Set NullValue'), _('Set NullValue'))
11404
11581
 
11405
11582
  # Add specific menu items for WolfArrayMB
11406
11583
  if isinstance(self.selected_object, WolfArrayMB):
@@ -11410,6 +11587,7 @@ class WolfMapViewer(wx.Frame):
11410
11587
  if isinstance(self.selected_object, Wolfresults_2D):
11411
11588
  self.popupmenu.Append(wx.ID_ANY, _('Convert to mono-block (result)'), _('Convert to mono-block'))
11412
11589
  self.popupmenu.Append(wx.ID_ANY, _('Convert to multi-blocks (result)'), _('Convert to multi-blocks'))
11590
+ self.popupmenu.Append(wx.ID_ANY, _('Extract current step as IC (result)'), _('Extract current step as IC'))
11413
11591
 
11414
11592
  if isinstance(self.selected_object, Zones | Bridge | Weir):
11415
11593
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
wolfhece/PyPalette.py CHANGED
@@ -158,7 +158,12 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
158
158
  if minval == -99999:
159
159
  dlg = wx.TextEntryDialog(None, _('Minimum value'), value=str(self.values[0]))
160
160
  ret = dlg.ShowModal()
161
- self.values[0] = dlg.GetValue()
161
+
162
+ try:
163
+ self.values[0] = float(dlg.GetValue())
164
+ except:
165
+ logging.warning('Bad value for minimum - No change')
166
+
162
167
  dlg.Destroy()
163
168
  else:
164
169
  self.values[0] = minval
@@ -172,12 +177,24 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
172
177
  if ret == wx.ID_YES:
173
178
  dlg = wx.TextEntryDialog(None, _('Step value'), value='1')
174
179
  ret = dlg.ShowModal()
175
- step = float(dlg.GetValue())
180
+
181
+ try:
182
+ step = float(dlg.GetValue())
183
+ except:
184
+ logging.warning('Bad value for step - using default value 0.1 m')
185
+ step = 0.1
186
+
176
187
  dlg.Destroy()
177
188
  else:
178
189
  dlg = wx.TextEntryDialog(None, _('Maximum value'), value=str(self.values[-1]))
179
190
  ret = dlg.ShowModal()
180
- self.values[-1] = float(dlg.GetValue())
191
+
192
+ try:
193
+ self.values[-1] = float(dlg.GetValue())
194
+ except:
195
+ logging.warning('Bad value for maximum - using min value + 1 m')
196
+ self.values[-1] = self.values[0] + 1.
197
+
181
198
  dlg.Destroy()
182
199
 
183
200
  elif maxval != -99999:
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 1
8
- self.patch = 115
8
+ self.patch = 116
9
9
 
10
10
  def __str__(self):
11
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: wolfhece
3
- Version: 2.1.115
3
+ Version: 2.1.116
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  License: Copyright (c) 2024 University of Liege. All rights reserved.
6
6
  Project-URL: Homepage, https://uee.uliege.be/hece
@@ -5,13 +5,13 @@ wolfhece/GraphProfile.py,sha256=OCgJo0YFFBI6H1z-5egJsOOoWF_iziiza0-bbPejNMc,6965
5
5
  wolfhece/Lidar2002.py,sha256=bX-nIzdpjD7rOfEgJpTeaW6rIdAXwDp_z4YTM9CgANY,6068
6
6
  wolfhece/ManageParams.py,sha256=EeuUI5Vvh9ixCvYf8YShMC1s1Yacc7OxOCN7q81gqiQ,517
7
7
  wolfhece/Model1D.py,sha256=SI4oNF_J3MdjiWZoizS8kuRXLMVyymX9dYfYJNVCQVI,476989
8
- wolfhece/PyConfig.py,sha256=Bb1T8qjgKMChadJYDrHO9uo6CwItiAXScZpYkDXqZF8,11387
8
+ wolfhece/PyConfig.py,sha256=gyl1MesSJZaVpC1XtvD78PpnE1VD3hGM3HPQXTJ3eJg,12963
9
9
  wolfhece/PyCrosssections.py,sha256=FnmM9DWY_SAF2EDH9Gu2PojXNtSTRF4-aYQuAAJXBh4,112771
10
- wolfhece/PyDraw.py,sha256=efChYsrkRWnVYJJecpVJoUUEajOGus6_05OHrmKMfc0,502367
10
+ wolfhece/PyDraw.py,sha256=_pPWREAVVWb7pU7SyeZBzWelTcZtCI5L0TtSPBcoMQw,509977
11
11
  wolfhece/PyGui.py,sha256=RlrLoCBdbiMnR4FSUD1yuy8fs--hxUl_zPu7zuduCLE,144706
12
12
  wolfhece/PyGuiHydrology.py,sha256=f60E8K9eGTnRq5RDF6yvt-ahf2AYegwQ9t25zZ2Mk1A,14946
13
13
  wolfhece/PyHydrographs.py,sha256=jwtSNMMACwarxrtN1UeQYth99UNrhwPx1IGgUwcooHA,3774
14
- wolfhece/PyPalette.py,sha256=n3Aj6vgxj8LCN-aNR4Q9NY215Cf4GMthb33UGsl3BUg,31828
14
+ wolfhece/PyPalette.py,sha256=Ayz0lqOPfUgjPpqvxragBSd7v47Z79roEy7thwVlH7M,32370
15
15
  wolfhece/PyParams.py,sha256=GRp1zZDUJIjs8PtjwScDdov-E9orr1JWOntDazN5AOw,98577
16
16
  wolfhece/PyPictures.py,sha256=m1kY0saW6Y9Q0bDCo47lW6XxDkBrbQG-Fd8uVn8G5ic,2514
17
17
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
@@ -80,7 +80,7 @@ wolfhece/apps/curvedigitizer.py,sha256=lEJJwgAfulrrWQc-U6ij6sj59hWN3SZl4Yu1kQxVz
80
80
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
81
81
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
82
82
  wolfhece/apps/splashscreen.py,sha256=SrustmIQeXnsiD-92OzjdGhBi-S7c_j-cSvuX4T6rtg,2929
83
- wolfhece/apps/version.py,sha256=EyQh37QGtlBEUyYiAlz_IouaM-UGYFtRP6aZcJqEcwg,389
83
+ wolfhece/apps/version.py,sha256=ftLcojZwQEigCIBvMIO3EoocbdCG04g8wDxbBkyoCvI,389
84
84
  wolfhece/apps/wolf.py,sha256=j_CgvsL8rwixbVvVD5Z0s7m7cHZ86gmFLojKGuetMls,729
85
85
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
86
86
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -293,8 +293,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
293
293
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
294
294
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
295
295
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
296
- wolfhece-2.1.115.dist-info/METADATA,sha256=qEqSZhvJvgQbQKdX-NHur3c_tbeYO7QeQYkDWrPvTlE,2587
297
- wolfhece-2.1.115.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
298
- wolfhece-2.1.115.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
299
- wolfhece-2.1.115.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
300
- wolfhece-2.1.115.dist-info/RECORD,,
296
+ wolfhece-2.1.116.dist-info/METADATA,sha256=x8r9B3T67NwRMVy1TAKiyCVP2e-oDsISGVdL2CmJO3I,2587
297
+ wolfhece-2.1.116.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
298
+ wolfhece-2.1.116.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
299
+ wolfhece-2.1.116.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
300
+ wolfhece-2.1.116.dist-info/RECORD,,