wolfhece 2.1.113__py3-none-any.whl → 2.1.115__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/PyGui.py CHANGED
@@ -2942,9 +2942,8 @@ class Wolf2DGPUModel(GenMapManager):
2942
2942
 
2943
2943
  if self._wp is not None:
2944
2944
  try:
2945
- if self._wp.Shown:
2946
- self._sim.sim.from_wolfparam(self._wp)
2947
- self._sim.sim._save_json()
2945
+ self._sim.sim.from_wolfparam(self._wp)
2946
+ self._sim.sim._save_json()
2948
2947
  except Exception as e:
2949
2948
  self._wp = None
2950
2949
  logging.debug(_('Error while saving parameters for simulation {}'.format(self._sim.sim.path.name)))
@@ -3047,6 +3046,14 @@ class Wolf2DGPUModel(GenMapManager):
3047
3046
 
3048
3047
  ret_infil=[]
3049
3048
  nmax = ma.max(self.arrays['infiltration_zones'].array)
3049
+
3050
+ if nmax == 99999:
3051
+ logging.warning(_('Maximum index in infiltration zones is 99999. It seems to be a bad null value - Check the array !'))
3052
+ logging.warning(_('Replacing 99999 by 0'))
3053
+ self.arrays['infiltration_zones'].array[self.arrays['infiltration_zones'].array == 99999] = 0
3054
+ nmax = ma.max(self.arrays['infiltration_zones'].array)
3055
+ logging.info(_('New maximum index in infiltration zones is {}'.format(nmax)))
3056
+
3050
3057
  nmin = ma.min(self.arrays['infiltration_zones'].array[self.arrays['infiltration_zones'].array > 0])
3051
3058
  l = ma.unique(self.arrays['infiltration_zones'].array[self.arrays['infiltration_zones'].array > 0]).tolist()
3052
3059
  chronos = self.sim.sim.infiltrations_chronology
@@ -3416,6 +3423,7 @@ class Wolf2DGPUModel(GenMapManager):
3416
3423
  """ Apply the changes """
3417
3424
 
3418
3425
  if self._wp is not None:
3426
+ self._wp.apply_changes_to_memory()
3419
3427
  self._callbackwp()
3420
3428
 
3421
3429
  def show_properties(self):
@@ -3633,9 +3641,11 @@ class Wolf2DGPUModel(GenMapManager):
3633
3641
  # Apply changes
3634
3642
  # -------------
3635
3643
  self._btn_apply = wx.Button(self._panel, label=_('Apply changes'))
3636
- self._btn_apply.SetToolTip(_('Apply the changes to the memory (not saved on disk)'))
3644
+ self._btn_apply.SetToolTip(_('Apply the changes to the memory (and save on disk)'))
3637
3645
  self._btn_apply.Bind(wx.EVT_BUTTON, self._apply_changes)
3638
3646
 
3647
+ self._sizer_principal.Add(self._btn_apply, 1, wx.EXPAND)
3648
+
3639
3649
  self._panel.SetSizer(self._sizer_gen)
3640
3650
 
3641
3651
  self._sizer_principal.Add(self._sizer_properties, 4, wx.EXPAND)
wolfhece/PyPalette.py CHANGED
@@ -352,6 +352,8 @@ class wolfpalette(wx.Frame, LinearSegmentedColormap):
352
352
  if fn != '' and fn is not None:
353
353
  plt.savefig(fn[:-4]+'_h.png', format='png')
354
354
 
355
+ fig.set_visible(False)
356
+
355
357
  return fig, ax
356
358
 
357
359
  def plot(self, fig: Figure, ax: plt.Axes):
@@ -59,7 +59,7 @@ class Triangulation(Element_To_Draw):
59
59
  self.nb_tri = len(tri)
60
60
  self.nb_pts = len(pts)
61
61
 
62
- self._start_move = None
62
+ self._move_start = None
63
63
  self._move_step = None # step for a move
64
64
  self._rotation_center = None
65
65
  self._rotation_step = None
@@ -580,6 +580,10 @@ class vectorproperties:
580
580
 
581
581
  self.used=True
582
582
 
583
+ # FIXME : to be changed
584
+ # if self.parent is not None:
585
+ # self.closed = self.parent.closed
586
+
583
587
  self.init_extra()
584
588
 
585
589
  def init_extra(self):
