wolfhece 2.2.37__py3-none-any.whl → 2.2.39__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.
Files changed (53) hide show
  1. wolfhece/Coordinates_operations.py +5 -0
  2. wolfhece/GraphNotebook.py +72 -1
  3. wolfhece/GraphProfile.py +1 -1
  4. wolfhece/MulticriteriAnalysis.py +1579 -0
  5. wolfhece/PandasGrid.py +62 -1
  6. wolfhece/PyCrosssections.py +194 -43
  7. wolfhece/PyDraw.py +891 -73
  8. wolfhece/PyGui.py +913 -72
  9. wolfhece/PyGuiHydrology.py +528 -74
  10. wolfhece/PyPalette.py +26 -4
  11. wolfhece/PyParams.py +33 -0
  12. wolfhece/PyPictures.py +2 -2
  13. wolfhece/PyVertex.py +32 -0
  14. wolfhece/PyVertexvectors.py +147 -75
  15. wolfhece/PyWMS.py +52 -36
  16. wolfhece/acceptability/acceptability.py +15 -8
  17. wolfhece/acceptability/acceptability_gui.py +507 -360
  18. wolfhece/acceptability/func.py +80 -183
  19. wolfhece/apps/version.py +1 -1
  20. wolfhece/compare_series.py +480 -0
  21. wolfhece/drawing_obj.py +12 -1
  22. wolfhece/hydrology/Catchment.py +228 -162
  23. wolfhece/hydrology/Internal_variables.py +43 -2
  24. wolfhece/hydrology/Models_characteristics.py +69 -67
  25. wolfhece/hydrology/Optimisation.py +893 -182
  26. wolfhece/hydrology/PyWatershed.py +267 -165
  27. wolfhece/hydrology/SubBasin.py +185 -140
  28. wolfhece/hydrology/climate_data.py +334 -0
  29. wolfhece/hydrology/constant.py +11 -0
  30. wolfhece/hydrology/cst_exchanges.py +76 -1
  31. wolfhece/hydrology/forcedexchanges.py +413 -49
  32. wolfhece/hydrology/hyetograms.py +2095 -0
  33. wolfhece/hydrology/read.py +65 -5
  34. wolfhece/hydrometry/kiwis.py +42 -26
  35. wolfhece/hydrometry/kiwis_gui.py +7 -2
  36. wolfhece/insyde_be/INBE_func.py +746 -0
  37. wolfhece/insyde_be/INBE_gui.py +1776 -0
  38. wolfhece/insyde_be/__init__.py +3 -0
  39. wolfhece/interpolating_raster.py +366 -0
  40. wolfhece/irm_alaro.py +1457 -0
  41. wolfhece/irm_qdf.py +889 -57
  42. wolfhece/lifewatch.py +6 -3
  43. wolfhece/picc.py +124 -8
  44. wolfhece/pyLandUseFlanders.py +146 -0
  45. wolfhece/pydownloader.py +2 -1
  46. wolfhece/pywalous.py +225 -31
  47. wolfhece/toolshydrology_dll.py +149 -0
  48. wolfhece/wolf_array.py +63 -25
  49. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/METADATA +3 -1
  50. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/RECORD +53 -42
  51. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/WHEEL +0 -0
  52. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/entry_points.txt +0 -0
  53. {wolfhece-2.2.37.dist-info → wolfhece-2.2.39.dist-info}/top_level.txt +0 -0
wolfhece/PyPalette.py CHANGED
@@ -653,7 +653,6 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
653
653
  self.colors[2, :] = [255, 0, 0, 255] # Rouge
654
654
  self.fill_segmentdata()
655
655
 
656
-
657
656
  def set_values_colors(self,
658
657
  values: typing.Union[list[float], np.ndarray],
659
658
  colors: typing.Union[list[tuple[int]], np.ndarray]):
@@ -698,6 +697,16 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
698
697
 
699
698
  self.fill_segmentdata()
700
699
 
