wolfhece 2.2.14__py3-none-any.whl → 2.2.15__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
@@ -92,6 +92,8 @@ try:
92
92
  from .math_parser.calculator import Calculator
93
93
  from .wintab.wintab import Wintab
94
94
  from .images_tiles import ImagesTiles
95
+ from .PyWMS import Alaro_Navigator, get_Alaro_legend
96
+
95
97
  except ImportError as e:
96
98
  print(e)
97
99
  raise ImportError("Error importing wolf_texture, xyz_file, mesh2d, PyPalette, wolfresults_2D, PyTranslate, PyVertex, RatingCurve, wolf_array, PyParams, mesh2d.bc_manager, PyVertexvectors, Results2DGPU, PyCrosssections, GraphNotebook, lazviewer, picc, wolf_zi_db, math_parser.calculator, wintab. Please check your installation.")
@@ -1956,6 +1958,8 @@ class WolfMapViewer(wx.Frame):
1956
1958
 
1957
1959
  active_fig: MplFigViewer
1958
1960
 
1961
+ alaro_navigator: Alaro_Navigator
1962
+
1959
1963
 
1960
1964
  # def check_user_activity(self, *args):
1961
1965
  # while True:
@@ -2008,8 +2012,6 @@ class WolfMapViewer(wx.Frame):
2008
2012
  self.treewidth = treewidth
2009
2013
  super(WolfMapViewer, self).__init__(wxparent, title=title, size=(w + self.treewidth, h))
2010
2014
 
2011
- self._tmp_vector_distance = None # distance computation the vector
2012
-
2013
2015
  self._wxlogging = wxlogging
2014
2016
  self.action = None # Action à entreprendre
2015
2017
  self.update_absolute_minmax = False # Force la MAJ de la palette
@@ -2092,6 +2094,8 @@ class WolfMapViewer(wx.Frame):
2092
2094
  self.menudrowning = None
2093
2095
  self.menudike = None
2094
2096
 
2097
+ self.alaro_navigator = None
2098
+
2095
2099
  self.filemenu = wx.Menu()
2096
2100
  openitem = self.filemenu.Append(wx.ID_OPEN, _('Open/Add project'), _('Open a full project from file'))
2097
2101
  saveproject = self.filemenu.Append(wx.ID_ANY, _('Save project as...'), _('Save the current project to file'))
@@ -2223,6 +2227,10 @@ class WolfMapViewer(wx.Frame):
2223
2227
  self.menu_contour_from_arrays = self.tools_menu.Append(wx.ID_ANY, _("Create contour from checked arrays..."), _("Create contour"))
2224
2228
  self.menu_calculator = self.tools_menu.Append(wx.ID_ANY, _("Calculator..."), _("Calculator"))
2225
2229
  self.menu_views = self.tools_menu.Append(wx.ID_ANY, _("Memory views..."), _("Memory views"))
2230
+
2231
+ self.menu_distances = self.tools_menu.Append(wx.ID_ANY, _("Memory distances..."), _("Memory distances"))
2232
+ self.menu_distances_add = self.tools_menu.Append(wx.ID_ANY, _("Add distances to viewer..."), _("Add memory distances"))
2233
+
2226
2234
  self.menu_digitizer = self.tools_menu.Append(wx.ID_ANY, _("Image digitizer..."), _("Image Digitizer"))
2227
2235
  self.calculator = None
2228
2236
  self.memory_views = None
@@ -2484,6 +2492,10 @@ class WolfMapViewer(wx.Frame):
2484
2492
 
2485
2493
  self.InitUI()
2486
2494
 
2495
+ self._tmp_vector_distance = None # distance computation the vector
2496
+ self._distances = Zones(mapviewer=self, idx=_('Distances/Areas'))
2497
+ self._distances.add_zone(zone(name='memory distances', parent=self._distances)) # distances memory
2498
+
2487
2499
  # self._wintab = Wintab(self.GetHandle())
2488
2500
 
2489
2501
  # if self._wintab:
@@ -5287,6 +5299,111 @@ class WolfMapViewer(wx.Frame):
5287
5299
  '2022': '2022',
5288
5300
  }}
5289
5301
 