@@ -716,7 +720,13 @@ class vectorproperties:
716
720
  self.color = getIfromRGB(props[('Draw','Color')])
717
721
  self.width = props[('Draw','Width')]
718
722
  self.style = props[('Draw','Style')]
723
+
724
+ old_closed = self.closed
719
725
  self.closed = props[('Draw','Closed')]
726
+
727
+ if old_closed != self.closed:
728
+ self.parent._reset_listogl()
729
+
720
730
  self.filled = props[('Draw','Filled')]
721
731
  self.transparent = props[('Draw','Transparent')]
722
732
  self.alpha = props[('Draw','Alpha')]
@@ -733,75 +743,15 @@ class vectorproperties:
733
743
  self.legendrelpos = props[('Legend','Relative position')]
734
744
 
735
745
  text = props[('Legend','Text')]
736
- if text is _('Not used'):
737
- pass
738
- elif text == _('name'):
739
- self.legendtext = self.parent.myname
740
- elif text == _('first z'):
741
- self.legendtext = str(self.parent.myvertices[0].z)
742
- elif text == _('length2D'):
743
- self.legendtext = str(self.parent.length2D)
744
- elif text == _('length3D'):
745
- self.legendtext = str(self.parent.length3D)
746
- elif text == _('id'):
747
- self.legendtext = str(self.parent.parentzone.myvectors.index(self.parent))
748
- else:
749
- self.legendtext = text
746
+
747
+ self.parent.set_legend_text(text)
750
748
 
751
749
  self.legendvisible = props[('Legend','Visible')]
752
750
 
753
751
  posx = props[('Legend','X')]
754
752
  posy = props[('Legend','Y')]
755
753
 
756
- if posx == _('Not used'):
757
- pass
758
- elif posx.lower() == _('median'):
759
- # valeur mediane selon x et y
760
- xy = self.parent.asnparray()
761
- self.legendx = np.median(xy[:,0])
762
- elif posx.lower() == _('mean'):
763
- # valeur moyenne selon x et y
764
- xy = self.parent.asnparray()
765
- self.legendx = np.mean(xy[:,0])
766
- elif posx.lower() == _('min'):
767
- # valeur minimale selon x et y
768
- xy = self.parent.asnparray()
769
- self.legendx = np.min(xy[:,0])
770
- elif posx.lower() == _('max'):
771
- # valeur maximale selon x et y
772
- xy = self.parent.asnparray()
773
- self.legendx = np.max(xy[:,0])
774
- elif posx.lower() == _('first'):
775
- self.legendx = self.parent.myvertices[0].x
776
- elif posx.lower() == _('last'):
777
- self.legendx = self.parent.myvertices[-1].x
778
- else:
779
- self.legendx = float(posx)
780
-
781
- if posy == _('Not used'):
782
- pass
783
- elif posy.lower() == _('median'):
784
- # valeur mediane selon x et y
785
- xy = self.parent.asnparray()
786
- self.legendy = np.median(xy[:,1])
787
- elif posy.lower() == _('mean'):
788
- # valeur moyenne selon x et y
789
- xy = self.parent.asnparray()
790
- self.legendy = np.mean(xy[:,1])
791
- elif posy.lower() == _('min'):
792
- # valeur minimale selon x et y
793
- xy = self.parent.asnparray()
794
- self.legendy = np.min(xy[:,1])
795
- elif posy.lower() == _('max'):
796
- # valeur maximale selon x et y
797
- xy = self.parent.asnparray()
798
- self.legendy = np.max(xy[:,1])
799
- elif posy.lower() == _('first'):
800
- self.legendy = self.parent.myvertices[0].y
801
- elif posy.lower() == _('last'):
802
- self.legendy = self.parent.myvertices[-1].y
803
- else:
804
- self.legendy = float(posy)
754
+ self.parent.set_legend_position(posx,posy)
805
755
 
806
756
  self.legendlength = props[('Legend','Length')]
807
757
  self.legendheight = props[('Legend','Height')]
@@ -816,9 +766,9 @@ class vectorproperties:
816
766
  move_step = props[('Move','Step [m]')]
817
767
 
818
768
  if posx != 99999. and posy != 99999.:
819
- self.parent._start_move = (posx,posy)
769
+ self.parent._move_start = (posx,posy)
820
770
  else:
821
- self.parent._start_move = None
771
+ self.parent._move_start = None
822
772
 