700
+ def set_values(self,
701
+ values: typing.Union[list[float], np.ndarray]):
702
+ """ Mise à jour des valeurs de la palette """
703
+
704
+ assert len(values) == self.nb, "Length of values must match the number of colors"
705
+
706
+ self.values = np.asarray(values, dtype=np.float64)
707
+
708
+ self.fill_segmentdata()
709
+
701
710
  def defaultgray(self):
702
711
  """Palette grise par défaut dans WOLF"""
703
712
 
@@ -882,7 +891,8 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
882
891
  self.nb = 2
883
892
  self.values = np.asarray([np.min(array), np.max(array)], dtype=np.float64)
884
893
  self.colors = np.asarray([[255, 255, 255, 255], [0, 0, 255, 255]], dtype=np.int32)
885
- self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
894
+ self.colorsflt = self.colors.astype(float)/255.
895
+ # self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
886
896
 
887
897
  self.fill_segmentdata()
888
898
 
@@ -892,7 +902,8 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
892
902
  self.nb = 2
893
903
  self.values = np.asarray([np.min(array), np.max(array)], dtype=np.float64)
894
904
  self.colors = np.asarray([[255, 255, 255, 255], [255, 0, 0, 255]], dtype=np.int32)
895
- self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
905
+ self.colorsflt = self.colors.astype(float)/255.
906
+ # self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
896
907
 
897
908
  self.fill_segmentdata()
898
909
 
@@ -902,6 +913,17 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
902
913
  self.nb = 2
903
914
  self.values = np.asarray([0., 1.], dtype=np.float64)
904
915
  self.colors = np.asarray([[255, 255, 255, 255], [0, 0, 255, 255]], dtype=np.int32)
905
- self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
916
+ self.colorsflt = self.colors.astype(float)/255.
917
+ # self.colorsflt = np.asarray([[0., 0., 0., 1.], [1., 1., 1., 1.]], dtype=np.float64)
918
+
919
+ self.fill_segmentdata()
920
+
921
+ def defaultblue3(self):
922
+ """Remplissage des valeurs de palette sur base d'une équirépartition de valeurs"""
923
+
924
+ self.nb = 3
925
+ self.values = np.asarray([0., 1., 10.], dtype=np.float64)
926
+ self.colors = np.asarray([[255, 255, 255, 255], [50, 130, 246, 255], [0, 0, 255, 255]], dtype=np.int32)
927
+ self.colorsflt = self.colors.astype(float)/255.
906
928
 
907
929
  self.fill_segmentdata()
wolfhece/PyParams.py CHANGED
@@ -846,6 +846,39 @@ class Wolf_Param(wx.Frame):
846
846
  dlg = wx.MessageDialog(None,'Nothing to do!')
847
847
  dlg.ShowModal()
848
848
 
849
+ def compare_active_to_default(self, remove_from_active_if_same:bool = True):
850
+ """
851
+ Compare active parameters to default parameters and remove those that are the same.
852
+
853
+ :param remove_from_active_if_same: If True, remove parameters from active if they are the same as default.
854
+ """
855
+
856
+ for group in self.myparams_default.keys():
857
+ for param_name in self.myparams_default[group].keys():
858
+ if self.is_in_active(group, param_name):
859
+
860
+ val_default = self.myparams_default[group][param_name][key_Param.VALUE]
861
+ val_active = self.myparams[group][param_name][key_Param.VALUE]
862
+
863
+ if val_active == val_default:
864
+ if remove_from_active_if_same:
865
+ # Remove from active parameters
866
+ del self.myparams[group][param_name]
867
+ # # Remove from property grid
868
+ # if self._is_in_propperty_page(self.page_active, group, param_name):
869
+ # self.prop.DeleteProperty(group + param_name)
870
+ else:
871
+ logging.debug(_('Parameter {} is the same as default and will not be removed'.format(param_name)))
872
+
873
+ # Iterate through the groups and remove empty ones
874
+ groups_to_remove = []
875
+ for group in self.myparams.keys():
876
+ if not self.myparams[group]:
877
+ groups_to_remove.append(group)
878
+
879
+ for group in groups_to_remove:
880
+ del self.myparams[group]
881
+
849
882
  @property
850
883
  def page_active(self) -> pg.PropertyGridPage:
851
884
  """ Return the active page """
wolfhece/PyPictures.py CHANGED
@@ -332,7 +332,7 @@ class PictureCollection(Zones):
332
332
 
333
333
  df = pd.read_excel(excel_file, sheet_name=sheet_name)
334
334
 
335
- for _, row in df.iterrows():
335
+ for __, row in df.iterrows():
336
336
  picture = row['Picture']
337
337
  x = row.get('X', None)
338
338
  y = row.get('Y', None)
@@ -405,7 +405,7 @@ class PictureCollection(Zones):
405
405
  name_column = column
406
406
  break
407
407
 
408
- for _, row in gdf.iterrows():
408
+ for __, row in gdf.iterrows():
409
409
  picture_path = row[name_column]
410
410
  if not isinstance(picture_path, str):
411
411
  logging.error(f"Invalid picture path in shapefile: {picture_path}")
wolfhece/PyVertex.py CHANGED
@@ -1011,6 +1011,18 @@ class cloud_vertices(Element_To_Draw):
1011
1011
  self._updatebounds(newcloud=cloud)
1012
1012
  pass
1013
1013
 
1014
+ def remove_vertex(self, id: int):
1015
+ """ Remove a vertex from the cloud
1016
+
1017
+ :param id: id of the vertex to remove
1018
+ """
1019
+
1020
+ if id in self.myvertices:
1021
+ del self.myvertices[id]
1022
+ self._updatebounds()
1023
+ else:
1024
+ logging.warning(_('Vertex with id {} not found in the cloud').format(id))
1025
+
1014
1026
  def add_vertices(self, vertices:list[wolfvertex]):
1015
1027
  """ Add a list of vertices to the cloud """
1016
1028
 
@@ -1061,6 +1073,13 @@ class cloud_vertices(Element_To_Draw):
1061
1073
 
1062
1074
  if self.myprop.legendvisible:
1063
1075
 
1076
+ dx = xmax - xmin
1077
+ dy = ymax - ymin
1078
+
1079
+ if dx > 50_000. or dy > 50_000.:
1080
+ logging.warning(_('Too large bounds for legend plot -- skipping'))
1081
+ return
1082
+
1064
1083
  mapviewer = self.get_mapviewer()
1065
1084
 
1066
1085
  which_legend = self.myprop.legendtext
@@ -1102,6 +1121,19 @@ class cloud_vertices(Element_To_Draw):
1102
1121
 
1103
1122
  text.paint()
1104
1123
 
1124
+ def reset_listogl(self):
1125
+ """
1126
+ Reset the OpenGL list
1127
+
1128
+ """
1129
+
1130
+ if self.gllist != 0:
1131
+ glDeleteLists(self.gllist, 1)
1132
+ self.gllist = 0
1133
+
1134
+ self.forceupdategl = True
1135
+ self.ongoing = False
1136
+
1105
1137
  def plot(self, update:bool=False, *args, **kwargs):
1106
1138
  """
1107
1139
  OpenGL plot of the cloud of vertices
@@ -877,11 +877,26 @@ class vectorproperties:
877
877
  added = '#TRUE#' if self.used else '#FALSE#'
878
878
  f.write(added+'\n')
879
879
 
880
+ @property
881
+ def image_path(self) -> Path:
882
+ """ Return the path of the attached image """
883
+ return Path(self.attachedimage)
884
+
885
+ @image_path.setter
886
+ def image_path(self, value:Path):
887
+ """ Set the path of the attached image """
888
+
889
+ if self.attachedimage != value:
890
+ self.unload_image()
891
+
892
+ self.attachedimage = Path(value)
893
+
880
894
  def load_unload_image(self):
881
895
  """ Load an attached image """
882
896
 
883
897
  if self.imagevisible:
884
898
  if self.attachedimage is not None:
899
+ self.attachedimage = Path(self.attachedimage)
885
900
  if self.attachedimage.exists():
886
901
 
887
902
  (xmin,xmax),(ymin,ymax) = self.parent.get_bounds_xx_yy()
@@ -911,9 +926,14 @@ class vectorproperties:
911
926
  else:
912
927
  logging.warning('Image not found : {}'.format(self.attachedimage))
913
928
  else:
914
- if self.textureimage is not None:
915
- self.textureimage.unload()
916
- self.textureimage = None
929
+ self.unload_image()
930
+
931
+ def unload_image(self):
932
+ """ Unload the attached image """
933
+
934
+ if self.textureimage is not None:
935
+ self.textureimage.unload()
936
+ self.textureimage = None
917
937
 
918
938
  def fill_property(self, props:Wolf_Param = None, updateOGL:bool = True):
919
939
  """