5302
+ """cat:Literal['orthoimage_coverage',
5303
+ 'orthoimage_coverage_2016',
5304
+ 'orthoimage_coverage_2017',
5305
+ 'orthoimage_coverage_2018',
5306
+ 'orthoimage_coverage_2019',
5307
+ 'orthoimage_coverage_2020',
5308
+ 'orthoimage_coverage_2021',
5309
+ 'orthoimage_coverage_2022']
5310
+ """
5311
+ ign_belgique = {'Orthophotos': {'Last': 'orthoimage_coverage',
5312
+ '2016': 'orthoimage_coverage_2016',
5313
+ '2017': 'orthoimage_coverage_2017',
5314
+ '2018': 'orthoimage_coverage_2018',
5315
+ '2019': 'orthoimage_coverage_2019',
5316
+ '2020': 'orthoimage_coverage_2020',
5317
+ '2021': 'orthoimage_coverage_2021',
5318
+ '2022': 'orthoimage_coverage_2022',}}
5319
+
5320
+ """ ['crossborder',
5321
+ 'crossborder_grey',
5322
+ 'overlay',
5323
+ 'topo',
5324
+ 'topo_grey']"""
5325
+ ign_cartoweb = {'CartoWeb': {'Crossborder': 'crossborder',
5326
+ 'Crossborder Grey': 'crossborder_grey',
5327
+ 'Overlay': 'overlay',
5328
+ 'Topographic': 'topo',
5329
+ 'Topographic Grey': 'topo_grey',}}
5330
+
5331
+ ign_postflood2021 = {'PostFlood2021': {'Flood 2021': 'orthoimage_flood'}}
5332
+
5333
+ """
5334
+ ['10_m_u__wind_component',
5335
+ '10_m_v__wind_component',
5336
+ '2_m_Max_temp_since_ppp',
5337
+ '2_m_Min_temp_since_ppp',
5338
+ '2_m_dewpoint_temperature',
5339
+ '2_m_temperature',
5340
+ '2m_Relative_humidity',
5341
+ 'Convective_rain',
5342
+ 'Convective_snow',
5343
+ 'Geopotential',
5344
+ 'Inst_flx_Conv_Cld_Cover',
5345
+ 'Inst_flx_High_Cld_Cover',
5346
+ 'Inst_flx_Low_Cld_Cover',
5347
+ 'Inst_flx_Medium_Cld_Cover',
5348
+ 'Inst_flx_Tot_Cld_cover',
5349
+ 'Large_scale_rain',
5350
+ 'Large_scale_snow',
5351
+ 'Mean_sea_level_pressure',
5352
+ 'Relative_humidity',
5353
+ 'Relative_humidity_isobaric',
5354
+ 'SBL_Meridian_gust',
5355
+ 'SBL_Zonal_gust',
5356
+ 'Specific_humidity',
5357
+ 'Surf_Solar_radiation',
5358
+ 'Surf_Thermal_radiation',
5359
+ 'Surface_CAPE',
5360
+ 'Surface_Temperature',
5361
+ 'Surface_orography',
5362
+ 'Temperature',
5363
+ 'Total_precipitation',
5364
+ 'U-velocity',
5365
+ 'V-velocity',
5366
+ 'Vertical_velocity',
5367
+ 'Wet_Bulb_Poten_Temper',
5368
+ 'freezing_level_zeroDegC_isotherm'],
5369
+ """
5370
+ alaro = {'ALARO': {'10m_u_wind_component': '10_m_u__wind_component',
5371
+ '10m_v_wind_component': '10_m_v__wind_component',
5372
+ '2m_Max_temp_since_ppp': '2_m_Max_temp_since_ppp',
5373
+ '2m_Min_temp_since_ppp': '2_m_Min_temp_since_ppp',
5374
+ '2m_dewpoint_temperature': '2_m_dewpoint_temperature',
5375
+ '2m_temperature': '2_m_temperature',
5376
+ '2m_Relative_humidity': '2m_Relative_humidity',
5377
+ 'Convective_rain': 'Convective_rain',
5378
+ 'Convective_snow': 'Convective_snow',
5379
+ 'Geopotential': 'Geopotential',
5380
+ 'Inst_flx_Conv_Cld_Cover': 'Inst_flx_Conv_Cld_Cover',
5381
+ 'Inst_flx_High_Cld_Cover': 'Inst_flx_High_Cld_Cover',
5382
+ 'Inst_flx_Low_Cld_Cover': 'Inst_flx_Low_Cld_Cover',
5383
+ 'Inst_flx_Medium_Cld_Cover': 'Inst_flx_Medium_Cld_Cover',
5384
+ 'Inst_flx_Tot_Cld_cover': 'Inst_flx_Tot_Cld_cover',
5385
+ 'Large_scale_rain': 'Large_scale_rain',
5386
+ 'Large_scale_snow': 'Large_scale_snow',
5387
+ 'Mean_sea_level_pressure': 'Mean_sea_level_pressure',
5388
+ 'Relative_humidity': 'Relative_humidity',
5389
+ 'Relative_humidity_isobaric': 'Relative_humidity_isobaric',
5390
+ 'SBL_Meridian_gust': 'SBL_Meridian_gust',
5391
+ 'SBL_Zonal_gust': 'SBL_Zonal_gust',
5392
+ 'Specific_humidity': 'Specific_humidity',
5393
+ 'Surf_Solar_radiation': 'Surf_Solar_radiation',
5394
+ 'Surf_Thermal_radiation': 'Surf_Thermal_radiation',
5395
+ 'Surface_CAPE': 'Surface_CAPE',
5396
+ 'Surface_Temperature': 'Surface_Temperature',
5397
+ 'Surface_orography': 'Surface_orography',
5398
+ 'Temperature': 'Temperature',
5399
+ 'Total_precipitation': 'Total_precipitation',
5400
+ 'U-velocity': 'U-velocity',
5401
+ 'V-velocity': 'V-velocity',
5402
+ 'Vertical_velocity': 'Vertical_velocity',
5403
+ 'Wet_Bulb_Poten_Temper': 'Wet_Bulb_Poten_Temper',
5404
+ 'freezing_level_zeroDegC_isotherm': 'freezing_level_zeroDegC_isotherm',}}
5405
+
5406
+
5290
5407
  for idx, (k, item) in enumerate(orthos.items()):
5291
5408
  for kdx, (m, subitem) in enumerate(item.items()):
5292
5409
  self.add_object(which='wmsback',
@@ -5308,6 +5425,27 @@ class WolfMapViewer(wx.Frame):
5308
5425
  self, xmin, xmax, ymin, ymax, -99999, 1024, LifeWatch=True),
5309
5426
  ToCheck=False, id='LifeWatch LC' + m)
5310
5427
 
5428
+ for idx, (k, item) in enumerate(ign_belgique.items()):
5429
+ for kdx, (m, subitem) in enumerate(item.items()):
5430
+ self.add_object(which='wmsback',
5431
+ newobj=imagetexture('Orthos IGN', m, k, subitem,
5432
+ self, xmin, xmax, ymin, ymax, -99999, 1024, IGN_Belgium=True),
5433
+ ToCheck=False, id='IGN ' + m)
5434
+
5435
+ for idx, (k, item) in enumerate(ign_cartoweb.items()):
5436
+ for kdx, (m, subitem) in enumerate(item.items()):
5437
+ self.add_object(which='wmsback',
5438
+ newobj=imagetexture('Cartoweb IGN', m, k, subitem,
5439
+ self, xmin, xmax, ymin, ymax, -99999, 1024, IGN_Cartoweb=True),
5440
+ ToCheck=False, id='IGN ' + m)
5441
+
5442
+ for idx, (k, item) in enumerate(ign_postflood2021.items()):
5443
+ for kdx, (m, subitem) in enumerate(item.items()):
5444
+ self.add_object(which='wmsback',
5445
+ newobj=imagetexture('IGN 2021', m, k, subitem,
5446
+ self, xmin, xmax, ymin, ymax, -99999, 1024, postFlood2021=True),
5447
+ ToCheck=False, id='orthos post2021')
5448
+
5311
5449
  self.add_object(which='wmsback',
5312
5450
  newobj=imagetexture('PPNC', 'Orthos France', 'OI.OrthoimageCoverage.HR', '',
5313
5451
  self, xmin, xmax, ymin, ymax, -99999, 1024, France=True, epsg='EPSG:27563'),
@@ -5331,6 +5469,20 @@ class WolfMapViewer(wx.Frame):
5331
5469
  self, xmin, xmax, ymin, ymax, -99999, 1024),
5332
5470
  ToCheck=False, id=m)
5333
5471
 
5472
+ for idx, (k, item) in enumerate(alaro.items()):
5473
+ for kdx, (m, subitem) in enumerate(item.items()):
5474
+ self.add_object(which='wmsfore',
5475
+ newobj=imagetexture('ALARO', m, k, subitem,
5476
+ self, xmin, xmax, ymin, ymax, -99999, 1024, Alaro=True),
5477
+ ToCheck=False, id='ALARO ' + m)
5478
+
5479
+ for idx, (k, item) in enumerate(ign_cartoweb.items()):
5480
+ for kdx, (m, subitem) in enumerate(item.items()):
5481
+ self.add_object(which='wmsfore',
5482
+ newobj=imagetexture('Cartoweb', m, k, subitem,
5483
+ self, xmin, xmax, ymin, ymax, -99999, 1024, IGN_Cartoweb=True),
5484
+ ToCheck=False, id='IGN_f ' + m)
5485
+
5334
5486
  # self.add_object(which='wmsfore',
5335
5487
  # newobj=imagetexture('Cadastre Flandres', 'Plan Parcellaire 2024 (Flandres)', 'Adpf', '',
5336
5488
  # self, xmin, xmax, ymin, ymax, -99999, 1024, Vlaanderen=True),
@@ -8309,6 +8461,20 @@ class WolfMapViewer(wx.Frame):
8309
8461
 
8310
8462
  self._memory_views_gui.Show()
8311
8463
 