823
773
  if move_step != 99999.:
824
774
  self.parent._move_step = move_step
@@ -959,68 +909,7 @@ if :\n \
959
909
  Then, add the current properties to the UI
960
910
  """
961
911
  self._defaultprop()
962
-
963
- self.myprops[('Draw','Color')] = getRGBfromI(self.color)
964
- self.myprops[('Draw','Width')] = self.width
965
- self.myprops[('Draw','Style')] = self.style
966
- self.myprops[('Draw','Closed')] = self.closed
967
- self.myprops[('Draw','Filled')] = self.filled
968
- self.myprops[('Draw','Transparent')]= self.transparent
969
- self.myprops[('Draw','Alpha')] = self.alpha
970
- self.myprops[('Draw','Flash')] = self.flash
971
-
972
- self.myprops[('Legend','Visible')] = self.legendvisible
973
- self.myprops[('Legend','Text')] = self.legendtext
974
- self.myprops[('Legend','Relative position')]=self.legendrelpos
975
- self.myprops[('Legend','X')] = self.legendx
976
- self.myprops[('Legend','Y')] = self.legendy
977
- self.myprops[('Legend','Bold')] = self.legendbold
978
- self.myprops[('Legend','Italic')] = self.legenditalic
979
-
980
- self.myprops[('Legend','Font name')]= self._convert_fontname2int(self.legendfontname)
981
-
982
- self.myprops[('Legend','Font size')]= self.legendfontsize
983
- self.myprops[('Legend','Color')] = getRGBfromI(self.legendcolor)
984
- self.myprops[('Legend','Underlined')]= self.legendunderlined
985
-
986
- self.myprops[('Legend','Length')] = self.legendlength
987
- self.myprops[('Legend','Height')] = self.legendheight
988
- self.myprops[('Legend','Priority')] = self.legendpriority
989
- self.myprops[('Legend','Orientation')]= self.legendorientation
990
-
991
- self.myprops[('Image','Attached image')] = str(self.attachedimage)
992
- self.myprops[('Image','To show')] = self.imagevisible
993
-
994
- if self.parent._rotation_center is not None:
995
- self.myprops[('Rotation','center X')] = self.parent._rotation_center[0]
996
- self.myprops[('Rotation','Center Y')] = self.parent._rotation_center[1]
997
- else:
998
- self.myprops[('Rotation','Center X')] = 99999.
999
- self.myprops[('Rotation','Center Y')] = 99999.
1000
-
1001
- if self.parent._rotation_step is not None:
1002
- self.myprops[('Rotation','Step [degree]')] = self.parent._rotation_step
1003
- else:
1004
- self.myprops[('Rotation','Step [degree]')] = 99999.
1005
-
1006
- self.myprops[('Rotation', 'Angle [degree]')] = 0.
1007
-
1008
- if self.parent._start_move is not None:
1009
- self.myprops[('Move','Start X')] = self.parent._start_move[0]
1010
- self.myprops[('Move','Start Y')] = self.parent._start_move[1]
1011
- else:
1012
- self.myprops[('Move','Start X')] = 99999.
1013
- self.myprops[('Move','Start Y')] = 99999.
1014
-
1015
- if self.parent._move_step is not None:
1016
- self.myprops[('Move','Step [m]')] = self.parent._move_step
1017
- else:
1018
- self.myprops[('Move','Step [m]')] = 99999.
1019
-
1020
- self.myprops[('Move','Delta X')] = 0.
1021
- self.myprops[('Move','Delta Y')] = 0.
1022
-
1023
- self.myprops.Populate()
912
+ self.update_myprops()
1024
913
  self.myprops.Layout()
1025
914
  self.myprops.SetSizeHints(500,800)
1026
915
  self.myprops.Show()
@@ -1068,7 +957,70 @@ if :\n \
1068
957
  else:
1069
958
  return 'Arial'
1070
959
 
960
+ def update_myprops(self):
961
+ """ Update the properties """
962
+
963
+ if self.myprops is not None:
964
+ self.myprops[('Draw','Color')] = getRGBfromI(self.color)
965
+ self.myprops[('Draw','Width')] = self.width
966
+ self.myprops[('Draw','Style')] = self.style
967
+ self.myprops[('Draw','Closed')] = self.closed
968
+ self.myprops[('Draw','Filled')] = self.filled
969
+ self.myprops[('Draw','Transparent')]= self.transparent
970
+ self.myprops[('Draw','Alpha')] = self.alpha
971
+ self.myprops[('Draw','Flash')] = self.flash
972
+
973
+ self.myprops[('Legend','Visible')] = self.legendvisible
974
+ self.myprops[('Legend','Text')] = self.legendtext
975
+ self.myprops[('Legend','Relative position')]=self.legendrelpos
976
+ self.myprops[('Legend','X')] = self.legendx
977
+ self.myprops[('Legend','Y')] = self.legendy
978
+ self.myprops[('Legend','Bold')] = self.legendbold
979
+ self.myprops[('Legend','Italic')] = self.legenditalic
980
+
981
+ self.myprops[('Legend','Font name')]= self._convert_fontname2int(self.legendfontname)
982
+
983
+ self.myprops[('Legend','Font size')]= self.legendfontsize
984
+ self.myprops[('Legend','Color')] = getRGBfromI(self.legendcolor)
985
+ self.myprops[('Legend','Underlined')]= self.legendunderlined
986
+
987
+ self.myprops[('Legend','Length')] = self.legendlength
988
+ self.myprops[('Legend','Height')] = self.legendheight
989
+ self.myprops[('Legend','Priority')] = self.legendpriority
990
+ self.myprops[('Legend','Orientation')]= self.legendorientation
991
+
992
+ self.myprops[('Image','Attached image')] = str(self.attachedimage)
993
+ self.myprops[('Image','To show')] = self.imagevisible
994
+
995
+ if self.parent._rotation_center is not None:
996
+ self.myprops[('Rotation','center X')] = self.parent._rotation_center[0]
997
+ self.myprops[('Rotation','Center Y')] = self.parent._rotation_center[1]
998
+ else:
999
+ self.myprops[('Rotation','Center X')] = 99999.
1000
+ self.myprops[('Rotation','Center Y')] = 99999.
1071
1001
 
1002
+ if self.parent._rotation_step is not None:
1003
+ self.myprops[('Rotation','Step [degree]')] = self.parent._rotation_step
1004
+ else:
1005
+ self.myprops[('Rotation','Step [degree]')] = 99999.
1006
+
1007
+ self.myprops[('Rotation', 'Angle [degree]')] = 0.
1008
+
1009
+ if self.parent._move_start is not None:
1010
+ self.myprops[('Move','Start X')] = self.parent._move_start[0]
1011
+ self.myprops[('Move','Start Y')] = self.parent._move_start[1]
1012
+ else:
1013
+ self.myprops[('Move','Start X')] = 99999.
1014
+ self.myprops[('Move','Start Y')] = 99999.
1015
+
1016
+ if self.parent._move_step is not None:
1017
+ self.myprops[('Move','Step [m]')] = self.parent._move_step
1018
+ else:
1019
+ self.myprops[('Move','Step [m]')] = 99999.
1020
+
1021
+ self.myprops[('Move','Delta X')] = 0.
1022
+ self.myprops[('Move','Delta Y')] = 0.
1023
+ self.myprops.Populate()
1072
1024
  class vector:
1073
1025
  """