@@ -1336,6 +1356,8 @@ class vector:
1336
1356
  self._lengthparts2D=None
1337
1357
  self._lengthparts3D=None
1338
1358
 
1359
+ self._simplified_geometry = False
1360
+
1339
1361
  if type(lines)==list:
1340
1362
  if len(lines)>0:
1341
1363
  self.myname=lines[0]
@@ -2373,30 +2395,32 @@ class vector:
2373
2395
  return tri.get_triangles_as_listwolfvertices()
2374
2396
 
2375
2397
  else:
2376
- # if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
2377
- # return [self.myvertices + [self.myvertices[0]]]
2378
- # else:
2379
- # return [self.myvertices]
2380
- xx, yy = self.polygon.exterior.xy
2398
+ if self._simplified_geometry:
2399
+ if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
2400
+ return [self.myvertices + [self.myvertices[0]]]
2401
+ else:
2402
+ return [self.myvertices]
2403
+ else:
2404
+ xx, yy = self.polygon.exterior.xy
2381
2405
 
2382
- # On translate les coordonnées pour éviter les erreurs de triangulation
2383
- tr_x = np.array(xx).min()
2384
- tr_y = np.array(yy).min()
2406
+ # On translate les coordonnées pour éviter les erreurs de triangulation
2407
+ tr_x = np.array(xx).min()
2408
+ tr_y = np.array(yy).min()
2385
2409
 
2386
- xx = np.array(xx)-tr_x
2387
- yy = np.array(yy)-tr_y
2410
+ xx = np.array(xx)-tr_x
2411
+ yy = np.array(yy)-tr_y
2388
2412
 
2389
- geom = {'vertices' : [[x,y] for x,y in zip(xx[:-1],yy[:-1])], 'segments' : [[i,i+1] for i in range(len(xx)-2)]+[[len(xx)-2,0]]}
2413
+ geom = {'vertices' : [[x,y] for x,y in zip(xx[:-1],yy[:-1])], 'segments' : [[i,i+1] for i in range(len(xx)-2)]+[[len(xx)-2,0]]}
2390
2414
 
2391
- try:
2392
- delaunay = triangle.triangulate(geom, 'p')
2393
- tri = []
2394
- for curtri in delaunay['triangles']:
2395
- # on traduit les coordonnées pour revenir dans le monde réel
2396
- tri.append([wolfvertex(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y) for i in range(3)])
2397
- return tri
2398
- except:
2399
- pass
2415
+ try:
2416
+ delaunay = triangle.triangulate(geom, 'p')
2417
+ tri = []
2418
+ for curtri in delaunay['triangles']:
2419
+ # on traduit les coordonnées pour revenir dans le monde réel
2420
+ tri.append([wolfvertex(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y) for i in range(3)])
2421
+ return tri
2422
+ except:
2423
+ pass
2400
2424
 
2401
2425
  else:
2402
2426
  if self.has_interior:
@@ -2657,13 +2681,17 @@ class vector:
2657
2681
 
2658
2682
  if self.myprop.imagevisible and self.myprop.used:
2659
2683
 
2660
- if self.myprop.textureimage is None:
2661
- self.myprop.load_unload_image()
2684
+ try:
2662
2685
 
