wolfhece 2.1.66__py3-none-any.whl → 2.1.67__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 +30 -7
- wolfhece/apps/version.py +1 -1
- wolfhece/hydrometry/kiwis.py +400 -116
- wolfhece/math_parser/calculator.py +29 -24
- wolfhece/wolf_array.py +17 -3
- {wolfhece-2.1.66.dist-info → wolfhece-2.1.67.dist-info}/METADATA +1 -1
- {wolfhece-2.1.66.dist-info → wolfhece-2.1.67.dist-info}/RECORD +10 -10
- {wolfhece-2.1.66.dist-info → wolfhece-2.1.67.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.66.dist-info → wolfhece-2.1.67.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.66.dist-info → wolfhece-2.1.67.dist-info}/top_level.txt +0 -0
wolfhece/PyDraw.py
CHANGED
@@ -8500,8 +8500,8 @@ class WolfMapViewer(wx.Frame):
|
|
8500
8500
|
# \n \
|
8501
8501
|
# !! ACTIONs !!\n \
|
8502
8502
|
# N : sélection noeud par noeud de la matrice courante\n \
|
8503
|
-
# B : sélection par vecteur
|
8504
|
-
# V : sélection par vecteur
|
8503
|
+
# b, B : sélection par vecteur de la matrice courante - zone intérieure\n \
|
8504
|
+
# v, V : sélection par vecteur de la matrice courante - trace du vecteur\n \
|
8505
8505
|
# r : reset de la sélection de la matrice courante\n \
|
8506
8506
|
# R : reset de toutes les sélections de la matrice courante\n \
|
8507
8507
|
# P : sélection de la section transversale par click souris\n \
|
@@ -8558,8 +8558,8 @@ class WolfMapViewer(wx.Frame):
|
|
8558
8558
|
'F11': _('Arrays : select by criteria'),
|
8559
8559
|
'F12': _('Arrays : operations'),
|
8560
8560
|
'n or N': _('Arrays : node-by-node selection'),
|
8561
|
-
'b or B': _('Arrays : temporary vector selection'),
|
8562
|
-
'v or V': _('Arrays :
|
8561
|
+
'b or B': _('Arrays : temporary/active vector selection - inside polygon'),
|
8562
|
+
'v or V': _('Arrays : temporary/active vector selection - along polyline'),
|
8563
8563
|
|
8564
8564
|
'r': _('Arrays : reset the selection'),
|
8565
8565
|
'R': _('Arrays : reset the selection and the associated dictionnary'),
|
@@ -9011,6 +9011,12 @@ class WolfMapViewer(wx.Frame):
|
|
9011
9011
|
elif key in LIST_1TO9:
|
9012
9012
|
|
9013
9013
|
if self.active_array is not None:
|
9014
|
+
|
9015
|
+
if self.active_array.SelectionData.myselection == 'all':
|
9016
|
+
logging.warning(_('No selection to transfer to the dictionary !'))
|
9017
|
+
logging.info(_('Please select some nodes before transfering to the dictionary, not ALL !'))
|
9018
|
+
return
|
9019
|
+
|
9014
9020
|
colors = [(0, 0, 255, 255), (0, 255, 0, 255), (0, 128, 255, 255), (255, 255, 0, 255), (255, 165, 0, 255), (128, 0, 128, 255), (255, 192, 203, 255), (165, 42, 42, 255), (128, 128, 128, 255)]
|
9015
9021
|
idx = LIST_1TO9.index(key)
|
9016
9022
|
if idx > 8:
|
@@ -9068,16 +9074,33 @@ class WolfMapViewer(wx.Frame):
|
|
9068
9074
|
if self.active_res2d is not None:
|
9069
9075
|
self.active_res2d.properties.select_node_by_node()
|
9070
9076
|
|
9077
|
+
if self.active_array is None and self.active_res2d is None:
|
9078
|
+
logging.warning(_('No active array or result 2D to select node by node !'))
|
9079
|
+
|
9071
9080
|
elif key == ord('V'): # V
|
9072
9081
|
if self.active_array is not None:
|
9073
|
-
|
9082
|
+
if shiftdown:
|
9083
|
+
self.active_array.myops.select_vector_inside_manager()
|
9084
|
+
else:
|
9085
|
+
self.active_array.myops.select_vector_inside_tmp()
|
9086
|
+
else:
|
9087
|
+
logging.warning(_('No active array to select the vector inside !'))
|
9074
9088
|
|
9075
9089
|
elif key == ord('B'): # B
|
9076
9090
|
if self.active_array is not None:
|
9077
|
-
|
9091
|
+
if shiftdown:
|
9092
|
+
self.active_array.myops.select_vector_under_manager()
|
9093
|
+
else:
|
9094
|
+
self.active_array.myops.select_vector_under_tmp()
|
9095
|
+
else:
|
9096
|
+
logging.warning(_('No active array to select the vector inside !'))
|
9078
9097
|
|
9079
9098
|
elif key == ord('P'): # P
|
9080
|
-
|
9099
|
+
|
9100
|
+
if self.active_cs is not None:
|
9101
|
+
self.start_action('Select nearest profile', _('Select nearest profile'))
|
9102
|
+
else:
|
9103
|
+
logging.warning(_('No active cross section to select the nearest profile !'))
|
9081
9104
|
|
9082
9105
|
elif key == ord('Z') and shiftdown: # Z
|
9083
9106
|
self.width = self.width / 1.1
|
wolfhece/apps/version.py
CHANGED
wolfhece/hydrometry/kiwis.py
CHANGED
@@ -22,6 +22,7 @@ import numpy as np
|
|
22
22
|
from enum import Enum
|
23
23
|
from typing import Literal
|
24
24
|
import urllib.parse
|
25
|
+
from pathlib import Path
|
25
26
|
|
26
27
|
import matplotlib.pyplot as plt
|
27
28
|
|
@@ -95,6 +96,9 @@ class kiwis_request_info(Enum):
|
|
95
96
|
Formats = "Formats"
|
96
97
|
Returnfields = "Returnfields"
|
97
98
|
OptionalFields = "Optionalfields"
|
99
|
+
Subdescription = "Subdescription"
|
100
|
+
Dateformats = "Dateformats"
|
101
|
+
Transformations= "Transformations"
|
98
102
|
|
99
103
|
class kiwis_token(Enum):
|
100
104
|
ACCESS_TOKEN_KEY = 'access_token'
|
@@ -136,6 +140,7 @@ class kiwis_keywords_horq(Enum):
|
|
136
140
|
VMAXAN = 'an.maximum'
|
137
141
|
VMAXANHYD = 'anHydro.maximum'
|
138
142
|
VMINANHYD = 'anHydro.minimum'
|
143
|
+
|
139
144
|
class kiwis_keywords_rain(Enum):
|
140
145
|
V5_10MIN = 'production'
|
141
146
|
V1H = '1h.total'
|
@@ -184,6 +189,22 @@ class quality_code(Enum):
|
|
184
189
|
VOID = (255, 'black', '.')
|
185
190
|
VOID2 = (-1, 'black', '.')
|
186
191
|
|
192
|
+
class station_fields(Enum):
|
193
|
+
STATION_ID = 'station_id'
|
194
|
+
STATION_NO = 'station_no'
|
195
|
+
STATION_NAME = 'station_name'
|
196
|
+
STATION_LOCAL_X = 'station_local_x'
|
197
|
+
STATION_LOCAL_Y = 'station_local_y'
|
198
|
+
STATION_LATITUDE = 'station_latitude'
|
199
|
+
STATION_LONGITUDE = 'station_longitude'
|
200
|
+
RIVER_NAME = 'river_name'
|
201
|
+
|
202
|
+
class timeseries_fields(Enum):
|
203
|
+
TS_ID = 'ts_id'
|
204
|
+
TS_NAME = 'ts_name'
|
205
|
+
TS_UNITNAME = 'ts_unitname'
|
206
|
+
TS_UNITSYMBOL ='ts_unitsymbol'
|
207
|
+
|
187
208
|
class hydrometry():
|
188
209
|
|
189
210
|
def __init__(self, url:str=URL_SPW, urltoken:str=URL_TOKEN, credential ='', dir='') -> None:
|
@@ -226,15 +247,24 @@ class hydrometry():
|
|
226
247
|
self.realstations = None
|
227
248
|
pass
|
228
249
|
|
250
|
+
def __str__(self) -> str:
|
251
|
+
ret='Columns in stations :\n'
|
252
|
+
for curcol in self.realstations.columns:
|
253
|
+
ret+=curcol+'\n'
|
254
|
+
return ret
|
255
|
+
|
229
256
|
def _get_commandstr(self, which:str):
|
257
|
+
""" Construction de la commande à envoyer au serveur KIWIS """
|
258
|
+
|
230
259
|
return self.url+'?request='+which.value+'&format=json'
|
231
260
|
|
232
261
|
def daily_token(self):
|
233
262
|
"""
|
234
263
|
Get daily token to be identified on hydrometry website
|
235
264
|
|
236
|
-
|
265
|
+
#FIXME: better manage error as response
|
237
266
|
"""
|
267
|
+
|
238
268
|
if self.credential == '':
|
239
269
|
self._header = None
|
240
270
|
return
|
@@ -247,64 +277,97 @@ class hydrometry():
|
|
247
277
|
else:
|
248
278
|
headers = {'Authorization' : 'Basic {}'.format(self.credential)}
|
249
279
|
data = {'grant_type' :'client_credentials'}
|
250
|
-
|
251
|
-
|
252
|
-
|
280
|
+
|
281
|
+
try:
|
282
|
+
self.token = requests.post(self.urltoken, data=data, headers=headers).json()
|
283
|
+
|
284
|
+
if 'error' in self.token:
|
285
|
+
self.token = None
|
286
|
+
self._header = {'Authorization': 'Bearer '}
|
287
|
+
return
|
288
|
+
|
289
|
+
with open(today, 'w') as f:
|
290
|
+
json.dump(self.token, f)
|
291
|
+
except:
|
292
|
+
self._header = {'Authorization': 'Bearer '}
|
293
|
+
return
|
294
|
+
self.token = None
|
253
295
|
|
254
296
|
self._header = {'Authorization': 'Bearer {}'.format(self.token['access_token'])}
|
255
297
|
|
256
298
|
def check_plot(self):
|
299
|
+
""" Instance is checked in mapviewer """
|
257
300
|
self.plotted = True
|
258
301
|
|
259
302
|
def uncheck_plot(self):
|
303
|
+
""" Instance is unchecked in mapviewer """
|
260
304
|
self.plotted = False
|
261
305
|
|
262
|
-
def save_struct(self,dir=''):
|
306
|
+
def save_struct(self, dir=''):
|
307
|
+
"""Sauvegarde des structures dans un répertoire
|
308
|
+
|
309
|
+
:param dir: répertoire de sauvegarde
|
310
|
+
"""
|
263
311
|
|
264
312
|
if dir=='':
|
265
313
|
return
|
266
314
|
|
267
|
-
|
268
|
-
|
269
|
-
self.groups.to_csv(join(dir,'groups.csv'))
|
270
|
-
self.requests.to_csv(join(dir,'requests.csv'))
|
315
|
+
dir = Path(dir)
|
316
|
+
dir.mkdir(parents=True, exist_ok=True)
|
271
317
|
|
272
|
-
|
318
|
+
self.sites.to_csv(dir / 'sites.csv')
|
319
|
+
self.stations.to_csv(dir / 'stations.csv')
|
320
|
+
self.groups.to_csv(dir / 'groups.csv')
|
321
|
+
self.requests.to_csv(dir / 'requests.csv')
|
322
|
+
|
323
|
+
def _get_stations_pythonlist(self, site_no:str|int, onlyreal:bool= True):
|
324
|
+
""" Obtention des stations pour le site en liste python
|
325
|
+
|
326
|
+
:param site_no: numéro du site
|
327
|
+
:param onlyreal: ne prendre que les stations réelles, pas les calculées
|
328
|
+
"""
|
273
329
|
|
274
330
|
if onlyreal:
|
275
|
-
stations = self.realstations[self.realstations[
|
331
|
+
stations = self.realstations[self.realstations[kiwis_site_fields.site_no.value]==site_no]
|
276
332
|
else:
|
277
|
-
stations = self.stations[self.stations[
|
333
|
+
stations = self.stations[self.stations[kiwis_site_fields.site_no.value]==site_no]
|
278
334
|
|
279
|
-
list_name_code = [curname+' --- '+curno for curname,curno in zip(stations[
|
280
|
-
list_code_name = [curno +' --- '+curname for curname,curno in zip(stations[
|
335
|
+
list_name_code = [curname+' --- '+curno for curname,curno in zip(stations[station_fields.STATION_NAME.value].values,stations[station_fields.STATION_NO.value].values)]
|
336
|
+
list_code_name = [curno +' --- '+curname for curname,curno in zip(stations[station_fields.STATION_NAME.value].values,stations[station_fields.STATION_NO.value].values)]
|
281
337
|
|
282
338
|
return list_name_code, list_code_name
|
283
339
|
|
284
340
|
def _get_sites_pythonlist(self):
|
341
|
+
""" Obtention des sites en liste python """
|
285
342
|
|
286
|
-
list_name_code = [curname+' --- '+curno for curname,curno in zip(self.sites[
|
343
|
+
list_name_code = [curname+' --- '+curno for curname,curno in zip(self.sites[kiwis_site_fields.site_name.value].values,self.sites[kiwis_site_fields.site_no.value].values)]
|
287
344
|
return list_name_code
|
288
345
|
|
289
346
|
def get_stations(self):
|
290
|
-
"""Obtention des stations pour le serveur courant
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
347
|
+
"""Obtention des stations pour le serveur courant.
|
348
|
+
|
349
|
+
Une requête sur le serveur KIWIS retourne les informations pour toutes les stations.
|
350
|
+
Une séparation entre station réelle et station calculée est ensuite effectuée:
|
351
|
+
- self.realstations
|
352
|
+
- self.compstations
|
353
|
+
|
354
|
+
Champs des stations :
|
355
|
+
- site_no : numéro du site ; le site correspond au réseau de mesure : DGH pour les stations du SPW-MI et DCENN pour les stations du SPW-ARNE ;
|
356
|
+
- station_no, station_name : code et nom de la station ;
|
357
|
+
- station_local_x, station_local_y : coordonnées de la station en Lambert belge 1972 ;
|
358
|
+
- station_latitude,station_longitude : coordonnées de la station en ETRS89 ;
|
359
|
+
- river_name : nom de la rivière, cette information n’est disponible que pour les stations de mesure de hauteur d’eau et de débits, les pluviomètres ne sont pas installés sur une rivière – il n’y a donc pas de nom de rivière associé ;
|
360
|
+
- parametertype_name : type de paramètre ;
|
361
|
+
- ts_id, ts_name : code et nom de la chronique ;
|
362
|
+
- ts_unitname, ts_unitsymbol : nom et symbole de l’unité de mesure ;
|
363
|
+
- ca_sta&ca_sta_returnfields=BV_DCE : nom du bassin versant principal suivi de son abréviation (2 lettres)
|
364
|
+
"""
|
365
|
+
|
366
|
+
returnfields = f'{kiwis_site_fields.site_no.value},'
|
367
|
+
returnfields += f'{station_fields.STATION_NO.value},{station_fields.STATION_NAME.value},{station_fields.STATION_ID.value},'
|
368
|
+
returnfields += f'{station_fields.STATION_LOCAL_X.value},{station_fields.STATION_LOCAL_Y.value},'
|
369
|
+
returnfields += f'{station_fields.STATION_LATITUDE.value},{station_fields.STATION_LONGITUDE.value},'
|
370
|
+
returnfields += f'{station_fields.RIVER_NAME.value},'
|
308
371
|
returnfields += 'ca_sta'
|
309
372
|
|
310
373
|
ca_sta_returnfields = 'station_gauge_datum,'
|
@@ -327,34 +390,67 @@ class hydrometry():
|
|
327
390
|
self.stations = pd.DataFrame(json_data[1:], columns = json_data[0])
|
328
391
|
|
329
392
|
#Conversion en minuscules
|
330
|
-
self.stations[
|
393
|
+
self.stations[station_fields.STATION_NAME.value]=self.stations[station_fields.STATION_NAME.value].str.lower()
|
331
394
|
|
332
395
|
# real stations are those with coordinates and not null
|
333
|
-
self.realstations = self.stations[(~pd.isnull(self.stations[
|
396
|
+
self.realstations = self.stations[(~pd.isnull(self.stations[station_fields.STATION_LOCAL_X.value])) & (self.stations[station_fields.STATION_LOCAL_X.value]!='')]
|
334
397
|
# computed stations are those without coordinates or null
|
335
|
-
self.compstations = self.stations[pd.isnull(self.stations[
|
398
|
+
self.compstations = self.stations[pd.isnull(self.stations[station_fields.STATION_LOCAL_X.value]) | self.stations[station_fields.STATION_LOCAL_X.value]!='']
|
336
399
|
|
337
400
|
def get_names_xy(self, site_no = None):
|
338
|
-
"""Obtention des noms et coordonnées des stations pour le site
|
401
|
+
"""Obtention des noms et coordonnées des stations pour le site
|
402
|
+
|
403
|
+
:param site_no: numéro du site
|
404
|
+
"""
|
405
|
+
|
406
|
+
if site_no is None:
|
407
|
+
stations_r = self.realstations
|
408
|
+
# stations_c = self.compstations
|
409
|
+
else:
|
410
|
+
stations_r = self.realstations[self.realstations[kiwis_site_fields.site_no.value]==site_no]
|
411
|
+
# stations_c = self.compstations[self.stations[kiwis_site_fields.site_no.value]==site_no]
|
412
|
+
|
413
|
+
if stations_r is None:
|
414
|
+
return ([],[],[])
|
415
|
+
else:
|
416
|
+
return ([curname + ' - ' + str(curid) for curname, curid in zip(stations_r[station_fields.STATION_NAME.value].values,
|
417
|
+
stations_r[station_fields.STATION_ID.value].values)],
|
418
|
+
stations_r[station_fields.STATION_LOCAL_X.value].values,
|
419
|
+
stations_r[station_fields.STATION_LOCAL_Y.value].values)
|
420
|
+
|
421
|
+
def get_names_latlon(self, site_no = None):
|
422
|
+
""" Obtention des noms et coordonnées des stations pour le site
|
423
|
+
|
424
|
+
:param site_no: numéro du site
|
425
|
+
"""
|
339
426
|
|
340
427
|
if site_no is None:
|
341
428
|
stations_r = self.realstations
|
342
429
|
# stations_c = self.compstations
|
343
430
|
else:
|
344
|
-
stations_r = self.realstations[self.realstations[
|
345
|
-
# stations_c = self.compstations[self.stations[
|
431
|
+
stations_r = self.realstations[self.realstations[kiwis_site_fields.site_no.value]==site_no]
|
432
|
+
# stations_c = self.compstations[self.stations[kiwis_site_fields.site_no.value]==site_no]
|
346
433
|
|
347
434
|
if stations_r is None:
|
348
435
|
return ([],[],[])
|
349
436
|
else:
|
350
|
-
return ([curname + ' - ' + str(curid) for curname, curid in zip(stations_r[
|
437
|
+
return ([curname + ' - ' + str(curid) for curname, curid in zip(stations_r[station_fields.STATION_NAME.value].values,
|
438
|
+
stations_r[station_fields.STATION_ID.value].values)],
|
439
|
+
stations_r[station_fields.STATION_LATITUDE.value].values,
|
440
|
+
stations_r[station_fields.STATION_LONGITUDE.value].values)
|
441
|
+
|
351
442
|
|
352
443
|
def select_inside(self, xll:float, yll:float, xur:float, yur:float, tolist=False):
|
353
444
|
"""
|
354
445
|
Recherche les stations dans une zone rectangulaire
|
355
446
|
|
356
|
-
xll
|
357
|
-
|
447
|
+
:param xll: X lower left - Lambert 72
|
448
|
+
:param yll: Y lower left - Lambert 72
|
449
|
+
:param xur: X upper right - Lambert 72
|
450
|
+
:param yur: Y upper right - Lambert 72
|
451
|
+
:param tolist: retourne une liste de noms et codes de stations et nom un dataframe
|
452
|
+
|
453
|
+
:return: liste de noms et codes de stations ou dataframe
|
358
454
|
"""
|
359
455
|
|
360
456
|
if xll>xur:
|
@@ -366,35 +462,103 @@ class hydrometry():
|
|
366
462
|
yll=yur
|
367
463
|
yur=tmpy
|
368
464
|
|
369
|
-
df = self.realstations[(self.realstations[
|
465
|
+
df = self.realstations[(self.realstations[station_fields.STATION_LOCAL_X.value].to_numpy(dtype=np.float64)>=xll) & (self.realstations[station_fields.STATION_LOCAL_X.value].to_numpy(dtype=np.float64)<=xur) & \
|
466
|
+
(self.realstations[station_fields.STATION_LOCAL_Y.value].to_numpy(dtype=np.float64)>=yll) & (self.realstations[station_fields.STATION_LOCAL_Y.value].to_numpy(dtype=np.float64)<=yur)]
|
467
|
+
if tolist:
|
468
|
+
list_name_code = [curname+' --- '+curno for curname,curno in zip(df[station_fields.STATION_NAME.value].values,df[station_fields.STATION_NO.value].values)]
|
469
|
+
return list_name_code
|
470
|
+
else:
|
471
|
+
return df
|
472
|
+
|
473
|
+
def select_inside_latlon(self, lonll:float, latll:float, lonur:float, latur:float, tolist=False):
|
474
|
+
"""
|
475
|
+
Recherche les stations dans une zone rectangulaire
|
476
|
+
|
477
|
+
:param lonll: Longitude lower left - WGS84
|
478
|
+
:param latll: Latitude lower left - WGS84
|
479
|
+
:param lonur: Longitude upper right - WGS84
|
480
|
+
:param latur: Latitude upper right - WGS84
|
481
|
+
:param tolist: retourne une liste de noms et codes de stations et nom un dataframe
|
482
|
+
|
483
|
+
:return: liste de noms et codes de stations ou dataframe
|
484
|
+
"""
|
485
|
+
|
486
|
+
if lonll>lonur:
|
487
|
+
tmpx=lonll
|
488
|
+
lonll=lonur
|
489
|
+
lonur=tmpx
|
490
|
+
if latll>latur:
|
491
|
+
tmpy=latll
|
492
|
+
latll=latur
|
493
|
+
latur=tmpy
|
494
|
+
|
495
|
+
df = self.realstations[(self.realstations[station_fields.STATION_LONGITUDE.value].to_numpy(dtype=np.float64)>=lonll) & (self.realstations[station_fields.STATION_LONGITUDE.value].to_numpy(dtype=np.float64)<=lonur) & \
|
496
|
+
(self.realstations[station_fields.STATION_LATITUDE.value].to_numpy(dtype=np.float64)>=latll) & (self.realstations[station_fields.STATION_LATITUDE.value].to_numpy(dtype=np.float64)<=latur)]
|
370
497
|
if tolist:
|
371
|
-
list_name_code = [curname+' --- '+curno for curname,curno in zip(df[
|
498
|
+
list_name_code = [curname+' --- '+curno for curname,curno in zip(df[station_fields.STATION_NAME.value].values,df[station_fields.STATION_NO.value].values)]
|
372
499
|
return list_name_code
|
373
500
|
else:
|
374
501
|
return df
|
375
502
|
|
376
|
-
def sort_nearests(self,x:float,y:float):
|
503
|
+
def sort_nearests(self, x:float, y:float):
|
504
|
+
"""
|
505
|
+
Trie les stations en fonction de la distance et retourne un index trié
|
506
|
+
|
507
|
+
:param x: coordonnée x - Lambert 72
|
508
|
+
:param y: coordonnée y - Lambert 72
|
509
|
+
"""
|
510
|
+
dist = np.asarray([(float(cur[station_fields.STATION_LOCAL_X.value]) - x)**2 + (float(cur[station_fields.STATION_LOCAL_Y.value]) - y)**2 for idx,cur in self.realstations.iterrows()])
|
511
|
+
index = np.arange(len(dist))[dist.argsort()]
|
512
|
+
|
513
|
+
return index
|
514
|
+
|
515
|
+
def sort_nearests_latlon(self, lon:float, lat:float):
|
377
516
|
"""
|
378
517
|
Trie les stations en fonction de la distance et retourne un index trié
|
518
|
+
|
519
|
+
:param lon: longitude - WGS84
|
520
|
+
:param lat: latitude - WGS84
|
379
521
|
"""
|
380
|
-
dist = np.asarray([(float(cur[
|
522
|
+
dist = np.asarray([(float(cur[station_fields.STATION_LATITUDE.value]) - lat)**2 + (float(cur[station_fields.STATION_LONGITUDE.value]) - lon)**2 for idx,cur in self.realstations.iterrows()])
|
381
523
|
index = np.arange(len(dist))[dist.argsort()]
|
382
524
|
|
383
525
|
return index
|
384
526
|
|
385
|
-
def find_nearest(self,x:float,y:float, tolist=False):
|
527
|
+
def find_nearest(self, x:float, y:float, tolist=False):
|
386
528
|
"""
|
387
529
|
Trouve la station la plus proche
|
530
|
+
|
531
|
+
:param x: coordonnée x - Lambert 72
|
532
|
+
:param y: coordonnée y - Lambert 72
|
388
533
|
"""
|
389
534
|
index = self.sort_nearests(x,y)
|
390
535
|
|
391
536
|
if tolist:
|
392
|
-
return [self.realstations.iloc[index[0]][
|
537
|
+
return [self.realstations.iloc[index[0]][station_fields.STATION_NAME.value]+' --- '+self.realstations.iloc[index[0]][station_fields.STATION_NO.value]]
|
538
|
+
else:
|
539
|
+
return self.realstations.iloc[index[0]]
|
540
|
+
|
541
|
+
def find_nearest_latlon(self, lon:float, lat:float, tolist=False):
|
542
|
+
"""
|
543
|
+
Trouve la station la plus proche
|
544
|
+
|
545
|
+
:param lon: longitude - WGS84
|
546
|
+
:param lat: latitude - WGS84
|
547
|
+
"""
|
548
|
+
|
549
|
+
index = self.sort_nearests_latlon(lon,lat)
|
550
|
+
|
551
|
+
if tolist:
|
552
|
+
return [self.realstations.iloc[index[0]][station_fields.STATION_NAME.value]+' --- '+self.realstations.iloc[index[0]][station_fields.STATION_NO.value]]
|
393
553
|
else:
|
394
554
|
return self.realstations.iloc[index[0]]
|
395
555
|
|
396
556
|
def get_timeseries_group(self, rfw:Literal['rain','waterdepth','flowrate'], time:Literal['5min','5or10min','1h','1d','1m']):
|
397
|
-
"""Obtention des stations pour le groupe souhaité
|
557
|
+
"""Obtention des stations pour le groupe souhaité
|
558
|
+
|
559
|
+
:param rfw: type de groupe - rain, flowrate, waterdepth
|
560
|
+
:param time: type de série - 5min, 5or10min, 1h, 1d, 1m
|
561
|
+
"""
|
398
562
|
|
399
563
|
if self.url!='':
|
400
564
|
stations=None
|
@@ -406,21 +570,31 @@ class hydrometry():
|
|
406
570
|
|
407
571
|
return stations
|
408
572
|
|
409
|
-
def get_sites(self):
|
410
|
-
"""Obtention des sites pour le serveur courant
|
411
|
-
|
573
|
+
def get_sites(self, forcerequest=False):
|
574
|
+
"""Obtention des sites pour le serveur courant
|
575
|
+
|
576
|
+
:param forcerequest: force la requête même si les données de cache sont déjà présentes"""
|
577
|
+
|
578
|
+
if self.dir!='' and exists(join(self.dir,'sites.csv')) and not forcerequest:
|
412
579
|
self.sites = pd.read_csv(join(self.dir,'sites.csv'),index_col=0)
|
413
|
-
elif self.url!='':
|
580
|
+
elif self.url!='' or forcerequest:
|
414
581
|
json_data = requests.get(self._get_commandstr(kiwis_command.getSiteList),verify=True, headers=self._header).json()
|
415
582
|
self.sites = pd.DataFrame(json_data[1:], columns = json_data[0])
|
583
|
+
else:
|
584
|
+
self.sites = None
|
585
|
+
|
586
|
+
def get_groups(self, forcerequest=False):
|
587
|
+
"""Obtention des groupes pour le serveur courant
|
416
588
|
|
417
|
-
|
418
|
-
|
419
|
-
if self.dir!='' and exists(join(self.dir,'groups.csv')):
|
589
|
+
:param forcerequest: force la requête même si les données de cache sont déjà présentes"""
|
590
|
+
|
591
|
+
if self.dir!='' and exists(join(self.dir,'groups.csv')) and not forcerequest:
|
420
592
|
self.groups = pd.read_csv(join(self.dir,'groups.csv'),index_col=0)
|
421
|
-
elif self.url!='':
|
593
|
+
elif self.url!='' or forcerequest:
|
422
594
|
json_data = requests.get(self._get_commandstr(kiwis_command.getGroupList),verify=True, headers=self._header).json()
|
423
595
|
self.groups = pd.DataFrame(json_data[1:], columns = json_data[0])
|
596
|
+
else:
|
597
|
+
self.groups = None
|
424
598
|
|
425
599
|
# def get_ratingcurves(self):
|
426
600
|
# """Obtention des courbes de tarage pour le serveur courant"""
|
@@ -430,15 +604,24 @@ class hydrometry():
|
|
430
604
|
# json_data = requests.get(self.url+'?request=getRatingCurveList&datasource=0&format=json',verify=True).json()
|
431
605
|
# self.ratingcurves = pd.DataFrame(json_data[1:], columns = json_data[0])
|
432
606
|
|
433
|
-
def get_requests(self):
|
434
|
-
"""Obtention des requêtes possibles pour le serveur courant
|
435
|
-
|
607
|
+
def get_requests(self, forcerequest=False):
|
608
|
+
"""Obtention des requêtes possibles pour le serveur courant
|
609
|
+
|
610
|
+
:param forcerequest: force la requête même si les données de cache sont déjà présentes"""
|
611
|
+
|
612
|
+
if self.dir!='' and exists(join(self.dir,'requests.csv')) and not forcerequest:
|
436
613
|
self.requests = pd.read_csv(join(self.dir,'requests.csv'),index_col=0)
|
437
|
-
elif self.url!='':
|
614
|
+
elif self.url!='' or forcerequest:
|
438
615
|
json_data = requests.get(self._get_commandstr(kiwis_command.getrequestinfo),verify=True, headers=self._header).json()
|
439
616
|
self.requests = pd.DataFrame(json_data[0]['Requests'])
|
617
|
+
else:
|
618
|
+
self.requests = None
|
619
|
+
|
620
|
+
def print_requestinfo(self, which:kiwis_command):
|
621
|
+
""" Affichage des informations pour une requête donnée
|
622
|
+
|
623
|
+
:param which: requête à afficher"""
|
440
624
|
|
441
|
-
def print_requestinfo(self,which:Enum):
|
442
625
|
if self.requests is None:
|
443
626
|
self.get_requests()
|
444
627
|
|
@@ -448,8 +631,13 @@ class hydrometry():
|
|
448
631
|
for cur in kiwis_request_info:
|
449
632
|
print(myrequest[cur.value])
|
450
633
|
|
451
|
-
def timeseries_list(self,stationname='',stationcode=''):
|
452
|
-
"""Récupération de la liste des TimeSeries pour l'id d'une station
|
634
|
+
def timeseries_list(self, stationname:str = '', stationcode:str = ''):
|
635
|
+
"""Récupération de la liste des TimeSeries pour l'id d'une station
|
636
|
+
soit via le nom de la station, soit via le code de la station.
|
637
|
+
|
638
|
+
:param stationname: nom de la station
|
639
|
+
:param stationcode: code de la station
|
640
|
+
"""
|
453
641
|
|
454
642
|
if stationname!='':
|
455
643
|
id=self.get_stationid(stationname)
|
@@ -463,12 +651,15 @@ class hydrometry():
|
|
463
651
|
|
464
652
|
return id,pd.DataFrame(json_data[1:], columns = json_data[0])
|
465
653
|
|
466
|
-
def save_all_lists(self,dir):
|
467
|
-
"""Sauveragde des listes pour toutes les stations
|
468
|
-
|
469
|
-
|
654
|
+
def save_all_lists(self, dir:str):
|
655
|
+
"""Sauveragde des listes pour toutes les stations
|
656
|
+
|
657
|
+
:param dir: répertoire de sauvegarde"""
|
470
658
|
|
471
|
-
|
659
|
+
for curstation in self.stations[station_fields.STATION_NO.value]:
|
660
|
+
self.save_list(stationcode=curstation, dir=dir)
|
661
|
+
|
662
|
+
def _get_filename_list(self, stationname:str='', stationcode:str=''):
|
472
663
|
"""retourne un nom de fichier avec la station et le code
|
473
664
|
|
474
665
|
Utile car dans certains noms de la BDD KIWIS il y a un caractère '/' qui ne peut être utilisé comme nom de fichier
|
@@ -484,7 +675,8 @@ class hydrometry():
|
|
484
675
|
|
485
676
|
return stationname.replace('/','-') + '_' + stationcode + '_' + str(id) + '.csv'
|
486
677
|
|
487
|
-
def _get_filename_series(self,stationname='',stationcode='',
|
678
|
+
def _get_filename_series(self,stationname:str='',stationcode:str='',
|
679
|
+
which:kiwis_default_q | kiwis_default_h | kiwis_keywords_horq | kiwis_keywords_rain = kiwis_default_q.Q_FULL):
|
488
680
|
"""retourne un nom de fichier avec la station et le code et le type de données
|
489
681
|
|
490
682
|
Utile car dans certains noms de la BDD KIWIS il y a un caractère '/' qui ne peut être utilisé comme nom de fichier
|
@@ -500,16 +692,24 @@ class hydrometry():
|
|
500
692
|
|
501
693
|
return stationname.replace('/','-') + '_' + stationcode + '_' + str(id) + '_' + which.value + '.csv'
|
502
694
|
|
503
|
-
def save_list(self,stationname='',stationcode='',dir=''):
|
504
|
-
"""Sauvegarde de la liste des des timeseries dans un fichier
|
505
|
-
|
506
|
-
|
695
|
+
def save_list(self, stationname:str = '', stationcode:str = '', dir:str = ''):
|
696
|
+
"""Sauvegarde de la liste des des timeseries dans un fichier
|
697
|
+
|
698
|
+
:param stationname: nom de la station
|
699
|
+
:param stationcode: code de la station
|
700
|
+
:param dir: répertoire de sauvegarde"""
|
701
|
+
|
702
|
+
dir = Path(dir)
|
703
|
+
if not dir.exists():
|
704
|
+
dir.mkdir(parents=True, exist_ok=True)
|
507
705
|
|
508
706
|
id,list=self.timeseries_list(stationname=stationname,stationcode=stationcode)
|
509
707
|
filename = self._get_filename_list(stationname,stationcode)
|
510
|
-
list.to_csv(
|
708
|
+
list.to_csv(dir / filename)
|
511
709
|
|
512
|
-
def timeseries(self,stationname='', stationcode
|
710
|
+
def timeseries(self,stationname:str='', stationcode:str='', dir:str='',
|
711
|
+
fromdate=datetime.now()-timedelta(60), todate=datetime.now(),
|
712
|
+
ts_name:str='', ts_id:str='', interval:int=3600, timezone:str = 'GMT+0'):
|
513
713
|
"""
|
514
714
|
Récupération des valeurs d'une TimeSerie
|
515
715
|
- sur base des dates
|
@@ -517,6 +717,16 @@ class hydrometry():
|
|
517
717
|
- le nom de la station ou le code ET le nom de la timeserie --> dans ce cas, la routine commence par retrouver l'id de la ts
|
518
718
|
- directement l'id de la timeserie
|
519
719
|
|
720
|
+
:param stationname: nom de la station
|
721
|
+
:param stationcode: code de la station
|
722
|
+
:param dir: répertoire de sauvegarde
|
723
|
+
:param fromdate: date de début
|
724
|
+
:param todate: date de fin
|
725
|
+
:param ts_name: nom de la timeserie
|
726
|
+
:param ts_id: id de la timeserie
|
727
|
+
:param interval: intervalle de temps
|
728
|
+
:param timezone: timezone
|
729
|
+
|
520
730
|
"""
|
521
731
|
|
522
732
|
if timezone=='Europe/Brussels' or timezone=='local':
|
@@ -542,11 +752,11 @@ class hydrometry():
|
|
542
752
|
if len(json_data)==1:
|
543
753
|
return None
|
544
754
|
|
545
|
-
ts_id = str(int(pd.DataFrame(json_data[1:], columns = json_data[0])[
|
755
|
+
ts_id = str(int(pd.DataFrame(json_data[1:], columns = json_data[0])[timeseries_fields.TS_ID.value].iloc[0]))
|
546
756
|
else:
|
547
757
|
filename = self._get_filename_list(stationname,stationcode)
|
548
758
|
curlist=pd.read_csv(join(dir,filename),index_col=0)
|
549
|
-
ts_id = str(int(curlist.loc(curlist[
|
759
|
+
ts_id = str(int(curlist.loc(curlist[timeseries_fields.TS_NAME.value==ts_name])[timeseries_fields.TS_ID.value]))
|
550
760
|
|
551
761
|
if "1h" in ts_name:
|
552
762
|
nb = (todate - fromdate).days*24
|
@@ -573,7 +783,10 @@ class hydrometry():
|
|
573
783
|
locts=[]
|
574
784
|
while curfrom<todate:
|
575
785
|
print(curfrom, curend)
|
576
|
-
|
786
|
+
tmpts = self.timeseries(stationname, stationcode, dir, curfrom, curend, ts_name, ts_id, timezone=timezone)
|
787
|
+
if len(tmpts)>0:
|
788
|
+
locts.append(tmpts)
|
789
|
+
|
577
790
|
curfrom = curend
|
578
791
|
curend = curfrom+timedelta(seconds=200000 * cursec)
|
579
792
|
if curend>todate:
|
@@ -596,7 +809,9 @@ class hydrometry():
|
|
596
809
|
|
597
810
|
return df.squeeze()
|
598
811
|
|
599
|
-
def timeseries_qc(self,stationname='', stationcode
|
812
|
+
def timeseries_qc(self, stationname:str='', stationcode:str='', dir:str='',
|
813
|
+
fromdate=datetime.now()-timedelta(60), todate=datetime.now(),
|
814
|
+
ts_name:str='', ts_id:str='', interval:int=3600, timezone:str = 'GMT+0'):
|
600
815
|
"""
|
601
816
|
Récupération des quality code d'une TimeSerie
|
602
817
|
- sur base des dates
|
@@ -604,6 +819,16 @@ class hydrometry():
|
|
604
819
|
- le nom de la station ou le code ET le nom de la timeserie --> dans ce cas, la routine commence par retrouver l'id de la ts
|
605
820
|
- directement l'id de la timeserie
|
606
821
|
|
822
|
+
:param stationname: nom de la station
|
823
|
+
:param stationcode: code de la station
|
824
|
+
:param dir: répertoire de sauvegarde
|
825
|
+
:param fromdate: date de début
|
826
|
+
:param todate: date de fin
|
827
|
+
:param ts_name: nom de la timeserie
|
828
|
+
:param ts_id: id de la timeserie
|
829
|
+
:param interval: intervalle de temps
|
830
|
+
:param timezone: timezone
|
831
|
+
|
607
832
|
"""
|
608
833
|
if timezone=='Europe/Brussels' or timezone=='local':
|
609
834
|
timezone=''
|
@@ -629,11 +854,11 @@ class hydrometry():
|
|
629
854
|
if len(json_data)==1:
|
630
855
|
return None
|
631
856
|
|
632
|
-
ts_id = str(int(pd.DataFrame(json_data[1:], columns = json_data[0])[
|
857
|
+
ts_id = str(int(pd.DataFrame(json_data[1:], columns = json_data[0])[timeseries_fields.TS_ID.value].iloc[0]))
|
633
858
|
else:
|
634
859
|
filename = self._get_filename_list(stationname,stationcode)
|
635
860
|
curlist=pd.read_csv(join(dir,filename),index_col=0)
|
636
|
-
ts_id = str(int(curlist.loc(curlist[
|
861
|
+
ts_id = str(int(curlist.loc(curlist[timeseries_fields.TS_NAME.value==ts_name])[timeseries_fields.TS_ID.value]))
|
637
862
|
|
638
863
|
if "1h" in ts_name:
|
639
864
|
nb = (todate - fromdate).days*24
|
@@ -683,14 +908,27 @@ class hydrometry():
|
|
683
908
|
|
684
909
|
return df.squeeze()
|
685
910
|
|
686
|
-
def fromcsv(self,dir='spw',stationname='',stationcode='',
|
911
|
+
def fromcsv(self, dir:str='spw', stationname:str='', stationcode:str='',
|
912
|
+
which:kiwis_default_q | kiwis_default_h | kiwis_keywords_horq | kiwis_keywords_rain = kiwis_default_q.Q_FULL,
|
913
|
+
fromdate:datetime=None, todate:datetime=None):
|
687
914
|
"""
|
688
|
-
Lecture depuis un fichier csv créé depuis un import précédent
|
689
|
-
Les fichiers doivent être disponibles depuis un sous-répertoire spw
|
915
|
+
Lecture depuis un fichier csv créé depuis un import précédent.
|
916
|
+
Les fichiers doivent être disponibles depuis un sous-répertoire spw.
|
917
|
+
|
918
|
+
:param dir: répertoire de sauvegarde
|
919
|
+
:param stationname: nom de la station
|
920
|
+
:param stationcode: code de la station
|
921
|
+
:param which: type de données
|
922
|
+
:param fromdate: date de début
|
923
|
+
:param todate: date de fin
|
924
|
+
|
690
925
|
"""
|
691
|
-
filename=
|
926
|
+
filename=self._get_filename_series(stationname,stationcode,which)
|
927
|
+
|
928
|
+
dir = Path(dir)
|
929
|
+
filename = dir / filename
|
692
930
|
|
693
|
-
if exists(
|
931
|
+
if filename.exists():
|
694
932
|
mydata= pd.read_csv(filename,header=0,index_col=0,parse_dates=True,engine='pyarrow').squeeze("columns")
|
695
933
|
else:
|
696
934
|
return
|
@@ -704,88 +942,134 @@ class hydrometry():
|
|
704
942
|
else:
|
705
943
|
return mydata[fromdate:todate]
|
706
944
|
|
707
|
-
def saveas(self,flow:pd.Series,dir:str,stationname='',stationcode='',
|
708
|
-
|
945
|
+
def saveas(self, flow:pd.Series, dir:str, stationname='', stationcode='',
|
946
|
+
which:kiwis_default_q | kiwis_default_h | kiwis_keywords_horq | kiwis_keywords_rain = kiwis_default_q.Q_FULL):
|
947
|
+
"""Sauvegarde d'une series pandas dans un fichier .csv
|
948
|
+
|
949
|
+
:param flow: série pandas
|
950
|
+
:param dir: répertoire de sauvegarde
|
951
|
+
:param stationname: nom de la station
|
952
|
+
:param stationcode: code de la station
|
953
|
+
:param which: type de données
|
954
|
+
"""
|
955
|
+
|
709
956
|
filename=self._get_filename_series(stationname,stationcode,which.value)
|
957
|
+
|
958
|
+
dir = Path(dir)
|
959
|
+
filename = dir / filename
|
960
|
+
|
710
961
|
flow.to_csv(filename,header=['Data'], date_format="%Y-%m-%dT%H:%M:%S.%f%z")
|
711
962
|
|
712
|
-
def get_stationid(self,name:str='',code=''):
|
713
|
-
"""Récupération de l'id sur base du nom ou du code
|
963
|
+
def get_stationid(self, name:str='', code:str='') -> int:
|
964
|
+
"""Récupération de l'id sur base du nom ou du code
|
965
|
+
|
966
|
+
:param name: nom de la station
|
967
|
+
:param code: code de la station"""
|
968
|
+
|
714
969
|
if name!='':
|
715
|
-
return int(self.stations.loc[self.stations[
|
970
|
+
return int(self.stations.loc[self.stations[station_fields.STATION_NAME.value]==name.lower()][station_fields.STATION_ID.value].iloc[0])
|
716
971
|
elif code!='':
|
717
|
-
return int(self.stations.loc[self.stations[
|
972
|
+
return int(self.stations.loc[self.stations[station_fields.STATION_NO.value]==code][station_fields.STATION_ID.value].iloc[0])
|
718
973
|
else:
|
719
974
|
return None
|
720
975
|
|
721
|
-
def get_gauge_datum(self,name:str='',code=''):
|
722
|
-
"""Récupération de l'altitude de référence sur base du nom ou du code
|
976
|
+
def get_gauge_datum(self,name:str='',code:str=''):
|
977
|
+
"""Récupération de l'altitude de référence sur base du nom ou du code
|
978
|
+
|
979
|
+
:param name: nom de la station
|
980
|
+
:param code: code de la station"""
|
981
|
+
|
723
982
|
try:
|
724
983
|
if name!='':
|
725
|
-
return self.stations.loc[self.stations[
|
984
|
+
return self.stations.loc[self.stations[station_fields.STATION_NAME.value]==name.lower()]['station_gauge_datum'].iloc[0]
|
726
985
|
elif code!='':
|
727
|
-
return self.stations.loc[self.stations[
|
986
|
+
return self.stations.loc[self.stations[station_fields.STATION_NO.value]==code]['station_gauge_datum'].iloc[0]
|
728
987
|
else:
|
729
988
|
return None
|
730
989
|
except:
|
731
990
|
return None
|
732
991
|
|
733
|
-
def get_catchment_size(self,name:str='',code=''):
|
734
|
-
"""Récupération de la surface du BV de référence sur base du nom ou du code
|
992
|
+
def get_catchment_size(self,name:str='',code:str=''):
|
993
|
+
"""Récupération de la surface du BV de référence sur base du nom ou du code
|
994
|
+
|
995
|
+
:param name: nom de la station
|
996
|
+
:param code: code de la station"""
|
997
|
+
|
735
998
|
try:
|
736
999
|
if name!='':
|
737
|
-
return self.stations.loc[self.stations[
|
1000
|
+
return self.stations.loc[self.stations[station_fields.STATION_NAME.value]==name.lower()]['CATCHMENT_SIZE'].iloc[0]
|
738
1001
|
elif code!='':
|
739
|
-
return self.stations.loc[self.stations[
|
1002
|
+
return self.stations.loc[self.stations[station_fields.STATION_NO.value]==code]['CATCHMENT_SIZE'].iloc[0]
|
740
1003
|
else:
|
741
1004
|
return None
|
742
1005
|
except:
|
743
1006
|
return None
|
744
1007
|
|
745
|
-
def get_bv_dce(self,name:str='',code=''):
|
746
|
-
"""Récupération du nom de BV au sens de la DCE "Directive Cadre Eau" sur base du nom ou du code
|
1008
|
+
def get_bv_dce(self,name:str='',code:str=''):
|
1009
|
+
"""Récupération du nom de BV au sens de la DCE "Directive Cadre Eau" sur base du nom ou du code
|
1010
|
+
|
1011
|
+
:param name: nom de la station
|
1012
|
+
:param code: code de la station"""
|
1013
|
+
|
747
1014
|
try:
|
748
1015
|
if name!='':
|
749
|
-
return self.stations.loc[self.stations[
|
1016
|
+
return self.stations.loc[self.stations[station_fields.STATION_NAME.value]==name.lower()]['BV_DCE'].iloc[0]
|
750
1017
|
elif code!='':
|
751
|
-
return self.stations.loc[self.stations[
|
1018
|
+
return self.stations.loc[self.stations[station_fields.STATION_NO.value]==code]['BV_DCE'].iloc[0]
|
752
1019
|
else:
|
753
1020
|
return None
|
754
1021
|
except:
|
755
1022
|
return None
|
756
1023
|
|
757
1024
|
def get_stationcode(self,name:str=''):
|
758
|
-
"""Récupération du code sur base du nom
|
1025
|
+
"""Récupération du code sur base du nom
|
1026
|
+
|
1027
|
+
:param name: nom de la station
|
1028
|
+
"""
|
1029
|
+
|
759
1030
|
if name!='':
|
760
|
-
return self.stations.loc[self.stations[
|
1031
|
+
return self.stations.loc[self.stations[station_fields.STATION_NAME.value]==name.lower()][station_fields.STATION_NO.value].squeeze()
|
761
1032
|
else:
|
762
1033
|
return None
|
763
1034
|
|
764
1035
|
def get_stationname(self,code:str=''):
|
765
|
-
"""Récupération du nom sur base du code
|
1036
|
+
"""Récupération du nom sur base du code
|
1037
|
+
|
1038
|
+
:param code: code de la station"""
|
1039
|
+
|
766
1040
|
if code!='':
|
767
|
-
return self.stations.loc[self.stations[
|
1041
|
+
return self.stations.loc[self.stations[station_fields.STATION_NO.value]==code][station_fields.STATION_NAME.value].squeeze()
|
768
1042
|
else:
|
769
1043
|
return None
|
770
1044
|
|
771
|
-
def get_siteid(self,name:str='',code=''):
|
772
|
-
"""Récupération de l'id sur base du nom ou du code
|
1045
|
+
def get_siteid(self,name:str='',code:str=''):
|
1046
|
+
"""Récupération de l'id sur base du nom ou du code
|
1047
|
+
|
1048
|
+
:param name: nom de la station
|
1049
|
+
:param code: code de la station"""
|
1050
|
+
|
773
1051
|
if name!='':
|
774
|
-
return int(self.sites.loc[self.sites[kiwis_site_fields.site_name.value]==name.lower()][
|
1052
|
+
return int(self.sites.loc[self.sites[kiwis_site_fields.site_name.value]==name.lower()][kiwis_site_fields.site_id.value])
|
775
1053
|
elif code!='':
|
776
|
-
return int(self.sites.loc[self.sites[kiwis_site_fields.site_no.value]==code][
|
1054
|
+
return int(self.sites.loc[self.sites[kiwis_site_fields.site_no.value]==code][kiwis_site_fields.site_id.value])
|
777
1055
|
else:
|
778
1056
|
return None
|
779
1057
|
|
780
|
-
def get_sitecode(self,name:str=''):
|
781
|
-
"""Récupération du code sur base du nom
|
1058
|
+
def get_sitecode(self, name:str=''):
|
1059
|
+
"""Récupération du code sur base du nom
|
1060
|
+
|
1061
|
+
:param name: nom de la station"""
|
1062
|
+
|
782
1063
|
if name!='':
|
783
1064
|
return self.sites.loc[self.sites[kiwis_site_fields.site_name.value]==name.lower()][kiwis_site_fields.site_no.value].squeeze()
|
784
1065
|
else:
|
785
1066
|
return None
|
786
1067
|
|
787
1068
|
def get_sitename(self,code:str=''):
|
788
|
-
"""Récupération du nom sur base du code
|
1069
|
+
"""Récupération du nom sur base du code
|
1070
|
+
|
1071
|
+
:param code: code de la station"""
|
1072
|
+
|
789
1073
|
if code!='':
|
790
1074
|
return self.sites.loc[self.sites[kiwis_site_fields.site_no.value]==code][kiwis_site_fields.site_name.value].squeeze()
|
791
1075
|
else:
|
@@ -10,14 +10,15 @@ copying or distribution of this file, via any medium, is strictly prohibited.
|
|
10
10
|
|
11
11
|
import wx
|
12
12
|
import logging
|
13
|
+
from pathlib import Path
|
13
14
|
|
14
15
|
|
15
16
|
from . import Parser, Expression
|
16
17
|
|
17
18
|
class Calculator(wx.Frame):
|
18
|
-
|
19
|
+
|
19
20
|
def __init__(self, mapviewer=None):
|
20
|
-
|
21
|
+
|
21
22
|
from ..PyDraw import WolfMapViewer, draw_type, WolfArray
|
22
23
|
|
23
24
|
super(Calculator, self).__init__(None, title='Calculator', size=(500, 300))
|
@@ -38,18 +39,23 @@ class Calculator(wx.Frame):
|
|
38
39
|
self._comment = wx.TextCtrl(self, style=wx.TE_RIGHT|wx.TE_RICH2|wx.TE_MULTILINE)
|
39
40
|
self.memory = wx.TextCtrl(self, style=wx.TE_RIGHT|wx.TE_RICH2|wx.TE_MULTILINE)
|
40
41
|
self.btn_reset_memory = wx.Button(self, label='Reset Memory')
|
41
|
-
|
42
|
+
|
42
43
|
self.Bind(wx.EVT_BUTTON, lambda v: self.bt_press(v.EventObject.Label))
|
43
44
|
|
44
|
-
self._btns[-1][-2].SetDefault()
|
45
|
+
self._btns[-1][-2].SetDefault()
|
45
46
|
|
46
47
|
self.Bind(wx.EVT_CHAR_HOOK, self.char_press)
|
47
48
|
self.btn_reset_memory.Bind(wx.EVT_BUTTON, lambda v: self._memory.clear())
|
48
|
-
|
49
|
+
|
49
50
|
self.SetSizer(self.pack([self._disp] + [self.pack(x) for x in self._btns] + [self.pack([self._comment, self.btn_reset_memory, self.memory])], orient=wx.VERTICAL))
|
50
51
|
|
51
52
|
self._disp.SetFocus()
|
52
53
|
|
54
|
+
icon = wx.Icon()
|
55
|
+
icon_path = Path(__file__).parent.parent / "apps/wolf_logo2.bmp"
|
56
|
+
icon.CopyFromBitmap(wx.Bitmap(str(icon_path), wx.BITMAP_TYPE_ANY))
|
57
|
+
self.SetIcon(icon)
|
58
|
+
|
53
59
|
self.Show()
|
54
60
|
|
55
61
|
def pack(self, items, orient=wx.HORIZONTAL):
|
@@ -57,11 +63,11 @@ class Calculator(wx.Frame):
|
|
57
63
|
sizer = wx.BoxSizer(orient)
|
58
64
|
sizer.AddMany((i, 1, wx.EXPAND|wx.ALL, 0) for i in items)
|
59
65
|
return sizer
|
60
|
-
|
66
|
+
|
61
67
|
@property
|
62
68
|
def command(self) -> str:
|
63
|
-
return self._disp.Value
|
64
|
-
|
69
|
+
return self._disp.Value
|
70
|
+
|
65
71
|
@command.setter
|
66
72
|
def command(self, value):
|
67
73
|
self._disp.Value = str(value)
|
@@ -70,16 +76,16 @@ class Calculator(wx.Frame):
|
|
70
76
|
@property
|
71
77
|
def comment(self) -> str:
|
72
78
|
return self._comment.Value
|
73
|
-
|
79
|
+
|
74
80
|
@comment.setter
|
75
81
|
def comment(self, value):
|
76
82
|
self._comment.Value = str(value)
|
77
83
|
|
78
84
|
def check_command(self) -> bool:
|
79
|
-
""" Check if the command is valid """
|
80
|
-
|
85
|
+
""" Check if the command is valid """
|
86
|
+
|
81
87
|
from ..PyDraw import draw_type
|
82
|
-
|
88
|
+
|
83
89
|
if '\n' in self.command:
|
84
90
|
self.evaluate_multilines()
|
85
91
|
return False
|
@@ -94,7 +100,7 @@ class Calculator(wx.Frame):
|
|
94
100
|
if self._mapviewer is not None:
|
95
101
|
id_arrays = self._mapviewer.get_list_keys(drawing_type=draw_type.ARRAYS,
|
96
102
|
checked_state=None)
|
97
|
-
|
103
|
+
|
98
104
|
for id_array in id_arrays:
|
99
105
|
self._memory[id_array] = self._mapviewer.get_obj_from_id(id_array, drawtype=draw_type.ARRAYS)
|
100
106
|
|
@@ -124,27 +130,27 @@ class Calculator(wx.Frame):
|
|
124
130
|
def evaluate(self, mem_last_command=True):
|
125
131
|
""" Evaluate the command """
|
126
132
|
from ..PyDraw import WolfArray, draw_type
|
127
|
-
|
133
|
+
|
128
134
|
if mem_last_command:
|
129
135
|
self._last_command = self.command
|
130
136
|
|
131
137
|
ret = self.check_command()
|
132
|
-
|
138
|
+
|
133
139
|
if ret:
|
134
140
|
args = {var:self._memory[var] for var in self._parsed_command.variables()}
|
135
141
|
res = self._parsed_command.evaluate(args)
|
136
142
|
|
137
143
|
if isinstance(res, dict):
|
138
|
-
|
144
|
+
|
139
145
|
comment = 'Storing\n'
|
140
|
-
|
146
|
+
|
141
147
|
for key, value in res.items():
|
142
148
|
self._memory[key] = value
|
143
149
|
comment += f'{key} = {value}\n'
|
144
|
-
|
150
|
+
|
145
151
|
self.comment = comment
|
146
152
|
self.command = ''
|
147
|
-
|
153
|
+
|
148
154
|
elif isinstance(res, str|int|float):
|
149
155
|
self.command = res
|
150
156
|
|
@@ -154,10 +160,10 @@ class Calculator(wx.Frame):
|
|
154
160
|
id = self.command
|
155
161
|
while id in ids:
|
156
162
|
id += '_'
|
157
|
-
|
163
|
+
|
158
164
|
self._mapviewer.add_object('array', newobj=res, id = id)
|
159
165
|
self.command = ''
|
160
|
-
|
166
|
+
|
161
167
|
return res
|
162
168
|
|
163
169
|
def char_press(self, e:wx.KeyEvent):
|
@@ -168,13 +174,13 @@ class Calculator(wx.Frame):
|
|
168
174
|
|
169
175
|
unicodekey = e.GetUnicodeKey()
|
170
176
|
key = e.GetKeyCode()
|
171
|
-
|
177
|
+
|
172
178
|
ctrl = e.ControlDown()
|
173
179
|
alt = e.AltDown()
|
174
180
|
shift= e.ShiftDown()
|
175
181
|
|
176
182
|
if unicodekey in egal_code:
|
177
|
-
if not shift :
|
183
|
+
if not shift :
|
178
184
|
self.evaluate()
|
179
185
|
return
|
180
186
|
|
@@ -186,4 +192,3 @@ class Calculator(wx.Frame):
|
|
186
192
|
elif key == '<': self.command =self._last_command
|
187
193
|
elif key == '=': self.evaluate()
|
188
194
|
else : self._disp.Value += key
|
189
|
-
|
wolfhece/wolf_array.py
CHANGED
@@ -2503,6 +2503,8 @@ class Ops_Array(wx.Frame):
|
|
2503
2503
|
logging.warning(_('Please add points to vector or select another !'))
|
2504
2504
|
return
|
2505
2505
|
|
2506
|
+
logging.info(_('Select nodes inside the active polygon/vector...'))
|
2507
|
+
|
2506
2508
|
self._select_vector_inside_manager(self.active_vector)
|
2507
2509
|
self.refresh_array()
|
2508
2510
|
|
@@ -2528,9 +2530,11 @@ class Ops_Array(wx.Frame):
|
|
2528
2530
|
""" Select nodes along the active zone (manager) """
|
2529
2531
|
|
2530
2532
|
if self.active_zone is None:
|
2531
|
-
|
2533
|
+
logging.warning(_('Please activate a zone !'))
|
2532
2534
|
return
|
2533
2535
|
|
2536
|
+
logging.info(_('Select nodes along the active zone - all polylines...'))
|
2537
|
+
|
2534
2538
|
for curvec in self.active_zone.myvectors:
|
2535
2539
|
self._select_vector_under_manager(curvec)
|
2536
2540
|
|
@@ -2539,9 +2543,11 @@ class Ops_Array(wx.Frame):
|
|
2539
2543
|
def select_vector_under_manager(self):
|
2540
2544
|
""" Select nodes along the active vector (manager) """
|
2541
2545
|
if self.active_vector is None:
|
2542
|
-
|
2546
|
+
logging.warning(_('Please activate a vector !'))
|
2543
2547
|
return
|
2544
2548
|
|
2549
|
+
logging.info(_('Select nodes along the active polyline/vector...'))
|
2550
|
+
|
2545
2551
|
self._select_vector_under_manager(self.active_vector)
|
2546
2552
|
self.refresh_array()
|
2547
2553
|
|
@@ -2567,6 +2573,7 @@ class Ops_Array(wx.Frame):
|
|
2567
2573
|
""" Select nodes inside the temporary vector """
|
2568
2574
|
|
2569
2575
|
if self.mapviewer is not None:
|
2576
|
+
logging.info(_('Select nodes inside a temporary polygon/vector...'))
|
2570
2577
|
logging.info(_('Please add points to vector by clicks !'))
|
2571
2578
|
|
2572
2579
|
self.mapviewer.start_action('select by tmp vector inside', _('Please draw a polygon...'))
|
@@ -2581,9 +2588,9 @@ class Ops_Array(wx.Frame):
|
|
2581
2588
|
def select_vector_under_tmp(self):
|
2582
2589
|
""" Select nodes along the temporary vector """
|
2583
2590
|
if self.mapviewer is not None:
|
2591
|
+
logging.info(_('Select nodes along a temporary polygon/vector...'))
|
2584
2592
|
logging.info(_('Please add points to vector by clicks !'))
|
2585
2593
|
|
2586
|
-
|
2587
2594
|
self.mapviewer.start_action('select by tmp vector along', _('Please draw a polyline...'))
|
2588
2595
|
self.vectmp.reset()
|
2589
2596
|
self.Active_vector(self.vectmp)
|
@@ -3272,6 +3279,10 @@ class SelectionData():
|
|
3272
3279
|
myvect.find_minmax()
|
3273
3280
|
mypoints = self.parent.get_ij_under_polyline(myvect)
|
3274
3281
|
|
3282
|
+
if len(mypoints) == 0:
|
3283
|
+
logging.info(_('No nodes under the polyline'))
|
3284
|
+
return
|
3285
|
+
|
3275
3286
|
self._add_nodes_to_selectionij(mypoints, verif=nbini != 0)
|
3276
3287
|
|
3277
3288
|
if self.parent.myops is not None:
|
@@ -6784,6 +6795,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
6784
6795
|
|
6785
6796
|
allij = np.unique(allij, axis=0)
|
6786
6797
|
|
6798
|
+
# filter negative indexes
|
6799
|
+
allij = allij[np.where((allij[:, 0] >= 0) & (allij[:, 1] >= 0) & (allij[:, 0] < self.nbx) & (allij[:, 1] < self.nby))]
|
6800
|
+
|
6787
6801
|
if usemask:
|
6788
6802
|
mymask = np.logical_not(self.array.mask[allij[:, 0], allij[:, 1]])
|
6789
6803
|
allij = allij[np.where(mymask)]
|
@@ -7,7 +7,7 @@ wolfhece/ManageParams.py,sha256=EeuUI5Vvh9ixCvYf8YShMC1s1Yacc7OxOCN7q81gqiQ,517
|
|
7
7
|
wolfhece/Model1D.py,sha256=uL1DJVmDI2xVSE7H6n3icn3QbsPtTHeg8E-6wkDloKw,476914
|
8
8
|
wolfhece/PyConfig.py,sha256=FB8u0belXOXTb03Ln6RdVWvMgjzi3oGPCmw2dWa3lNg,8332
|
9
9
|
wolfhece/PyCrosssections.py,sha256=FnmM9DWY_SAF2EDH9Gu2PojXNtSTRF4-aYQuAAJXBh4,112771
|
10
|
-
wolfhece/PyDraw.py,sha256=
|
10
|
+
wolfhece/PyDraw.py,sha256=yHbr9KolS2j0uL9wbzV6McwXvZHVeSSZ64y6-wJot5s,411135
|
11
11
|
wolfhece/PyGui.py,sha256=oBIBpgBQRR_XXucKE5-RFrtqKj0DRg9VlUCRo8Mzalc,105009
|
12
12
|
wolfhece/PyGuiHydrology.py,sha256=f60E8K9eGTnRq5RDF6yvt-ahf2AYegwQ9t25zZ2Mk1A,14946
|
13
13
|
wolfhece/PyHydrographs.py,sha256=jwtSNMMACwarxrtN1UeQYth99UNrhwPx1IGgUwcooHA,3774
|
@@ -48,7 +48,7 @@ wolfhece/pywalous.py,sha256=yRaWJjKckXef1d9D5devP0yFHC9uc6kRV4G5x9PNq9k,18972
|
|
48
48
|
wolfhece/rain_SPWMI.py,sha256=qCfcmF7LajloOaCwnTrrSMzyME03YyilmRUOqrPrv3U,13846
|
49
49
|
wolfhece/textpillow.py,sha256=map7HsGYML_o5NHRdFg2s_TVQed_lDnpYNDv27MM0Vw,14130
|
50
50
|
wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
|
51
|
-
wolfhece/wolf_array.py,sha256=
|
51
|
+
wolfhece/wolf_array.py,sha256=QmAcZNRMdGwqXRO3MsRMREYW_3ZdJ41i9gg4WMtAbLM,376746
|
52
52
|
wolfhece/wolf_hist.py,sha256=7jeVrgSkM3ErJO6SRMH_PGzfLjIdw8vTy87kesldggk,3582
|
53
53
|
wolfhece/wolf_texture.py,sha256=DS5eobLxrq9ljyebYfpMSQPn8shkUAZZVfqrOKN_QUU,16951
|
54
54
|
wolfhece/wolf_tiles.py,sha256=2Ho2I20rHRY81KXxjgLOYISdF4OkJ2d6omeY4shDoGI,10386
|
@@ -72,7 +72,7 @@ wolfhece/apps/check_install.py,sha256=Xoi_d8MzKzNAy2xqEpERdsqgRPu0hbBWukI0WkIYzD
|
|
72
72
|
wolfhece/apps/curvedigitizer.py,sha256=Yps4bcayzbsz0AoVc_dkSk35dEhhn_esIBy1Ziefgmk,5334
|
73
73
|
wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
|
74
74
|
wolfhece/apps/splashscreen.py,sha256=SrustmIQeXnsiD-92OzjdGhBi-S7c_j-cSvuX4T6rtg,2929
|
75
|
-
wolfhece/apps/version.py,sha256=
|
75
|
+
wolfhece/apps/version.py,sha256=cRc1I581AOhBuOpRqqnB83bANUXPq9N2wF1OVKOBfno,388
|
76
76
|
wolfhece/apps/wolf.py,sha256=j_CgvsL8rwixbVvVD5Z0s7m7cHZ86gmFLojKGuetMls,729
|
77
77
|
wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
|
78
78
|
wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
|
@@ -126,7 +126,7 @@ wolfhece/hydrology/read.py,sha256=itMat6MMn4Y14C3SMU_9JMBtpXFjG4mLNMfXXd5U6Ns,93
|
|
126
126
|
wolfhece/hydrology/slope_manager.py,sha256=vlek0z8qcqB61eleiksyOe3QR1vpbtwfeowy6ms7_Fg,5580
|
127
127
|
wolfhece/hydrology/wolfMap_treatment.py,sha256=eAxr24zJGwmDof1aZpcxewVvv_bWDvoO8t9Wwf99Mlo,10606
|
128
128
|
wolfhece/hydrometry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
129
|
-
wolfhece/hydrometry/kiwis.py,sha256=
|
129
|
+
wolfhece/hydrometry/kiwis.py,sha256=m3LGNxmB_ZY_ug-8BCM8jK_VqN6LtWRGpbPWtgRYFSE,46460
|
130
130
|
wolfhece/hydrometry/kiwis_gui.py,sha256=lApsSeBMJNAR1yocggdoHwz_xe6M_oaZ_E13CfHAlQA,23124
|
131
131
|
wolfhece/hydrometry/kiwis_wolfgui.py,sha256=GPa5YNp2V2ZlxYQjPiCXERgPuWB_zij4ec2yHpRvoFA,4027
|
132
132
|
wolfhece/hydrometry/kiwispie.py,sha256=akOaV46WwzISVlCcPz_phjsBrI_rDACUzdELtjx-xNg,13498
|
@@ -213,7 +213,7 @@ wolfhece/mar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
213
213
|
wolfhece/mar/commontools.py,sha256=vCmoNI2sMOco6Y4KPpKb7WORq45qFU_lSxbKGV9oZ8A,53824
|
214
214
|
wolfhece/mar/interface_MAR_WOLF.py,sha256=MWeXaHLDT4Eo9jZOAvz013lmpgGYT1v9VUYGAgBgSRU,21454
|
215
215
|
wolfhece/math_parser/__init__.py,sha256=mrD_uFDDZzvyxQkY8ESqcy1bvM7e3__Gi2b_vijvoo8,27977
|
216
|
-
wolfhece/math_parser/calculator.py,sha256=
|
216
|
+
wolfhece/math_parser/calculator.py,sha256=VCXCT5zhyMSgkO5O8dwIhRht9NNBqA0h1QPliOD4N28,6046
|
217
217
|
wolfhece/mesh2d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
218
218
|
wolfhece/mesh2d/bc_manager.py,sha256=QTGkb5TR8Y5xVnGUXPXzscGyTEQ6PA8CZPkVNwrlR1Y,53265
|
219
219
|
wolfhece/mesh2d/cell_tracker.py,sha256=mPmnD5lEf3gLPuLqtAIo-Gp-ipAwQdPxzjWOGt0b7jM,8958
|
@@ -283,8 +283,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
|
|
283
283
|
wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
|
284
284
|
wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
285
285
|
wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
|
286
|
-
wolfhece-2.1.
|
287
|
-
wolfhece-2.1.
|
288
|
-
wolfhece-2.1.
|
289
|
-
wolfhece-2.1.
|
290
|
-
wolfhece-2.1.
|
286
|
+
wolfhece-2.1.67.dist-info/METADATA,sha256=77W5WHquObr8qkk2A97PzjeORUnqfXAh_0Vo-F0cAaw,2570
|
287
|
+
wolfhece-2.1.67.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
288
|
+
wolfhece-2.1.67.dist-info/entry_points.txt,sha256=Q5JuIWV4odeIJI3qc6fV9MwRoz0ezqPVlFC1Ppm_vdQ,395
|
289
|
+
wolfhece-2.1.67.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
|
290
|
+
wolfhece-2.1.67.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|