wolfhece 2.2.13__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)
@@ -41,12 +45,16 @@ def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES',
41
45
 
42
46
  try:
43
47
  wms=WebMapService('https://geoservices.wallonie.be/arcgis/services/'
44
- + catloc+'/MapServer/WMSServer',version='1.3.0')
48
+ + catloc+'/MapServer/WMSServer',version='1.3.0', timeout=5)
45
49
  except:
46
- wms=WebMapService('https://eservices.minfin.fgov.be/arcgis/services/'
47
- + catloc+'/MapServer/WMSServer',version='1.3.0')
48
- # wms=WebMapService('http://ccff02.minfin.fgov.be/geoservices/arcgis/services/'
49
- # + catloc+'/MapServer/WMSServer',version='1.3.0')
50
+ try:
51
+ wms=WebMapService('https://eservices.minfin.fgov.be/arcgis/services/'
52
+ + catloc+'/MapServer/WMSServer',version='1.3.0')
53
+ # wms=WebMapService('http://ccff02.minfin.fgov.be/geoservices/arcgis/services/'
54
+ # + catloc+'/MapServer/WMSServer',version='1.3.0')
55
+ except:
56
+ logging.warning(_('Impossible to get data from web services'))
57
+ return None
50
58
 
51
59
  ppkm = 300
52
60
  if w is None and h is None:
@@ -72,7 +80,7 @@ def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES',
72
80
  out = open('aqualim.png', 'wb')
73
81
  out.write(img.read())
74
82
  out.close()
75
- return BytesIO(b'1')
83
+ return None
76
84
  else:
77
85
  mycontents=list(wms.contents)
78
86
  curcont=['0']
@@ -113,7 +121,7 @@ def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES',
113
121
  return BytesIO(img.read())
114
122
  except:
115
123
  logging.warning(_('Impossible to get data from web services'))
116
- pass
124
+ return None
117
125
 
118
126
  def getVlaanderen(cat:Literal['Adpf'],
119
127
  xl:float,
@@ -128,10 +136,10 @@ def getVlaanderen(cat:Literal['Adpf'],
128
136
 
129
137
  try:
130
138
  wms=WebMapService('https://geo.api.vlaanderen.be/'
131
- + catloc+'/wms',version='1.3.0')
139
+ + catloc+'/wms',version='1.3.0', timeout=5)
132
140
  except:
133
141
  logging.warning(_('Impossible to get data from web services'))
134
- return
142
+ return None
135
143
 
136
144
  ppkm = 300
137
145
  if w is None and h is None:
@@ -168,7 +176,7 @@ def getVlaanderen(cat:Literal['Adpf'],
168
176
  return BytesIO(img.read())
169
177
  except:
170
178
  logging.warning(_('Impossible to get data from web services'))
171
- pass
179
+ return None
172
180
 
173
181
 
174
182
  def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
@@ -191,7 +199,7 @@ def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
191
199
  out = open('ignFrance.png', 'wb')
192
200
  out.write(img.read())
193
201
  out.close()
194
- return BytesIO(b'1')
202
+ return None
195
203
  else:
196
204
  return BytesIO(img.read())
197
205
 
@@ -206,7 +214,7 @@ def getLifeWatch(cat:Literal['None'],
206
214
  format:Literal['image/png', 'image/png; mode=8bit']='image/png') -> BytesIO:
207
215
 
208
216
  wms=WebMapService(f'https://maps.elie.ucl.ac.be/cgi-bin/mapserv72?map=/maps_server/lifewatch/mapfiles/LW_Ecotopes/latest/{cat}.map&SERVICE=wms',
209
- version='1.3.0')
217
+ version='1.3.0', timeout=10)
210
218
 
211
219
  ppkm = 300
212
220
  if w is None and h is None:
@@ -249,7 +257,7 @@ def getLifeWatch(cat:Literal['None'],
249
257
  out = open('LifeWatch.png', 'wb')
250
258
  out.write(img.read())
251
259
  out.close()
252
- return BytesIO(b'1')
260
+ return None
253
261
  else:
254
262
  mycontents=list(wms.contents)
255
263
  curcont=['lc_hr_raster'] # 'MS
@@ -266,13 +274,640 @@ def getLifeWatch(cat:Literal['None'],
266
274
  return BytesIO(img.read())
267
275
  except:
268
276
  logging.warning(_('Impossible to get data from web services'))
269
- pass
277
+ return None
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
+
270
905
 
271
906
  if __name__=='__main__':
272
907
  # me=pyproj.CRS.from_epsg(27573)
273
908
  # t=pyproj.Transformer.from_crs(27573,4326)
274
909
  # getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
275
- img = getLifeWatch('',250000,160000,252000,162000,1000,1000,False)
910
+ img = getAlaro('Total_precipitation',250000,160000,252000,162000,1000,1000,False)
276
911
  img = Image.open(img)
277
912
  img.show()
278
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 = 13
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,21 +323,81 @@ 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,
319
349
  self.width, self.height, False)
320
- image = Image.open(mybytes)
350
+
351
+ if mybytes is None:
352
+ logging.warning(_('Error opening image file : ') + str(self.category + '/' + self.subcategory))
353
+ return
354
+
355
+ try:
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
+
388
+ except Exception as e:
389
+ logging.warning(_('Error opening image file : ') + str(self.category + '/' + self.subcategory))
390
+ return
321
391
 
322
392
  glBindTexture(GL_TEXTURE_2D, self.idtexture[0])
323
393
  if self.subcategory[:5] == 'ORTHO':
324
- 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,
325
395
  image.tobytes())
326
396
  elif image.mode == 'RGB':
327
- 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,
328
398
  image.tobytes())