2663
- if self.myprop.textureimage is not None:
2664
- self.myprop.textureimage.paint()
2665
- else:
2666
- logging.warning(_('No image texture available for plot'))
2686
+ if self.myprop.textureimage is None:
2687
+ self.myprop.load_unload_image()
2688
+
2689
+ if self.myprop.textureimage is not None:
2690
+ self.myprop.textureimage.paint()
2691
+ else:
2692
+ logging.warning(_('No image texture available for plot'))
2693
+ except Exception as e:
2694
+ logging.error(_('Error while plotting image texture: {}').format(e))
2667
2695
 
2668
2696
  def plot_matplotlib(self, ax:plt.Axes | tuple[Figure, Axes] = None):
2669
2697
  """
@@ -3310,8 +3338,8 @@ class vector:
3310
3338
  k1,cums1,lengthparts1=self.get_segment(s1,is3D,adim,True)
3311
3339
  k2,cums2,lengthparts2=self.get_segment(s2,is3D,adim,False)
3312
3340
 
3313
- pond1 = max((cums1-s1)/lengthparts1[k1],0.)
3314
- pond2 = min((cums2-s2)/lengthparts2[k2],1.)
3341
+ pond1 = max((cums1-s1)/lengthparts1[k1],0.) if lengthparts1[k1] > 0. else 0.
3342
+ pond2 = min((cums2-s2)/lengthparts2[k2],1.) if lengthparts2[k2] > 0. else 1.
3315
3343
 
3316
3344
  v1= wolfvertex(self.myvertices[k1].x*pond1+self.myvertices[k1+1].x*(1.-pond1),
3317
3345
  self.myvertices[k1].y*pond1+self.myvertices[k1+1].y*(1.-pond1),
@@ -3521,6 +3549,12 @@ class vector:
3521
3549
  self.myprop.legendy = centroid.y
3522
3550
  self.myprop.legendtext = text if text else self.myname
3523
3551
 
3552
+ def set_legend_visible(self, visible:bool=True):
3553
+ """
3554
+ Set the visibility of the legend.
3555
+ """
3556
+ self.myprop.legendvisible = visible
3557
+
3524
3558
  def set_legend_position_to_centroid(self):
3525
3559
  """
3526
3560
  Positionne la légende au centre du vecteur
@@ -3882,6 +3916,8 @@ class vector:
3882
3916
  """ Permet de retrouver un vertex sur base de son index """
3883
3917
  if ndx>=0 and ndx < self.nbvertices:
3884
3918
  return self.myvertices[ndx]
3919
+ elif ndx < 0 and abs(ndx) <= self.nbvertices:
3920
+ return self.myvertices[ndx + self.nbvertices]
3885
3921
  else:
3886
3922
  logging.warning(_('Index out of range'))
3887
3923
 
@@ -3891,15 +3927,27 @@ class vector:
3891
3927
  self.myvertices[ndx] = value
3892
3928
  self._reset_listogl()
3893
3929
  self.reset_linestring()
3930
+ elif ndx < 0 and abs(ndx) <= self.nbvertices:
3931
+ self.myvertices[ndx + self.nbvertices] = value
3932
+ self._reset_listogl()
3933
+ self.reset_linestring()
3894
3934
  else:
3895
3935
  logging.warning(_('Index out of range'))
3896
3936
 
3897
3937
  def __delitem__(self, ndx:int):
3898
- """ Permet de supprimer un vertex sur base de son index """
3938
+ """ Permet de supprimer un vertex sur base de son index.
3939
+
3940
+ Exemple:
3941
+ del myvector[0] # Supprime le premier vertex
3942
+ """
3899
3943
  if ndx>=0 and ndx < self.nbvertices:
3900
3944
  self.myvertices.pop(ndx)
3901
3945
  self._reset_listogl()
3902
3946
  self.reset_linestring()
3947
+ elif ndx < 0 and abs(ndx) <= self.nbvertices:
3948
+ self.myvertices.pop(ndx + self.nbvertices)
3949
+ self._reset_listogl()
3950
+ self.reset_linestring()
3903
3951
  else:
3904
3952
  logging.warning(_('Index out of range'))
3905
3953
 
@@ -3966,6 +4014,25 @@ class vector:
3966
4014
  inside = [self.polygon.contains(Point(curxy)) for curxy in xy]
3967
4015
 
3968
4016
  return inside