1074
1026
  Objet de gestion d'informations vectorielles
@@ -1091,7 +1043,8 @@ class vector:
1091
1043
  mytree:TreeListCtrl
1092
1044
  myitem:TreeItemId
1093
1045
 
1094
- def __init__(self, lines:list=[], is2D=True, name='NoName', parentzone:"zone"=None, fromshapely=None) -> None:
1046
+ def __init__(self, lines:list=[], is2D=True, name='NoName',
1047
+ parentzone:"zone"=None, fromshapely=None, fromnumpy:np.ndarray = None) -> None:
1095
1048
  """
1096
1049
 
1097
1050
  :param lines: utile pour lecture de fichier
@@ -1102,8 +1055,8 @@ class vector:
1102
1055
  """
1103
1056
 
1104
1057
  self.myname=''
1105
- self.is2D = is2D
1106
- self.closed=False
1058
+ self.is2D = is2D # Force a 2D interpretation of the vertices, even if a z coordinate is present.
1059
+ # self.closed=False # True if the vector is a polygon. !! The last vertex is not necessarily the same as the first one. In this case, some routines will add a virtual segment at the end. !!
1107
1060
 
1108
1061
  self.mytree = None
1109
1062
 
@@ -1154,7 +1107,7 @@ class vector:
1154
1107
  self.myprop=vectorproperties(parent=self)