329
399
  else:
330
- 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,
331
401
  image.tobytes())
332
402
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
333
403
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
@@ -348,10 +418,10 @@ class imagetexture(Element_To_Draw):
348
418
  self.xmax = cx + dx * coeff
349
419
  self.ymin = cy - dy * coeff
350
420
  self.ymax = cy + dy * coeff
351
- self.width = self.mapviewer.canvaswidth * 2 * coeff
352
- 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)
353
423
 
354
- 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]
355
425
  if self.newview != self.oldview:
356
426
  self.load()
357
427
  self.oldview = self.newview
@@ -431,7 +501,7 @@ class Text_Image_Texture(genericImagetexture):
431
501
  self.width = self.myImage.width
432
502
  self.height = self.myImage.height
433
503
 
434
- 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]
435
505
 
436
506
  def findscale(self):
437
507
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.13
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
@@ -75,19 +75,13 @@ Requires-Dist: contextily
75
75
  Requires-Dist: pefile
76
76
  Requires-Dist: wolfpydike
77
77
 
78
- Ce paquet contient l'interface graphique Python du logiciel WOLF (HECE - ULiège) de même que plusieurs outils de traitements topographique, hydraulique et hydrologique.
78
+ This package contains the Python graphical interface for the WOLF software (HECE - ULiège), along with several tools for topographic, hydraulic, and hydrological processing.
79
79
 
80
- Les codes de calcul ne sont pas contenus dans ce paquet.
80
+ The core numerical codes are not included in this package.
81
81
 
82
- Version 2.1.x compatible Numpy 1.23.5
83
- Version 2.2.x compatible Numpy 2.1.3
82
+ - Version 2.1.x is compatible with Numpy 1.23.5.
83
+ - Version 2.2.x is compatible with Numpy 2.1.3.
84
84
 
85
- --
85
+ Since version 2.2.11, we support Python 3.10 and 3.11.
86
86
 
87
-
88
- This package contains the Python graphical interface of the WOLF software (HECE - ULiège), as well as several topographic, hydraulic, and hydrological processing tools.
89
-
90
- The numerical codes are not included in this package.
91
-
92
- Version 2.1.x compatible Numpy 1.23.5
93
- Version 2.2.x compatible Numpy 2.1.3
87
+ Python 3.12 and 3.13 are supported experimentally.
@@ -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=LWkQk3R7miiVal-n5K5P5ClSQJA_vi5ImBxYGuxCx9A,9122
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=IvFtekT5iLU2sivZOOlJXpE4CevjTQYSxHaOp4cH_wI,17723
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=d7VnTStgGHxEQxAc33py4-P5wUeDm7KqWqqQhg67lVw,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.13.dist-info/METADATA,sha256=uManH-6owmjo2fqAuRXToSiNmuGW07Z4EvZg4OnjwZQ,2908
337
- wolfhece-2.2.13.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
338
- wolfhece-2.2.13.dist-info/entry_points.txt,sha256=ZZ-aSfbpdcmo-wo84lRFzBN7LaSnD1XRGSaAKVX-Gpc,522
339
- wolfhece-2.2.13.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
340
- wolfhece-2.2.13.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