4017
+
4018
+ def get_first_point_inside(self, xy: cloud_vertices | np.ndarray):
4019
+ """
4020
+ Returns the first point (x, y) inside the polygon.
4021
+
4022
+ :param xy: Point cloud (cloud_vertices or np.ndarray)
4023
+ :type xy: cloud_vertices | np.ndarray
4024
+ :return: Coordinates (x, y) of the first point found inside, or None if none
4025
+ :rtype: tuple[float, float] | None
4026
+ """
4027
+ self.prepare_shapely(True)
4028
+
4029
+ if isinstance(xy, cloud_vertices):
4030
+ xy = xy.get_xyz()[:, 0:2]
4031
+
4032
+ for curxy in xy:
4033
+ if self.polygon.contains(Point(curxy)):
4034
+ return float(curxy[0]), float(curxy[1])
4035
+ return None
3969
4036
 
3970
4037
  def split_cloud(self, cloud_to_split:cloud_vertices):
3971
4038
  """ Split a cloud of vertices on the vector """
@@ -4023,7 +4090,7 @@ class vector:
4023
4090
  def area(self):
4024
4091
  """ Alias for surface """
4025
4092
  return self.surface
4026
-
4093
+
4027
4094
  def interpolate_coordinates(self):
4028
4095
  """
4029
4096
  Interpole les valeurs Z des vertices sur base des seules valeurs connues,
@@ -4133,8 +4200,8 @@ class zone:
4133
4200
 
4134
4201
  def check_if_interior_exists(self):
4135
4202
  """ Check if the zone has at least one vector with interior points """
4136
- for curvec in self.myvectors:
4137
- curvec.check_if_interior_exists()
4203
+
4204
+ list(map(lambda curvec: curvec.check_if_interior_exists(), self.myvectors))
4138
4205
 
4139
4206
  def add_values(self, key:str, values:np.ndarray):
4140
4207
  """ add values to the zone """
@@ -4143,8 +4210,7 @@ class zone:
4143
4210
  logging.warning(_('Number of vectors and values do not match'))
4144
4211
  return
4145
4212
 
4146
- for curvec, curval in zip(self.myvectors, values):
4147
- curvec.add_value(key, curval)
4213
+ list(map(lambda cur: cur[0].add_value(key, cur[1]), zip(self.myvectors, values)))
4148
4214
 
4149
4215
  def get_values(self, key:str) -> np.ndarray:
4150
4216
  """ get values from the zone """
@@ -4154,25 +4220,21 @@ class zone:
4154
4220
  def set_colors_from_value(self, key:str, cmap:wolfpalette | Colormap | cm.ScalarMappable, vmin:float= 0., vmax:float= 1.):
4155
4221
  """ Set the colors for the zone """
4156
4222
 
4157
- for curvec in self.myvectors:
4158
- curvec.set_color_from_value(key, cmap, vmin, vmax)
4223
+ list(map(lambda curvec: curvec.set_color_from_value(key, cmap, vmin, vmax), self.myvectors))
4159
4224
 
4160
4225
  def set_alpha(self, alpha:int):
4161
4226
  """ Set the alpha for the zone """
4162
4227
 
4163
- for curvec in self.myvectors:
4164
- curvec.set_alpha(alpha)
4228
+ list(map(lambda curvec: curvec.set_alpha(alpha), self.myvectors))
4165
4229
 
4166
4230
  def set_filled(self, filled:bool):
4167
4231
  """ Set the filled for the zone """
4168
4232
 
4169
- for curvec in self.myvectors:
4170
- curvec.set_filled(filled)
4233
+ list(map(lambda curvec: curvec.set_filled(filled), self.myvectors))
4171
4234
 
4172
4235
  def check_if_open(self):
4173
4236
  """ Check if the vectors in the zone are open """
4174
- for curvec in self.myvectors:
4175
- curvec.check_if_open()
4237
+ list(map(lambda curvect: curvect.check_if_open(), self.myvectors))
4176
4238
 
4177
4239
  def buffer(self, distance:float, resolution:int=16, inplace:bool = False) -> 'zone':
4178
4240
  """ Create a new zone with a buffer around each vector """
@@ -4197,24 +4259,21 @@ class zone:
4197
4259
  Set the legend text for the zone
4198
4260
  """