8464
+ elif itemlabel == _("Memory distances..."):
8465
+
8466
+ if self._distances is not None:
8467
+ if self._distances[-1].nbvectors == 0:
8468
+ logging.warning(_('No vector to show !'))
8469
+ return
8470
+
8471
+ self._distances.showstructure(self)
8472
+
8473
+ elif itemlabel == _("Add distances to viewer..."):
8474
+
8475
+ if self._distances is not None:
8476
+ self.add_object('vector', newobj=self._distances, ToCheck=True, id='Distances')
8477
+
8312
8478
  elif itemlabel == _("Create bridge and export gltf..."):
8313
8479
 
8314
8480
  if self.active_cs is None:
@@ -11477,8 +11643,32 @@ class WolfMapViewer(wx.Frame):
11477
11643
  size = float(dlg.GetValue())
11478
11644
  curobj.creategrid(size, self.xmin, self.ymin, self.xmax, self.ymax)
11479
11645
 
11646
+ if 'alaro' in curobj.idx and check:
11647
+ if self.alaro_navigator is None:
11648
+ self.alaro_navigator = Alaro_Navigator(self, curobj.idx, 'Alaro')
11649
+ self.alaro_navigator.Show()
11650
+
11480
11651
  self.Refresh()
11481
11652
 
11653
+ def _alaro_update_time(self):
11654
+ """ Update the time of the alaro navigator """
11655
+
11656
+ objs = self.get_list_objects(drawing_type=draw_type.WMSFORE, checked_state=True)
11657
+ for obj in objs:
11658
+ obj.time = self.alaro_navigator.time_str
11659
+ obj.alpha = self.alaro_navigator.alpha
11660
+ obj.force_alpha = True
11661
+
11662
+ self._update_foreground()
11663
+ self.Paint()
11664
+
11665
+ def _alaro_legends(self):
11666
+ """ Show images of the checked alaro layers"""
11667
+ objs = self.get_list_objects(drawing_type=draw_type.WMSFORE, checked_state=True)
11668
+ for obj in objs:
11669
+ img = Image.open(get_Alaro_legend(obj.idx.replace('alaro ', '')))
11670
+ img.show()
11671
+
11482
11672
  def getXY(self, pospix):
11483
11673
 
11484
11674
  width, height = self.canvas.GetSize()
@@ -12994,6 +13184,13 @@ class WolfMapViewer(wx.Frame):
12994
13184
 
12995
13185
  if self.action == 'distance along vector':
12996
13186
 
