wolfhece 2.2.33__py3-none-any.whl → 2.2.34__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/wolf_zi_db.py CHANGED
@@ -17,11 +17,15 @@ from enum import Enum
17
17
  from pathlib import Path
18
18
  from typing import Literal, Union
19
19
  import wx
20
+ from tqdm import tqdm
21
+ import re
20
22
 
21
23
  from shapely.geometry import Polygon
22
24
 
23
25
  from .PyVertexvectors import Zones, zone, vector, wolfvertex
26
+ from .textpillow import Font_Priority
24
27
  from .wolf_texture import genericImagetexture
28
+ from .PyPictures import PictureCollection
25
29
  from .PyTranslate import _
26
30
 
27
31
  class ColNames_PlansTerriers(Enum):
@@ -38,6 +42,90 @@ class ColNames_PlansTerriers(Enum):
38
42
  LOWRES = 'Acces2'
39
43
  RIVER = 'River'
40
44
 
45
+ class ColNames_Ouvrages(Enum):
46
+ """ Enum for the column names in the database """
47
+
48
+ KEY = 'Clé primaire'
49
+ X1 = 'X Lambert gauche'
50
+ X2 = 'X Lambert droit'
51
+ Y1 = 'Y Lambert gauche'
52
+ Y2 = 'Y Lambert droit'
53
+ REMARK = 'Remarques'
54
+ RIVER = 'Lieu'
55
+ PHOTO1 = 'Photo1'
56
+ PHOTO2 = 'Photo2'
57
+ PHOTO3 = 'Photo3'
58
+ PHOTO4 = 'Photo4'
59
+ PHOTO5 = 'Photo5'
60
+ PHOTO6 = 'Photo6'
61
+ PHOTO7 = 'Photo7'
62
+ PHOTO8 = 'Photo8'
63
+ PHOTO9 = 'Photo9'
64
+ PHOTO10 = 'Photo10'
65
+ DATE = 'Date'
66
+
67
+ class ColNames_Particularites(Enum):
68
+ """ Enum for the column names in the database """
69
+
70
+ KEY = 'Clé primaire'
71
+ X = 'Xlambert'
72
+ Y = 'Ylambert'
73
+ REMARK = 'Commentaires'
74
+ RIVER = 'Rivière'
75
+ PHOTO1 = 'Photo 1'
76
+ PHOTO2 = 'Photo 2'
77
+ PHOTO3 = 'Photo 3'
78
+ PHOTO4 = 'Photo 4'
79
+ PHOTO5 = 'Photo 5'
80
+ ORIENTATION = 'Orientation'
81
+ DATE = 'Date'
82
+
83
+ class ColNames_Enquetes(Enum):
84
+ """ Enum for the column names in the database """
85
+
86
+ KEY = 'Clé primaire'
87
+ X = 'XLambert'
88
+ Y = 'YLambert'
89
+ RIVER = 'Rivière'
90
+ PHOTO = 'Photo'
91
+ ORIENTATION = 'Orientation'
92
+ DATE = 'Date'
93
+
94
+ def _test_bounds(x:float, y:float, bounds:list[list[float, float], list[float, float]]) -> bool:
95
+ """ Test if the coordinates are inside the bounds
96
+
97
+ :param x: The x coordinate
98
+ :type x: float
99
+ :param y: The y coordinate
100
+ :type y: float
101
+ :param bounds: The bounds to test against - [ [xmin, xmax], [ymin, ymax] ]
102
+ :type bounds: list[list[float, float], list[float, float]]
103
+ :return: True if the coordinates are inside the bounds, False otherwise
104
+ :rtype: bool
105
+ """
106
+
107
+ if bounds is None:
108
+ return True
109
+
110
+ xmin, xmax = bounds[0]
111
+ ymin, ymax = bounds[1]
112
+
113
+ return xmin <= x <= xmax and ymin <= y <= ymax
114
+
115
+
116
+ def _sanitize_legendtext(text:str) -> str:
117
+ """ Sanitize the legend text by replacing newlines and special characters
118
+
119
+ :param text: The text to sanitize
120
+ :type text: str
121
+ :return: The sanitized text
122
+ :rtype: str
123
+ """
124
+ text = str(text)
125
+ # replace newlines and special characters
126
+ text = re.sub(r'(_x000D_\n|\n)', ' - ', text)
127
+
128
+ return text.strip()
41
129
  class ZI_Databse_Elt():