1155
1108
 
1156
1109
  self._cache_vertices = None
1157
- self._start_move = None
1110
+ self._move_start = None
1158
1111
  self._move_step = None
1159
1112
 
1160
1113
  self._rotation_center = None
@@ -1172,6 +1125,106 @@ class vector:
1172
1125
  if fromshapely is not None:
1173
1126
  self.import_shapelyobj(fromshapely)
1174
1127
 
1128
+ if fromnumpy is not None:
1129
+ self.add_vertices_from_array(fromnumpy)
1130
+
1131
+ def set_legend_text(self, text:str):
1132
+ """ Set the legend text """
1133
+
1134
+ if text is _('Not used'):
1135
+ pass
1136
+ elif text == _('name'):
1137
+ self.myprop.legendtext = self.myname
1138
+ elif text == _('first z'):
1139
+ if self.nbvertices>0:
1140
+ self.myprop.legendtext = str(self.myvertices[0].z)
1141
+ else:
1142
+ self.myprop.legendtext = ''
1143
+ elif text == _('length2D'):
1144
+ self.myprop.legendtext = str(self.length2D)
1145
+ elif text == _('length3D'):
1146
+ self.myprop.legendtext = str(self.length3D)
1147
+ elif text == _('id'):
1148
+ if self.parentzone is not None:
1149
+ self.myprop.legendtext = str(self.parentzone.myvectors.index(self))
1150
+ else:
1151
+ self.myprop.legendtext = ''
1152
+ else:
1153
+ self.myprop.legendtext = str(text)
1154
+
1155
+ self.myprop.update_myprops()
1156
+
1157
+ def set_legend_position(self, x:str | float, y:str | float):
1158
+ """ Set the legend position """
1159
+
1160
+ if isinstance(x, str):
1161
+ if x == _('Not used'):
1162
+ pass
1163
+ elif x.lower() == _('median'):
1164
+ # valeur mediane selon x et y
1165
+ xy = self.asnparray()
1166
+ self.myprop.legendx = np.median(xy[:,0])
1167
+ elif x.lower() == _('mean'):
1168
+ # valeur moyenne selon x et y
1169
+ xy = self.asnparray()
1170
+ self.myprop.legendx = np.mean(xy[:,0])
1171
+ elif x.lower() == _('min'):
1172
+ # valeur minimale selon x et y
1173
+ xy = self.asnparray()
1174
+ self.myprop.legendx = np.min(xy[:,0])
1175
+ elif x.lower() == _('max'):
1176
+ # valeur maximale selon x et y
1177
+ xy = self.asnparray()
1178
+ self.myprop.legendx = np.max(xy[:,0])
1179
+ elif x.lower() == _('first'):
1180
+ self.myprop.legendx = self.myvertices[0].x
1181
+ elif x.lower() == _('last'):
1182
+ self.myprop.legendx = self.myvertices[-1].x
1183
+ else:
1184
+ self.myprop.legendx = float(x)
1185
+ elif isinstance(x, float):
1186
+ self.myprop.legendx = x
1187
+
1188
+ if isinstance(y, str):
1189
+ if y == _('Not used'):
1190
+ pass
1191
+ elif y.lower() == _('median'):
1192
+ # valeur mediane selon x et y
1193
+ xy = self.asnparray()
1194
+ self.myprop.legendy = np.median(xy[:,1])
1195
+ elif y.lower() == _('mean'):
1196
+ # valeur moyenne selon x et y
1197
+ xy = self.asnparray()
1198
+ self.myprop.legendy = np.mean(xy[:,1])
1199
+ elif y.lower() == _('min'):
1200
+ # valeur minimale selon x et y
1201
+ xy = self.asnparray()
1202
+ self.myprop.legendy = np.min(xy[:,1])
1203
+ elif y.lower() == _('max'):
1204
+ # valeur maximale selon x et y
1205
+ xy = self.asnparray()
1206
+ self.myprop.legendy = np.max(xy[:,1])
1207
+ elif y.lower() == _('first'):
1208
+ self.myprop.legendy = self.myvertices[0].y
1209
+ elif y.lower() == _('last'):
1210
+ self.myprop.legendy = self.myvertices[-1].y
1211
+ else:
1212
+ self.myprop.legendy = float(y)
1213
+ elif isinstance(y, float):
1214
+ self.myprop.legendy = y
1215
+
1216
+ self.myprop.update_myprops()
1217
+
1218
+ @property
1219
+ def closed(self) -> bool:
1220
+ return self.myprop.closed
1221
+
1222
+ @closed.setter
1223
+ def closed(self, value:bool):
1224
+ self.myprop.closed = value
1225
+ if self.myprop.myprops is not None:
1226
+ self.myprop.myprops.Populate()
1227
+
1175
1228
  def set_cache(self):
