wolfhece 2.1.126__py3-none-any.whl → 2.1.127__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
@@ -1356,6 +1356,264 @@ class Select_Begin_end_interval_step(wx.Dialog):
1356
1356
 
1357
1357
  self.Hide()
1358
1358
 
1359
+
1360
+ class PrecomputedDEM_DTM(Enum):
1361
+ """ Enum for Precomputed DEM/DTM array """
1362
+
1363
+ DEMDTM_50cm = "AllData.vrt"
1364
+ DEMDTM_1m_average = "Combine_1m_average.vrt"
1365
+ DEMDTM_1m_min = "Combine_1m_minimum.vrt"
1366
+ DEMDTM_1m_max = "Combine_1m_maximum.vrt"
1367
+ DEMDTM_2m_average = "Combine_2m_average.vrt"
1368
+ DEMDTM_2m_min = "Combine_2m_minimum.vrt"
1369
+ DEMDTM_2m_max = "Combine_2m_maximum.vrt"
1370
+ DEMDTM_5m_average = "Combine_5m_average.vrt"
1371
+ DEMDTM_5m_min = "Combine_5m_minimum.vrt"
1372
+ DEMDTM_5m_max = "Combine_5m_maximum.vrt"
1373
+ DEMDTM_10m_average = "Combine_10m_average.vrt"
1374
+ DEMDTM_10m_min = "Combine_10m_minimum.vrt"
1375
+ DEMDTM_10m_max = "Combine_10m_maximum.vrt"
1376
+
1377
+ class Precomputed_DEM_DTM_Dialog(wx.Dialog):
1378
+ """ wx.Dialog to select Precomputed DEM/DTM array
1379
+
1380
+ Resolutions are 50cm, 1m, 2m, 5m, 10m
1381
+ Operators are average, min, max
1382
+ """
1383
+
1384
+ def __init__(self, parent, title, directory:Path | str, mapviewer:"WolfMapViewer"):
1385
+
1386
+ super(Precomputed_DEM_DTM_Dialog, self).__init__(parent, title=title, size=(500, 350), style = wx.DEFAULT_FRAME_STYLE & ~ (wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX))
1387
+
1388
+ self._dir = Path(directory)
1389
+ self._header = None
1390
+ self._vrt = None
1391
+ self._mapviewer = mapviewer
1392
+
1393
+ self.available_vrt()
1394
+
1395
+ self._panel = wx.Panel(self)
1396
+ sizer = wx.BoxSizer(wx.VERTICAL)
1397
+
1398
+ # Listbox with all available operators
1399
+ self._res = ['50cm', '1m', '2m', '5m', '10m']
1400
+ self._ops = ['average', 'minimum', 'maximum']
1401
+ self._resolution = wx.ListBox(self._panel, choices=self._res, style=wx.LB_SINGLE)
1402
+ self._resolution.Bind(wx.EVT_LISTBOX, self.OnSelectResolution)
1403
+
1404
+ self._operations = wx.ListBox(self._panel, choices=[], style=wx.LB_SINGLE)
1405
+
1406
+ sizer.Add(self._resolution, 1, wx.EXPAND | wx.ALL, 2)
1407
+ sizer.Add(self._operations, 1, wx.EXPAND | wx.ALL, 2)
1408
+
1409
+ sizer_btns = wx.BoxSizer(wx.HORIZONTAL)
1410
+ self._cmd_sameactive = wx.Button(self._panel, wx.ID_APPLY, _('Same as active array...'))
1411
+ self._cmd_sameas = wx.Button(self._panel, wx.ID_APPLY, _('Same as file...'))
1412
+ self._cmd_zoom = wx.Button(self._panel, wx.ID_APPLY, _('On current zoom...'))
1413
+
1414
+ self._cmd_sameas.Bind(wx.EVT_BUTTON, self.OnSameAs)
1415
+ self._cmd_zoom.Bind(wx.EVT_BUTTON, self.OnZoom)
1416
+ self._cmd_sameactive.Bind(wx.EVT_BUTTON, self.OnSameActive)
1417
+
1418
+ sizer_btns.Add(self._cmd_sameactive, 1, wx.EXPAND | wx.ALL, 2)
1419
+ sizer_btns.Add(self._cmd_sameas, 1, wx.EXPAND | wx.ALL, 2)
1420
+ sizer_btns.Add(self._cmd_zoom, 1, wx.EXPAND | wx.ALL, 2)
1421
+
1422
+ sizer.Add(sizer_btns, 1, wx.EXPAND | wx.ALL, 2)
1423
+
1424
+ self._panel.SetSizer(sizer)
1425
+
1426
+ self.CenterOnScreen()
1427
+
1428
+ self.SetIcon(wx.Icon(str(Path(__file__).parent / "apps/wolf_logo2.bmp")))
1429
+
1430
+ self.Show()
1431
+
1432
+ def OnSameAs(self, event):
1433
+ """ Set the Precomputed DEM/DTM array to the same bounds as an existing array """
1434
+
1435
+ dlg = wx.FileDialog(self, _('Select a file'), str(self._dir), '', "All supported formats|*.bin;*.tif;*.tiff;*.top;*.flt;*.npy;*.npz;*.vrt|bin (*.bin)|*.bin|Elevation WOLF2D (*.top)|*.top|Geotif (*.tif)|*.tif|Float ESRI (*.flt)|*.flt|Numpy (*.npy)|*.npy|Numpy named arrays(*.npz)|*.npz|all (*.*)|*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
1436
+ ret = dlg.ShowModal()
1437
+
1438
+ if ret == wx.ID_OK:
1439
+ fname = Path(dlg.GetPath())
1440
+
1441
+ self._header = header_wolf()
1442
+ self._header.read_txt_header(fname)
1443
+
1444
+ res = self._resolution.GetStringSelection()
1445
+ if res == '50cm':
1446
+ res = 0.5
1447
+ elif res in ['1m', '2m', '5m', '10m']:
1448
+ res = float(res[:-1])
1449
+ else:
1450
+ logging.error('Resolution not found')
1451
+ return
1452
+
1453
+ if self._header.dx != res or self._header.dy != res:
1454
+ logging.warning(_('Resolution not the same'))
1455
+ logging.warning(_('Forcing resolution to {}m').format(res))
1456
+
1457
+ self._header.origx = float(int(self._header.origx / res) * res)
1458
+ self._header.origy = float(int(self._header.origy / res) * res)
1459
+ self._header.nbx = int(np.ceil(float(self._header.nbx) * self._header.dx / res))
1460
+ self._header.nby = int(np.ceil(float(self._header.nby) * self._header.dy / res))
1461
+ self._header.dx = res
1462
+ self._header.dy = res
1463
+
1464
+ logging.info(_('New header:'))
1465
+ logging.info(self._header)
1466
+
1467
+ self.add_array()
1468
+ self.Hide()
1469
+
1470
+ def OnSameActive(self, event):
1471
+ """ Set the Precomputed DEM/DTM array to the same bounds as the active array """
1472
+
1473
+ if self._mapviewer is None:
1474
+ logging.error('No mapviewer to get the active array')
1475
+ return
1476
+
1477
+ active = self._mapviewer.active_array
1478
+ if active is None:
1479
+ logging.error('No active array to get the bounds')
1480
+ return
1481
+
1482
+ self._header = active.get_header()
1483
+
1484
+ res = self._resolution.GetStringSelection()
1485
+ if res == '50cm':
1486
+ res = 0.5
1487
+ elif res in ['1m', '2m', '5m', '10m']:
1488
+ res = float(res[:-1])
1489
+ else:
1490
+ logging.error('Resolution not found')
1491
+ return
1492
+
1493
+ if self._header.dx != res or self._header.dy != res:
1494
+ logging.warning(_('Resolution not the same'))
1495
+ logging.warning(_('Forcing resolution to {}m').format(res))
1496
+
1497
+ self._header.origx = float(int(self._header.origx / res) * res)
1498
+ self._header.origy = float(int(self._header.origy / res) * res)
1499
+ self._header.nbx = int(np.ceil(float(self._header.nbx) * self._header.dx / res))
1500
+ self._header.nby = int(np.ceil(float(self._header.nby) * self._header.dy / res))
1501
+ self._header.dx = res
1502
+ self._header.dy = res
1503
+
1504
+ logging.info(_('New header:'))
1505
+ logging.info(self._header)
1506
+
1507
+ newarray = self.add_array()
1508
+
1509
+ #copy palette
1510
+ if newarray is not None:
1511
+ newarray.mypal.automatic = False
1512
+ newarray.mypal.values = active.mypal.values
1513
+
1514
+ self.Hide()
1515
+ self._mapviewer.Refresh()
1516
+
1517
+ def OnZoom(self, event):
1518
+ """ Set the Precomputed DEM/DTM array to the current zoom """
1519
+
1520
+ if self._mapviewer is None:
1521
+ logging.error('No mapviewer to get the current zoom')
1522
+ return
1523
+
1524
+ onzoom = [self._mapviewer.xmin, self._mapviewer.xmax, self._mapviewer.ymin, self._mapviewer.ymax]
1525
+
1526
+ self._header = header_wolf()
1527
+
1528
+ # round to the nearest resolution
1529
+ self._header.origx = float(int(onzoom[0]))
1530
+ self._header.origy = float(int(onzoom[2]))
1531
+
1532
+ res = self._resolution.GetSelection()
1533
+ if res == '50cm':
1534
+ res = 0.5
1535
+ elif res in ['1m', '2m', '5m', '10m']:
1536
+ res = float(res[:-1])
1537
+ else:
1538
+ logging.error('Resolution not found')
1539
+ return
1540
+
1541
+ self._header.dx = res
1542
+ self._header.dy = res
1543
+
1544
+ self._header.nbx = int(float(np.ceil(onzoom[1]) - np.int(onzoom[0])) / res)
1545
+ self._header.nby = int(float(np.ceil(onzoom[3]) - np.int(onzoom[2])) / res)
1546
+
1547
+ self.add_array()
1548
+ self.Hide()
1549
+ self._mapviewer.Refresh()
1550
+
1551
+ @property
1552
+ def selected_vrt(self):
1553
+
1554
+ res = self._resolution.GetStringSelection()
1555
+ op = self._operations.GetStringSelection()
1556
+
1557
+ vrt_names = [cur.name for cur in self._vrt]
1558
+ if res == '50cm':
1559
+ if PrecomputedDEM_DTM.DEMDTM_50cm.value in vrt_names:
1560
+ return self._dir / PrecomputedDEM_DTM.DEMDTM_50cm.value
1561
+ elif res in ['1m', '2m', '5m', '10m']:
1562
+ to_test = 'Combine_{}_{}.vrt'.format(res, op)
1563
+ if to_test in vrt_names:
1564
+ return self._dir / to_test
1565
+ else:
1566
+ logging.error('Operator not found')
1567
+ return None
1568
+ else:
1569
+ logging.error('Resolution not found')
1570
+ return None
1571
+
1572
+ def add_array(self):
1573
+ """ Add a new array to the viewer """
1574
+
1575
+ if self._mapviewer is None:
1576
+ logging.error('No mapviewer to add the array')
1577
+ return
1578
+
1579
+ if self._header is None:
1580
+ logging.error('No header defined')
1581
+ return
1582
+
1583
+ vrt = self.selected_vrt
1584
+ if vrt is None:
1585
+ logging.error('No vrt selected')
1586
+ return
1587
+
1588
+ newarray = WolfArray(vrt, crop= [[self._header.origx, self._header.origx + self._header.nbx * self._header.dx], [self._header.origy, self._header.origy + self._header.nby * self._header.dy]])
1589
+ self._mapviewer.add_object(newobj = newarray, id = vrt.stem)
1590
+
1591
+ return newarray
1592
+
1593
+ def OnSelectResolution(self, event):
1594
+ """ Select the resolution """
1595
+
1596
+ res = self._resolution.GetStringSelection()
1597
+
1598
+ vrt_names = [i.name for i in self._vrt]
1599
+ if res == '50cm':
1600
+ if PrecomputedDEM_DTM.DEMDTM_50cm.value in vrt_names:
1601
+ self._operations.Set(['No operator to choose - 50cm resolution'])
1602
+ elif res in ['1m', '2m', '5m', '10m']:
1603
+ to_test = {i: 'Combine_{}_{}.vrt'.format(res, i) for i in self._ops}
1604
+ self._operations.Set([i for i, val in to_test.items() if val in vrt_names])
1605
+ else:
1606
+ self._operations.Set([''])
1607
+
1608
+
1609
+ def available_vrt(self):
1610
+ """ List all available vrt files in the directory """
1611
+
1612
+ self._vrt = [i for i in self._dir.iterdir() if i.suffix == '.vrt']
1613
+ # test if vrt are in PrecomputedDEM_DTM
1614
+ self._vrt = [i for i in self._vrt if i.name in [j.value for j in PrecomputedDEM_DTM]]
1615
+
1616
+
1359
1617
  class WolfMapViewer(wx.Frame):
1360
1618
  """
1361
1619
  Fenêtre de visualisation de données WOLF grâce aux WxWidgets
@@ -1622,6 +1880,20 @@ class WolfMapViewer(wx.Frame):
1622
1880
  addweirs = self.menuaddobj.Append(wx.ID_ANY, _('Add weirs...'), _('Add bridges from directory'))
1623
1881
  addview = self.menuaddobj.Append(wx.ID_ANY, _('Add view...'), _('Add view from project file'))
1624
1882
 
1883
+ self.precomputed_menu = None
1884
+ if self.default_dem != "":
1885
+ self.filemenu.AppendSeparator()
1886
+ self.precomputed_menu = wx.Menu()
1887
+ self.precomputed_menu.Append(wx.ID_ANY,_('Precomputed DEM'))
1888
+ self.filemenu.Append(wx.ID_ANY, _('Precomputed...'), self.precomputed_menu)
1889
+ if self.default_dtm != "":
1890
+ if self.precomputed_menu is None:
1891
+ self.filemenu.AppendSeparator()
1892
+ self.precomputed_menu = wx.Menu()
1893
+ self.filemenu.Append(wx.ID_ANY, _('Precomputed...'), self.precomputed_menu)
1894
+
1895
+ self.precomputed_menu.Append(wx.ID_ANY,_('Precomputed DTM'))
1896
+
1625
1897
  self.filemenu.AppendSeparator()
1626
1898
  addscan = self.filemenu.Append(wx.ID_FILE5, _('Recursive scan...'), _('Add recursively'))
1627
1899
 
@@ -1683,6 +1955,7 @@ class WolfMapViewer(wx.Frame):
1683
1955
 
1684
1956
  self.analyzeplot = wx.Menu()
1685
1957
  self.analyzeexport = wx.Menu()
1958
+ self.analyzeinpaint = wx.Menu()
1686
1959
 
1687
1960
  plotvect = self.analyzeplot.Append(wx.ID_ANY, _("Plot active vector..."),
1688
1961
  _("Plot the active vector and linked arrays"))
@@ -1693,6 +1966,13 @@ class WolfMapViewer(wx.Frame):
1693
1966
 
1694
1967
  self.analyzemenu.Append(wx.ID_ANY,_('Plot...'),self.analyzeplot)
1695
1968
  self.analyzemenu.Append(wx.ID_ANY,_('Export...'),self.analyzeexport)
1969
+ self.analyzemenu.Append(wx.ID_ANY,_('Inpaint...'),self.analyzeinpaint)
1970
+
1971
+
1972
+ self.analyzeinpaint.Append(wx.ID_ANY, _("Inpaint active array..."), _("Inpaint active array"))
1973
+ self.analyzeinpaint.Append(wx.ID_ANY, _("Inpaint waterlevel..."), _("Inpaint a waterlevel result array based on sepcified dem and dtm data"))
1974
+ self.analyzeinpaint.Append(wx.ID_ANY, _("Inpaint array with mask..."), _("Inpaint an array based on sepcified mask and test data"))
1975
+
1696
1976
  self.analyzemenu.AppendSeparator()
1697
1977
 
1698
1978
  masksimul = self.analyzemenu.Append(wx.ID_ANY, _("Load and apply mask (nap)..."), _("Apply mask from sim2D"))
@@ -3344,6 +3624,33 @@ class WolfMapViewer(wx.Frame):
3344
3624
  else:
3345
3625
  return None
3346
3626
 
3627
+ @property
3628
+ def default_dem(self) -> Path:
3629
+ """ Return the default DEM file from configs """
3630
+ config = self.get_configuration()
3631
+ if config is None:
3632
+ return Path('')
3633
+ else:
3634
+ return Path(config[ConfigurationKeys.DIRECTORY_DEM])
3635
+
3636
+ @property
3637
+ def default_dtm(self) -> Path:
3638
+ """ Return the default DTM file from configs """
3639
+ config = self.get_configuration()
3640
+ if config is None:
3641
+ return Path('')
3642
+ else:
3643
+ return Path(config[ConfigurationKeys.DIRECTORY_DTM])
3644
+
3645
+ @property
3646
+ def default_laz(self):
3647
+ """ Return the default LAZ file from configs """
3648
+ config = self.get_configuration()
3649
+ if config is None:
3650
+ return Path('')
3651
+ else:
3652
+ return Path(config[ConfigurationKeys.DIRECTORY_LAZ])
3653
+
3347
3654
  @property
3348
3655
  def bkg_color(self):
3349
3656
  """ Return the background color from configs """
@@ -6322,10 +6629,10 @@ class WolfMapViewer(wx.Frame):
6322
6629
 
6323
6630
  return classification
6324
6631
 
6325
- def init_laz_from_gridinfos(self, dirlaz:str = None, classification:Literal['SPW-Geofit 2023', 'SPW 2013-2014'] = 'SPW-Geofit 2023'):
6632
+ def init_laz_from_gridinfos(self, dirlaz:str = None, classification:Literal['SPW-Geofit 2023', 'SPW 2013-2014', 'SPW 2021-2022'] = 'SPW-Geofit 2023'):
6326
6633
 
6327
6634
  if dirlaz is None:
6328
- dlg = wx.DirDialog(None, _('Choose directory where LAZ data/gridinfo are stored'))
6635
+ dlg = wx.DirDialog(None, _('Choose directory where LAZ data/gridinfo are stored'), defaultPath= str(self.default_laz))
6329
6636
  ret = dlg.ShowModal()
6330
6637
  if ret != wx.ID_OK:
6331
6638
  return
@@ -6343,6 +6650,8 @@ class WolfMapViewer(wx.Frame):
6343
6650
  return
6344
6651
  elif classification == 'SPW 2013-2014':
6345
6652
  self.mylazgrid.colors.init_2013()
6653
+ elif classification == "SPW 2021-2022":
6654
+ self.mylazgrid.colors.init_2021_2022()
6346
6655
  else:
6347
6656
  self.mylazgrid.colors.init_2023()
6348
6657
 
@@ -7234,6 +7543,35 @@ class WolfMapViewer(wx.Frame):
7234
7543
  elif itemlabel == _("Load and apply mask (nap)..."):
7235
7544
  self.loadnap_and_apply()
7236
7545
 
7546
+ elif itemlabel == _("Inpaint active array..."):
7547
+
7548
+ if self.active_array is None:
7549
+ logging.warning(_('No active array !'))
7550
+ return
7551
+
7552
+ nb = self.active_array.count_holes()
7553
+ if nb == 0:
7554
+ logging.warning(_('No hole in the array !'))
7555
+ return
7556
+
7557
+ dlg = wx.SingleChoiceDialog(None, _('Ignore the last ones ?'), _('Holes'), [str(i) for i in range(10)], style=wx.CHOICEDLG_STYLE)
7558
+ if dlg.ShowModal() == wx.ID_CANCEL:
7559
+ dlg.Destroy()
7560
+ return
7561
+
7562
+ nb = dlg.GetSelection()
7563
+ dlg.Destroy()
7564
+
7565
+ self.active_array.inpaint(ignore_last=nb)
7566
+
7567
+ elif itemlabel == _("Inpaint waterlevel..."):
7568
+
7569
+ dlg = InPaint_waterlevel(None, _("Choose the array to inpaint"), (400,400), self)
7570
+
7571
+ elif itemlabel == _("Inpaint array with mask..."):
7572
+
7573
+ dlg = InPaint_array(None, _("Choose the array to inpaint"), (400,400), self)
7574
+
7237
7575
  elif itemlabel == _("Filter inundation arrays..."):
7238
7576
  self.filter_inundation()
7239
7577
 
@@ -7872,6 +8210,16 @@ class WolfMapViewer(wx.Frame):
7872
8210
  elif itemlabel == _('Add array and crop...'):
7873
8211
  self.add_object(which='array_crop', ToCheck=True)
7874
8212
 
8213
+ elif itemlabel == _('Precomputed DEM'):
8214
+
8215
+ dlg = Precomputed_DEM_DTM_Dialog(self, _('Precomputed DEM'), self.default_dem, self)
8216
+ ret = dlg.ShowModal()
8217
+
8218
+ elif itemlabel == _('Precomputed DTM'):
8219
+
8220
+ dlg = Precomputed_DEM_DTM_Dialog(self, _('Precomputed DTM'), self.default_dtm, self)
8221
+ ret = dlg.ShowModal()
8222
+
7875
8223
  elif itemlabel == _('Create array from bathymetry file...'):
7876
8224
 
7877
8225
  self.add_object(which='array_xyz', ToCheck=True)
@@ -9819,6 +10167,8 @@ class WolfMapViewer(wx.Frame):
9819
10167
  curlist.pop(idx)
9820
10168
  curlist.insert(idx-1,myobj)
9821
10169
 
10170
+ self.Refresh()
10171
+
9822
10172
  def downobj(self):
9823
10173
  """Down selected item into general tree"""
9824
10174
 
@@ -9851,13 +10201,20 @@ class WolfMapViewer(wx.Frame):
9851
10201
 
9852
10202
  for curlist in self.all_lists:
9853
10203
  if myobj in curlist:
9854
- idx = curlist.index(myobj)
9855
- if idx==len(curlist)-2:
9856
- curlist.append(myobj)
9857
- curlist.pop(idx)
9858
- elif idx<len(curlist)-1:
9859
- curlist.insert(idx+1,myobj)
9860
- curlist.pop(idx)
10204
+ if len(curlist)>1:
10205
+ idx = curlist.index(myobj)
10206
+ if idx == len(curlist)-1:
10207
+ # dernier --> rien à faire
10208
+ pass
10209
+ elif idx==len(curlist)-2:
10210
+ # avant-dernier --> passage en dernier
10211
+ curlist.append(myobj)
10212
+ curlist.pop(idx)
10213
+ elif idx<len(curlist)-2:
10214
+ curlist.insert(idx+2,myobj)
10215
+ curlist.pop(idx)
10216
+
10217
+ self.Refresh()
9861
10218
 
9862
10219
  def OnShowPopup(self, event):
9863
10220
  pos = event.GetPosition()
@@ -12008,6 +12365,7 @@ class WolfMapViewer(wx.Frame):
12008
12365
  # CTRL+Shift+F4 : choix du pas sur base du temps (particle system)\n \
12009
12366
  # F5 : autoscale\n \
12010
12367
  # F7 : refresh\n \
12368
+ # F8 : Zoom on Whole Walonia\n \
12011
12369
  # F9 : sélection de toutes les mailles dans la matrice courante\n \
12012
12370
  # F11 : sélection sur matrice courante\n \
12013
12371
  # F12 : opération sur matrice courante\n \
@@ -12075,6 +12433,7 @@ class WolfMapViewer(wx.Frame):
12075
12433
 
12076
12434
  'F5': _('Drawing : autoscale'),
12077
12435
  'F7': _('Drawing : refresh'),
12436
+ 'F8': _('Drawing : zoom on whole Walonia'),
12078
12437
  'Arrows': _('Drawing : lateral movements'),
12079
12438
  'c or C': _('Drawing : copy canvas to Clipboard wo axes'),
12080
12439
  'ALT+C': _('Drawing : copy canvas to Clipboard as Matplotlib image'),
@@ -12724,6 +13083,9 @@ class WolfMapViewer(wx.Frame):
12724
13083
  elif key == wx.WXK_F7:
12725
13084
  self.update()
12726
13085
 
13086
+ elif key == wx.WXK_F8:
13087
+ self.zoom_on_whole_walonia()
13088
+
12727
13089
  elif key == wx.WXK_F12 or key == wx.WXK_F11:
12728
13090
  if self.active_array is not None:
12729
13091
  self.active_array.myops.SetTitle(_('Operations on array: ')+self.active_array.idx)
@@ -12992,6 +13354,23 @@ class WolfMapViewer(wx.Frame):
12992
13354
 
12993
13355
  self.treelist.PopupMenu(self.popupmenu)
12994
13356
 
13357
+ def zoom_on_whole_walonia(self):
13358
+ """ Zoom on the whole Walonia """
13359
+
13360
+ xmin = 40_000
13361
+ xmax = 300_000
13362
+ ymin = 10_000
13363
+ ymax = 175_000
13364
+
13365
+ self.mousex = (xmin + xmax) / 2.
13366
+ self.mousey = (ymin + ymax) / 2.
13367
+
13368
+ self.width = xmax - xmin
13369
+ self.height = ymax - ymin
13370
+
13371
+ self.setbounds()
13372
+
13373
+
12995
13374
  def update(self):
12996
13375
  """
12997
13376
  Update backgournd et foreground elements and arrays if local minmax is checked.
@@ -13898,4 +14277,328 @@ class Compare_Arrays_Results():
13898
14277
 
13899
14278
  self.set_elements()
13900
14279
  self.set_diff()
13901
- self.set_viewers()
14280
+ self.set_viewers()
14281
+
14282
+ class InPaint_waterlevel(wx.Dialog):
14283
+
14284
+ def __init__(self, parent, title:str = _('Inpainting'), size:tuple[int,int] = (400,400), mapviewer:WolfMapViewer=None, **kwargs):
14285
+
14286
+ super().__init__(parent, title = title, size = size, **kwargs)
14287
+
14288
+ self._array: WolfArray = None
14289
+ self._dem: WolfArray = None
14290
+ self._dtm: WolfArray = None
14291
+
14292
+ self._mapviewer = mapviewer
14293
+
14294
+ self._init_UI()
14295
+
14296
+ def _init_UI(self):
14297
+ """ Create 2 listboxes for the arrays and the masks """
14298
+ import shutil
14299
+
14300
+ if self._mapviewer is None:
14301
+ logging.warning(_('No mapviewer --> Nothing to do'))
14302
+ return
14303
+
14304
+ self._sizer = wx.BoxSizer(wx.VERTICAL)
14305
+
14306
+ self._sizer_lists = wx.BoxSizer(wx.HORIZONTAL)
14307
+ self._sizer_arrays = wx.BoxSizer(wx.VERTICAL)
14308
+ self._sizer_ignore = wx.BoxSizer(wx.VERTICAL)
14309
+
14310
+ self._label_arrays = wx.StaticText(self, wx.ID_ANY, _('Array'))
14311
+ self._listbox_arrays = wx.ListBox(self, wx.ID_ANY, choices = self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14312
+ self._label_dem = wx.StaticText(self, wx.ID_ANY, _('DEM'))
14313
+ self._listbox_dems = wx.ListBox(self, wx.ID_ANY, choices = ['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14314
+ self._label_dtm = wx.StaticText(self, wx.ID_ANY, _('DTM'))
14315
+ self._listbox_dtm = wx.ListBox(self, wx.ID_ANY, choices = ['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14316
+
14317
+ self._label_ignore = wx.StaticText(self, wx.ID_ANY, _('Ignore last holes'))
14318
+ self._listbox_ignore = wx.ListBox(self, wx.ID_ANY, choices = [str(i) for i in range(10)], style = wx.LB_SINGLE)
14319
+
14320
+ self._sizer_ignore.Add(self._label_ignore, 0, wx.EXPAND)
14321
+ self._sizer_ignore.Add(self._listbox_ignore, 1, wx.EXPAND)
14322
+
14323
+ self._sizer_arrays.Add(self._label_arrays, 0, wx.EXPAND)
14324
+ self._sizer_arrays.Add(self._listbox_arrays, 1, wx.EXPAND)
14325
+ self._sizer_arrays.Add(self._label_dem, 0, wx.EXPAND)
14326
+ self._sizer_arrays.Add(self._listbox_dems, 1, wx.EXPAND)
14327
+ self._sizer_arrays.Add(self._label_dtm, 0, wx.EXPAND)
14328
+ self._sizer_arrays.Add(self._listbox_dtm, 1, wx.EXPAND)
14329
+
14330
+ self._sizer_lists.Add(self._sizer_arrays, 1, wx.EXPAND)
14331
+ self._sizer_lists.Add(self._sizer_ignore, 1, wx.EXPAND)
14332
+
14333
+ self._sizer.Add(self._sizer_lists, 1, wx.EXPAND)
14334
+
14335
+ self._sizer_btns = wx.BoxSizer(wx.HORIZONTAL)
14336
+
14337
+ self._sizer_inpaint = wx.BoxSizer(wx.VERTICAL)
14338
+ self._btn_inpaint = wx.Button(self, wx.ID_ANY, _('Inpaint'))
14339
+ self._sizer_inpaint.Add(self._btn_inpaint, 1, wx.EXPAND)
14340
+
14341
+ self._check_fortran = wx.CheckBox(self, wx.ID_ANY, _('Use Fortran'))
14342
+ self._check_fortran.SetValue(False)
14343
+ if shutil.which('holes.exe') is not None:
14344
+ self._sizer_inpaint.Add(self._check_fortran, 1, wx.EXPAND)
14345
+
14346
+ self._btn_update_ids = wx.Button(self, wx.ID_ANY, _('Update IDs'))
14347
+ self._btn_select_holes = wx.Button(self, wx.ID_ANY, _('Select holes'))
14348
+ self._btn_create_mask = wx.Button(self, wx.ID_ANY, _('Create mask'))
14349
+
14350
+ self._sizer_btns.Add(self._sizer_inpaint, 1, wx.EXPAND)
14351
+ self._sizer_btns.Add(self._btn_update_ids, 1, wx.EXPAND)
14352
+ self._sizer_btns.Add(self._btn_select_holes, 1, wx.EXPAND)
14353
+ self._sizer_btns.Add(self._btn_create_mask, 1, wx.EXPAND)
14354
+
14355
+ self._sizer.Add(self._sizer_btns, 1, wx.EXPAND)
14356
+
14357
+ self.SetSizer(self._sizer)
14358
+
14359
+ self._listbox_arrays.Bind(wx.EVT_LISTBOX, self.OnSelectArray)
14360
+ self._listbox_dems.Bind(wx.EVT_LISTBOX, self.OnSelectMask)
14361
+ self._listbox_dtm.Bind(wx.EVT_LISTBOX, self.OnSelectDTM)
14362
+ self._btn_inpaint.Bind(wx.EVT_BUTTON, self.OnInpaint)
14363
+ self._btn_update_ids.Bind(wx.EVT_BUTTON, self.OnUpdateIDs)
14364
+ self._btn_select_holes.Bind(wx.EVT_BUTTON, self.OnSelectHoles)
14365
+ self._btn_create_mask.Bind(wx.EVT_BUTTON, self.OnCreateMask)
14366
+
14367
+ self._listbox_dems.SetSelection(0)
14368
+ self._listbox_dtm.SetSelection(0)
14369
+ self._listbox_ignore.SetSelection(1)
14370
+
14371
+ self.CenterOnScreen()
14372
+ self.Show()
14373
+
14374
+ def OnUpdateIDs(self, e):
14375
+ """ Update the list of arrays/mask/dtm """
14376
+
14377
+ self._listbox_arrays.Set(self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14378
+ self._listbox_dems.Set(['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14379
+ self._listbox_dtm.Set(['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14380
+
14381
+ def OnSelectArray(self, e):
14382
+ """ Select an array """
14383
+
14384
+ self._array = self._mapviewer.getobj_from_id(self._listbox_arrays.GetStringSelection())
14385
+
14386
+ def OnSelectMask(self, e):
14387
+ """ Select a mask """
14388
+
14389
+ mask_ = self._listbox_dems.GetStringSelection()
14390
+ if mask_ == 'None':
14391
+ self._dem = None
14392
+ else:
14393
+ self._dem = self._mapviewer.getobj_from_id(self._listbox_dems.GetStringSelection())
14394
+
14395
+ def OnSelectDTM(self, e):
14396
+ """ Select a DTM """
14397
+
14398
+ dtm_ = self._listbox_dtm.GetStringSelection()
14399
+ if dtm_ == 'None':
14400
+ self._dtm = None
14401
+ else:
14402
+ self._dtm = self._mapviewer.getobj_from_id(self._listbox_dtm.GetStringSelection())
14403
+
14404
+ def OnInpaint(self, e):
14405
+ """ Inpaint the array with the mask """
14406
+
14407
+ if self._array is None:
14408
+ logging.warning(_('Select an array, a mask and a DTM'))
14409
+
14410
+ else:
14411
+ times, wl, wd = self._array._inpaint_waterlevel_dem_dtm(self._dem, self._dtm, ignore_last= self._listbox_ignore.GetSelection(), use_fortran= self._check_fortran.GetValue())
14412
+ logging.info(_('Inpainting done !'))
14413
+
14414
+ dlg = wx.MessageDialog(None, _('Add water depth to the viewer ?'), _('Water depth'), style = wx.YES_NO|wx.YES_DEFAULT)
14415
+ ret = dlg.ShowModal()
14416
+
14417
+ if ret == wx.ID_YES:
14418
+ self._mapviewer.add_object('array', newobj = wd, id = 'wd_' + self._array.idx)
14419
+
14420
+ dlg.Destroy()
14421
+
14422
+ def OnSelectHoles(self, e):
14423
+ """ Select the holes in the array """
14424
+
14425
+ if self._array is None:
14426
+ logging.warning(_('Select an array'))
14427
+ return
14428
+
14429
+ self._array.select_holes(ignore_last = self._listbox_ignore.GetSelection())
14430
+ self._mapviewer.Paint()
14431
+
14432
+ def OnCreateMask(self, e):
14433
+ """ Create a mask from the array """
14434
+
14435
+ if self._array is None:
14436
+ logging.warning(_('Select an array, a mask and a DTM'))
14437
+ return
14438
+
14439
+ if self._dem is None:
14440
+ logging.warning(_('Select a dem'))
14441
+ return
14442
+
14443
+ if self._dtm is None:
14444
+ logging.warning(_('Select a dtm'))
14445
+ return
14446
+
14447
+ newmask = self._array._create_building_holes_dem_dtm(self._dem, self._dtm, ignore_last= self._listbox_ignore.GetSelection())
14448
+ self._mapviewer.add_object('array', newobj = newmask, id = 'mask_' + self._array.idx)
14449
+
14450
+ class InPaint_array(wx.Dialog):
14451
+
14452
+ def __init__(self, parent, title:str = _('Inpainting'), size:tuple[int,int] = (400,400), mapviewer:WolfMapViewer=None, **kwargs):
14453
+
14454
+ super().__init__(parent, title = title, size = size, **kwargs)
14455
+
14456
+ self._array: WolfArray = None
14457
+ self._mask: WolfArray = None
14458
+ self._test: WolfArray = None
14459
+
14460
+ self._mapviewer = mapviewer
14461
+
14462
+ self._init_UI()
14463
+
14464
+ def _init_UI(self):
14465
+ """ Create 2 listboxes for the arrays and the masks """
14466
+ import shutil
14467
+
14468
+ if self._mapviewer is None:
14469
+ logging.warning(_('No mapviewer --> Nothing to do'))
14470
+ return
14471
+
14472
+ self._sizer = wx.BoxSizer(wx.VERTICAL)
14473
+
14474
+ self._sizer_lists = wx.BoxSizer(wx.HORIZONTAL)
14475
+ self._sizer_arrays = wx.BoxSizer(wx.VERTICAL)
14476
+ self._sizer_ignore = wx.BoxSizer(wx.VERTICAL)
14477
+
14478
+ self._label_arrays = wx.StaticText(self, wx.ID_ANY, _('Array'))
14479
+ self._listbox_arrays = wx.ListBox(self, wx.ID_ANY, choices = self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14480
+ self._label_masks = wx.StaticText(self, wx.ID_ANY, _('Mask == where to inpaint'))
14481
+ self._listbox_masks = wx.ListBox(self, wx.ID_ANY, choices = ['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14482
+ self._label_test = wx.StaticText(self, wx.ID_ANY, _('Test == local inpainted value must be greater than this value'))
14483
+ self._listbox_test = wx.ListBox(self, wx.ID_ANY, choices = ['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS), style = wx.LB_SINGLE)
14484
+
14485
+ self._label_ignore = wx.StaticText(self, wx.ID_ANY, _('Ignore last holes'))
14486
+ self._listbox_ignore = wx.ListBox(self, wx.ID_ANY, choices = [str(i) for i in range(10)], style = wx.LB_SINGLE)
14487
+
14488
+ self._sizer_ignore.Add(self._label_ignore, 0, wx.EXPAND)
14489
+ self._sizer_ignore.Add(self._listbox_ignore, 1, wx.EXPAND)
14490
+
14491
+ self._sizer_arrays.Add(self._label_arrays, 0, wx.EXPAND)
14492
+ self._sizer_arrays.Add(self._listbox_arrays, 1, wx.EXPAND)
14493
+ self._sizer_arrays.Add(self._label_masks, 0, wx.EXPAND)
14494
+ self._sizer_arrays.Add(self._listbox_masks, 1, wx.EXPAND)
14495
+ self._sizer_arrays.Add(self._label_test, 0, wx.EXPAND)
14496
+ self._sizer_arrays.Add(self._listbox_test, 1, wx.EXPAND)
14497
+
14498
+ self._sizer_lists.Add(self._sizer_arrays, 1, wx.EXPAND)
14499
+ self._sizer_lists.Add(self._sizer_ignore, 1, wx.EXPAND)
14500
+
14501
+ self._sizer.Add(self._sizer_lists, 1, wx.EXPAND)
14502
+
14503
+ self._sizer_btns = wx.BoxSizer(wx.HORIZONTAL)
14504
+
14505
+ self._sizer_inpaint = wx.BoxSizer(wx.VERTICAL)
14506
+ self._btn_inpaint = wx.Button(self, wx.ID_ANY, _('Inpaint'))
14507
+ self._sizer_inpaint.Add(self._btn_inpaint, 1, wx.EXPAND)
14508
+
14509
+ self._btn_update_ids = wx.Button(self, wx.ID_ANY, _('Update IDs'))
14510
+ self._btn_select_holes = wx.Button(self, wx.ID_ANY, _('Select holes'))
14511
+ self._btn_create_mask = wx.Button(self, wx.ID_ANY, _('Create mask'))
14512
+
14513
+ self._sizer_btns.Add(self._sizer_inpaint, 1, wx.EXPAND)
14514
+ self._sizer_btns.Add(self._btn_update_ids, 1, wx.EXPAND)
14515
+ self._sizer_btns.Add(self._btn_select_holes, 1, wx.EXPAND)
14516
+ self._sizer_btns.Add(self._btn_create_mask, 1, wx.EXPAND)
14517
+
14518
+ self._sizer.Add(self._sizer_btns, 1, wx.EXPAND)
14519
+
14520
+ self.SetSizer(self._sizer)
14521
+
14522
+ self._listbox_arrays.Bind(wx.EVT_LISTBOX, self.OnSelectArray)
14523
+ self._listbox_masks.Bind(wx.EVT_LISTBOX, self.OnSelectMask)
14524
+ self._listbox_test.Bind(wx.EVT_LISTBOX, self.OnSelectTest)
14525
+ self._btn_inpaint.Bind(wx.EVT_BUTTON, self.OnInpaint)
14526
+ self._btn_update_ids.Bind(wx.EVT_BUTTON, self.OnUpdateIDs)
14527
+ self._btn_select_holes.Bind(wx.EVT_BUTTON, self.OnSelectHoles)
14528
+ self._btn_create_mask.Bind(wx.EVT_BUTTON, self.OnCreateMask)
14529
+
14530
+ self._listbox_masks.SetSelection(0)
14531
+ self._listbox_test.SetSelection(0)
14532
+ self._listbox_ignore.SetSelection(0)
14533
+
14534
+ self.CenterOnScreen()
14535
+ self.Show()
14536
+
14537
+ def OnUpdateIDs(self, e):
14538
+ """ Update the list of arrays/mask/dtm """
14539
+
14540
+ self._listbox_arrays.Set(self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14541
+ self._listbox_masks.Set(['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14542
+ self._listbox_test.Set(['None'] + self._mapviewer.get_list_keys(drawing_type = draw_type.ARRAYS))
14543
+
14544
+ def OnSelectArray(self, e):
14545
+ """ Select an array """
14546
+
14547
+ self._array = self._mapviewer.getobj_from_id(self._listbox_arrays.GetStringSelection())
14548
+
14549
+ def OnSelectMask(self, e):
14550
+ """ Select a mask """
14551
+
14552
+ mask_ = self._listbox_masks.GetStringSelection()
14553
+ if mask_ == 'None':
14554
+ self._mask = None
14555
+ else:
14556
+ self._mask = self._mapviewer.getobj_from_id(self._listbox_masks.GetStringSelection())
14557
+
14558
+ def OnSelectTest(self, e):
14559
+ """ Select a DTM """
14560
+
14561
+ dtm_ = self._listbox_test.GetStringSelection()
14562
+ if dtm_ == 'None':
14563
+ self._test = None
14564
+ else:
14565
+ self._test = self._mapviewer.getobj_from_id(self._listbox_test.GetStringSelection())
14566
+
14567
+ def OnInpaint(self, e):
14568
+ """ Inpaint the array with the mask """
14569
+
14570
+ if self._array is None:
14571
+ logging.warning(_('Select an array, a mask and a DTM'))
14572
+
14573
+ else:
14574
+
14575
+ times, wl, wd = self._array.inpaint(self._mask, self._test, ignore_last= self._listbox_ignore.GetSelection())
14576
+ logging.info(_('Inpainting done !'))
14577
+
14578
+ dlg = wx.MessageDialog(None, _('Add extra array to the viewer ?'), _('Inerpolation - test data'), style = wx.YES_NO|wx.YES_DEFAULT)
14579
+ ret = dlg.ShowModal()
14580
+
14581
+ if ret == wx.ID_YES:
14582
+ self._mapviewer.add_object('array', newobj = wd, id = 'extra_' + self._array.idx)
14583
+
14584
+ dlg.Destroy()
14585
+
14586
+ def OnSelectHoles(self, e):
14587
+ """ Select the holes in the array """
14588
+
14589
+ if self._mask is None:
14590
+ logging.warning(_('Select a mask array'))
14591
+ return
14592
+
14593
+ self._mask.select_holes(ignore_last = self._listbox_ignore.GetSelection())
14594
+ self._mapviewer.Paint()
14595
+
14596
+ def OnCreateMask(self, e):
14597
+ """ Create a mask from the array """
14598
+
14599
+ if self._array is None:
14600
+ logging.warning(_('Select an array'))
14601
+ return
14602
+
14603
+ newmask = self._array.create_mask_holes(ignore_last= self._listbox_ignore.GetSelection())
14604
+ self._mapviewer.add_object('array', newobj = newmask, id = 'mask_' + self._array.idx)