13187
+ dlg = wx.MessageDialog(None, _('Memorize the vector ?'), _('Confirm'), wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
13188
+ ret = dlg.ShowModal()
13189
+ dlg.Destroy()
13190
+
13191
+ if ret == wx.ID_YES:
13192
+ self._distances[-1].add_vector(self._tmp_vector_distance, forceparent=True, update_struct=True)
13193
+
12997
13194
  self._tmp_vector_distance = None
12998
13195
 
12999
13196
  elif self.action == 'pick landmap':
@@ -6631,8 +6631,9 @@ class Zones(wx.Frame, Element_To_Draw):
6631
6631
  """
6632
6632
  Affichage des propriétés des zones
6633
6633
 
6634
- parent : soit une instance 'WolfMapViewer', soit une instance 'Ops_Array' --> est utile pour transférer la propriété 'active_vector' et obtenir diverses informations
6635
- si parent est d'un autre type, il faut s'assurer que les options/actions sont consistantes
6634
+ :param parent: soit une instance 'WolfMapViewer', soit une instance 'Ops_Array' --> est utile pour transférer la propriété 'active_vector' et obtenir diverses informations
6635
+ si parent est d'un autre type, il faut s'assurer que les options/actions sont consistantes
6636
+ :param forceupdate: si True, on force la mise à jour de la structure
6636
6637
 
6637
6638
  """
6638
6639
  self.showstructure(parent, forceupdate)
@@ -6652,8 +6653,9 @@ class Zones(wx.Frame, Element_To_Draw):
6652
6653
  """
6653
6654
  Affichage de la structure des zones
6654
6655
 
6655
- parent : soit une instance 'WolfMapViewer', soit une instance 'Ops_Array' --> est utile pour transférer la propriété 'active_vector' et obtenir diverses informations
6656
- si parent est d'un autre type, il faut s'assurer que les options/actions sont consistantes
6656
+ :param parent: soit une instance 'WolfMapViewer', soit une instance 'Ops_Array' --> est utile pour transférer la propriété 'active_vector' et obtenir diverses informations
6657
+ si parent est d'un autre type, il faut s'assurer que les options/actions sont consistantes
6658
+ :param forceupdate: si True, on force la mise à jour de la structure
6657
6659
 
6658
6660
  """
6659
6661
  if self.parent is None:
wolfhece/PyWMS.py CHANGED
@@ -17,8 +17,12 @@ import wx
17
17
  import logging
18
18
  from typing import Union, Literal
19
19
  from enum import Enum
20
+ from datetime import datetime, timedelta
20
21
 
21
- from .PyTranslate import _
22
+ try:
23
+ from .PyTranslate import _
24
+ except:
25
+ from wolfhece.PyTranslate import _
22
26
 
23
27
  def to_image(mybytes:BytesIO) -> Image:
24
28
  return Image.open(mybytes)
@@ -272,11 +276,638 @@ def getLifeWatch(cat:Literal['None'],
272
276
  logging.warning(_('Impossible to get data from web services'))
273
277
  return None
274
278
 
279
+ def getNGI(cat:Literal['orthoimage_coverage',
280
+ 'orthoimage_coverage_2016',
281
+ 'orthoimage_coverage_2017',
282
+ 'orthoimage_coverage_2018',
283
+ 'orthoimage_coverage_2019',
284
+ 'orthoimage_coverage_2020',
285
+ 'orthoimage_coverage_2021',
286
+ 'orthoimage_coverage_2022'],
287
+ xl:float,
288
+ yl:float,
289
+ xr:float,
290
+ yr:float,
291
+ w:int = None,
292
+ h:int = None,
293
+ tofile=True,
294
+ format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
295
+
296
+ wms=WebMapService(f'https://wms.ngi.be/inspire/ortho/service?',
297
+ version='1.3.0', timeout=10)
298
+
299
+ ppkm = 300
300
+ if w is None and h is None:
301
+ real_w = (xr-xl)/1000
302
+ real_h = (yr-yl)/1000
303
+ w = int(real_w * ppkm)
304
+ h = int(real_h * ppkm)
305
+ elif w is None:
306
+ real_w = (xr-xl)/1000
307
+ real_h = (yr-yl)/1000
308
+ ppkm = h/real_h
309
+ w = int(real_w * ppkm)
310
+ # h = int(real_h * ppkm)
311
+ elif h is None:
312
+ real_w = (xr-xl)/1000
313
+ real_h = (yr-yl)/1000
314
+ ppkm = w/real_w
315
+ # w = int(real_w * ppkm)
316
+ h = int(real_h * ppkm)
317
+
318
+ MAXSIZE = 4000
319
+ if w > MAXSIZE:
320
+ pond = w / MAXSIZE
321
+ w = MAXSIZE
322
+ h = int(h / pond)
323
+ if h > MAXSIZE:
324
+ pond = h / MAXSIZE
325
+ h = MAXSIZE
326
+ w = int(w / pond)
327
+
328
+ if tofile:
329
+ img=wms.getmap(layers=['lc_hr_raster'],
330
+ # styles=['default'],
331
+ srs='EPSG:31370',
332
+ bbox=(xl,yl,xr,yr),
333
+ size=(w,h),
334
+ format='image/png',
335
+ transparent=False)
336
+
337
+ out = open('LifeWatch.png', 'wb')
338
+ out.write(img.read())
339
+ out.close()
340
+ return None
341
+ else:
342
+ mycontents=list(wms.contents) # List all available layers
343
+ curcont=[cat] # 'MS
344
+ curstyles=['1']
345
+
346
+ # convert from EPSG:31370 to EPSG:3812
347
+ transf=pyproj.Transformer.from_crs('EPSG:31370','EPSG:3812')
348
+ x1,y1=transf.transform(xl,yl)
349
+ x2,y2=transf.transform(xr,yr)
350
+
351
+ try:
352
+ img=wms.getmap(layers=curcont,
353
+ # styles=curstyles,
354
+ srs='EPSG:3812',
355
+ bbox=(x1,y1,x2,y2),
356
+ size=(w,h),
357
+ format=format,
358
+ transparent=False)
359
+
360
+ return BytesIO(img.read())
361
+
362
+ except:
363
+ logging.warning(_('Impossible to get data from web services'))
364
+ return None
365
+
366
+ def getCartoweb(cat:Literal['crossborder',
367
+ 'crossborder_grey',
368
+ 'overlay',
369
+ 'topo',
370
+ 'topo_grey'],
371
+ xl:float,
372
+ yl:float,
373
+ xr:float,
374
+ yr:float,
375
+ w:int = None,
376
+ h:int = None,
377
+ tofile=True,
378
+ format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
379
+
380
+ wms=WebMapService(f'https://cartoweb.wms.ngi.be/service?',
381
+ version='1.3.0', timeout=10)
382
+
383
+ ppkm = 300
384
+ if w is None and h is None:
385
+ real_w = (xr-xl)/1000
386
+ real_h = (yr-yl)/1000
387
+ w = int(real_w * ppkm)
388
+ h = int(real_h * ppkm)
389
+ elif w is None:
390
+ real_w = (xr-xl)/1000
391
+ real_h = (yr-yl)/1000
392
+ ppkm = h/real_h
393
+ w = int(real_w * ppkm)
394
+ # h = int(real_h * ppkm)
395
+ elif h is None:
396
+ real_w = (xr-xl)/1000
397
+ real_h = (yr-yl)/1000
398
+ ppkm = w/real_w
399
+ # w = int(real_w * ppkm)
400
+ h = int(real_h * ppkm)
401
+
402
+ MAXSIZE = 2000
403
+ if w > MAXSIZE:
404
+ pond = w / MAXSIZE
405
+ w = MAXSIZE
406
+ h = int(h / pond)
407
+ if h > MAXSIZE:
408
+ pond = h / MAXSIZE
409
+ h = MAXSIZE
410
+ w = int(w / pond)
411
+
412
+ if tofile:
413
+ img=wms.getmap(layers=['lc_hr_raster'],
414
+ # styles=['default'],
415
+ srs='EPSG:31370',
416
+ bbox=(xl,yl,xr,yr),
417
+ size=(w,h),
418
+ format='image/png',
419
+ transparent=False)
420
+
421
+ out = open('LifeWatch.png', 'wb')
422
+ out.write(img.read())
423
+ out.close()
424
+ return None
425
+ else:
426
+ mycontents=list(wms.contents) # List all available layers
427
+ curcont=[cat] # 'MS
428
+ curstyles=['1']
429
+
430
+ try:
431
+ img=wms.getmap(layers=curcont,
432
+ # styles=curstyles,
433
+ srs='EPSG:31370',
434
+ bbox=(xl,yl,xr,yr),
435
+ size=(w,h),
436
+ format=format,
437
+ transparent=True)
438
+
439
+ return BytesIO(img.read())
440
+
441
+ except:
442
+ logging.warning(_('Impossible to get data from web services'))
443
+ return None
444
+
445
+ def getOrthoPostFlood2021(cat:Literal['orthoimage_flood'],
446
+ xl:float,
447
+ yl:float,
448
+ xr:float,
449
+ yr:float,
450
+ w:int = None,
451
+ h:int = None,
452
+ tofile=True,
453
+ format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
454
+
455
+ wms=WebMapService(f'https://wms.ngi.be/inspire/flood_ortho/service?',
456
+ version='1.3.0', timeout=10)
457
+
458
+ ppkm = 300
459
+ if w is None and h is None:
460
+ real_w = (xr-xl)/1000
461
+ real_h = (yr-yl)/1000
462
+ w = int(real_w * ppkm)
463
+ h = int(real_h * ppkm)
464
+ elif w is None:
465
+ real_w = (xr-xl)/1000
466
+ real_h = (yr-yl)/1000
467
+ ppkm = h/real_h
468
+ w = int(real_w * ppkm)
469
+ # h = int(real_h * ppkm)
470
+ elif h is None:
471
+ real_w = (xr-xl)/1000
472
+ real_h = (yr-yl)/1000
473
+ ppkm = w/real_w
474
+ # w = int(real_w * ppkm)
475
+ h = int(real_h * ppkm)
476
+
477
+ MAXSIZE = 4000
478
+ if w > MAXSIZE:
479
+ pond = w / MAXSIZE
480
+ w = MAXSIZE
481
+ h = int(h / pond)
482
+ if h > MAXSIZE:
483
+ pond = h / MAXSIZE
484
+ h = MAXSIZE
485
+ w = int(w / pond)
486
+
487
+ if tofile:
488
+ img=wms.getmap(layers=['lc_hr_raster'],
489
+ # styles=['default'],
490
+ srs='EPSG:31370',
491
+ bbox=(xl,yl,xr,yr),
492
+ size=(w,h),
493
+ format='image/png',
494
+ transparent=False)
495
+
496
+ out = open('LifeWatch.png', 'wb')
497
+ out.write(img.read())
498
+ out.close()
499
+ return None
500
+ else:
501
+ mycontents=list(wms.contents) # List all available layers
502
+ curcont=[cat] # 'MS
503
+ curstyles=['1']
504
+
505
+ # convert from EPSG:31370 to EPSG:3812
506
+ transf=pyproj.Transformer.from_crs('EPSG:31370','EPSG:3812')
507
+ x1,y1=transf.transform(xl,yl)
508
+ x2,y2=transf.transform(xr,yr)
509
+
510
+ try:
511
+ img=wms.getmap(layers=curcont,
512
+ # styles=curstyles,
513
+ srs='EPSG:3812',
514
+ bbox=(x1,y1,x2,y2),
515
+ size=(w,h),
516
+ format=format,
517
+ transparent=False)
518
+
519
+ return BytesIO(img.read())
520
+
521
+ except:
522
+ logging.warning(_('Impossible to get data from web services'))
523
+ return None
524
+
525
+ def get_Alaro_times():
526
+ wms=WebMapService(f'https://opendata.meteo.be/service/alaro/wms?',
527
+ version='1.3.0', timeout=10)
528
+ times = wms['Total_precipitation'].timepositions[0].split('/')
529
+
530
+ return times
531
+
532
+ def get_Alaro_legend(layer:str):
533
+ """ Get the legend of the layer
534
+
535
+ :param layer: name of the layer
536
+ :return: legend of the layer
537
+ """
538
+ import requests
539
+ from io import BytesIO
540
+ layers = ['10_m_u__wind_component',
541
+ '10_m_v__wind_component',
542
+ '2_m_Max_temp_since_ppp',
543
+ '2_m_Min_temp_since_ppp',
544
+ '2_m_dewpoint_temperature',
545
+ '2_m_temperature',
546
+ '2m_Relative_humidity',
547
+ 'Convective_rain',
548
+ 'Convective_snow',
549
+ 'Geopotential',
550
+ 'Inst_flx_Conv_Cld_Cover',
551
+ 'Inst_flx_High_Cld_Cover',
552
+ 'Inst_flx_Low_Cld_Cover',
553
+ 'Inst_flx_Medium_Cld_Cover',
554
+ 'Inst_flx_Tot_Cld_cover',
555
+ 'Large_scale_rain',
556
+ 'Large_scale_snow',
557
+ 'Mean_sea_level_pressure',
558
+ 'Relative_humidity',
559
+ 'Relative_humidity_isobaric',
560
+ 'SBL_Meridian_gust',
561
+ 'SBL_Zonal_gust',
562
+ 'Specific_humidity',
563
+ 'Surf_Solar_radiation',
564
+ 'Surf_Thermal_radiation',
565
+ 'Surface_CAPE',
566
+ 'Surface_Temperature',
567
+ 'Surface_orography',
568
+ 'Temperature',
569
+ 'Total_precipitation',
570
+ 'U-velocity',
571
+ 'V-velocity',
572
+ 'Vertical_velocity',
573
+ 'Wet_Bulb_Poten_Temper',
574
+ 'freezing_level_zeroDegC_isotherm']
575
+
576
+ layers_lowercase = [l.lower() for l in layers]
577
+ if layer.lower() not in layers_lowercase:
578
+ logging.warning(_('Layer not found in the list of available layers'))
579
+ return None
580
+
581
+ layer = layers[layers_lowercase.index(layer.lower())]
582
+
583
+ ows = "https://opendata.meteo.be/geoserver/alaro/ows?"
584
+
585
+ legend = requests.get(ows, params={'layer': layer,
586
+ 'width': 50,
587
+ 'height': 50,
588
+ 'format': 'image/png',
589
+ 'service': 'WMS',
590
+ 'version': '1.3.0',
591
+ 'request': 'GetLegendGraphic'})
592
+
593
+ return BytesIO(legend.content)
594
+
595
+ def getAlaro(cat:Literal['10_m_u__wind_component',
596
+ '10_m_v__wind_component',
597
+ '2_m_Max_temp_since_ppp',
598
+ '2_m_Min_temp_since_ppp',
599
+ '2_m_dewpoint_temperature',
600
+ '2_m_temperature',
601
+ '2m_Relative_humidity',
602
+ 'Convective_rain',
603
+ 'Convective_snow',
604
+ 'Geopotential',
605
+ 'Inst_flx_Conv_Cld_Cover',
606
+ 'Inst_flx_High_Cld_Cover',
607
+ 'Inst_flx_Low_Cld_Cover',
608
+ 'Inst_flx_Medium_Cld_Cover',
609
+ 'Inst_flx_Tot_Cld_cover',
610
+ 'Large_scale_rain',
611
+ 'Large_scale_snow',
612
+ 'Mean_sea_level_pressure',
613
+ 'Relative_humidity',
614
+ 'Relative_humidity_isobaric',
615
+ 'SBL_Meridian_gust',
616
+ 'SBL_Zonal_gust',
617
+ 'Specific_humidity',
618
+ 'Surf_Solar_radiation',
619
+ 'Surf_Thermal_radiation',
620
+ 'Surface_CAPE',
621
+ 'Surface_Temperature',
622
+ 'Surface_orography',
623
+ 'Temperature',
624
+ 'Total_precipitation',
625
+ 'U-velocity',
626
+ 'V-velocity',
627
+ 'Vertical_velocity',
628
+ 'Wet_Bulb_Poten_Temper',
629
+ 'freezing_level_zeroDegC_isotherm'],
630
+ xl:float,
631
+ yl:float,
632
+ xr:float,
633
+ yr:float,
634
+ w:int = None,
635
+ h:int = None,
636
+ tofile=True,
637
+ format:Literal['image/png', 'image/GeoTIFF']='image/png',
638
+ time = None) -> BytesIO:
639
+
640
+ wms=WebMapService(f'https://opendata.meteo.be/service/alaro/wms?',
641
+ version='1.3.0', timeout=10)
642
+
643
+ ppkm = 300
644
+ if w is None and h is None:
645
+ real_w = (xr-xl)/1000
646
+ real_h = (yr-yl)/1000
647
+ w = int(real_w * ppkm)
648
+ h = int(real_h * ppkm)
649
+ elif w is None:
650
+ real_w = (xr-xl)/1000
651
+ real_h = (yr-yl)/1000
652
+ ppkm = h/real_h
653
+ w = int(real_w * ppkm)
654
+ # h = int(real_h * ppkm)
655
+ elif h is None:
656
+ real_w = (xr-xl)/1000
657
+ real_h = (yr-yl)/1000
658
+ ppkm = w/real_w
659
+ # w = int(real_w * ppkm)
660
+ h = int(real_h * ppkm)
661
+
662
+ MAXSIZE = 2000
663
+ if w > MAXSIZE:
664
+ pond = w / MAXSIZE
665
+ w = MAXSIZE
666
+ h = int(h / pond)
667
+ if h > MAXSIZE:
668
+ pond = h / MAXSIZE
669
+ h = MAXSIZE
670
+ w = int(w / pond)
671
+
672
+ if tofile:
673
+ img=wms.getmap(layers=['lc_hr_raster'],
674
+ # styles=['default'],
675
+ srs='EPSG:31370',
676
+ bbox=(xl,yl,xr,yr),
677
+ size=(w,h),
678
+ format='image/png',
679
+ transparent=False)
680
+
681
+ out = open('LifeWatch.png', 'wb')
682
+ out.write(img.read())
683
+ out.close()
684
+ return None
685
+ else:
686
+ mycontents=list(wms.contents) # List all available layers
687
+ curcont=[cat] # 'MS
688
+ curstyles=['1']
689
+
690
+ # test = get_Alaro_legend(cat)
691
+
692
+ try:
693
+ if time is None:
694
+ time = wms[cat].timepositions[0].split('/')[0]
695
+
696
+ img=wms.getmap(layers=curcont,
697
+ # styles=curstyles,
698
+ srs='EPSG:31370',
699
+ bbox=(xl,yl,xr,yr),
700
+ size=(w,h),
701
+ format=format,
702
+ transparent=False,
703
+ time = time)
704
+
705
+ return BytesIO(img.read())
706
+
707
+ except:
708
+ logging.warning(_('Impossible to get data from web services'))
709
+ return None
710
+
711
+ class Alaro_Navigator(wx.Frame):
712
+ """ Frame to navigate through Alaro data
713
+
714
+ Propose a caolendar to select the time of the data
715
+ """
716
+
717
+ def __init__(self, parent, id, title):
718
+ super(Alaro_Navigator, self).__init__(parent, title=title, size=(500, 150))
719
+
720
+ panel = wx.Panel(self)
721
+ vbox = wx.BoxSizer(wx.VERTICAL)
722
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
723
+ hbox_start_end = wx.BoxSizer(wx.HORIZONTAL)
724
+ hbox_interv_alpha = wx.BoxSizer(wx.HORIZONTAL)
725
+
726
+ t_start, t_end, interv = get_Alaro_times()
727
+ self._start_date = wx.TextCtrl(panel, value=t_start.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
728
+ self._end_date = wx.TextCtrl(panel, value=t_end.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
729
+ self._interval = wx.TextCtrl(panel, value=interv.replace('PT',''), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
730
+
731
+ self._btn_previous = wx.Button(panel, label=_('Previous'), size=(100, -1))
732
+ self._btn_next = wx.Button(panel, label=_('Next'), size=(100, -1))
733
+ self._time = wx.TextCtrl(panel, value=t_start.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_CENTER | wx.TE_PROCESS_ENTER)
734
+ self._alpha = wx.TextCtrl(panel, value='1.0', size=(100, -1), style=wx.TE_CENTER | wx.TE_PROCESS_ENTER)
735
+ self._alpha.SetToolTip(_('Transparency of the image (0-1)'))
736
+
737
+ self._btn_legend = wx.Button(panel, label=_('Legend'), size=(100, -1))
738
+ self._btn_legend.Bind(wx.EVT_BUTTON, self.OnLegend)
739
+
740
+ self._time.Bind(wx.EVT_TEXT_ENTER, self.OnEnterTime)
741
+
742
+ hbox.Add(self._btn_previous, 1, flag=wx.EXPAND | wx.ALL, border=1)
743
+ hbox.Add(self._time, 1, flag=wx.EXPAND | wx.ALL, border=1)
744
+ hbox.Add(self._btn_next, 1, flag=wx.EXPAND | wx.ALL, border=1)
745
+
746
+ hbox_start_end.Add(self._start_date, 1, flag=wx.EXPAND | wx.ALL, border=1)
747
+ hbox_start_end.Add(self._end_date, 1, flag=wx.EXPAND | wx.ALL, border=1)
748
+
749
+ hbox_interv_alpha.Add(self._interval, 1, flag=wx.EXPAND | wx.ALL, border=1)
750
+ hbox_interv_alpha.Add(self._alpha, 1, flag=wx.EXPAND | wx.ALL, border=1)
751
+
752
+ vbox.Add(hbox, 1, flag=wx.EXPAND | wx.ALL, border=1)
753
+ vbox.Add(hbox_start_end, 1, flag=wx.EXPAND | wx.ALL, border=1)
754
+ vbox.Add(hbox_interv_alpha, 1, flag=wx.EXPAND | wx.ALL, border=1)
755
+ vbox.Add(self._btn_legend, 1, flag=wx.EXPAND | wx.ALL, border=1)
756
+
757
+ panel.SetSizer(vbox)
758
+
759
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
760
+ self._btn_previous.Bind(wx.EVT_BUTTON, self.OnPrevious)
761
+ self._btn_next.Bind(wx.EVT_BUTTON, self.OnNext)
762
+
763
+ def OnPrevious(self, event):
764
+ """ Hour minus interval
765
+ """
766
+
767
+ try:
768
+ time = self.time
769
+
770
+ # force the time to be rounded to the nearest interval
771
+ interval = timedelta(hours=1)
772
+ # nullify the minutes and seconds
773
+ time = time.replace(minute=0, second=0, microsecond=0, hour=time.hour - 1)
774
+
775
+ # check is the time is in the interval
776
+ if time < self.start or time > self.end:
777
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
778
+ return
779
+
780
+ self.time = time
781
+ except ValueError:
782
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
783
+ return
784
+ except Exception as e:
785
+ wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
786
+ return
787
+
788
+ self.Parent._alaro_update_time()
789
+
790
+ event.Skip()
791
+
792
+ def OnNext(self, event):
793
+ """ Hour plus interval
794
+ """
795
+
796
+ try:
797
+ time = self.time
798
+
799
+ # force the time to be rounded to the nearest interval
800
+ interval = timedelta(hours=1)
801
+ # nullify the minutes and seconds
802
+ time = time.replace(minute=0, second=0, microsecond=0, hour=time.hour + 1)
803
+
804
+ # check is the time is in the interval
805
+ if time < self.start or time > self.end:
806
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
807
+ return
808
+
809
+ self.time = time
810
+ except ValueError:
811
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
812
+ return
813
+ except Exception as e:
814
+ wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
815
+ return
816
+
817
+ self.Parent._alaro_update_time()
818
+
819
+ event.Skip()
820
+
821
+ def OnCloseWindow(self, event):
822
+ self.Hide()
823
+
824
+ event.Skip()
825
+
826
+ def OnLegend(self, event):
827
+ """ Called when the user press the legend button
828
+ """
829
+
830
+ # get the legend of the layer
831
+ layer = self.Parent._alaro_legends()
832
+
833
+ event.Skip()
834
+
835
+ def OnEnterTime(self, event):
836
+ """ Called when the user press enter in the time text box
837
+ """
838
+
839
+ # time must be rounded to the nearest interval
840
+ try:
841
+ time = self.time
842
+
843
+ # force the time to be rounded to the nearest interval
844
+ interval = timedelta(hours=1)
845
+ # nullify the minutes and seconds
846
+ time = time.replace(minute=0, second=0, microsecond=0)
847
+
848
+ # check is the time is in the interval
849
+ if time < self.start or time > self.end:
850
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
851
+ return
852
+
853
+ self.time = time
854
+ except ValueError:
855
+ wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
856
+ return
857
+ except Exception as e:
858
+ wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
859
+ return
860
+
861
+ self.Parent._alaro_update_time()
862
+
863
+ event.Skip()
864
+
865
+ @property
866
+ def start(self):
867
+ """ Return the start date selected by the user
868
+ """
869
+ return datetime.strptime(self._start_date.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
870
+
871
+ @property
872
+ def end(self):
873
+ """ Return the end date selected by the user
874
+ """
875
+ return datetime.strptime(self._end_date.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
876
+
877
+ @property
878
+ def time(self):
879
+ """ Return the time selected by the user
880
+ """
881
+ return datetime.strptime(self._time.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
882
+
883
+ @time.setter
884
+ def time(self, value:datetime):
885
+ """ Set the time selected by the user
886
+ """
887
+ self._time.SetValue(value.strftime('%Y-%m-%dT%H:%M:%SZ'))
888
+
889
+ @property
890
+ def time_str(self):
891
+ """ Return the time selected by the user as string
892
+ """
893
+ return self._time.GetValue()
894
+
895
+ @property
896
+ def alpha(self):
897
+ """ Return the alpha value selected by the user
898
+ """
899
+ try:
900
+ return float(self._alpha.GetValue())
901
+ except:
902
+ self._alpha.SetValue('1.0')
903
+ return 1.0
904
+
905
+
275
906
  if __name__=='__main__':
276
907
  # me=pyproj.CRS.from_epsg(27573)
277
908
  # t=pyproj.Transformer.from_crs(27573,4326)
278
909
  # getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
279
- img = getLifeWatch('',250000,160000,252000,162000,1000,1000,False)
910
+ img = getAlaro('Total_precipitation',250000,160000,252000,162000,1000,1000,False)
280
911
  img = Image.open(img)
281
912
  img.show()
282
913
  pass
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 2
8
- self.patch = 14
8
+ self.patch = 15
9
9
 
10
10
  def __str__(self):
11
11
 
wolfhece/wolf_texture.py CHANGED
@@ -26,7 +26,7 @@ import math
26
26
  import numpy as np
27
27
 
28
28
  from .PyTranslate import _
29
- from .PyWMS import getIGNFrance, getWalonmap, getVlaanderen, getLifeWatch
29
+ from .PyWMS import getIGNFrance, getWalonmap, getVlaanderen, getLifeWatch, getNGI, getCartoweb, getOrthoPostFlood2021, getAlaro
30
30
  from .textpillow import Font_Priority, Text_Image,Text_Infos
31
31
  from .drawing_obj import Element_To_Draw
32
32
 
@@ -121,7 +121,7 @@ class genericImagetexture(Element_To_Draw):
121
121
 
122
122
  self.update_minmax()
123
123
 
124
- self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height]
124
+ self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height, self.time]
125
125
 
126
126
  self.load()
127
127
 
@@ -189,7 +189,7 @@ class genericImagetexture(Element_To_Draw):
189
189
 
190
190
  self.update_minmax()
191
191
 
192
- self.newview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height]
192
+ self.newview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height, self.time]
193
193
  if self.newview != self.oldview:
194
194
  self.load()
195
195
  self.oldview = self.newview
@@ -254,7 +254,9 @@ class imagetexture(Element_To_Draw):
254
254
  xmin:float, xmax:float, ymin:float, ymax:float,
255
255
  width:int = 1000, height:int = 1000,
256
256
  France:bool = False, epsg='31370', Vlaanderen:bool = False,
257
- LifeWatch:bool = False) -> None:
257
+ LifeWatch:bool = False, IGN_Belgium:bool = False,
258
+ IGN_Cartoweb:bool = False, postFlood2021:bool = False,
259
+ Alaro:bool = False) -> None:
258
260
 
259
261
  super().__init__(label+cat+subc, plotted=False, mapviewer=mapviewer, need_for_wx=False)
260
262
 
@@ -266,6 +268,10 @@ class imagetexture(Element_To_Draw):
266
268
  self.France = France
267
269
  self.Vlaanderen = Vlaanderen
268
270
  self.LifeWatch = LifeWatch
271
+ self.IGN_Belgium = IGN_Belgium
272
+ self.IGN_Cartoweb = IGN_Cartoweb
273
+ self.postFlood2021 = postFlood2021
274
+ self.Alaro = Alaro
269
275
 
270
276
  self.epsg = epsg
271
277
 
@@ -276,6 +282,10 @@ class imagetexture(Element_To_Draw):
276
282
  self.idtexture = (GLuint * 1)()
277
283
  self.idx = 'texture_{}'.format(self.idtexture)
278
284
 
285
+ self.time = None
286
+ self.alpha = 1.0
287
+ self.force_alpha = False
288
+
279
289
  try:
280
290
  glGenTextures(1, self.idtexture)
281
291
  except:
@@ -288,7 +298,7 @@ class imagetexture(Element_To_Draw):
288
298
  self.category = cat # .upper()
289
299
  self.name = label
290
300
  self.subcategory = subc # .upper()
291
- self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height]
301
+ self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height, self.time]
292
302
 
293
303
  self.load()
294
304
 
@@ -313,6 +323,26 @@ class imagetexture(Element_To_Draw):
313
323
  mybytes = getLifeWatch(self.category + '_' + self.subcategory,
314
324
  self.xmin, self.ymin, self.xmax, self.ymax,
315
325
  self.width, self.height, False)
326
+ elif self.IGN_Belgium:
327
+ mybytes = getNGI(self.subcategory,
328
+ self.xmin, self.ymin, self.xmax, self.ymax,
329
+ self.width, self.height, False)
330
+
331
+ elif self.IGN_Cartoweb:
332
+ mybytes = getCartoweb(self.subcategory,
333
+ self.xmin, self.ymin, self.xmax, self.ymax,
334
+ self.width, self.height, False)
335
+
336
+ elif self.postFlood2021:
337
+ mybytes = getOrthoPostFlood2021(self.subcategory,
338
+ self.xmin, self.ymin, self.xmax, self.ymax,
339
+ self.width, self.height, False)
340
+
341
+ elif self.Alaro:
342
+ mybytes = getAlaro(self.subcategory,
343
+ self.xmin, self.ymin, self.xmax, self.ymax,
344
+ self.width, self.height, False, time= self.time)
345
+
316
346
  else:
317
347
  mybytes = getWalonmap(self.category + '/' + self.subcategory,
318
348
  self.xmin, self.ymin, self.xmax, self.ymax,
@@ -323,20 +353,51 @@ class imagetexture(Element_To_Draw):
323
353
  return
324
354
 
325
355
  try:
326
- image = Image.open(mybytes)
356
+ if isinstance(mybytes, bytes | BytesIO):
357
+ image = Image.open(mybytes)
358
+
359
+ if image.mode != 'RGBA':
360
+ image = image.convert('RGBA')
361
+
362
+ if self.force_alpha:
363
+ if self.alpha < 0.0:
364
+ self.alpha = 0.0
365
+ if self.alpha > 1.0:
366
+ self.alpha = 1.0
367
+
368
+ alpha = Image.new('L', image.size, int(self.alpha * 255))
369
+
370
+ image.putalpha(alpha)
371
+
372
+ elif isinstance(mybytes, str):
373
+ image = Image.open(mybytes).convert('RGB')
374
+
375
+ if image.width != self.width or image.height != self.height:
376
+ image = image.resize((self.width, self.height), Image.ANTIALIAS)
377
+
378
+ image_memory = BytesIO()
379
+ image.save(image_memory, format='PNG')
380
+ image = Image.open(image_memory)
381
+
382
+ elif isinstance(mybytes, Image.Image):
383
+ image = mybytes
384
+ else:
385
+ logging.error(_('Unknown type of image file : ') + str(type(mybytes)))
386
+ return
387
+
327
388
  except Exception as e:
328
389
  logging.warning(_('Error opening image file : ') + str(self.category + '/' + self.subcategory))
329
390
  return
330
391
 
331
392
  glBindTexture(GL_TEXTURE_2D, self.idtexture[0])
332
393
  if self.subcategory[:5] == 'ORTHO':
333
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
394
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
334
395
  image.tobytes())
335
396
  elif image.mode == 'RGB':
336
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE,
397
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE,
337
398
  image.tobytes())
338
399
  else:
339
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
400
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
340
401
  image.tobytes())
341
402
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
342
403
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
@@ -357,10 +418,10 @@ class imagetexture(Element_To_Draw):
357
418
  self.xmax = cx + dx * coeff
358
419
  self.ymin = cy - dy * coeff
359
420
  self.ymax = cy + dy * coeff
360
- self.width = self.mapviewer.canvaswidth * 2 * coeff
361
- self.height = self.mapviewer.canvasheight * 2 * coeff
421
+ self.width = int(self.mapviewer.canvaswidth * 2 * coeff)
422
+ self.height = int(self.mapviewer.canvasheight * 2 * coeff)
362
423
 
363
- self.newview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height]
424
+ self.newview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height, self.time]
364
425
  if self.newview != self.oldview:
365
426
  self.load()
366
427
  self.oldview = self.newview
@@ -440,7 +501,7 @@ class Text_Image_Texture(genericImagetexture):
440
501
  self.width = self.myImage.width
441
502
  self.height = self.myImage.height
442
503
 
443
- self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height]
504
+ self.oldview = [self.xmin, self.xmax, self.ymin, self.ymax, self.width, self.height, self.time]
444
505
 
445
506
  def findscale(self):
446
507
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.14
3
+ Version: 2.2.15
4
4
  Author-email: Pierre Archambeau <pierre.archambeau@uliege.be>
5
5
  Project-URL: Homepage, https://uee.uliege.be/hece
6
6
  Project-URL: Issues, https://uee.uliege.be/hece
@@ -8,7 +8,7 @@ wolfhece/Model1D.py,sha256=SI4oNF_J3MdjiWZoizS8kuRXLMVyymX9dYfYJNVCQVI,476989
8
8
  wolfhece/PandasGrid.py,sha256=YIleVkUkoP2MjtQBZ9Xgwk61zbgMj4Pmjj-clVTfPRs,2353
9
9
  wolfhece/PyConfig.py,sha256=Y0wtSIFpAMYa7IByh7hbW-WEOVjNsQEduq7vhIYdZQw,16716