4199
4261
 
4200
- for curvect in self.myvectors:
4201
- curvect.set_legend_text(text)
4262
+ list(map(lambda curvect: curvect.set_legend_text(text), self.myvectors))
4202
4263
 
4203
4264
  def set_legend_text_from_values(self, key:str):
4204
4265
  """
4205
4266
  Set the legend text for the zone from a value
4206
4267
  """
4207
4268
 
4208
- for curvect in self.myvectors:
4209
- curvect.set_legend_text_from_value(key)
4269
+ list(map(lambda curvect: curvect.set_legend_text_from_value(key), self.myvectors))
4270
+
4210
4271
 
4211
4272
  def set_legend_position(self, x, y):
4212
4273
  """
4213
4274
  Set the legend position for the zone
4214
4275
  """
4215
-
4216
- for curvect in self.myvectors:
4217
- curvect.set_legend_position(x, y)
4276
+ list(map(lambda curvect: curvect.set_legend_position(x, y), self.myvectors))
4218
4277
 
4219
4278
  @property
4220
4279
  def area(self):
@@ -4230,15 +4289,14 @@ class zone:
4230
4289
  """
4231
4290
  Set the cache for the zone and all its vectors
4232
4291
  """
4233
- for curvect in self.myvectors:
4234
- curvect.set_cache()
4292
+
4293
+ list(map(lambda curvect: curvect.set_cache(), self.myvectors))
4235
4294
 
4236
4295
  def clear_cache(self):
4237
4296
  """
4238
4297
  Clear the cache for the zone and all its vectors
4239
4298
  """
4240
- for curvect in self.myvectors:
4241
- curvect.clear_cache()
4299
+ list(map(lambda curvect: curvect.clear_cache(), self.myvectors))
4242
4300
 
4243
4301
  self._move_start = None
4244
4302
  self._move_step = None
@@ -4598,8 +4656,9 @@ class zone:
4598
4656
  else:
4599
4657
  fig = ax.figure
4600
4658
 
4601
- for curvect in self.myvectors:
4602
- curvect.plot_matplotlib(ax)
4659
+ # for curvect in self.myvectors:
4660
+ # curvect.plot_matplotlib(ax)
4661
+ list(map(lambda curvect: curvect.plot_matplotlib(ax), self.myvectors))
4603
4662
 
4604
4663
  return fig, ax
4605
4664
 
@@ -4898,6 +4957,7 @@ class zone:
4898
4957
  # cs.set_zones(True)
4899
4958
 
4900
4959
  interp = Interpolators(banks, cs, ds)
4960
+ interp.export_gltf()
4901
4961
 
4902
4962
  return interp
4903
4963
 
@@ -6290,9 +6350,13 @@ class zone:
6290
6350
  """
6291
6351
  Set the legend to the centroid of the vectors
6292
6352
  """
6353
+ list(map(lambda curvec: curvec.set_legend_to_centroid(), self.myvectors))
6293
6354
 
6294
- for curvec in self.myvectors:
6295
- curvec.set_legend_position_to_centroid()
6355
+ def set_legend_visible(self, visible:bool=True):
6356
+ """
6357
+ Set the visibility of the legend for all vectors in the zone
6358
+ """
6359
+ list(map(lambda curvec: curvec.set_legend_visible(visible), self.myvectors))
6296
6360
 
6297
6361
  class Zones(wx.Frame, Element_To_Draw):
