wolfhece 2.1.114__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/PyDraw.py CHANGED
@@ -682,6 +682,8 @@ class DragdropFileTarget(wx.FileDropTarget):
682
682
  else:
683
683
  return False
684
684
 
685
+ pgbar = wx.ProgressDialog(_('Loading files'), _('Loading files'), maximum=len(filenames), parent=self.window, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
686
+
685
687
  for name in filenames:
686
688
 
687
689
  if Path(name).is_dir():
@@ -691,7 +693,7 @@ class DragdropFileTarget(wx.FileDropTarget):
691
693
  continue
692
694
 
693
695
  if test_if_array(name):
694
- ids = self.window.get_list_keys(draw_type.ARRAYS)
696
+ ids = self.window.get_list_keys(draw_type.ARRAYS, checked_state=None)
695
697
  id = Path(name).stem
696
698
  while id in ids:
697
699
  id = id + '_1'
@@ -703,7 +705,7 @@ class DragdropFileTarget(wx.FileDropTarget):
703
705
  logging.error(_('Error while loading array : ') + name)
704
706
 
705
707
  elif test_if_arrayMB(name):
706
- ids = self.window.get_list_keys(draw_type.ARRAYS)
708
+ ids = self.window.get_list_keys(draw_type.ARRAYS, checked_state=None)
707
709
  id = Path(name).stem
708
710
  while id in ids:
709
711
  id = id + '_1'
@@ -715,7 +717,7 @@ class DragdropFileTarget(wx.FileDropTarget):
715
717
  logging.error(_('Error while loading array : ') + name)
716
718
 
717
719
  elif test_if_vector(name):
718
- ids = self.window.get_list_keys(draw_type.VECTORS)
720
+ ids = self.window.get_list_keys(draw_type.VECTORS, checked_state=None)
719
721
  id = Path(name).stem
720
722
  while id in ids:
721
723
  id = id + '_1'
@@ -727,7 +729,7 @@ class DragdropFileTarget(wx.FileDropTarget):
727
729
  logging.error(_('Error while loading vector : ') + name)
728
730
 
729
731
  elif test_if_cloud(name):
730
- ids = self.window.get_list_keys(draw_type.CLOUD)
732
+ ids = self.window.get_list_keys(draw_type.CLOUD, checked_state=None)
731
733
  id = Path(name).stem
732
734
  while id in ids:
733
735
  id = id + '_1'
@@ -738,6 +740,10 @@ class DragdropFileTarget(wx.FileDropTarget):
738
740
  except:
739
741
  logging.error(_('Error while loading cloud : ') + name)
740
742
 
743
+ pgbar.Update(pgbar.GetValue() + 1)
744
+
745
+ pgbar.Destroy()
746
+
741
747
  return True
742
748
 
743
749
 
@@ -1152,6 +1158,10 @@ class WolfMapViewer(wx.Frame):
1152
1158
  active_imagestiles: ImagesTiles
1153
1159
  active_particle_system: Particle_system
1154
1160
  active_viewer3d: Wolf_Viewer3D
1161
+ active_bridges: Bridges
1162
+ active_bridge: Bridge
1163
+ active_weirs : Weirs
1164
+ active_weir : Weir
1155
1165
 
1156
1166
  def __init__(self,
1157
1167
  wxparent = None,
@@ -1245,6 +1255,8 @@ class WolfMapViewer(wx.Frame):
1245
1255
 
1246
1256
  self.menuwolf2d = None
1247
1257
  self.menu_landmap = None
1258
+ self.menu_bridge = None
1259
+ self.menu_weir = None
1248
1260
  self.menu2d_cache_setup = None
1249
1261
  self.menuparticlesystem = None
1250
1262
  self.menu2dGPU = None
@@ -1487,6 +1499,10 @@ class WolfMapViewer(wx.Frame):
1487
1499
  self.active_tile = None
1488
1500
  self.selected_treeitem = None
1489
1501
  self.selected_object = None
1502
+ self.active_bridges = None
1503
+ self.active_bridge = None
1504
+ self.active_weirs = None
1505
+ self.active_weir = None
1490
1506
 
1491
1507
  curtool = self.tools[ID_SORTALONG] = {}
1492
1508
  curtool['menu'] = self.sortalong
@@ -2267,21 +2283,33 @@ class WolfMapViewer(wx.Frame):
2267
2283
  dlg.Destroy()
2268
2284
  return
2269
2285
 
2270
- 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)):
2271
2289
  curmodel: Wolfresults_2D
2272
2290
  curmodel.epsilon = neweps
2273
2291
  curmodel._epsilon_default = neweps
2274
2292
  curmodel.read_oneresult(curmodel.current_result)
2275
2293
  curmodel.set_currentview()
2276
2294
 
2295
+ pgbar.Update(id, _('Setting epsilon for result {}'.format(curmodel.idx)))
2296
+
2297
+ pgbar.Destroy()
2298
+
2277
2299
  elif itemlabel == _("Filter independent"):
2278
2300
 
2279
2301
  self.menu_filter_independent.IsChecked = not self.menu_filter_independent.IsChecked
2280
2302
 
2281
- 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)):
2282
2306
  curmodel: Wolfresults_2D
2283
2307
  curmodel.to_filter_independent = not self.menu_filter_independent.IsChecked
2284
2308
 
2309
+ pgbar.Update(id, _('Filtering independent zones for result {}'.format(curmodel.idx)))
2310
+
2311
+ pgbar.Destroy()
2312
+
2285
2313
  # elif itemlabel == _("Manage boundary conditions..."):
2286
2314
 
2287
2315
  # if self.active_res2d is not None:
@@ -2972,6 +3000,26 @@ class WolfMapViewer(wx.Frame):
2972
3000
  else:
2973
3001
  return config[ConfigurationKeys.TICKS_SIZE]
2974
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
+
2975
3023
  @property
2976
3024
  def assembly_mode(self) -> str:
2977
3025
  """ Return the assembly mode from configs """
@@ -3166,185 +3214,10 @@ class WolfMapViewer(wx.Frame):
3166
3214
  return
3167
3215
  self.start_action('rotate triangles', 'Rotate the current triangulation -- Please select 1 point for the center')
3168
3216
 