10
10
  wolfhece/PyCrosssections.py,sha256=igU_ELrg5VrHU6RNbF5tHxPyVImpR3xdpfopJYc7haw,114711
11
- wolfhece/PyDraw.py,sha256=MUxnzykOYLJFkF9tA6nutkasSTyDEuNzbwnfa_vmZF8,635057
11
+ wolfhece/PyDraw.py,sha256=XyISYI30lJA6ueh_-zcQakLagTeW7C9SnjHz6UYm-u8,645007
12
12
  wolfhece/PyGui.py,sha256=jhpOPYRDG3ms1oi7FUs2W80T4SdPssZEnijxqFtn6vA,145199
13
13
  wolfhece/PyGuiHydrology.py,sha256=sKafpOopBg50L5llZCI_fZtbebVTDtxvoRI6-osUwhg,14745
14
14
  wolfhece/PyHydrographs.py,sha256=1P5XAURNqCvtSsMQXhOn1ihjTpr725sRsZdlCEhhk6M,3730
@@ -17,8 +17,8 @@ wolfhece/PyParams.py,sha256=Dh9C_WYICMjo3m9roRySsu8ZgFzzYhSr6RpbaXZni0M,99423
17
17
  wolfhece/PyPictures.py,sha256=m1kY0saW6Y9Q0bDCo47lW6XxDkBrbQG-Fd8uVn8G5ic,2514