42
130
  """ Class to store the database elements """
43
131
 
@@ -211,7 +299,9 @@ class PlansTerrier(Zones):
211
299
  logging.error('No file selected or the file does not exist.')
212
300
  return
213
301
 
302
+ logging.info(f'Reading database from {self.filename}')
214
303
  self.db = pd.read_excel(self.filename, sheet_name='Plans_Terriers')
304
+ logging.info(f'Database read successfully from {self.filename}')
215
305
 
216
306
  rivers = list(self.db[ColNames_PlansTerriers.RIVER.value].unique())
217
307
  rivers.sort()
@@ -289,7 +379,7 @@ class PlansTerrier(Zones):
289
379
  curvector.add_vertex(wolfvertex(x=curelt.origx, y=curelt.endy))
290
380
  curvector.close_force()
291
381
  else:
292
- logging.error(f'File {fullpath} does not exist')
382
+ logging.debug(f'File {fullpath} does not exist')
293
383
 
294
384
  break
295
385
 
@@ -348,4 +438,498 @@ class PlansTerrier(Zones):
348
438
  super().plot(sx, sy, xmin, ymin, xmax, ymax, size)
349
439
 
350
440
  for curtexture in self.textures.values():
351
- curtexture.plot(sx, sy, xmin, ymin, xmax, ymax, size)
441
+ curtexture.plot(sx, sy, xmin, ymin, xmax, ymax, size)
442
+
443
+
444
+ class Ouvrages(PictureCollection):
445
+ """ Class to handle the "Ouvrages" -- Pictures of the structures in the ZI. """
446
+
447
+ def __init__(self, parent=None, idx: str = '', plotted: bool = True, mapviewer=None, rivers:list[str] = None) -> None:
448
+ """
449
+ Constructor for the Ouvrages class.
450
+
451
+ :param parent: The wx parent of the object
452
+ :type parent: wx.Window
453
+ :param idx: The index of the object
454
+ :type idx: str
455
+ :param plotted: If the object is plotted
456
+ :type plotted: bool
457
+ :param mapviewer: The mapviewer object
458
+ :type mapviewer: MapViewer
459
+ :param rivers: The list of rivers to display
460
+ :type rivers: list[str]
461
+ """
462
+
463
+ super().__init__(parent = parent, idx = idx, plotted = plotted, mapviewer = mapviewer)
464
+
465
+ self.wx_exists = wx.GetApp() is not None
466
+ self.db = None
467
+ self.rivers = rivers
468
+ self.initialized = False
469
+
470
+ self._columns = ColNames_Ouvrages
471
+
472
+ def check_plot(self):
473
+ """ Activate the plot if the object is initialized """
474
+
475
+ if not self.initialized:
476
+
477
+ # try to get the filename from the parent mapviewer
478
+ if self.mapviewer is not None:
479
+ self.filename = self.mapviewer.default_hece_database
480
+ bounds = self.mapviewer.get_bounds()
481
+
482
+ if 'bridge' in self.idx.lower() or 'pont' in self.idx.lower():
483
+ self.read_db(self.filename, sel_rivers=self.rivers, sheet_name='Ponts', bounds=bounds)
484
+ elif 'weir' in self.idx.lower() or 'seuil' in self.idx.lower():
485
+ self.read_db(self.filename, sel_rivers=self.rivers, sheet_name='Seuils', bounds=bounds)
486
+ elif 'survey' in self.idx.lower() or 'enquete' in self.idx.lower():
487
+ self.read_db(self.filename, sel_rivers=self.rivers, sheet_name='Photos', bounds=bounds)
488
+ elif 'features' in self.idx.lower() or 'particularit' in self.idx.lower():
489
+ self.read_db(self.filename, sel_rivers=self.rivers, sheet_name='Particularités', bounds=bounds)
490
+
491
+ if self.initialized:
492
+ super().check_plot()
493
+
494
+ def read_db(self, filename:str | Path,
495
+ sel_rivers: list[str] = None,
496
+ sheet_name: str = 'Ponts',
497
+ bounds: list[list[float, float], list[float, float]] = None):
498
+ """ Read the database (Excel file) and create the zones and the vectors.
499
+
500
+ The user will be prompted to select the rivers to display.
501
+
502
+ :param filename: The path to the Excel file containing the database
503
+ :type filename: str | Path
504
+ :param sel_rivers: The list of rivers to display, if None, the user will be prompted to select the rivers
505
+ :type sel_rivers: list[str] | None
506
+ :param sheet_name: The name of the sheet in the Excel file to read
507
+ :type sheet_name: str
508
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
509
+ :type bounds: list[list[float, float], list[float, float]] | None
510
+ """
511
+
512
+ self.filename = Path(filename)
513
+
514
+ if not self.filename.exists() or filename == '':
515
+
516
+ if self.wx_exists:
517
+
518
+ dlg= wx.FileDialog(None, _("Choose a file"), defaultDir= "", wildcard="Excel (*.xlsx)|*.xlsx", style = wx.FD_OPEN)
519
+ ret = dlg.ShowModal()
520
+ if ret == wx.ID_OK:
521
+ self.filename = Path(dlg.GetPath())
522
+ dlg.Destroy()
523
+ else:
524
+ logging.error('No file selected')
525
+ dlg.Destroy()
526
+ return
527
+
528
+ else:
529
+ logging.error('No file selected or the file does not exist.')
530
+ return
531
+
532
+ try:
533
+ logging.info(f'Reading database from {self.filename}')
534
+ self.db = pd.read_excel(self.filename, sheet_name=sheet_name)
535
+ logging.info(f'Database read successfully from {self.filename}')
536
+ except ValueError as e:
537
+ logging.error(f"Error reading the Excel file: {e}")
538
+ return
539
+
540
+ rivers = list(self.db[ColNames_Ouvrages.RIVER.value].unique())
541
+ rivers.sort()
542
+
543
+ self.rivers = []
544
+
545
+ if sel_rivers is None and self.wx_exists:
546
+
547
+ with wx.MessageDialog(None, _("Choose the rivers to display"), _("Rivers"), wx.YES_NO | wx.ICON_QUESTION) as dlg:
548
+
549
+ if dlg.ShowModal() == wx.ID_YES:
550
+
551
+ with wx.MultiChoiceDialog(None, _("Choose the rivers to display"), _("Rivers"), rivers) as dlg_river:
552
+ ret = dlg_river.ShowModal()
553
+
554
+ if ret == wx.ID_OK:
555
+ for curidx in dlg_river.GetSelections():
556
+ self.rivers.append(rivers[curidx])
557
+ else:
558
+ self.rivers = rivers
559
+
560
+ elif sel_rivers is not None:
561
+
562
+ for curruver in sel_rivers:
563
+ if curruver in rivers:
564
+ self.rivers.append(curruver)
565
+ else:
566
+ logging.error(f'River {curruver} not found in the database -- Ignoring !')
567
+
568
+ self._filter_db(bounds)
569
+
570
+ self.initialized = True
571
+
572
+ def _filter_db(self, bounds: list[list[float, float], list[float, float]] = None):
573
+ """ Filter the database based on the selected rivers and bounds.
574
+
575
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
576
+ :type bounds: list[list[float, float], list[float, float]] | None
577
+ """
578
+
579
+ if len(self.rivers) == 0:
580
+ locdb = self.db
581
+ else:
582
+ locdb = self.db[self.db[ColNames_Ouvrages.RIVER.value].isin(self.rivers)]
583
+
584
+ for id, curline in tqdm(locdb.iterrows()):
585
+ river = curline[ColNames_Ouvrages.RIVER.value]
586
+
587
+ paths = []
588
+ for col in [ColNames_Ouvrages.PHOTO1,
589
+ ColNames_Ouvrages.PHOTO2,
590
+ ColNames_Ouvrages.PHOTO3,
591
+ ColNames_Ouvrages.PHOTO4,
592
+ ColNames_Ouvrages.PHOTO5,
593
+ ColNames_Ouvrages.PHOTO6,
594
+ ColNames_Ouvrages.PHOTO7,
595
+ ColNames_Ouvrages.PHOTO8,
596
+ ColNames_Ouvrages.PHOTO9,
597
+ ColNames_Ouvrages.PHOTO10]:
598
+
599
+ fullpath = curline[col.value]
600
+
601
+ fullpath = fullpath.replace(r'\\192.168.2.185\Intranet\Data\Données et Photos de crues\Ouvrages',
602
+ str(self.filename.parent) +r'\Ouvrages')
603
+ if fullpath == '0':
604
+ break
605
+
606
+ fullpath = Path(fullpath)
607
+
608
+ if fullpath.exists():
609
+ paths.append(fullpath)
610
+ else:
611
+ logging.debug(f'File {fullpath} does not exist')
612
+
613
+ if not paths:
614
+ logging.debug(f'No valid paths found for river {river} in the database')
615
+ continue
616
+
617
+ nb = len(paths)
618
+ x1 = curline[ColNames_Ouvrages.X1.value]
619
+ x2 = curline[ColNames_Ouvrages.X2.value]
620
+ y1 = curline[ColNames_Ouvrages.Y1.value]
621
+ y2 = curline[ColNames_Ouvrages.Y2.value]
622
+
623
+ keyzone = river.strip() + '_' + paths[0].stem
624
+ # make a mosaic - max 3 pictures per row
625
+
626
+ xref = (x1 + x2) / 2
627
+ yref = (y1 + y2) / 2
628
+
629
+ if bounds is not None and not _test_bounds(xref, yref, bounds):
630
+ logging.debug(f'Coordinates are out of bounds -- Skipping line {id}')
631
+ continue
632
+
633
+ for i in range(nb):
634
+ picture = paths[i]
635
+
636
+ x = xref + (i % 3) * self._default_size
637
+ y = yref + (i // 3) * self._default_size
638
+
639
+ if x < 1000. and y < 1000.:
640
+ logging.error(f'Coordinates for river {river} are not set -- Skipping picture {picture}')
641
+ continue
642
+
643
+ self.add_picture(picture, x=x, y=y, name=picture.stem, keyzone=keyzone)
644
+
645
+ pic = self[(keyzone, picture.stem)]
646
+ pic.myprop.legendtext = _sanitize_legendtext(curline[ColNames_Ouvrages.REMARK.value])
647
+ pic.myprop.legendx = pic.centroid.x
648
+ pic.myprop.legendy = pic.centroid.y
649
+ pic.myprop.legendpriority = Font_Priority.WIDTH
650
+ pic.myprop.legendlength = 100
651
+
652
+ self.find_minmax(True)
653
+
654
+ class Particularites(Ouvrages):
655
+ """ Class to handle the "Particularités" -- Pictures of the particularities in the ZI. """
656
+
657
+ def __init__(self, parent=None, idx = '', plotted = True, mapviewer=None, rivers = None):
658
+ super().__init__(parent = parent, idx = idx, plotted = plotted, mapviewer = mapviewer, rivers = rivers)
659
+
660
+ self._columns = ColNames_Particularites
661
+
662
+ def read_db(self, filename:str | Path,
663
+ sel_rivers: list[str] = None,
664
+ sheet_name: str = 'Particularités',
665
+ bounds: list[list[float, float], list[float, float]] = None):
666
+ """ Read the database (Excel file) and create the zones and the vectors.
667
+
668
+ The user will be prompted to select the rivers to display.
669
+
670
+ :param filename: The path to the Excel file containing the database
671
+ :type filename: str | Path
672
+ :param sel_rivers: The list of rivers to display, if None, the user will be prompted to select the rivers
673
+ :type sel_rivers: list[str] | None
674
+ :param sheet_name: The name of the sheet in the Excel file to read
675
+ :type sheet_name: str
676
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
677
+ :type bounds: list[list[float, float], list[float, float]] | None
678
+ """
679
+
680
+ self.filename = Path(filename)
681
+
682
+ if not self.filename.exists() or filename == '':
683
+
684
+ if self.wx_exists:
685
+
686
+ dlg= wx.FileDialog(None, _("Choose a file"), defaultDir= "", wildcard="Excel (*.xlsx)|*.xlsx", style = wx.FD_OPEN)
687
+ ret = dlg.ShowModal()
688
+ if ret == wx.ID_OK:
689
+ self.filename = Path(dlg.GetPath())
690
+ dlg.Destroy()
691
+ else:
692
+ logging.error('No file selected')
693
+ dlg.Destroy()
694
+ return
695
+
696
+ else:
697
+ logging.error('No file selected or the file does not exist.')
698
+ return
699
+
700
+ try:
701
+ logging.info(f'Reading database from {self.filename}')
702
+ self.db = pd.read_excel(self.filename, sheet_name=sheet_name)
703
+ logging.info(f'Database read successfully from {self.filename}')
704
+ except ValueError as e:
705
+ logging.error(f"Error reading the Excel file: {e}")
706
+ return
707
+
708
+ rivers = list(self.db[ColNames_Particularites.RIVER.value].unique())
709
+ rivers.sort()
710
+
711
+ self.rivers = []
712
+
713
+ if sel_rivers is None and self.wx_exists:
714
+
715
+ with wx.MessageDialog(None, _("Choose the rivers to display"), _("Rivers"), wx.YES_NO | wx.ICON_QUESTION) as dlg:
716
+
717
+ if dlg.ShowModal() == wx.ID_YES:
718
+
719
+ with wx.MultiChoiceDialog(None, _("Choose the rivers to display"), _("Rivers"), rivers) as dlg_river:
720
+ ret = dlg_river.ShowModal()
721
+
722
+ if ret == wx.ID_OK:
723
+ for curidx in dlg_river.GetSelections():
724
+ self.rivers.append(rivers[curidx])
725
+ else:
726
+ self.rivers = rivers
727
+
728
+ elif sel_rivers is not None:
729
+
730
+ for curruver in sel_rivers:
731
+ if curruver in rivers:
732
+ self.rivers.append(curruver)
733
+ else:
734
+ logging.error(f'River {curruver} not found in the database -- Ignoring !')
735
+
736
+ self._filter_db(bounds)
737
+
738
+ self.initialized = True
739
+
740
+ def _filter_db(self, bounds: list[list[float, float], list[float, float]] = None):
741
+ """ Filter the database based on the selected rivers and bounds.
742
+
743
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
744
+ :type bounds: list[list[float, float], list[float, float]] |
745
+ """
746
+
747
+ if len(self.rivers) == 0:
748
+ locdb = self.db
749
+ else:
750
+ locdb = self.db[self.db[ColNames_Particularites.RIVER.value].isin(self.rivers)]
751
+
752
+ for id, curline in tqdm(locdb.iterrows()):
753
+ river = curline[ColNames_Particularites.RIVER.value]
754
+
755
+ paths = []
756
+ for col in [ColNames_Particularites.PHOTO1,
757
+ ColNames_Particularites.PHOTO2,
758
+ ColNames_Particularites.PHOTO3,
759
+ ColNames_Particularites.PHOTO4,
760
+ ColNames_Particularites.PHOTO5]:
761
+
762
+ fullpath = curline[col.value]
763
+
764
+ fullpath = fullpath.replace(r'\\192.168.2.185\Intranet\Data\Données et Photos de crues',
765
+ str(self.filename.parent))
766
+ fullpath = Path(fullpath)
767
+
768
+ if fullpath.exists():
769
+ paths.append(fullpath)
770
+ else:
771
+ logging.debug(f'File {fullpath} does not exist')
772
+
773
+ if not paths:
774
+ logging.debug(f'No valid paths found for river {river} in the database')
775
+ continue
776
+
777
+ nb = len(paths)
778
+ xref = curline[ColNames_Particularites.X.value]
779
+ yref = curline[ColNames_Particularites.Y.value]
780
+
781
+ keyzone = river.strip() + '_' + paths[0].stem
782
+ # make a mosaic - max 3 pictures per row
783
+
784
+ if bounds is not None and not _test_bounds(xref, yref, bounds):
785
+ logging.info(f'Coordinates are out of bounds -- Skipping line {id}')
786
+ continue
787
+
788
+ for i in range(nb):
789
+ picture = paths[i]
790
+ x = xref + (i % 3) * self._default_size
791
+ y = yref + (i // 3) * self._default_size
792
+
793
+ self.add_picture(picture, x=x, y=y, name=picture.stem, keyzone=keyzone)
794
+
795
+ pic = self[(keyzone, picture.stem)]
796
+ pic.myprop.legendtext = _sanitize_legendtext(curline[ColNames_Particularites.REMARK.value])
797
+ pic.myprop.legendx = pic.centroid.x
798
+ pic.myprop.legendy = pic.centroid.y
799
+ pic.myprop.legendpriority = Font_Priority.WIDTH
800
+ pic.myprop.legendlength = 100
801
+
802
+
803
+ self.find_minmax(True)
804
+
805
+ class Enquetes(Ouvrages):
806
+ """ Class to handle the "Enquêtes" -- Pictures of the surveys in the ZI. """
807
+ def __init__(self, parent=None, idx = '', plotted = True, mapviewer=None, rivers = None):
808
+ super().__init__(parent = parent, idx = idx, plotted = plotted, mapviewer = mapviewer, rivers = rivers)
809
+
810
+ self._columns = ColNames_Enquetes
811
+
812
+ def read_db(self, filename:str | Path,
813
+ sel_rivers: list[str] = None,
814
+ sheet_name: str = 'Photos',
815
+ bounds: list[list[float, float], list[float, float]] = None):
816
+ """ Read the database (Excel file) and create the zones and the vectors.
817
+
818
+ The user will be prompted to select the rivers to display.
819
+
820
+ :param filename: The path to the Excel file containing the database
821
+ :type filename: str | Path
822
+ :param sel_rivers: The list of rivers to display, if None, the user will be prompted to select the rivers
823
+ :type sel_rivers: list[str] | None
824
+ :param sheet_name: The name of the sheet in the Excel file to read
825
+ :type sheet_name: str
826
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
827
+ :type bounds: list[list[float, float], list[float, float]] |
828
+ """
829
+
830
+ self.filename = Path(filename)
831
+
832
+ if not self.filename.exists() or filename == '':
833
+
834
+ if self.wx_exists:
835
+
836
+ dlg= wx.FileDialog(None, _("Choose a file"), defaultDir= "", wildcard="Excel (*.xlsx)|*.xlsx", style = wx.FD_OPEN)
837
+ ret = dlg.ShowModal()
838
+ if ret == wx.ID_OK:
839
+ self.filename = Path(dlg.GetPath())
840
+ dlg.Destroy()
841
+ else:
842
+ logging.error('No file selected')
843
+ dlg.Destroy()
844
+ return
845
+
846
+ else:
847
+ logging.error('No file selected or the file does not exist.')
848
+ return
849
+
850
+ try:
851
+ logging.info(f'Reading database from {self.filename}')
852
+ self.db = pd.read_excel(self.filename, sheet_name=sheet_name)
853
+ logging.info(f'Database read successfully from {self.filename}')
854
+ except ValueError as e:
855
+ logging.error(f"Error reading the Excel file: {e}")
856
+ return
857
+
858
+ rivers = list(self.db[ColNames_Enquetes.RIVER.value].unique())
859
+ rivers.sort()
860
+
861
+ self.rivers = []
862
+
863
+ if sel_rivers is None and self.wx_exists:
864
+
865
+ with wx.MessageDialog(None, _("Choose the rivers to display"), _("Rivers"), wx.YES_NO | wx.ICON_QUESTION) as dlg:
866
+
867
+ if dlg.ShowModal() == wx.ID_YES:
868
+
869
+ with wx.MultiChoiceDialog(None, _("Choose the rivers to display"), _("Rivers"), rivers) as dlg_river:
870
+ ret = dlg_river.ShowModal()
871
+
872
+ if ret == wx.ID_OK:
873
+ for curidx in dlg_river.GetSelections():
874
+ self.rivers.append(rivers[curidx])
875
+ else:
876
+ self.rivers = rivers
877
+
878
+ elif sel_rivers is not None:
879
+
880
+ for curruver in sel_rivers:
881
+ if curruver in rivers:
882
+ self.rivers.append(curruver)
883
+ else:
884
+ logging.error(f'River {curruver} not found in the database -- Ignoring !')
885
+
886
+ self._filter_db(bounds)
887
+
888
+ self.initialized = True
889
+
890
+ def _filter_db(self, bounds: list[list[float, float], list[float, float]] = None):
891
+ """ Filter the database based on the selected rivers and bounds.
892
+
893
+ :param bounds: The bounds of the area to display, if None, no test on coordinates will be done - [ [xmin, xmax], [ymin, ymax] ]
894
+ :type bounds: list[list[float, float], list[float, float]] |
895
+ """
896
+
897
+ if len(self.rivers) == 0:
898
+ locdb = self.db
899
+ else:
900
+ locdb = self.db[self.db[ColNames_Enquetes.RIVER.value].isin(self.rivers)]
901
+
902
+ for id, curline in tqdm(locdb.iterrows()):
903
+ river = curline[ColNames_Enquetes.RIVER.value]
904
+
905
+ fullpath = curline[ColNames_Enquetes.PHOTO.value]
906
+
907
+ fullpath = fullpath.replace(r'\\192.168.2.185\Intranet\Data\Données et Photos de crues',
908
+ str(self.filename.parent))
909
+ fullpath = Path(fullpath)
910
+
911
+ if not fullpath.exists():
912
+ logging.debug(f'File {fullpath} does not exist')
913
+ continue
914
+
915
+ x = curline[ColNames_Enquetes.X.value]
916
+ y = curline[ColNames_Enquetes.Y.value]
917
+
918
+ if bounds is not None and not _test_bounds(x, y, bounds):
919
+ logging.info(f'Coordinates are out of bounds -- Skipping line {id}')
920
+ continue
921
+
922
+ keyzone = river.strip()
923
+
924
+ picture = fullpath
925
+ self.add_picture(picture, x=x, y=y, name=picture.stem, keyzone=keyzone)
926
+
927
+ pic = self[(keyzone, picture.stem)]
928
+ pic.myprop.legendtext = _sanitize_legendtext(curline[ColNames_Enquetes.DATE.value])
929
+ pic.myprop.legendx = pic.centroid.x
930
+ pic.myprop.legendy = pic.centroid.y
931
+ pic.myprop.legendpriority = Font_Priority.WIDTH
932
+ pic.myprop.legendlength = 100
933
+
934
+
935
+ self.find_minmax(True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wolfhece
3
- Version: 2.2.33
3
+ Version: 2.2.34
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