6298
6362
  """
@@ -6321,6 +6385,7 @@ class Zones(wx.Frame, Element_To_Draw):
6321
6385
  parent=None,
6322
6386
  is2D=True,
6323
6387
  idx: str = '',
6388
+ colname: str = None,
6324
6389
  plotted: bool = True,
6325
6390
  mapviewer=None,
6326
6391
  need_for_wx: bool = False,
@@ -6427,7 +6492,7 @@ class Zones(wx.Frame, Element_To_Draw):
6427
6492
 
6428
6493
  elif self.filename.endswith('.shp'):
6429
6494
  self.is2D=False
6430
- self.import_shapefile(self.filename, bbox=bbox)
6495
+ self.import_shapefile(self.filename, bbox=bbox, colname=colname)
6431
6496
  only_firstlast = True # We limit the number of vertices to the first and last ones to accelerate the process
6432
6497
 
6433
6498
  elif self.filename.endswith('.gpkg'):
@@ -6491,9 +6556,9 @@ class Zones(wx.Frame, Element_To_Draw):
6491
6556
  self.colorize_data(colors, filled=True)
6492
6557
 
6493
6558
  if plotted and self.has_OGLContext and not self.shared:
6494
- logging.info(_('Preparing OpenGL lists'))
6559
+ logging.debug(_('Preparing OpenGL lists'))
6495
6560
  self.prep_listogl()
6496
- logging.info(_('OpenGL lists ready'))
6561
+ logging.debug(_('OpenGL lists ready'))
6497
6562
 
6498
6563
  @property
6499
6564
  def mynames(self) -> list[str]:
@@ -6759,9 +6824,10 @@ class Zones(wx.Frame, Element_To_Draw):
6759
6824
 
6760
6825
  logging.info(_('Importing shapefile {}'.format(fn)))
6761
6826
  content = gpd.read_file(fn, bbox=bbox)
6762
-
6763
- self.import_GeoDataFrame(content, colname=colname)
6764
-
6827
+
6828
+ self.import_GeoDataFrame(content=content, colname=colname)
6829
+
6830
+
6765
6831
  def import_GeoDataFrame(self, content:gpd.GeoDataFrame,
6766
6832
  bbox:Polygon = None, colname:str = None):
6767
6833
  """
@@ -6786,24 +6852,24 @@ class Zones(wx.Frame, Element_To_Draw):
6786
6852
  idx, row = row
6787
6853
  keys = list(row.keys())
6788
6854
  if colname in keys:
6789
- name = row[colname]
6855
+ name = str(row[colname])
6790
6856
  elif 'NAME' in keys:
6791
- name = row['NAME']
6857
+ name = str(row['NAME'])
6792
6858
  elif 'location' in keys:
6793
- name = row['location'] # tuilage gdal
6859
+ name = str(row['location']) # tuilage gdal
6794
6860
  elif 'Communes' in keys:
6795
- name = row['Communes']
6861
+ name = str(row['Communes'])
6796
6862
  elif 'name' in keys:
6797
- name = row['name']
6863
+ name = str(row['name'])
6798
6864
  elif 'MAJ_NIV3T' in keys:
6799
6865
  # WALOUS
6800
- name = row['MAJ_NIV3T']
6866
+ name = str(row['MAJ_NIV3T'])
6801
6867
  elif 'NATUR_DESC' in keys:
6802
- name = row['NATUR_DESC']
6868
+ name = str(row['NATUR_DESC'])
6803
6869
  elif 'mun_name_f' in keys:
6804
- name = row['mun_name_f'].replace('[','').replace(']','').replace("'",'')
6870
+ name = str(row['mun_name_f']).replace('[','').replace(']','').replace("'",'')
6805
6871
  elif 'mun_name_fr' in keys:
6806
- name = row['mun_name_fr']
6872
+ name = str(row['mun_name_fr'])
6807
6873
  else:
6808
6874
  name = str(idx)
6809
6875
 
@@ -7300,6 +7366,12 @@ class Zones(wx.Frame, Element_To_Draw):
7300
7366
  if forceparent:
7301
7367
  addedzone.parent = self
7302
7368
 
7369
+ def create_zone(self, name:str = '') -> zone:
7370
+ """ Create a new zone and add it to the list of zones """
7371
+ newzone = zone(name=name, parent=self, is2D=self.is2D)
7372
+ self.myzones.append(newzone)
7373
+ return newzone
7374
+
7303
7375
  def find_minmax(self, update=False, only_firstlast:bool=False):
7304
7376
  """
7305
7377
  Trouve les bornes des vertices pour toutes les zones et tous les vecteurs