18
18
  wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
19
19
  wolfhece/PyVertex.py,sha256=WT2UprotBUEA6rvs8kXfPRscKrhIL4_pya2UylzoBJE,50385
20
- wolfhece/PyVertexvectors.py,sha256=yPqE1rmqCSAucjNjSo1_srKHMwjqYWe0lx7S2Wbpryw,327905
21
- wolfhece/PyWMS.py,sha256=e6cMA72xLnpFZQtM99lItTyIfUQKz0f5f1iL_bwJVPQ,9303
20
+ wolfhece/PyVertexvectors.py,sha256=D-7aLqxAcJ39xDx1fwA1zzP1uFR28IiZUjFwpQEcv8E,328102
21
+ wolfhece/PyWMS.py,sha256=-wU-oWS5il1z702gYd90xHx5O7PvGNr9nb693oue_cI,31412
22
22
  wolfhece/RatingCurve.py,sha256=bUjIrQjvIjkD4V-z8bZmA6pe1ILtYNM0-3fT6YUY1RU,22498
23
23
  wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
24
24
  wolfhece/RatingCurve_xml.py,sha256=cUjReVMHFKtakA2wVey5zz6lCgHlSr72y7ZfswZDvTM,33891
@@ -60,7 +60,7 @@ wolfhece/tools2d_dll.py,sha256=oU0m9XYAf4CZsMoB68IuKeE6SQh-AqY7O5NVED8r9uw,13125
60
60
  wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
