"""
Author: HECE - University of Liege, Pierre Archambeau
Date: 2024
Copyright (c) 2024 University of Liege. All rights reserved.
This script and its content are protected by copyright law. Unauthorized
copying or distribution of this file, via any medium, is strictly prohibited.
"""
from owslib.wms import WebMapService
from PIL import Image
from io import BytesIO
import pyproj
import urllib.parse as ul
import wx
import logging
from typing import Union, Literal
from enum import Enum
from datetime import datetime, timedelta
try:
from .PyTranslate import _
except:
from wolfhece.PyTranslate import _
[docs]
def to_image(mybytes:BytesIO) -> Image:
return Image.open(mybytes)
[docs]
def getWalonmap(cat:Literal['IMAGERIE/ORTHO_2021', 'ALEA', 'CADMAP', 'LIDAXES', '$IDW', 'EAU/ZONES_INONDEES'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True) -> BytesIO:
if cat.find('$')>0:
catloc=cat[:cat.find('$')]
elif cat.find('_wo_alea')>0:
catloc=cat[:cat.find('_wo_alea')]
else:
catloc=cat
try:
wms=WebMapService('https://geoservices.wallonie.be/arcgis/services/'
+ catloc+'/MapServer/WMSServer',version='1.3.0', timeout=5)
except:
try:
wms=WebMapService('https://eservices.minfin.fgov.be/arcgis/services/'
+ catloc+'/MapServer/WMSServer',version='1.3.0')
# wms=WebMapService('http://ccff02.minfin.fgov.be/geoservices/arcgis/services/'
# + catloc+'/MapServer/WMSServer',version='1.3.0')
except:
logging.warning(_('Impossible to get data from web services'))
return None
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
if tofile:
img=wms.getmap(layers=['0'],styles=['default'],srs='EPSG:31370',bbox=(xl,yl,xr,yr),size=(w,h),format='image/png',transparent=True)
out = open('aqualim.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents)
curcont=['0']
curstyles=['default']
if cat.find('ALEA')>0:
ech=(xr-xl)/w
if ech>6.5:
curcont=['6'] #au-dessus du 1:25000
else:
curcont=['5'] #en-dessous du 1:25000 et au-dessus de 1:5000
elif cat.find('CADMAP')>0:
curcont=['0,1']
curstyles=['default,default']
elif cat.find('LIMITES_ADMINISTRATIVES')>0:
curcont=['0,1,2,3']
curstyles=['default,default,default,default']
elif cat.find('wms')>0:
curcont=['1,2,3,4,5']
curstyles=['default,default,default,default,default']
elif cat.find('LIDAXES')>0:
curcont=['4,5,6,7,8,9,11,13']
curstyles=['default,default,default,default,default,default,default,default']
elif cat.find('IDW')>0:
curcont=['0']
curstyles=['default']
elif cat.find('ZONES_INONDEES')>0:
if 'wo_alea' in cat:
curcont = list(wms.contents)[1:]
curstyles=['default']*len(curcont)
else:
curcont = list(wms.contents)
curstyles=['default']*len(curcont)
try:
img=wms.getmap(layers=curcont,styles=curstyles,srs='EPSG:31370',bbox=(xl,yl,xr,yr),size=(w,h),format='image/png',transparent=True)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def getVlaanderen(cat:Literal['Adpf'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True) -> BytesIO:
catloc=cat
try:
wms=WebMapService('https://geo.api.vlaanderen.be/'
+ catloc+'/wms',version='1.3.0', timeout=5)
except:
logging.warning(_('Impossible to get data from web services'))
return None
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
if tofile:
img=wms.getmap(layers=['0'],styles=['default'],srs='EPSG:31370',bbox=(xl,yl,xr,yr),size=(w,h),format='image/png',transparent=True)
out = open('aqualim.png', 'wb')
out.write(img.read())
out.close()
return BytesIO(b'1')
else:
mycontents=list(wms.contents)
curcont=['Adpf']
curstyles=['default']
try:
img=wms.getmap(layers=curcont,styles=curstyles,srs='EPSG:31370',bbox=(xl,yl,xr,yr),size=(w,h),format='image/png',transparent=True)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def getIGNFrance(cat:str,epsg:str,xl,yl,xr,yr,w,h,tofile=True) -> BytesIO:
if epsg!='EPSG:4326':
transf=pyproj.Transformer.from_crs(epsg,'EPSG:4326')
y1,x1=transf.transform(xl,yl)
y2,x2=transf.transform(xr,yr)
else:
x1=xl
x2=xr
y1=yl
y2=yr
wms=WebMapService('https://wxs.ign.fr/inspire/inspire/r/wms',version='1.3.0')
img=wms.getmap(layers=[cat],styles=[''],srs='EPSG:4326',bbox=(x1,y1,x2,y2),size=(w,h),format='image/png',transparent=True)
if tofile:
out = open('ignFrance.png', 'wb')
out.write(img.read())
out.close()
return None
else:
return BytesIO(img.read())
[docs]
def getLifeWatch(cat:Literal['None'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True,
format:Literal['image/png', 'image/png; mode=8bit']='image/png') -> BytesIO:
wms=WebMapService(f'https://maps.elie.ucl.ac.be/cgi-bin/mapserv72?map=/maps_server/lifewatch/mapfiles/LW_Ecotopes/latest/{cat}.map&SERVICE=wms',
version='1.3.0', timeout=10)
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
MAXSIZE = 2048
if w > MAXSIZE:
pond = w / MAXSIZE
w = MAXSIZE
h = int(h / pond)
if h > MAXSIZE:
pond = h / MAXSIZE
h = MAXSIZE
w = int(w / pond)
if tofile:
img=wms.getmap(layers=['lc_hr_raster'],
# styles=['default'],
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format='image/png',
transparent=False)
out = open('LifeWatch.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents)
curcont=['lc_hr_raster'] # 'MS
curstyles=['1']
try:
img=wms.getmap(layers=curcont,
# styles=curstyles,
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format=format,
transparent=False)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def getNGI(cat:Literal['orthoimage_coverage',
'orthoimage_coverage_2016',
'orthoimage_coverage_2017',
'orthoimage_coverage_2018',
'orthoimage_coverage_2019',
'orthoimage_coverage_2020',
'orthoimage_coverage_2021',
'orthoimage_coverage_2022'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True,
format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
wms=WebMapService(f'https://wms.ngi.be/inspire/ortho/service?',
version='1.3.0', timeout=10)
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
MAXSIZE = 4000
if w > MAXSIZE:
pond = w / MAXSIZE
w = MAXSIZE
h = int(h / pond)
if h > MAXSIZE:
pond = h / MAXSIZE
h = MAXSIZE
w = int(w / pond)
if tofile:
img=wms.getmap(layers=['lc_hr_raster'],
# styles=['default'],
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format='image/png',
transparent=False)
out = open('LifeWatch.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents) # List all available layers
curcont=[cat] # 'MS
curstyles=['1']
# convert from EPSG:31370 to EPSG:3812
transf=pyproj.Transformer.from_crs('EPSG:31370','EPSG:3812')
x1,y1=transf.transform(xl,yl)
x2,y2=transf.transform(xr,yr)
try:
img=wms.getmap(layers=curcont,
# styles=curstyles,
srs='EPSG:3812',
bbox=(x1,y1,x2,y2),
size=(w,h),
format=format,
transparent=False)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def getCartoweb(cat:Literal['crossborder',
'crossborder_grey',
'overlay',
'topo',
'topo_grey'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True,
format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
wms=WebMapService(f'https://cartoweb.wms.ngi.be/service?',
version='1.3.0', timeout=10)
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
MAXSIZE = 2000
if w > MAXSIZE:
pond = w / MAXSIZE
w = MAXSIZE
h = int(h / pond)
if h > MAXSIZE:
pond = h / MAXSIZE
h = MAXSIZE
w = int(w / pond)
if tofile:
img=wms.getmap(layers=['lc_hr_raster'],
# styles=['default'],
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format='image/png',
transparent=False)
out = open('LifeWatch.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents) # List all available layers
curcont=[cat] # 'MS
curstyles=['1']
try:
img=wms.getmap(layers=curcont,
# styles=curstyles,
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format=format,
transparent=True)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def getOrthoPostFlood2021(cat:Literal['orthoimage_flood'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True,
format:Literal['image/png', 'image/GeoTIFF']='image/png') -> BytesIO:
wms=WebMapService(f'https://wms.ngi.be/inspire/flood_ortho/service?',
version='1.3.0', timeout=10)
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
MAXSIZE = 4000
if w > MAXSIZE:
pond = w / MAXSIZE
w = MAXSIZE
h = int(h / pond)
if h > MAXSIZE:
pond = h / MAXSIZE
h = MAXSIZE
w = int(w / pond)
if tofile:
img=wms.getmap(layers=['lc_hr_raster'],
# styles=['default'],
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format='image/png',
transparent=False)
out = open('LifeWatch.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents) # List all available layers
curcont=[cat] # 'MS
curstyles=['1']
# convert from EPSG:31370 to EPSG:3812
transf=pyproj.Transformer.from_crs('EPSG:31370','EPSG:3812')
x1,y1=transf.transform(xl,yl)
x2,y2=transf.transform(xr,yr)
try:
img=wms.getmap(layers=curcont,
# styles=curstyles,
srs='EPSG:3812',
bbox=(x1,y1,x2,y2),
size=(w,h),
format=format,
transparent=False)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
def get_Alaro_times():
wms=WebMapService(f'https://opendata.meteo.be/service/alaro/wms?',
version='1.3.0', timeout=10)
times = wms['Total_precipitation'].timepositions[0].split('/')
return times
[docs]
def get_Alaro_legend(layer:str):
""" Get the legend of the layer
:param layer: name of the layer
:return: legend of the layer
"""
import requests
from io import BytesIO
layers = ['10_m_u__wind_component',
'10_m_v__wind_component',
'2_m_Max_temp_since_ppp',
'2_m_Min_temp_since_ppp',
'2_m_dewpoint_temperature',
'2_m_temperature',
'2m_Relative_humidity',
'Convective_rain',
'Convective_snow',
'Geopotential',
'Inst_flx_Conv_Cld_Cover',
'Inst_flx_High_Cld_Cover',
'Inst_flx_Low_Cld_Cover',
'Inst_flx_Medium_Cld_Cover',
'Inst_flx_Tot_Cld_cover',
'Large_scale_rain',
'Large_scale_snow',
'Mean_sea_level_pressure',
'Relative_humidity',
'Relative_humidity_isobaric',
'SBL_Meridian_gust',
'SBL_Zonal_gust',
'Specific_humidity',
'Surf_Solar_radiation',
'Surf_Thermal_radiation',
'Surface_CAPE',
'Surface_Temperature',
'Surface_orography',
'Temperature',
'Total_precipitation',
'U-velocity',
'V-velocity',
'Vertical_velocity',
'Wet_Bulb_Poten_Temper',
'freezing_level_zeroDegC_isotherm']
layers_lowercase = [l.lower() for l in layers]
if layer.lower() not in layers_lowercase:
logging.warning(_('Layer not found in the list of available layers'))
return None
layer = layers[layers_lowercase.index(layer.lower())]
ows = "https://opendata.meteo.be/geoserver/alaro/ows?"
legend = requests.get(ows, params={'layer': layer,
'width': 50,
'height': 50,
'format': 'image/png',
'service': 'WMS',
'version': '1.3.0',
'request': 'GetLegendGraphic'})
return BytesIO(legend.content)
[docs]
def getAlaro(cat:Literal['10_m_u__wind_component',
'10_m_v__wind_component',
'2_m_Max_temp_since_ppp',
'2_m_Min_temp_since_ppp',
'2_m_dewpoint_temperature',
'2_m_temperature',
'2m_Relative_humidity',
'Convective_rain',
'Convective_snow',
'Geopotential',
'Inst_flx_Conv_Cld_Cover',
'Inst_flx_High_Cld_Cover',
'Inst_flx_Low_Cld_Cover',
'Inst_flx_Medium_Cld_Cover',
'Inst_flx_Tot_Cld_cover',
'Large_scale_rain',
'Large_scale_snow',
'Mean_sea_level_pressure',
'Relative_humidity',
'Relative_humidity_isobaric',
'SBL_Meridian_gust',
'SBL_Zonal_gust',
'Specific_humidity',
'Surf_Solar_radiation',
'Surf_Thermal_radiation',
'Surface_CAPE',
'Surface_Temperature',
'Surface_orography',
'Temperature',
'Total_precipitation',
'U-velocity',
'V-velocity',
'Vertical_velocity',
'Wet_Bulb_Poten_Temper',
'freezing_level_zeroDegC_isotherm'],
xl:float,
yl:float,
xr:float,
yr:float,
w:int = None,
h:int = None,
tofile=True,
format:Literal['image/png', 'image/GeoTIFF']='image/png',
time = None) -> BytesIO:
wms=WebMapService(f'https://opendata.meteo.be/service/alaro/wms?',
version='1.3.0', timeout=10)
ppkm = 300
if w is None and h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
w = int(real_w * ppkm)
h = int(real_h * ppkm)
elif w is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = h/real_h
w = int(real_w * ppkm)
# h = int(real_h * ppkm)
elif h is None:
real_w = (xr-xl)/1000
real_h = (yr-yl)/1000
ppkm = w/real_w
# w = int(real_w * ppkm)
h = int(real_h * ppkm)
MAXSIZE = 2000
if w > MAXSIZE:
pond = w / MAXSIZE
w = MAXSIZE
h = int(h / pond)
if h > MAXSIZE:
pond = h / MAXSIZE
h = MAXSIZE
w = int(w / pond)
if tofile:
img=wms.getmap(layers=['lc_hr_raster'],
# styles=['default'],
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format='image/png',
transparent=False)
out = open('LifeWatch.png', 'wb')
out.write(img.read())
out.close()
return None
else:
mycontents=list(wms.contents) # List all available layers
curcont=[cat] # 'MS
curstyles=['1']
# test = get_Alaro_legend(cat)
try:
if time is None:
time = wms[cat].timepositions[0].split('/')[0]
img=wms.getmap(layers=curcont,
# styles=curstyles,
srs='EPSG:31370',
bbox=(xl,yl,xr,yr),
size=(w,h),
format=format,
transparent=False,
time = time)
return BytesIO(img.read())
except:
logging.warning(_('Impossible to get data from web services'))
return None
[docs]
class Alaro_Navigator(wx.Frame):
""" Frame to navigate through Alaro data
Propose a caolendar to select the time of the data
"""
def __init__(self, parent, id, title):
super(Alaro_Navigator, self).__init__(parent, title=title, size=(500, 150))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox_start_end = wx.BoxSizer(wx.HORIZONTAL)
hbox_interv_alpha = wx.BoxSizer(wx.HORIZONTAL)
t_start, t_end, interv = get_Alaro_times()
[docs]
self._start_date = wx.TextCtrl(panel, value=t_start.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
[docs]
self._end_date = wx.TextCtrl(panel, value=t_end.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
[docs]
self._interval = wx.TextCtrl(panel, value=interv.replace('PT',''), size=(100, -1), style=wx.TE_READONLY | wx.TE_CENTER)
[docs]
self._btn_previous = wx.Button(panel, label=_('Previous'), size=(100, -1))
[docs]
self._btn_next = wx.Button(panel, label=_('Next'), size=(100, -1))
[docs]
self._time = wx.TextCtrl(panel, value=t_start.replace('.000Z', 'Z'), size=(100, -1), style=wx.TE_CENTER | wx.TE_PROCESS_ENTER)
[docs]
self._alpha = wx.TextCtrl(panel, value='1.0', size=(100, -1), style=wx.TE_CENTER | wx.TE_PROCESS_ENTER)
self._alpha.SetToolTip(_('Transparency of the image (0-1)'))
[docs]
self._btn_legend = wx.Button(panel, label=_('Legend'), size=(100, -1))
self._btn_legend.Bind(wx.EVT_BUTTON, self.OnLegend)
self._time.Bind(wx.EVT_TEXT_ENTER, self.OnEnterTime)
hbox.Add(self._btn_previous, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox.Add(self._time, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox.Add(self._btn_next, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox_start_end.Add(self._start_date, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox_start_end.Add(self._end_date, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox_interv_alpha.Add(self._interval, 1, flag=wx.EXPAND | wx.ALL, border=1)
hbox_interv_alpha.Add(self._alpha, 1, flag=wx.EXPAND | wx.ALL, border=1)
vbox.Add(hbox, 1, flag=wx.EXPAND | wx.ALL, border=1)
vbox.Add(hbox_start_end, 1, flag=wx.EXPAND | wx.ALL, border=1)
vbox.Add(hbox_interv_alpha, 1, flag=wx.EXPAND | wx.ALL, border=1)
vbox.Add(self._btn_legend, 1, flag=wx.EXPAND | wx.ALL, border=1)
panel.SetSizer(vbox)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
self._btn_previous.Bind(wx.EVT_BUTTON, self.OnPrevious)
self._btn_next.Bind(wx.EVT_BUTTON, self.OnNext)
[docs]
def OnPrevious(self, event):
""" Hour minus interval
"""
try:
time = self.time
# force the time to be rounded to the nearest interval
interval = timedelta(hours=1)
# nullify the minutes and seconds
time = time.replace(minute=0, second=0, microsecond=0, hour=time.hour - 1)
# check is the time is in the interval
if time < self.start or time > self.end:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.time = time
except ValueError:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
except Exception as e:
wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.Parent._alaro_update_time()
event.Skip()
[docs]
def OnNext(self, event):
""" Hour plus interval
"""
try:
time = self.time
# force the time to be rounded to the nearest interval
interval = timedelta(hours=1)
# nullify the minutes and seconds
time = time.replace(minute=0, second=0, microsecond=0, hour=time.hour + 1)
# check is the time is in the interval
if time < self.start or time > self.end:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.time = time
except ValueError:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
except Exception as e:
wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.Parent._alaro_update_time()
event.Skip()
[docs]
def OnCloseWindow(self, event):
self.Hide()
event.Skip()
[docs]
def OnLegend(self, event):
""" Called when the user press the legend button
"""
# get the legend of the layer
layer = self.Parent._alaro_legends()
event.Skip()
[docs]
def OnEnterTime(self, event):
""" Called when the user press enter in the time text box
"""
# time must be rounded to the nearest interval
try:
time = self.time
# force the time to be rounded to the nearest interval
interval = timedelta(hours=1)
# nullify the minutes and seconds
time = time.replace(minute=0, second=0, microsecond=0)
# check is the time is in the interval
if time < self.start or time > self.end:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.time = time
except ValueError:
wx.MessageBox(_('The date is not valid'), _('Error'), wx.OK | wx.ICON_ERROR)
return
except Exception as e:
wx.MessageBox(_('An error occurred: ') + str(e), _('Error'), wx.OK | wx.ICON_ERROR)
return
self.Parent._alaro_update_time()
event.Skip()
@property
[docs]
def start(self):
""" Return the start date selected by the user
"""
return datetime.strptime(self._start_date.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
@property
[docs]
def end(self):
""" Return the end date selected by the user
"""
return datetime.strptime(self._end_date.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
@property
[docs]
def time(self):
""" Return the time selected by the user
"""
return datetime.strptime(self._time.GetValue(), '%Y-%m-%dT%H:%M:%SZ')
@time.setter
def time(self, value:datetime):
""" Set the time selected by the user
"""
self._time.SetValue(value.strftime('%Y-%m-%dT%H:%M:%SZ'))
@property
[docs]
def time_str(self):
""" Return the time selected by the user as string
"""
return self._time.GetValue()
@property
[docs]
def alpha(self):
""" Return the alpha value selected by the user
"""
try:
return float(self._alpha.GetValue())
except:
self._alpha.SetValue('1.0')
return 1.0
if __name__=='__main__':
# me=pyproj.CRS.from_epsg(27573)
# t=pyproj.Transformer.from_crs(27573,4326)
# getIGNFrance('OI.OrthoimageCoverage.HR','EPSG:27563',878000,332300,879000,333300,1000,1000)
[docs]
img = getAlaro('Total_precipitation',250000,160000,252000,162000,1000,1000,False)
img = Image.open(img)
img.show()
pass