1176
1229
  """ Set the cache for the vertices """
1177
1230
 
@@ -1723,7 +1776,12 @@ class vector:
1723
1776
 
1724
1777
  if is_open:
1725
1778
  self.add_vertex(self.myvertices[0])
1726
- self.closed=True
1779
+ self.closed=True
1780
+
1781
+ def force_to_close(self):
1782
+ """ Force the vector to be closed """
1783
+
1784
+ self.close_force()
1727
1785
 
1728
1786
  def _nblines(self):
1729
1787
  """
@@ -1838,15 +1896,21 @@ class vector:
1838
1896
 
1839
1897
  return len(not_in_use) > 0
1840
1898
 
1841
- def get_subpolygons(self):
1899
+ def get_subpolygons(self) -> list[list[wolfvertex]]:
1842
1900
  """
1843
1901
  Return a list of polygons from the vector
1844
1902
 
1845
1903
  If the vector has no interior, the list contains the whole vector as a polygon
1846
1904
  """
1847
1905
 
1906
+ if self.nbvertices == 0:
1907
+ return []
1908
+
1848
1909
  if self.myprop.filled:
1849
- return [self.myvertices]
1910
+ if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
1911
+ return [self.myvertices + [self.myvertices[0]]]
1912
+ else:
1913
+ return [self.myvertices]
1850
1914
 
1851
1915
  else:
1852
1916
  if self.has_interior:
@@ -1870,7 +1934,10 @@ class vector:
1870
1934
 
1871
1935
  return alls
1872
1936
  else:
1873
- return [self.myvertices]
1937
+ if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
1938
+ return [self.myvertices + [self.myvertices[0]]]
1939
+ else:
1940
+ return [self.myvertices]
1874
1941
 
1875
1942
  def plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None):
1876
1943
  """
@@ -2991,6 +3058,45 @@ class vector:
2991
3058
 
2992
3059
  return cloud_inside, cloud_outside
2993
3060
 
3061
+
3062
+ def check_if_closed(self) -> bool:
3063
+ """
3064
+ Check if the vector is closed
3065
+ """
3066
+
3067
+ return not self.check_if_open()
3068
+
3069
+
3070
+ def check_if_open(self) -> bool:
3071
+ """ Check if the vector is open """
3072
+
3073
+ is_open = not((self.myvertices[-1] is self.myvertices[0]) or \
3074
+ (self.myvertices[-1].x==self.myvertices[0].x and \
3075
+ self.myvertices[-1].y==self.myvertices[0].y))
3076
+
3077
+ if not self.is2D :
3078
+ is_open = is_open or self.myvertices[-1].z!=self.myvertices[0].z
3079
+
3080
+ self.closed = not is_open
3081
+
3082
+ return is_open
3083
+
3084
+ @property
3085
+ def surface(self):
3086
+ """
3087
+ Compute the surface of the vector
3088
+ """
3089
+
3090
+ if self.closed:
3091
+ return self.asshapely_pol().area
3092
+ else:
3093
+ return 0.
3094
+
3095
+ @property
3096
+ def area(self):
3097
+ """ Alias for surface """
3098
+ return self.surface
3099
+
2994
3100
  class zone:
2995
3101
  """
2996
3102
  Objet de gestion d'informations vectorielles
@@ -3034,7 +3140,7 @@ class zone:
3034
3140
  self.has_legend = False # indicate if at least one vector in the zone has a legend
3035
3141
  self.has_image = False # indicate if at least one vector in the zone has an image
3036
3142
 
3037
- self._start_move = None # starting point for a move
3143
+ self._move_start = None # starting point for a move
3038
3144
  self._move_step = None # step for a move
3039
3145
  self._rotation_center = None # center of rotation
3040
3146
  self._rotation_step = None # step for rotation
@@ -3072,6 +3178,27 @@ class zone:
3072
3178
  # Object can be created from a shapely object
3073
3179
  self.import_shapelyobj(fromshapely)
3074
3180
 
3181
+ def set_legend_text(self, text:str):
3182
+ """
3183
+ Set the legend text for the zone
3184
+ """
3185
+
3186
+ for curvect in self.myvectors:
3187
+ curvect.set_legend_text(text)
3188
+
3189
+ def set_legend_position(self, x, y):
3190
+ """
3191
+ Set the legend position for the zone
3192
+ """
3193
+
3194
+ for curvect in self.myvectors:
3195
+ curvect.set_legend_position(x, y)
3196
+
3197
+ @property
3198
+ def area(self):
3199
+ """ Compute the area of the zone """
3200
+ return sum([curvec.surface for curvec in self.myvectors])
3201
+
3075
3202
  def set_cache(self):
3076
3203
  """
3077
3204
  Set the cache for the zone and all its vectors
@@ -3086,7 +3213,7 @@ class zone:
3086
3213
  for curvect in self.myvectors:
3087
3214
  curvect.clear_cache()
3088
3215
 
3089
- self._start_move = None
3216
+ self._move_start = None
3090
3217
  self._move_step = None
3091
3218
  self._rotation_center = None
3092
3219
  self._rotation_step = None
@@ -3436,6 +3563,11 @@ class zone:
3436
3563
 
3437
3564
  inside : True = le point est contenu ; False = le point le plus proche
3438
3565
  """
3566
+
3567
+ if self.nbvectors==0:
3568
+ logging.warning(_('No vector in zone -- {}').format(self.myname))
3569
+ return
3570
+
3439
3571
  curvect:vector
3440
3572
  self.selected_vectors.clear()
3441
3573
 
@@ -4932,7 +5064,7 @@ class Zones(wx.Frame, Element_To_Draw):
4932
5064
  self.ty=ty
4933
5065
  self.myzones=[]
4934
5066
 
4935
- self._start_move = None
5067
+ self._move_start = None
4936
5068
  self._move_step = None
4937
5069
  self._rotation_center = None
4938
5070
  self._rotation_step = None
@@ -5087,6 +5219,21 @@ class Zones(wx.Frame, Element_To_Draw):
5087
5219
  if names.count(curzone.myname)>1:
5088
5220
  curzone.myname += '_'+str(idx)
5089
5221
 
5222
+ def set_legend_text(self, text:str):
5223
+ """
5224
+ Set the legend text for the zones
5225
+ """
5226
+
5227
+ for curzone in self.myzones:
5228
+ curzone.set_legend_text(text)
5229
+
5230
+ def set_legend_position(self, x, y):
5231
+ """
5232
+ Set the legend position for the zones
5233
+ """
5234
+
5235
+ for curzone in self.myzones:
5236
+ curzone.set_legend_position(x, y)
5090
5237
 
5091
5238
  @property
5092
5239
  def nbzones(self):
@@ -7337,9 +7484,9 @@ class Zones(wx.Frame, Element_To_Draw):
7337
7484
  posx = self._myprops[('Move','Start X')]
7338
7485
  posy = self._myprops[('Move','Start Y')]
7339
7486
  if posx != 99999. and posy != 99999.:
7340
- self._start_move = (posx,posy)
7487
+ self._move_start = (posx,posy)
7341
7488
  else:
7342
- self._start_move = None
7489
+ self._move_start = None
7343
7490
 
7344
7491
  step = self._myprops[('Move','Step [m]')]
7345
7492
  if step != 99999.:
@@ -7408,9 +7555,9 @@ class Zones(wx.Frame, Element_To_Draw):
7408
7555
 
7409
7556
  self._myprops['Rotation', 'Angle [degree]'] = 0.
7410
7557
 
7411
- if self._start_move is not None:
7412
- self._myprops[('Move', 'Start X')] = self._start_move[0]
7413
- self._myprops[('Move', 'Start Y')] = self._start_move[1]
7558
+ if self._move_start is not None:
7559
+ self._myprops[('Move', 'Start X')] = self._move_start[0]
7560
+ self._myprops[('Move', 'Start Y')] = self._move_start[1]
7414
7561
  else:
7415
7562
  self._myprops[('Move', 'Start X')] = 99999.
7416
7563
  self._myprops[('Move', 'Start Y')] = 99999.