61
61
  wolfhece/wolf_array.py,sha256=PlImSCX5lUeoqPR7ogqak_Zl6dLyGn5EXUzeD_6-xAU,497218
62
62
  wolfhece/wolf_hist.py,sha256=7jeVrgSkM3ErJO6SRMH_PGzfLjIdw8vTy87kesldggk,3582
63
- wolfhece/wolf_texture.py,sha256=KlT8g4dBmH819n8mqQ8pCHLGST1C5bd4OaR_et5wsUM,18092
63
+ wolfhece/wolf_texture.py,sha256=_YMMz3w1re70rrpO_AcFlb7QC4R3_631Hgnl5BRNH1o,20832
64
64
  wolfhece/wolf_tiles.py,sha256=v-HohqaWuMYdn75XLnA22dlloAG90iwnIqrgnB0ASQ4,10488
65
65
  wolfhece/wolf_vrt.py,sha256=wbxXVN7TL9zgdyF79S-4e3pje6wJEAgBEfF_Y8kkzxs,14271
66
66
  wolfhece/wolf_zi_db.py,sha256=baE0niMCzybWGSvPJc5FNxo9ZxsGfU4p-FmfiavFHAs,12967
@@ -86,7 +86,7 @@ wolfhece/apps/curvedigitizer.py,sha256=lEJJwgAfulrrWQc-U6ij6sj59hWN3SZl4Yu1kQxVz
86
86
  wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
87
87
  wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
88
88
  wolfhece/apps/splashscreen.py,sha256=eCPAUYscZPWDYKBHDBWum_VIcE7WXOCBe1GLHL3KUmU,3088
89
- wolfhece/apps/version.py,sha256=K1wI1QprwJhkLzJfrbY1MD9huUZViybAZpuclY2ssps,388
89
+ wolfhece/apps/version.py,sha256=0IImrhN7acakKZi7KU7SSwA22Tx6X_NNUXIqvorewWc,388
90
90
  wolfhece/apps/wolf.py,sha256=j_CgvsL8rwixbVvVD5Z0s7m7cHZ86gmFLojKGuetMls,729
91
91
  wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
92
92
  wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
@@ -333,8 +333,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
333
333
  wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
334
334
  wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
335
335
  wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
336
- wolfhece-2.2.14.dist-info/METADATA,sha256=Y7UYL2Y3HjkDspeALQzelJ9yNiWX4bx42gHbYLXjrJA,2731
337
- wolfhece-2.2.14.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
338
- wolfhece-2.2.14.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
339
- wolfhece-2.2.14.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
340
- wolfhece-2.2.14.dist-info/RECORD,,
336
+ wolfhece-2.2.15.dist-info/METADATA,sha256=0ZU3v8YJGzebmgGIryaoqn00Mx_VoXPxCjdHy77z3pc,2731
337
+ wolfhece-2.2.15.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
338
+ wolfhece-2.2.15.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
339
+ wolfhece-2.2.15.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
340
+ wolfhece-2.2.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.1)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5