3169
- def copy_canvasogl(self, mpl:bool= True, ds:float= 0., figsizes= [10.,10.], palette:wolfpalette = None):
3170
- """
3171
- Generate image based on UI context and copy to the Clipboard
3172
3217
 
3173
- :param mpl: Using Matplolib as renderer. Defaults to True.
3174
- :type mpl: bool, optional
3175
- :parem ds: Ticks size. Defaults to 0..
3176
- :type ds: float, optional
3177
- :parem figsizes: fig size in inches
3178
- :type figsizes: list, optional
3179
- """
3180
-
3181
- if wx.TheClipboard.Open():
3182
- self.Paint()
3183
-
3184
- if self.SetCurrentContext():
3185
-
3186
- myimage = self.get_canvas_as_image()
3187
-
3188
- # # Récupération du buffer OpenGL
3189
- # glPixelStorei(GL_PACK_ALIGNMENT, 1)
3190
- # data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3191
- # # Création d'une image sur base du buffer
3192
- # myimage: Image.Image
3193
- # myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3194
- # # On tranpose car OpenGL travaille avec comme référence le coin inférieur gauche
3195
- # myimage = myimage.transpose(1)
3196
-
3197
- metadata = PngInfo()
3198
- metadata.add_text('xmin', str(self.xmin))
3199
- metadata.add_text('ymin', str(self.ymin))
3200
- metadata.add_text('xmax', str(self.xmax))
3201
- metadata.add_text('ymax', str(self.ymax))
3202
-
3203
- if mpl:
3204
- if ds == 0.:
3205
- ds = self.ticks_size # Global parameters
3206
-
3207
- if ds == 0.:
3208
- ds = 100.
3209
-
3210
- nb_ticks_x = (self.xmax - self.xmin) // ds
3211
- nb_ticks_y = (self.ymax - self.ymin) // ds
3212
-
3213
- if nb_ticks_x > 10 or nb_ticks_y > 10:
3214
- logging.error(_('Too many ticks for the image. Please raise the ticks size in the global options.'))
3215
- return
3216
-
3217
- # Création d'une graphique Matplotlib
3218
- extent = (self.xmin, self.xmax, self.ymin, self.ymax)
3219
- fig, ax = plt.subplots(1, 1)
3220
-
3221
- w, h = [self.width, self.height]
3222
-
3223
- # neww = figsizes[0]/figsizes[1] *h
3224
- neww = figsizes[0]
3225
- newh = h/w * figsizes[0]
3226
-
3227
- fig.set_size_inches(neww, newh)
3228
-
3229
- pos = ax.imshow(myimage,
3230
- origin='upper',
3231
- extent=extent)
3232
-
3233
- x1 = np.ceil((self.xmin // ds) * ds)
3234
- if x1 < self.xmin:
3235
- x1 += ds
3236
- x2 = int((self.xmax // ds) * ds)
3237
- if x2 > self.xmax:
3238
- x2 -= ds
3239
- y1 = np.ceil((self.ymin // ds) * ds)
3240
- if y1 < self.ymin:
3241
- y1 += ds
3242
- y2 = int((self.ymax // ds) * ds)
3243
- if y2 > self.ymax:
3244
- y2 -= ds
3245
-
3246
- x_label_list = np.linspace(x1, x2, int((x2 - x1) / ds) + 1, True)
3247
- if self.ticks_bounds:
3248
- x_label_list = np.insert(x_label_list, 0, self.xmin)
3249
- x_label_list = np.insert(x_label_list, -1, self.xmax)
3250
- x_label_list = np.unique(x_label_list)
3251
-
3252
- y_label_list = np.linspace(y1, y2, int((y2 - y1) / ds) + 1, True)
3253
- if self.ticks_bounds:
3254
- y_label_list = np.insert(y_label_list, 0, self.ymin)
3255
- y_label_list = np.insert(y_label_list, -1, self.ymax)
3256
- y_label_list = np.unique(y_label_list)
3257
-
3258
- ax.set_xticks(x_label_list)
3259
- ax.set_yticks(y_label_list)
3260
-
3261
- ax.set_xticklabels(plt.FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize=14, rotation=30)
3262
- ax.set_yticklabels(plt.FormatStrFormatter('%.1f').format_ticks(y_label_list), fontsize=14)
3263
-
3264
- ax.set_xlabel('X [m]')
3265
- ax.set_ylabel('Y [m]')
3266
-
3267
- #création de 2 buffers
3268
- buf = io.BytesIO()
3269
- #sauvegarde de la figure au format png
3270
- fig.tight_layout()
3271
- fig.savefig(buf, format='png')
3272
-
3273
- #déplacement au début du buffer
3274
- buf.seek(0)
3275
- #lecture du buffer et conversion en image avec PIL
3276
- im = Image.open(buf)
3277
-
3278
- if palette is None:
3279
- palette = self.palette_for_copy
3280
- # if self.active_array is not None:
3281
- # palette = self.active_array.mypal
3282
- # elif self.active_res2d is not None:
3283
- # palette = self.active_res2d.mypal
3284
-
3285
- if palette is not None:
3286
- if palette.values is not None:
3287
- bufpal = io.BytesIO()
3288
- palette.export_image(bufpal,'v')
3289
- bufpal.seek(0)
3290
-
3291
- #lecture du buffer et conversion en image avec PIL
3292
- impal = Image.open(bufpal)
3293
- impal = impal.resize((int(impal.size[0]*im.size[1]*.8/impal.size[1]),int(im.size[1]*.8)))
3294
-
3295
- imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
3296
-
3297
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3298
- imnew.paste(im.convert('RGB'),(0,0))
3299
- imnew.paste(impal.convert('RGB'),(im.size[0]-10, int((im.size[1]-impal.size[1])/3)))
3300
- im=imnew
3301
- else:
3302
- imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3303
-
3304
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3305
- imnew.paste(im.convert('RGB'),(0,0))
3306
- im=imnew
3307
- else:
3308
- imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3309
-
3310
- # On colle l'image du buffer et la palette pour ne former qu'une seul image à copier dans le clipboard
3311
- imnew.paste(im.convert('RGB'),(0,0))
3312
- im=imnew
3313
-
3314
- #création d'un objet bitmap wx
3315
- wxbitmap = wx.Bitmap().FromBuffer(im.width,im.height,im.tobytes())
3316
-
3317
- # objet wx exportable via le clipboard
3318
- dataobj = wx.BitmapDataObject()
3319
- dataobj.SetBitmap(wxbitmap)
3320
-
3321
- wx.TheClipboard.SetData(dataobj)
3322
- wx.TheClipboard.Close()
3323
-
3324
- buf.close()
3325
-
3326
- return fig, ax, im
3327
-
3328
- else:
3329
- """ Création d'un objet bitmap wx sur base du canvas
3330
- et copie dans le clipboard
3331
- """
3332
- # wxbitmap = wx.Bitmap().FromBuffer(myimage.width,myimage.height,myimage.tobytes())
3333
- wxbitmap = wx.Bitmap().FromBufferRGBA(myimage.width,myimage.height,myimage.tobytes())
3334
-
3335
- # objet wx exportable via le clipboard
3336
- dataobj = wx.BitmapDataObject()
3337
- dataobj.SetBitmap(wxbitmap)
3338
-
3339
- wx.TheClipboard.SetData(dataobj)
3340
- wx.TheClipboard.Close()
3341
-
3342
- return myimage
3343
-
3344
- else:
3345
- wx.MessageBox("Can't open the clipboard", "Error")
3346
-
3347
- 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=''):
3348
3221
  """
3349
3222
  This method takes a matplotlib figure and axe and,
3350
3223
  returns a clear screenshot of the information displayed in the wolfpy GUI.
@@ -3400,19 +3273,22 @@ class WolfMapViewer(wx.Frame):
3400
3273
  myax.set_xticks(x_label_list)
3401
3274
  myax.set_yticks(y_label_list)
3402
3275
 
3403
- myax.set_xticklabels(FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize = 'xx-small', rotation = 90)
3404
- 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)
3405
3280
  myax.xaxis.set_ticks_position('top')
3406
3281
  myax.xaxis.set_label_position('top')
3407
3282
 
3408
- myax.set_xlabel('X - coordinates ($m$)')
3409
- myax.set_ylabel('Y - coordinates ($m$)')
3283
+ myax.set_xlabel('X ($m$)')
3284
+ myax.set_ylabel('Y ($m$)')
3410
3285
  myax.xaxis.set_ticks_position('bottom')
3411
3286
  myax.xaxis.set_label_position('bottom')
3412
3287
 
3413
3288
  if title!='':
3414
3289
  myax.set_title(title)
3415
3290
 
3291
+ fig.tight_layout()
3416
3292
  fig.canvas.draw()
3417
3293
  fig.canvas.flush_events()
3418
3294
 
@@ -3562,37 +3438,213 @@ class WolfMapViewer(wx.Frame):
3562
3438
 
3563
3439
  el_time = str(timedelta(seconds=int(times[self.active_res2d.current_result])))
3564
3440
 
3565
- self.display_canvasogl(fig=fig,
3566
- ax=ax[0],
3567
- title=_('Current time {:0>8} s'.format(el_time)))
3441
+ self.display_canvasogl(fig=fig,
3442
+ ax=ax[0],
3443
+ title=_('Current time {:0>8} s'.format(el_time)))
3444
+
3445
+ for curmodel in self.iterator_over_objects(draw_type.RES2D):
3446
+ curmodel: Wolfresults_2D
3447
+ curmodel.step_interval_results = 1
3448
+
3449
+
3450
+ def get_canvas_as_image(self) -> Image.Image:
3451
+ """
3452
+ Récupère la fenêtre OpenGL sous forme d'image
3453
+ """
3454
+
3455
+ self.Paint()
3456
+
3457
+ if self.SetCurrentContext():
3458
+ glPixelStorei(GL_PACK_ALIGNMENT, 1)
3459
+ data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3460
+ myimage: Image.Image
3461
+ myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3462
+ myimage = myimage.transpose(1)
3463
+
3464
+ return myimage
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()
3568
3618
 
3569
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
3570
- curmodel: Wolfresults_2D
3571
- curmodel.step_interval_results = 1
3619
+ return fig, ax, im
3572
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())
3573
3627
 
3574
- def get_canvas_as_image(self) -> Image.Image:
3575
- """
3576
- Récupère la fenêtre OpenGL sous forme d'image
3577
- """
3628
+ # objet wx exportable via le clipboard
3629
+ dataobj = wx.BitmapDataObject()
3630
+ dataobj.SetBitmap(wxbitmap)
3578
3631
 
3579
- self.Paint()
3632
+ wx.TheClipboard.SetData(dataobj)
3633
+ wx.TheClipboard.Close()
3580
3634
 
3581
- if self.SetCurrentContext():
3582
- glPixelStorei(GL_PACK_ALIGNMENT, 1)
3583
- data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3584
- myimage: Image.Image
3585
- myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3586
- myimage = myimage.transpose(1)
3635
+ return myimage
3587
3636
 
3588
- return myimage
3637
+ else:
3638
+ wx.MessageBox("Can't open the clipboard", "Error")
3589
3639
 
3590
3640
  def save_canvasogl(self,
3591
3641
  fn:str='',
3592
3642
  mpl:bool=True,
3593
3643
  ds:float=0.,
3594
3644
  dpi:int= 300,
3595
- add_title:bool = False):
3645
+ add_title:bool = False,
3646
+ figsizes= [10.,10.],
3647
+ arrayid_as_title:bool = False):
3596
3648
  """
3597
3649
  Sauvegarde de la fenêtre d'affichage dans un fichier
3598
3650
 
@@ -3601,6 +3653,7 @@ class WolfMapViewer(wx.Frame):
3601
3653
  :param ds: Ticks interval
3602
3654
  """
3603
3655
 
3656
+ # FIXME : SHOULD BE MERGEd WITH copy_canvasogl
3604
3657
  fn = str(fn)
3605
3658
 
3606
3659
  if fn == '':
@@ -3616,19 +3669,7 @@ class WolfMapViewer(wx.Frame):
3616
3669
  fn += '.png'
3617
3670
 
3618
3671
  if self.SetCurrentContext():
3619
- # glPixelStorei(GL_PACK_ALIGNMENT, 1)
3620
- # data = glReadPixels(0, 0, self.canvaswidth, self.canvasheight, GL_RGBA, GL_UNSIGNED_BYTE)
3621
- # myimage: Image.Image
3622
- # myimage = Image.frombuffer("RGBA", (self.canvaswidth, self.canvasheight), data)
3623
- # myimage = myimage.transpose(1)
3624
-
3625
- myimage = self.get_canvas_as_image()
3626
-
3627
- metadata = PngInfo()
3628
- metadata.add_text('xmin', str(self.xmin))
3629
- metadata.add_text('ymin', str(self.ymin))
3630
- metadata.add_text('xmax', str(self.xmax))
3631
- metadata.add_text('ymax', str(self.ymax))
3672
+ self.Paint()
3632
3673
 
3633
3674
  if mpl:
3634
3675
  if ds == 0.:
@@ -3646,69 +3687,70 @@ class WolfMapViewer(wx.Frame):
3646
3687
  ds = float(dlg.GetValue())
3647
3688
  dlg.Destroy()
3648
3689
 
3690
+ # Création d'un graphique Matplotlib
3649
3691
  extent = (self.xmin, self.xmax, self.ymin, self.ymax)
3650
- # fig, ax = plt.subplots(1, 1)
3651
- 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]
3652
3694
 
3653
- ax = axes[0]
3654
- self.display_canvasogl(fig=fig,ax=axes[0])
3695
+ neww = figsizes[0]
3696
+ newh = h/w * figsizes[0]
3655
3697
 
3656
- # pos = ax.imshow(myimage, origin='upper',
3657
- # extent=extent)
3658
- # fig.colorbar(pos,ax=ax)
3698
+ fig.set_size_inches(neww, newh)
3659
3699
 
3660
- x1 = np.ceil((self.xmin // ds) * ds)
3661
- if x1 < self.xmin:
3662
- x1 += ds
3663
- x2 = int((self.xmax // ds) * ds)
3664
- if x2 > self.xmax:
3665
- x2 -= ds
3666
- y1 = np.ceil((self.ymin // ds) * ds)
3667
- if y1 < self.ymin:
3668
- y1 += ds
3669
- y2 = int((self.ymax // ds) * ds)
3670
- if y2 > self.ymax:
3671
- y2 -= ds
3700
+ pot_title = self.viewer_name
3701
+ if arrayid_as_title:
3702
+ pot_title = self.active_array.idx
3672
3703
 
3673
- x_label_list = np.linspace(x1, x2, int((x2 - x1) / ds) + 1, True)
3674
- x_label_list = np.insert(x_label_list, 0, self.xmin)
3675
- x_label_list = np.insert(x_label_list, -1, self.xmax)
3676
- 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)
3677
3708
 
3678
- y_label_list = np.linspace(y1, y2, int((y2 - y1) / ds) + 1, True)
3679
- y_label_list = np.insert(y_label_list, 0, self.ymin)
3680
- y_label_list = np.insert(y_label_list, -1, self.ymax)
3681
- 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')
3682
3713
 
3683
- ax.set_xticks(x_label_list)
3684
- 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)
3718
+
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)
3685
3723
 
3686
- ax.set_xticklabels(plt.FormatStrFormatter('%.1f').format_ticks(x_label_list), fontsize=8, rotation=30)
3687
- ax.set_yticklabels(plt.FormatStrFormatter('%.1f').format_ticks(y_label_list), fontsize=8)
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)))
3688
3727
 
3689
- ax.set_xlabel('X [m]')
3690
- ax.set_ylabel('Y [m]')
3728
+ imnew = Image.new('RGB',(im.size[0]+impal.size[0], im.size[1]), (255,255,255))
3691
3729
 
3692
- if self.palette_for_copy.values is not None:
3693
- self.palette_for_copy.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()
3694
3735
  else:
3695
- axes[1].clear()
3696
- axes[1].axis('off')
3736
+ imnew = Image.new('RGB', (im.size[0], im.size[1]), (255,255,255))
3697
3737
 
3698
- # if self.active_array is not None:
3699
- # self.active_array.mypal.export_image(None, h_or_v='v', figax=(fig,axes[1]))
3700
- # elif self.active_res2d is not None:
3701
- # self.active_res2d.mypal.export_image(None, h_or_v='v', figax=(fig,axes[1]))
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
3702
3741
 
3703
- # self.Paint()
3704
-
3705
- if add_title:
3706
- ax.set_title(self.viewer_name)
3707
- fig.set_size_inches(12, 10)
3708
- fig.tight_layout()
3742
+ im.save(fn, dpi=(dpi, dpi))
3743
+ fig.set_visible(False)
3744
+ buf.close()
3709
3745
 
3710
- fig.savefig(fn, dpi=dpi)
3711
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()
3712
3754
  myimage.save(fn, pnginfo=metadata)
3713
3755
 
3714
3756
  return fn, ds
@@ -4828,195 +4870,201 @@ class WolfMapViewer(wx.Frame):
4828
4870
  A compléter...
4829
4871
 
4830
4872
  """
4873
+ curdir = Path(os.getcwd())
4874
+
4831
4875
  myproject = Wolf_Param(None, filename=fn, toShow=False)
4832
4876
 
4833
4877
  mykeys = ['cross_sections', 'vector', 'array']
4834
4878
 
4835
- with wx.lib.busy.BusyInfo(_('Opening project')):
4836
- wait = wx.BusyCursor()
4837
- if 'which' in myproject.myparams.keys():
4838
- which = myproject.myparams['which']['action'][key_Param.VALUE]
4839
- if which == 'compare':
4840
- ListCompare = []
4841
- if 'array' in myproject.myparams.keys():
4842
- for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4843
- ListCompare.append(WolfArray(normpath(curname[key_Param.VALUE])))
4844
-
4845
- self.set_compare(ListCompare)
4846
- return
4879
+ if 'which' in myproject.myparams.keys():
4880
+ which = myproject.myparams['which']['action'][key_Param.VALUE]
4881
+ if which == 'compare':
4882
+ ListCompare = []
4883
+ if 'array' in myproject.myparams.keys():
4884
+ for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4885
+ ListCompare.append(WolfArray(normpath(curname[key_Param.VALUE])))
4847
4886
 
4848
- if 'cross_sections' in myproject.myparams.keys():
4849
- for curid, curname in zip(myproject.myparams['cross_sections'].keys(),
4850
- myproject.myparams['cross_sections'].values()):
4851
- if curid != 'format' and curid != 'dirlaz':
4852
- mycs = crosssections(curname[key_Param.VALUE],
4853
- format=myproject.myparams['cross_sections']['format'][key_Param.VALUE],
4854
- dirlaz=myproject.myparams['cross_sections']['dirlaz'][key_Param.VALUE],
4855
- mapviewer = self)
4856
-
4857
- self.add_object('cross_sections', newobj=mycs, id=curid)
4887
+ self.set_compare(ListCompare)
4888
+ return
4858
4889
 
4890
+ if 'cross_sections' in myproject.myparams.keys():
4891
+ for curid, curname in zip(myproject.myparams['cross_sections'].keys(),
4892
+ myproject.myparams['cross_sections'].values()):
4893
+ if curid != 'format' and curid != 'dirlaz':
4894
+ mycs = crosssections(curname[key_Param.VALUE],
4895
+ format=myproject.myparams['cross_sections']['format'][key_Param.VALUE],
4896
+ dirlaz=myproject.myparams['cross_sections']['dirlaz'][key_Param.VALUE],
4897
+ mapviewer = self)
4859
4898
 
4860
- if myproject.get_group('tiles') is not None:
4899
+ self.add_object('cross_sections', newobj=mycs, id=curid)
4861
4900
 
4862
- curid = myproject.get_param('tiles', 'id')
4863
- curfile = myproject.get_param('tiles', 'tiles_file')
4864
- curdatadir = myproject.get_param('tiles', 'data_dir')
4865
- curcompdir = myproject.get_param('tiles', 'comp_dir')
4866
4901
 
4867
- if exists(curfile):
4868
- mytiles = Tiles(filename= curfile, parent=self, linked_data_dir=curdatadir)
4869
- mytiles.set_comp_dir(curcompdir)
4870
- self.add_object('tiles', newobj=mytiles, id=curid)
4871
- else:
4872
- logging.info(_('Bad parameter in project file - tiles : ')+ curfile)
4902
+ if myproject.get_group('tiles') is not None:
4873
4903
 
4874
- if myproject.get_group('laz_grid') is not None:
4904
+ curid = myproject.get_param('tiles', 'id')
4905
+ curfile = myproject.get_param('tiles', 'tiles_file')
4906
+ curdatadir = myproject.get_param('tiles', 'data_dir')
4907
+ curcompdir = myproject.get_param('tiles', 'comp_dir')
4875
4908
 
4876
- curdatadir = myproject.get_param('laz_grid', 'data_dir')
4909
+ if exists(curfile):
4910
+ mytiles = Tiles(filename= curfile, parent=self, linked_data_dir=curdatadir)
4911
+ mytiles.set_comp_dir(curcompdir)
4912
+ self.add_object('tiles', newobj=mytiles, id=curid)
4913
+ else:
4914
+ logging.info(_('Bad parameter in project file - tiles : ')+ curfile)
4877
4915
 
4878
- self.init_laz_from_gridinfos(curdatadir)
4916
+ if myproject.get_group('laz_grid') is not None:
4879
4917
 
4880
- if 'vector' in myproject.myparams.keys():
4881
- for curid, curname in zip(myproject.myparams['vector'].keys(), myproject.myparams['vector'].values()):
4882
- if exists(curname[key_Param.VALUE]):
4883
- myvec = Zones(curname[key_Param.VALUE], parent=self, mapviewer = self)
4884
- self.add_object('vector', newobj=myvec, id=curid)
4885
- else:
4886
- logging.info(_('Bad parameter in project file - vector : ')+ curname[key_Param.VALUE])
4918
+ curdatadir = myproject.get_param('laz_grid', 'data_dir')
4887
4919
 
4888
- if 'array' in myproject.myparams.keys():
4889
- for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4920
+ self.init_laz_from_gridinfos(curdatadir)
4890
4921
 
4891
- if exists(curname[key_Param.VALUE]):
4892
- curarray = WolfArray(curname[key_Param.VALUE], mapviewer=self)
4893
- self.add_object('array', newobj=curarray, id=curid)
4894
- else:
4895
- logging.info(_('Bad parameter in project file - array : ')+ curname[key_Param.VALUE])
4922
+ if 'vector' in myproject.myparams.keys():
4923
+ for curid, curname in zip(myproject.myparams['vector'].keys(), myproject.myparams['vector'].values()):
4924
+ if exists(curname[key_Param.VALUE]):
4925
+ myvec = Zones(curname[key_Param.VALUE], parent=self, mapviewer = self)
4926
+ self.add_object('vector', newobj=myvec, id=curid)
4927
+ else:
4928
+ logging.info(_('Bad parameter in project file - vector : ')+ curname[key_Param.VALUE])
4896
4929
 
4897
- if 'cloud' in myproject.myparams.keys():
4898
- for curid, curname in zip(myproject.myparams['cloud'].keys(), myproject.myparams['cloud'].values()):
4899
- if exists(curname[key_Param.VALUE]):
4900
- mycloud = cloud_vertices(curname[key_Param.VALUE], mapviewer=self)
4901
- self.add_object('cloud', newobj=mycloud, id=curid)
4902
- else:
4903
- logging.info(_('Bad parameter in project file - cloud : ')+ curname[key_Param.VALUE])
4930
+ if 'array' in myproject.myparams.keys():
4931
+ for curid, curname in zip(myproject.myparams['array'].keys(), myproject.myparams['array'].values()):
4904
4932
 
4905
- if 'wolf2d' in myproject.myparams.keys():
4906
- for curid, curname in zip(myproject.myparams['wolf2d'].keys(), myproject.myparams['wolf2d'].values()):
4907
- if exists(curname[key_Param.VALUE]):
4908
- curwolf = Wolfresults_2D(curname[key_Param.VALUE], mapviewer=self)
4909
- self.add_object('res2d', newobj=curwolf, id=curid)
4910
- else:
4911
- logging.info(_('Bad parameter in project file - wolf2d : ')+ curname[key_Param.VALUE])
4933
+ if exists(curname[key_Param.VALUE]):
4934
+ curarray = WolfArray(curname[key_Param.VALUE], mapviewer=self)
4935
+ self.add_object('array', newobj=curarray, id=curid)
4936
+ else:
4937
+ logging.info(_('Bad parameter in project file - array : ')+ curname[key_Param.VALUE])
4912
4938
 
4913
- self.menu_wolf2d()
4939
+ if 'cloud' in myproject.myparams.keys():
4940
+ for curid, curname in zip(myproject.myparams['cloud'].keys(), myproject.myparams['cloud'].values()):
4941
+ if exists(curname[key_Param.VALUE]):
4942
+ mycloud = cloud_vertices(curname[key_Param.VALUE], mapviewer=self)
4943
+ self.add_object('cloud', newobj=mycloud, id=curid)
4944
+ else:
4945
+ logging.info(_('Bad parameter in project file - cloud : ')+ curname[key_Param.VALUE])
4914
4946
 
4915
- if 'gpu2d' in myproject.myparams.keys():
4916
- for curid, curname in zip(myproject.myparams['gpu2d'].keys(), myproject.myparams['gpu2d'].values()):
4917
- if exists(curname[key_Param.VALUE]):
4947
+ if 'wolf2d' in myproject.myparams.keys():
4948
+ for curid, curname in zip(myproject.myparams['wolf2d'].keys(), myproject.myparams['wolf2d'].values()):
4949
+ if exists(curname[key_Param.VALUE]):
4950
+ curwolf = Wolfresults_2D(curname[key_Param.VALUE], mapviewer=self)
4951
+ self.add_object('res2d', newobj=curwolf, id=curid)
4952
+ else:
4953
+ logging.info(_('Bad parameter in project file - wolf2d : ')+ curname[key_Param.VALUE])
4918
4954
 
4919
- if 'simul_gpu_results' in curname[key_Param.VALUE]:
4920
- curwolf = wolfres2DGPU(Path(curname[key_Param.VALUE]), mapviewer=self)
4921
- else:
4922
- if exists(join(curname[key_Param.VALUE], 'simul_gpu_results')):
4923
- curwolf = wolfres2DGPU(Path(join(curname[key_Param.VALUE], 'simul_gpu_results')), mapviewer=self)
4924
- else:
4925
- logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
4955
+ self.menu_wolf2d()
4926
4956
 
4927
- self.add_object('res2d', newobj=curwolf, id=curid)
4928
- else:
4929
- logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
4957
+ if 'gpu2d' in myproject.myparams.keys():
4930
4958
 
4931
- self.menu_wolf2d()
4932
- self.menu_2dgpu()
4959
+ pgbar = wx.ProgressDialog(_('Loading GPU results'), _('Loading GPU results'), maximum=len(myproject.myparams['gpu2d'].keys()), parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE)
4933
4960
 
4934
- if 'palette' in myproject.myparams.keys():
4935
- self.project_pal = {}
4936
- for curid, curname in zip(myproject.myparams['palette'].keys(), myproject.myparams['palette'].values()):
4937
- if exists(curname[key_Param.VALUE]):
4938
- mypal = wolfpalette(None, '')
4939
- mypal.readfile(curname[key_Param.VALUE])
4940
- mypal.automatic = False
4961
+ for curid, curname in zip(myproject.myparams['gpu2d'].keys(), myproject.myparams['gpu2d'].values()):
4962
+ if exists(curname[key_Param.VALUE]):
4941
4963
 
4942
- self.project_pal[curid] = mypal
4964
+ if 'simul_gpu_results' in curname[key_Param.VALUE]:
4965
+ curwolf = wolfres2DGPU(curdir / Path(curname[key_Param.VALUE]), mapviewer=self)
4943
4966
  else:
4944
- logging.info(_('Bad parameter in project file - palette : ')+ curname[key_Param.VALUE])
4945
-
4946
- if 'palette-array' in myproject.myparams.keys():
4947
- curarray: WolfArray
4948
- if self.project_pal is not None:
4949
- for curid, curname in zip(myproject.myparams['palette-array'].keys(),
4950
- myproject.myparams['palette-array'].values()):
4951
- if curname[key_Param.VALUE] in self.project_pal.keys():
4952
- curarray = self.getobj_from_id(curid)
4953
- if curarray is not None:
4954
- mypal:wolfpalette
4955
- mypal = self.project_pal[curname[key_Param.VALUE]]
4956
- curarray.mypal = mypal
4957
- if mypal.automatic:
4958
- curarray.myops.palauto.SetValue(1)
4959
- else:
4960
- curarray.myops.palauto.SetValue(0)
4961
- curarray.updatepalette(0)
4962
- curarray.delete_lists()
4963
- else:
4964
- logging.warning(_('Bad parameter in project file - palette-array : ')+ curid)
4965
-
4966
- if 'cross_sections_link' in myproject.myparams.keys():
4967
- if 'linkzones' in myproject.myparams['cross_sections_link'].keys():
4968
- idx = myproject.myparams['cross_sections_link']['linkzones'][key_Param.VALUE]
4967
+ if exists(join(curname[key_Param.VALUE], 'simul_gpu_results')):
4968
+ curwolf = wolfres2DGPU(curdir / Path(join(curname[key_Param.VALUE], 'simul_gpu_results')), mapviewer=self)
4969
+ else:
4970
+ logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
4969
4971
 
4970
- for curzones in self.iterator_over_objects(draw_type.VECTORS):
4971
- curzones: Zones
4972
- if curzones.idx == idx:
4973
- self.active_cs.link_external_zones(curzones)
4972
+ self.add_object('res2d', newobj=curwolf, id=curid)
4973
+ else:
4974
+ logging.info(_('Bad directory : ')+ curname[key_Param.VALUE])
4974
4975
 
4975
- zonename = ''
4976
- vecname = ''
4976
+ pgbar.Update(pgbar.GetValue() + 1)
4977
4977
 
4978
- if 'sortzone' in myproject.myparams['cross_sections_link'].keys():
4979
- zonename = myproject.myparams['cross_sections_link']['sortzone'][key_Param.VALUE]
4980
- if 'sortname' in myproject.myparams['cross_sections_link'].keys():
4981
- vecname = myproject.myparams['cross_sections_link']['sortname'][key_Param.VALUE]
4978
+ pgbar.Destroy()
4982
4979
 
4983
- if zonename != '' and vecname != '':
4984
- names = [cur.myname for cur in curzones.myzones]
4985
- idx = names.index(zonename)
4986
- curzone = curzones.myzones[idx]
4987
- names = [cur.myname for cur in curzone.myvectors]
4988
- idx = names.index(vecname)
4989
- curvec = curzone.myvectors[idx]
4980
+ self.menu_wolf2d()
4981
+ self.menu_2dgpu()
4990
4982
 
4991
- if curvec is not None:
4992
- curvec: vector
4993
- self.active_cs.sort_along(curvec.asshapely_ls(), curvec.myname, False)
4983
+ if 'palette' in myproject.myparams.keys():
4984
+ self.project_pal = {}
4985
+ for curid, curname in zip(myproject.myparams['palette'].keys(), myproject.myparams['palette'].values()):
4986
+ if exists(curname[key_Param.VALUE]):
4987
+ mypal = wolfpalette(None, '')
4988
+ mypal.readfile(curname[key_Param.VALUE])
4989
+ mypal.automatic = False
4994
4990
 
4995
- if 'vector_array_link' in myproject.myparams.keys():
4996
- for curid, curname in zip(myproject.myparams['vector_array_link'].keys(), myproject.myparams['vector_array_link'].values()):
4991
+ self.project_pal[curid] = mypal
4992
+ else:
4993
+ logging.info(_('Bad parameter in project file - palette : ')+ curname[key_Param.VALUE])
4997
4994
 
4998
- locvec = None
4999
- locarray = None
5000
- for curvec in self.myvectors:
5001
- if curvec.idx == curname[key_Param.VALUE].lower():
5002
- locvec=curvec
5003
- break
4995
+ if 'palette-array' in myproject.myparams.keys():
4996
+ curarray: WolfArray
4997
+ if self.project_pal is not None:
4998
+ for curid, curname in zip(myproject.myparams['palette-array'].keys(),
4999
+ myproject.myparams['palette-array'].values()):
5000
+ if curname[key_Param.VALUE] in self.project_pal.keys():
5001
+ curarray = self.getobj_from_id(curid)
5002
+ if curarray is not None:
5003
+ mypal:wolfpalette
5004
+ mypal = self.project_pal[curname[key_Param.VALUE]]
5005
+ curarray.mypal = mypal
5006
+ if mypal.automatic:
5007
+ curarray.myops.palauto.SetValue(1)
5008
+ else:
5009
+ curarray.myops.palauto.SetValue(0)
5010
+ curarray.updatepalette(0)
5011
+ curarray.delete_lists()
5012
+ else:
5013
+ logging.warning(_('Bad parameter in project file - palette-array : ')+ curid)
5014
+
5015
+ if 'cross_sections_link' in myproject.myparams.keys():
5016
+ if 'linkzones' in myproject.myparams['cross_sections_link'].keys():
5017
+ idx = myproject.myparams['cross_sections_link']['linkzones'][key_Param.VALUE]
5018
+
5019
+ for curzones in self.iterator_over_objects(draw_type.VECTORS):
5020
+ curzones: Zones
5021
+ if curzones.idx == idx:
5022
+ self.active_cs.link_external_zones(curzones)
5023
+
5024
+ zonename = ''
5025
+ vecname = ''
5026
+
5027
+ if 'sortzone' in myproject.myparams['cross_sections_link'].keys():
5028
+ zonename = myproject.myparams['cross_sections_link']['sortzone'][key_Param.VALUE]
5029
+ if 'sortname' in myproject.myparams['cross_sections_link'].keys():
5030
+ vecname = myproject.myparams['cross_sections_link']['sortname'][key_Param.VALUE]
5031
+
5032
+ if zonename != '' and vecname != '':
5033
+ names = [cur.myname for cur in curzones.myzones]
5034
+ idx = names.index(zonename)
5035
+ curzone = curzones.myzones[idx]
5036
+ names = [cur.myname for cur in curzone.myvectors]
5037
+ idx = names.index(vecname)
5038
+ curvec = curzone.myvectors[idx]
5039
+
5040
+ if curvec is not None:
5041
+ curvec: vector
5042
+ self.active_cs.sort_along(curvec.asshapely_ls(), curvec.myname, False)
5043
+
5044
+ if 'vector_array_link' in myproject.myparams.keys():
5045
+ for curid, curname in zip(myproject.myparams['vector_array_link'].keys(), myproject.myparams['vector_array_link'].values()):
5046
+
5047
+ locvec = None
5048
+ locarray = None
5049
+ for curvec in self.myvectors:
5050
+ if curvec.idx == curname[key_Param.VALUE].lower():
5051
+ locvec=curvec
5052
+ break
5004
5053
 
5005
- for curarray in self.myarrays:
5006
- if curarray.idx == curid.lower():
5007
- locarray=curarray
5008
- break
5054
+ for curarray in self.myarrays:
5055
+ if curarray.idx == curid.lower():
5056
+ locarray=curarray
5057
+ break
5009
5058
 
5010
- if locvec is not None and locarray is not None:
5059
+ if locvec is not None and locarray is not None:
5011
5060
 
5012
- locarray.linkedvec = locvec.myzones[0].myvectors[0]
5061
+ locarray.linkedvec = locvec.myzones[0].myvectors[0]
5013
5062
 
5014
- else:
5063
+ else:
5015
5064
 
5016
- logging.warning(_('Bad vec-array association in project file !'))
5017
- logging.warning(curid)
5018
- logging.warning(curname[key_Param.VALUE])
5019
- del wait
5065
+ logging.warning(_('Bad vec-array association in project file !'))
5066
+ logging.warning(curid)
5067
+ logging.warning(curname[key_Param.VALUE])
5020
5068
 
5021
5069
  def save_project(self, fn):
5022
5070
  myproject = Wolf_Param(None, toShow=False)
@@ -5598,7 +5646,9 @@ class WolfMapViewer(wx.Frame):
5598
5646
 
5599
5647
  self.currently_readresults = True
5600
5648
 
5601
- 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)):
5602
5652
  curmodel: Wolfresults_2D
5603
5653
  logging.info(_('Updating {} - Last result'.format(curmodel.idx)))
5604
5654
 
@@ -5606,6 +5656,10 @@ class WolfMapViewer(wx.Frame):
5606
5656
  curmodel.set_currentview()
5607
5657
  self._update_sim_explorer(curmodel)
5608
5658
 
5659
+ pgbar.Update(id + 1, _('Reading results') + ' - ' + curmodel.idx)
5660
+
5661
+ pgbar.Destroy()
5662
+
5609
5663
  self.Refresh()
5610
5664
  self.currently_readresults = False
5611
5665
  self._update_mytooltip()
@@ -5765,8 +5819,10 @@ class WolfMapViewer(wx.Frame):
5765
5819
  filename = file.GetPath()
5766
5820
  file.Destroy()
5767
5821
 
5822
+ old_dir = os.getcwd()
5768
5823
  os.chdir(os.path.dirname(filename))
5769
5824
  self.read_project(filename)
5825
+ os.chdir(old_dir)
5770
5826
 
5771
5827
  elif itemlabel == _('Shortcuts'):
5772
5828
  # show shortcuts in log
@@ -6568,8 +6624,21 @@ class WolfMapViewer(wx.Frame):
6568
6624
 
6569
6625
  nb = dlg.GetValue()
6570
6626
  dlg.Destroy()
6571
- for i in range(nb):
6572
- 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 !'))
6573
6642
 
6574
6643
  elif itemlabel == _('3D viewer'):
6575
6644
 
@@ -7477,6 +7546,44 @@ class WolfMapViewer(wx.Frame):
7477
7546
 
7478
7547
  return ret
7479
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
+
7480
7587
  def assembly_images(self, all_images, mode:Literal['horizontal', 'vertical', 'square']= 'square'):
7481
7588
  """ Assembly images
7482
7589
 
@@ -7492,6 +7599,9 @@ class WolfMapViewer(wx.Frame):
7492
7599
 
7493
7600
  images = [Image.open(fn) for (fn, ds), viewername in all_images]
7494
7601
 
7602
+ if len(images) in [1,2] and (mode == 'square' or mode == 2):
7603
+ mode = 'horizontal'
7604
+
7495
7605
  widths, heights = zip(*(i.size for i in images))
7496
7606
 
7497
7607
  if mode == 'horizontal' or mode==0:
@@ -7581,7 +7691,7 @@ class WolfMapViewer(wx.Frame):
7581
7691
  filterjson = "json (*.json)|*.json|all (*.*)|*.*"
7582
7692
  filterall = "all (*.*)|*.*"
7583
7693
  filterres2d = "all (*.*)|*.*"
7584
- filterVector = "vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|dxf (*.dxf)|*.dxf|shp (*.shp)|*.shp|all (*.*)|*.*"
7694
+ filterVector = "All supported formats|*.vec;*.vecz;*.dxf;*.shp|vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|dxf (*.dxf)|*.dxf|shp (*.shp)|*.shp|all (*.*)|*.*"
7585
7695
  filterCloud = "xyz (*.xyz)|*.xyz|dxf (*.dxf)|*.dxf|text (*.txt)|*.txt|shp (*.shp)|*.shp|all (*.*)|*.*"
7586
7696
  filtertri = "tri (*.tri)|*.tri|text (*.txt)|*.txt|dxf (*.dxf)|*.dxf|gltf (*.gltf)|*.gltf|gltf binary (*.glb)|*.glb|*.*'all (*.*)|*.*"
7587
7697
  filterCs = "vecz WOLF (*.vecz)|*.vecz|txt 2022 (*.txt)|*.txt|WOLF (*.sxy)|*.sxy|text 2000 (*.txt)|*.txt|all (*.*)|*.*"
@@ -7824,8 +7934,13 @@ class WolfMapViewer(wx.Frame):
7824
7934
  wait = wx.BusyCursor()
7825
7935
  newobj = Bridges(filename, mapviewer=self)
7826
7936
  del wait
7937
+
7827
7938
  self.myvectors.append(newobj)
7828
7939
 
7940
+ self.active_bridges = newobj
7941
+
7942
+ self.menu_bridges()
7943
+
7829
7944
  elif which.lower() == 'weirs':
7830
7945
  curdict = self.myvectors
7831
7946
  curtree = self.myitemsvector
@@ -7837,6 +7952,10 @@ class WolfMapViewer(wx.Frame):
7837
7952
  del wait
7838
7953
  self.myvectors.append(newobj)
7839
7954
 
7955
+ self.active_weirs = newobj
7956
+
7957
+ self.menu_weirs()
7958
+
7840
7959
  elif which.lower() in ['tiles', 'tilescomp']:
7841
7960
  curdict = self.mytiles
7842
7961
  curtree = self.myitemsvector
@@ -8622,6 +8741,8 @@ class WolfMapViewer(wx.Frame):
8622
8741
  self.selected_object.write_all()
8623
8742
  elif type(self.selected_object) is Zones:
8624
8743
  self.selected_object.saveas()
8744
+ elif type(self.selected_object) in [Bridge, Weir]:
8745
+ self.selected_object.saveas()
8625
8746
  elif type(self.selected_object) is Triangulation:
8626
8747
  self.selected_object.saveas()
8627
8748
  elif isinstance(self.selected_object, Particle_system):
@@ -8742,7 +8863,7 @@ class WolfMapViewer(wx.Frame):
8742
8863
 
8743
8864
  self.selected_object.write_all()
8744
8865
  fdlg.Destroy()
8745
- elif type(self.selected_object) is Zones:
8866
+ elif type(self.selected_object) in [Zones, Bridge, Weir]:
8746
8867
  filterArray = "vec (*.vec)|*.vec|vecz (*.vecz)|*.vecz|Shapefile (*.shp)|*.shp|all (*.*)|*.*"
8747
8868
  fdlg = wx.FileDialog(self, "Choose file name for Vector :" + self.selected_object.idx, wildcard=filterArray,
8748
8869
  style=wx.FD_SAVE)
@@ -8772,8 +8893,9 @@ class WolfMapViewer(wx.Frame):
8772
8893
  elif text == _('Properties'):
8773
8894
 
8774
8895
  myobj = self.selected_object
8775
- if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui]:
8896
+ if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui, Bridge, Weir]:
8776
8897
  myobj.show_properties()
8898
+
8777
8899
  elif isinstance(myobj, cloud_vertices):
8778
8900
  myobj.show_properties()
8779
8901
 
@@ -8820,6 +8942,24 @@ class WolfMapViewer(wx.Frame):
8820
8942
  else:
8821
8943
  logging.warning(_('Rebin not yet implemented for this type of object'))
8822
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
+
8823
8963
  elif _('Convert to mono-block') in text:
8824
8964
 
8825
8965
  if isinstance(self.selected_object, WolfArrayMB):
@@ -8854,9 +8994,33 @@ class WolfMapViewer(wx.Frame):
8854
8994
  else:
8855
8995
  logging.warning(_('Convert to multi-blocks not yet implemented for this type of object'))
8856
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
+
8857
9021
  elif _('Export to Shape file') in text:
8858
9022
 
8859
- if isinstance(self.selected_object, Zones):
9023
+ if isinstance(self.selected_object, Zones | Bridge | Weir):
8860
9024
  filterArray = "Shapefile (*.shp)|*.shp"
8861
9025
  fdlg = wx.FileDialog(self, "Choose file name for Zones :" + self.selected_object.idx, wildcard=filterArray,
8862
9026
  style=wx.FD_SAVE)
@@ -8867,7 +9031,7 @@ class WolfMapViewer(wx.Frame):
8867
9031
 
8868
9032
  elif _('Export active zone to Shape file') in text:
8869
9033
 
8870
- if isinstance(self.selected_object, Zones):
9034
+ if isinstance(self.selected_object, Zones | Bridge | Weir):
8871
9035
 
8872
9036
  filterArray = "Shapefile (*.shp)|*.shp"
8873
9037
  fdlg = wx.FileDialog(self, "Choose file name for Vector :" + self.selected_object.idx, wildcard=filterArray,
@@ -9094,12 +9258,12 @@ class WolfMapViewer(wx.Frame):
9094
9258
  logging.warning(_('No triangles selected -- Please select a triangulation first !'))
9095
9259
  return
9096
9260
 
9097
- if self.active_tri._start_move is None:
9098
- self.active_tri._start_move = (x, y)
9261
+ if self.active_tri._move_start is None:
9262
+ self.active_tri._move_start = (x, y)
9099
9263
  return
9100
9264
 
9101
- delta_x = x - self.active_tri._start_move[0]
9102
- delta_y = y - self.active_tri._start_move[1]
9265
+ delta_x = x - self.active_tri._move_start[0]
9266
+ delta_y = y - self.active_tri._move_start[1]
9103
9267
 
9104
9268
  if shiftdown:
9105
9269
  delta_y = 0.
@@ -9109,7 +9273,7 @@ class WolfMapViewer(wx.Frame):
9109
9273
 
9110
9274
  self.active_tri.move(delta_x, delta_y)
9111
9275
  self.active_tri.reset_plot()
9112
- self.active_tri._start_move = None
9276
+ self.active_tri._move_start = None
9113
9277
  self.active_tri.clear_cache()
9114
9278
  self.end_action(_('End move triangulation'))
9115
9279
 
@@ -9149,6 +9313,12 @@ class WolfMapViewer(wx.Frame):
9149
9313
  self.active_landmap.load_texture(x,y, which='low')
9150
9314
  self.Refresh()
9151
9315
 
9316
+ elif self.action == 'pick bridge':
9317
+ self.pick_bridge(x, y)
9318
+
9319
+ elif self.action == 'pick weir':
9320
+ self.pick_weir(x, y)
9321
+
9152
9322
  elif self.action == 'bridge gltf':
9153
9323
  # Create a bridge in gltf format
9154
9324
 
@@ -9356,12 +9526,12 @@ class WolfMapViewer(wx.Frame):
9356
9526
  logging.warning(_('No vector selected -- Please select a vector first !'))
9357
9527
  return
9358
9528
 
9359
- if self.active_vector._start_move is None:
9360
- self.active_vector._start_move = (x, y)
9529
+ if self.active_vector._move_start is None:
9530
+ self.active_vector._move_start = (x, y)
9361
9531
  return
9362
9532
 
9363
- delta_x = x - self.active_vector._start_move[0]
9364
- delta_y = y - self.active_vector._start_move[1]
9533
+ delta_x = x - self.active_vector._move_start[0]
9534
+ delta_y = y - self.active_vector._move_start[1]
9365
9535
 
9366
9536
  if shiftdown:
9367
9537
  delta_y = 0.
@@ -9400,8 +9570,8 @@ class WolfMapViewer(wx.Frame):
9400
9570
  logging.warning(_('No zone selected -- Please select a zone first !'))
9401
9571
  return
9402
9572
 
9403
- if self.active_zone._start_move is None:
9404
- self.active_zone._start_move = (x, y)
9573
+ if self.active_zone._move_start is None:
9574
+ self.active_zone._move_start = (x, y)
9405
9575
  return
9406
9576
 
9407
9577
  if shiftdown:
@@ -9410,7 +9580,7 @@ class WolfMapViewer(wx.Frame):
9410
9580
  if alt:
9411
9581
  delta_x = 0.
9412
9582
 
9413
- self.active_zone.move(x - self.active_zone._start_move[0], y - self.active_zone._start_move[1])
9583
+ self.active_zone.move(x - self.active_zone._move_start[0], y - self.active_zone._move_start[1])
9414
9584
  self.active_zone.clear_cache()
9415
9585
  self.end_action(_('End move zone'))
9416
9586
 
@@ -9657,6 +9827,18 @@ class WolfMapViewer(wx.Frame):
9657
9827
  if ctrl:
9658
9828
  myobj.show_properties()
9659
9829
 
9830
+ elif type(myobj) == Bridge:
9831
+ self.active_bridge = myobj
9832
+
9833
+ if ctrl:
9834
+ myobj.show_properties()
9835
+
9836
+ elif type(myobj) == Weir:
9837
+ self.active_weir = myobj
9838
+
9839
+ if ctrl:
9840
+ myobj.show_properties()
9841
+
9660
9842
  elif isinstance(myobj, PlansTerrier):
9661
9843
  self.active_landmap = myobj
9662
9844
 
@@ -10131,10 +10313,10 @@ class WolfMapViewer(wx.Frame):
10131
10313
 
10132
10314
  if self.action == 'move vector':
10133
10315
  if self.active_vector is not None:
10134
- if self.active_vector._start_move is not None:
10316
+ if self.active_vector._move_start is not None:
10135
10317
 
10136
- delta_x = x - self.active_vector._start_move[0]
10137
- delta_y = y - self.active_vector._start_move[1]
10318
+ delta_x = x - self.active_vector._move_start[0]
10319
+ delta_y = y - self.active_vector._move_start[1]
10138
10320
 
10139
10321
  if shiftdown:
10140
10322
  delta_y = 0.
@@ -10146,10 +10328,10 @@ class WolfMapViewer(wx.Frame):
10146
10328
 
10147
10329
  if self.action == 'move triangles':
10148
10330
  if self.active_tri is not None:
10149
- if self.active_tri._start_move is not None:
10331
+ if self.active_tri._move_start is not None:
10150
10332
 
10151
- delta_x = x - self.active_tri._start_move[0]
10152
- delta_y = y - self.active_tri._start_move[1]
10333
+ delta_x = x - self.active_tri._move_start[0]
10334
+ delta_y = y - self.active_tri._move_start[1]
10153
10335
 
10154
10336
  if shiftdown:
10155
10337
  delta_y = 0.
@@ -10174,9 +10356,9 @@ class WolfMapViewer(wx.Frame):
10174
10356
 
10175
10357
  if self.action == 'move zone':
10176
10358
  if self.active_zone is not None:
10177
- if self.active_zone._start_move is not None:
10178
- delta_x = x - self.active_zone._start_move[0]
10179
- delta_y = y - self.active_zone._start_move[1]
10359
+ if self.active_zone._move_start is not None:
10360
+ delta_x = x - self.active_zone._move_start[0]
10361
+ delta_y = y - self.active_zone._move_start[1]
10180
10362
 
10181
10363
  if shiftdown:
10182
10364
  delta_y = 0.
@@ -10532,6 +10714,8 @@ class WolfMapViewer(wx.Frame):
10532
10714
  # CTRL+L : chargement d'une matrice sur base du nom de fichier de la tile\n \
10533
10715
  # \n \
10534
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 \
10535
10719
 
10536
10720
  groups = ['Results', 'Particle system', 'Drawing', 'Arrays', 'Cross sections', 'Zones', 'Action', 'Tree', 'Tiles', 'GLTF/GLB', 'App']
10537
10721
 
@@ -10563,7 +10747,8 @@ class WolfMapViewer(wx.Frame):
10563
10747
  'Arrows': _('Drawing : lateral movements'),
10564
10748
  'c or C': _('Drawing : copy canvas to Clipboard wo axes'),
10565
10749
  'ALT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
10566
- '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'),
10567
10752
 
10568
10753
  'CTRL+o': _('Results : increase transparency of the current result'),
10569
10754
  'CTRL+O': _('Results : decrease transparency of the current result'),
@@ -10827,7 +11012,7 @@ class WolfMapViewer(wx.Frame):
10827
11012
  newarray.nullify_border(width=1)
10828
11013
 
10829
11014
  #keys for arrays
10830
- keys = self.get_list_keys(draw_type.ARRAYS, checked_state=False)
11015
+ keys = self.get_list_keys(draw_type.ARRAYS, checked_state=None)
10831
11016
  new_key = self.active_array.idx + '_crop'
10832
11017
 
10833
11018
  while new_key in keys:
@@ -10884,12 +11069,20 @@ class WolfMapViewer(wx.Frame):
10884
11069
  # Copie du canvas dans le clipboard pour transfert vers autre application
10885
11070
  # Copie des canvas liés
10886
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
+
10887
11077
  from tempfile import TemporaryDirectory
10888
11078
 
10889
11079
  logging.info(_('Creating images'))
10890
11080
 
10891
11081
  with TemporaryDirectory() as tmpdirname:
10892
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
10893
11086
  im_assembly = self.assembly_images(all_images, mode= self.assembly_mode)
10894
11087
 
10895
11088
  logging.info(_('Creating images - done'))
@@ -10942,7 +11135,44 @@ class WolfMapViewer(wx.Frame):
10942
11135
 
10943
11136
  logging.info(_('Values copied to clipboard'))
10944
11137
 
10945
- 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:
10946
11176
  if self.active_array is None:
10947
11177
  dlg = wx.MessageDialog(self,
10948
11178
  _('The active array is None - Please active an array from which to copy the selection !'),
@@ -11316,9 +11546,11 @@ class WolfMapViewer(wx.Frame):
11316
11546
  tracks.append(_('Convert to mono-block'))
11317
11547
  tracks.append(_('Convert to mono-block (result)'))
11318
11548
  tracks.append(_('Convert to multi-blocks (result)'))
11549
+ tracks.append(_('Extract current step as IC (result)'))
11319
11550
  tracks.append(_('Export to Shape file'))
11320
11551
  tracks.append(_('Export active zone to Shape file'))
11321
11552
  tracks.append(_('Rebin'))
11553
+ tracks.append(_('Set NullValue'))
11322
11554
 
11323
11555
  # Récupération des items du menu contextuel
11324
11556
  menuitems = self.popupmenu.GetMenuItems()
@@ -11345,6 +11577,7 @@ class WolfMapViewer(wx.Frame):
11345
11577
  self.popupmenu.Append(wx.ID_ANY, _('Boundary conditions'), _('Boundary conditions'))
11346
11578
  self.popupmenu.Append(wx.ID_ANY, _('Contours'))
11347
11579
  self.popupmenu.Append(wx.ID_ANY, _('Rebin'), _('Change the spatial resolution'))
11580
+ self.popupmenu.Append(wx.ID_ANY, _('Set NullValue'), _('Set NullValue'))
11348
11581
 
11349
11582
  # Add specific menu items for WolfArrayMB
11350
11583
  if isinstance(self.selected_object, WolfArrayMB):
@@ -11354,8 +11587,9 @@ class WolfMapViewer(wx.Frame):
11354
11587
  if isinstance(self.selected_object, Wolfresults_2D):
11355
11588
  self.popupmenu.Append(wx.ID_ANY, _('Convert to mono-block (result)'), _('Convert to mono-block'))
11356
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'))
11357
11591
 
11358
- if isinstance(self.selected_object, Zones):
11592
+ if isinstance(self.selected_object, Zones | Bridge | Weir):
11359
11593
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
11360
11594
  self.popupmenu.Append(wx.ID_ANY, _('Export active zone to Shape file'), _('Export active zone to Shape file'))
11361
11595
 
@@ -11808,6 +12042,117 @@ class WolfMapViewer(wx.Frame):
11808
12042
  self.zoom_on(zoom)
11809
12043
 
11810
12044
 
12045
+ def menu_bridges(self):
12046
+
12047
+ if self.menu_bridge is None:
12048
+ self.menu_bridge = wx.Menu()
12049
+ self.menubar.Append(self.menu_bridge, _('&Bridges'))
12050
+
12051
+ self._menu_add_bridge = self.menu_bridge.Append(wx.ID_ANY, _('New bridge'), _('Add a new bridge to the active collection...'))
12052
+ self._menu_find_bridge = self.menu_bridge.Append(wx.ID_ANY, _('Pick bridge'), _("Pick the mouse's nearest bridge"))
12053
+ self._menu_edit_bridge = self.menu_bridge.Append(wx.ID_ANY, _('Edit bridge'), _('Edit the active bridge'))
12054
+
12055
+ self.Bind(wx.EVT_MENU, self.OnAddBridge, self._menu_add_bridge)
12056
+ self.Bind(wx.EVT_MENU, self.OnEditBridge, self._menu_edit_bridge)
12057
+ self.Bind(wx.EVT_MENU, self.OnFindBridge, self._menu_find_bridge)
12058
+
12059
+ def OnAddBridge(self, e):
12060
+ """ Add a bridge """
12061
+
12062
+ if self.active_bridges is None:
12063
+ logging.warning(_('No bridge collection !'))
12064
+ return
12065
+
12066
+ newid = wx.TextEntryDialog(None, _('Enter the new bridge id'), _('New bridge id'), 'bridge')
12067
+ if newid.ShowModal() == wx.ID_OK:
12068
+
12069
+ newid = newid.GetValue()
12070
+ while newid in self.get_list_keys(drawing_type=draw_type.VECTORS):
12071
+ newid = newid + '_'
12072
+
12073
+ newbridge = self.active_bridges.addnew(newid)
12074
+ self.add_object('vector', newobj=newbridge, id=newid)
12075
+
12076
+ def OnEditBridge(self, e):
12077
+ """ Edit a bridge """
12078
+
12079
+ if self.active_bridge is None:
12080
+ logging.warning(_('No active bridge to edit !'))
12081
+ return
12082
+
12083
+ keys = self.get_list_keys(drawing_type=draw_type.VECTORS)
12084
+
12085
+ newid = self.active_bridge.idx
12086
+ while newid in keys:
12087
+ newid = newid + '_'
12088
+
12089
+ self.add_object('vector', newobj=self.active_bridge, id= newid)
12090
+
12091
+ def OnFindBridge(self, e):
12092
+ """ Find the nearest bridge """
12093
+
12094
+ self.start_action('Pick bridge', _('Right click to pick the nearest bridge'))
12095
+
12096
+ def pick_bridge(self, x:float, y:float):
12097
+ """ Find the nearest bridge """
12098
+
12099
+ if self.active_bridges is None:
12100
+ logging.warning(_('No bridges to pick !'))
12101
+ return
12102
+
12103
+ self.active_bridge = self.active_bridges.find_nearest(x,y)
12104
+
12105
+ def menu_weirs(self):
12106
+
12107
+ if self.menu_weir is None:
12108
+ self.menu_weir = wx.Menu()
12109
+ self.menubar.Append(self.menu_weir, _('&Weirs'))
12110
+
12111
+ self._menu_add_weir = self.menu_weir.Append(wx.ID_ANY, _('New weir'), _('Add a new weir to the active collection'))
12112
+ self._menu_find_weir = self.menu_weir.Append(wx.ID_ANY, _('Pick weir'), _("Pick the mouse's nearest weir"))
12113
+ self._menu_edit_weir = self.menu_weir.Append(wx.ID_ANY, _('Edit weir'), _('Edit the active weir'))
12114
+
12115
+ self.Bind(wx.EVT_MENU, self.OnAddWeir, self._menu_add_weir)
12116
+ self.Bind(wx.EVT_MENU, self.OnEditWeir, self._menu_edit_weir)
12117
+ self.Bind(wx.EVT_MENU, self.OnFindWeir, self._menu_find_weir)
12118
+
12119
+ def OnAddWeir(self, e):
12120
+ """ Add a weir """
12121
+
12122
+ logging.info(_('!! To be implemented !!'))
12123
+ pass
12124
+
12125
+ def OnEditWeir(self, e):
12126
+ """ Edit a weir """
12127
+
12128
+ if self.active_weir is None:
12129
+ logging.warning(_('No active weir to edit !'))
12130
+ return
12131
+
12132
+ keys = self.get_list_keys(drawing_type=draw_type.VECTORS)
12133
+
12134
+ newid = self.active_weir.idx
12135
+ while newid in keys:
12136
+ newid = newid + '_'
12137
+
12138
+ self.add_object('vector', newobj=self.active_weir, id= newid)
12139
+
12140
+ def OnFindWeir(self, e):
12141
+ """ Find the nearest weir """
12142
+
12143
+ self.start_action('Pick weir', _('Right click to pick the nearest weir'))
12144
+
12145
+ def pick_weir(self, x:float, y:float):
12146
+ """ Find the nearest weir """
12147
+
12148
+ if self.active_weirs is None:
12149
+ logging.warning(_('No weirs to pick !'))
12150
+ return
12151
+
12152
+ self.active_weir = self.active_weirs.find_nearest(x,y)
12153
+
12154
+
12155
+
11811
12156
  class Comp_Type(Enum):
11812
12157
  ARRAYS = 1
11813
12158
  ARRAYS_MB = 2
@@ -11852,6 +12197,21 @@ class Compare_Arrays_Results():
11852
12197
 
11853
12198
  return Comp_Type.RES2D, file
11854
12199
 
12200
+ elif file.suffix in ('.bin', '.tif', '.tiff', '.npy', '.npz', '.top', '.frott', '.nap', '.hbin', '.hbinb', '.qxbin', '.qxbinb', '.qybin', '.qybinb', '.inf') :
12201
+
12202
+ if file.suffix in ('.bin', '.top', '.frott', '.nap', '.hbin', '.hbinb', '.qxbin', '.qxbinb', '.qybin', '.qybinb', '.inf'):
12203
+ if file.with_suffix(file.suffix + '.txt').exists():
12204
+
12205
+ test = WolfArray(file, preload=False)
12206
+ test.read_txt_header()
12207
+
12208
+ mb = test.nb_blocks > 0
12209
+
12210
+ if mb:
12211
+ return Comp_Type.ARRAYS_MB, file
12212
+
12213
+ return Comp_Type.ARRAYS, file
12214
+
11855
12215
  elif (file.parent / 'simul_gpu_results').exists():
11856
12216
  file = file.parent / 'simul_gpu_results'
11857
12217
  return Comp_Type.RES2D_GPU, file
@@ -11859,24 +12219,8 @@ class Compare_Arrays_Results():
11859
12219
  elif (file.parent.parent / 'simul_gpu_results').exists():
11860
12220
  file = file.parent.parent / 'simul_gpu_results'
11861
12221
  return Comp_Type.RES2D_GPU, file
11862
-
11863
12222
  else:
11864
- if file.suffix in ('.bin', '.tif', '.tiff', '.npy', '.npz', '.top', '.frott', '.nap', '.hbin', '.hbinb', '.qxbin', '.qxbinb', '.qybin', '.qybinb', '.inf') :
11865
-
11866
- if file.suffix in ('.bin', '.top', '.frott', '.nap', '.hbin', '.hbinb', '.qxbin', '.qxbinb', '.qybin', '.qybinb', '.inf'):
11867
- if file.with_suffix(file.suffix + '.txt').exists():
11868
-
11869
- test = WolfArray(file, preload=False)
11870
- test.read_txt_header()
11871
-
11872
- mb = test.nb_blocks > 0
11873
-
11874
- if mb:
11875
- return Comp_Type.ARRAYS_MB, file
11876
-
11877
- return Comp_Type.ARRAYS, file
11878
- else:
11879
- return None, None
12223
+ return None, None
11880
12224
 
11881
12225
  def add(self, file_or_dir:Union[str, Path] = None):
11882
12226