wolfhece 2.1.127__py3-none-any.whl → 2.1.129__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 +52 -3
- wolfhece/PyPalette.py +36 -0
- wolfhece/PyParams.py +7 -3
- wolfhece/PyVertexvectors.py +579 -70
- wolfhece/apps/version.py +1 -1
- wolfhece/coupling/hydrology_2d.py +295 -192
- wolfhece/eikonal.py +13 -3
- wolfhece/hydrology/Catchment.py +153 -52
- wolfhece/hydrology/Comparison.py +29 -25
- wolfhece/hydrology/Optimisation.py +309 -178
- wolfhece/hydrology/PostProcessHydrology.py +6 -3
- wolfhece/hydrology/PyWatershed.py +93 -93
- wolfhece/hydrology/RetentionBasin.py +21 -14
- wolfhece/hydrology/SubBasin.py +128 -12
- wolfhece/hydrology/constant.py +3 -0
- wolfhece/hydrology/cst_exchanges.py +364 -38
- wolfhece/hydrology/plot_hydrology.py +32 -16
- wolfhece/hydrology/read.py +16 -6
- wolfhece/lagrange_multiplier.py +205 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/math_parser/calculator.py +1 -0
- wolfhece/pybridges.py +2 -2
- wolfhece/pypolygons_scen.py +2 -2
- wolfhece/radar/wolfradar.py +75 -22
- wolfhece/shapes/__init__.py +0 -0
- wolfhece/shapes/circle.py +335 -0
- wolfhece/wolf_array.py +834 -40
- wolfhece/wolfresults_2D.py +204 -13
- {wolfhece-2.1.127.dist-info → wolfhece-2.1.129.dist-info}/METADATA +5 -5
- {wolfhece-2.1.127.dist-info → wolfhece-2.1.129.dist-info}/RECORD +33 -30
- {wolfhece-2.1.127.dist-info → wolfhece-2.1.129.dist-info}/WHEEL +1 -1
- {wolfhece-2.1.127.dist-info → wolfhece-2.1.129.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.127.dist-info → wolfhece-2.1.129.dist-info}/top_level.txt +0 -0
wolfhece/PyVertexvectors.py
CHANGED
@@ -25,6 +25,9 @@ from scipy.interpolate import interp1d
|
|
25
25
|
import matplotlib.pyplot as plt
|
26
26
|
from matplotlib.axes import Axes
|
27
27
|
from matplotlib.figure import Figure
|
28
|
+
from matplotlib import cm
|
29
|
+
from matplotlib.colors import Colormap
|
30
|
+
|
28
31
|
import struct
|
29
32
|
import pyvista as pv
|
30
33
|
from typing import Union, Literal
|
@@ -36,7 +39,7 @@ import io
|
|
36
39
|
from typing import Union, Literal
|
37
40
|
from pathlib import Path
|
38
41
|
import triangle
|
39
|
-
|
42
|
+
from concurrent.futures import ThreadPoolExecutor, wait
|
40
43
|
|
41
44
|
|
42
45
|
from .wolf_texture import genericImagetexture
|
@@ -47,6 +50,7 @@ from .PyParams import Wolf_Param, Type_Param, new_json
|
|
47
50
|
from .wolf_texture import Text_Image_Texture,Text_Infos
|
48
51
|
from .drawing_obj import Element_To_Draw
|
49
52
|
from .matplotlib_fig import Matplotlib_Figure as MplFig
|
53
|
+
from .PyPalette import wolfpalette
|
50
54
|
|
51
55
|
class Triangulation(Element_To_Draw):
|
52
56
|
def __init__(self, fn='', pts=[], tri=[], idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
|
@@ -581,12 +585,53 @@ class vectorproperties:
|
|
581
585
|
|
582
586
|
self.used=True
|
583
587
|
|
588
|
+
self._values = {}
|
589
|
+
|
584
590
|
# FIXME : to be changed
|
585
591
|
# if self.parent is not None:
|
586
592
|
# self.closed = self.parent.closed
|
587
593
|
|
588
594
|
self.init_extra()
|
589
595
|
|
596
|
+
def __getitem__(self, key:str) -> Union[int,float,bool,str]:
|
597
|
+
""" Get a value """
|
598
|
+
if key in self._values:
|
599
|
+
return self._values[key]
|
600
|
+
else:
|
601
|
+
return None
|
602
|
+
|
603
|
+
def __setitem__(self, key:str, value:Union[int,float,bool,str]):
|
604
|
+
""" Set a value """
|
605
|
+
self._values[key] = value
|
606
|
+
|
607
|
+
def set_color_from_value(self, key:str, cmap:wolfpalette | str | Colormap | cm.ScalarMappable, vmin:float= 0., vmax:float= 1.):
|
608
|
+
""" Set the color from a value """
|
609
|
+
|
610
|
+
if key in self._values:
|
611
|
+
val = self._values[key]
|
612
|
+
|
613
|
+
# Test if val is a numeric value or can be converted to a numeric value
|
614
|
+
try:
|
615
|
+
val = float(val)
|
616
|
+
except:
|
617
|
+
logging.warning('Value {} is not a numeric value'.format(val))
|
618
|
+
self.color = 0
|
619
|
+
return
|
620
|
+
|
621
|
+
val_adim = (val-vmin)/(vmax-vmin)
|
622
|
+
|
623
|
+
if isinstance(cmap, wolfpalette):
|
624
|
+
self.color = getIfromRGB(cmap.get_rgba_oneval(val))
|
625
|
+
elif isinstance(cmap, str):
|
626
|
+
cmap = cm.get_cmap(cmap)
|
627
|
+
self.color = getIfromRGB(cmap(val_adim, bytes=True))
|
628
|
+
elif isinstance(cmap, Colormap):
|
629
|
+
self.color = getIfromRGB(cmap(val_adim, bytes=True))
|
630
|
+
elif isinstance(cmap, cm.ScalarMappable):
|
631
|
+
self.color = getIfromRGB(cmap.to_rgba(val, bytes=True)[:3])
|
632
|
+
else:
|
633
|
+
self.color = 0
|
634
|
+
|
590
635
|
def init_extra(self):
|
591
636
|
"""
|
592
637
|
Init extra properties --> not compatible with VB6, Fortran codes
|
@@ -1124,8 +1169,8 @@ class vector:
|
|
1124
1169
|
self._rotation_center = None
|
1125
1170
|
self._rotation_step = None
|
1126
1171
|
|
1127
|
-
self.
|
1128
|
-
self.
|
1172
|
+
self._linestring = None
|
1173
|
+
self._polygon = None
|
1129
1174
|
|
1130
1175
|
# Utile surtout pour les sections en travers
|
1131
1176
|
self.zdatum = 0.
|
@@ -1139,6 +1184,56 @@ class vector:
|
|
1139
1184
|
if fromnumpy is not None:
|
1140
1185
|
self.add_vertices_from_array(fromnumpy)
|
1141
1186
|
|
1187
|
+
def add_value(self, key:str, value:Union[int,float,bool,str]):
|
1188
|
+
""" Add a value to the properties """
|
1189
|
+
self.myprop[key] = value
|
1190
|
+
|
1191
|
+
def get_value(self, key:str) -> Union[int,float,bool,str]:
|
1192
|
+
""" Get a value from the properties """
|
1193
|
+
return self.myprop[key]
|
1194
|
+
|
1195
|
+
def set_color_from_value(self, key:str, cmap:wolfpalette | Colormap | cm.ScalarMappable, vmin:float= 0., vmax:float= 1.):
|
1196
|
+
""" Set the color from a value """
|
1197
|
+
self.myprop.set_color_from_value(key, cmap, vmin, vmax)
|
1198
|
+
|
1199
|
+
def set_alpha(self, alpha:int):
|
1200
|
+
""" Set the alpha value """
|
1201
|
+
self.myprop.alpha = alpha
|
1202
|
+
self.myprop.transparent = alpha != 0
|
1203
|
+
|
1204
|
+
def set_filled(self, filled:bool):
|
1205
|
+
""" Set the filled value """
|
1206
|
+
self.myprop.filled = filled
|
1207
|
+
|
1208
|
+
@property
|
1209
|
+
def polygon(self) -> Polygon:
|
1210
|
+
""" Return the polygon """
|
1211
|
+
|
1212
|
+
if self._polygon is None:
|
1213
|
+
self.prepare_shapely(linestring=False)
|
1214
|
+
return self._polygon
|
1215
|
+
|
1216
|
+
@property
|
1217
|
+
def linestring(self) -> LineString:
|
1218
|
+
""" Return the linestring """
|
1219
|
+
|
1220
|
+
if self._linestring is None:
|
1221
|
+
self.prepare_shapely(polygon=False)
|
1222
|
+
return self._linestring
|
1223
|
+
|
1224
|
+
def buffer(self, distance:float, resolution:int=16, inplace:bool=True) -> "vector":
|
1225
|
+
""" Create a new vector buffered around the vector """
|
1226
|
+
|
1227
|
+
poly = self.polygon
|
1228
|
+
buffered = poly.buffer(distance, resolution=resolution)
|
1229
|
+
|
1230
|
+
if inplace:
|
1231
|
+
self.import_shapelyobj(buffered)
|
1232
|
+
return self
|
1233
|
+
else:
|
1234
|
+
newvec = vector(fromshapely=buffered, name=self.myname)
|
1235
|
+
return newvec
|
1236
|
+
|
1142
1237
|
def set_legend_text(self, text:str):
|
1143
1238
|
""" Set the legend text """
|
1144
1239
|
|
@@ -1165,6 +1260,14 @@ class vector:
|
|
1165
1260
|
|
1166
1261
|
self.myprop.update_myprops()
|
1167
1262
|
|
1263
|
+
def set_legend_text_from_value(self, key:str, visible:bool=True):
|
1264
|
+
""" Set the legend text from a value """
|
1265
|
+
|
1266
|
+
if key in self.myprop._values:
|
1267
|
+
self.myprop.legendtext = str(self.myprop._values[key])
|
1268
|
+
self.myprop.legendvisible = visible
|
1269
|
+
self.myprop.update_myprops()
|
1270
|
+
|
1168
1271
|
def set_legend_position(self, x:str | float, y:str | float):
|
1169
1272
|
""" Set the legend position """
|
1170
1273
|
|
@@ -1392,14 +1495,16 @@ class vector:
|
|
1392
1495
|
def import_shapelyobj(self, obj):
|
1393
1496
|
""" Importation d'un objet shapely """
|
1394
1497
|
|
1498
|
+
self.myvertices = []
|
1395
1499
|
if isinstance(obj, LineString):
|
1396
|
-
|
1397
|
-
|
1398
|
-
self.add_vertices_from_array(
|
1500
|
+
self.is2D = not obj.has_z
|
1501
|
+
xyz = np.array(obj.coords)
|
1502
|
+
self.add_vertices_from_array(xyz)
|
1503
|
+
|
1399
1504
|
elif isinstance(obj, Polygon):
|
1400
|
-
|
1401
|
-
|
1402
|
-
self.add_vertices_from_array(
|
1505
|
+
self.is2D = not obj.has_z
|
1506
|
+
xyz = np.array(obj.exterior.coords)
|
1507
|
+
self.add_vertices_from_array(xyz)
|
1403
1508
|
self.close_force()
|
1404
1509
|
else:
|
1405
1510
|
logging.warning(_('Object type {} not supported -- Update "import_shapelyobj"').format(type(obj)))
|
@@ -1513,7 +1618,7 @@ class vector:
|
|
1513
1618
|
if self.nbvertices==0:
|
1514
1619
|
return False
|
1515
1620
|
|
1516
|
-
poly = self.
|
1621
|
+
poly = self.polygon
|
1517
1622
|
inside2 = poly.contains(Point([x,y]))
|
1518
1623
|
return inside2
|
1519
1624
|
|
@@ -1580,7 +1685,7 @@ class vector:
|
|
1580
1685
|
xyz[:,2]+=self.zdatum
|
1581
1686
|
return xyz
|
1582
1687
|
|
1583
|
-
def prepare_shapely(self, prepare_shapely:bool = True):
|
1688
|
+
def prepare_shapely(self, prepare_shapely:bool = True, linestring:bool = True, polygon:bool = True):
|
1584
1689
|
"""
|
1585
1690
|
Conversion Linestring Shapely et rétention de l'objet afin d'éviter de multiples appel
|
1586
1691
|
par ex. dans une boucle.
|
@@ -1588,17 +1693,23 @@ class vector:
|
|
1588
1693
|
:param prepare_shapely: Préparation de l'objet Shapely pour une utilisation optimisée
|
1589
1694
|
- True par défaut
|
1590
1695
|
- see https://shapely.readthedocs.io/en/stable/reference/shapely.prepare.html
|
1696
|
+
:param linestring: Préparation du linestring
|
1697
|
+
:param polygon: Préparation du polygon
|
1591
1698
|
|
1592
1699
|
"""
|
1593
1700
|
|
1594
1701
|
self.reset_linestring()
|
1595
1702
|
|
1596
|
-
|
1597
|
-
|
1703
|
+
if linestring:
|
1704
|
+
self._linestring = self.asshapely_ls()
|
1705
|
+
if polygon:
|
1706
|
+
self._polygon = self.asshapely_pol()
|
1598
1707
|
|
1599
1708
|
if prepare_shapely:
|
1600
|
-
|
1601
|
-
|
1709
|
+
if linestring:
|
1710
|
+
prepare(self._linestring)
|
1711
|
+
if polygon:
|
1712
|
+
prepare(self._polygon)
|
1602
1713
|
|
1603
1714
|
|
1604
1715
|
def projectontrace(self, trace):
|
@@ -1663,6 +1774,8 @@ class vector:
|
|
1663
1774
|
def intersection(self, vec2:"vector" = None, eval_dist=False,norm=False, force_single=False):
|
1664
1775
|
"""
|
1665
1776
|
Calcul de l'intersection avec un autre vecteur
|
1777
|
+
Attention, le shapely du vecteur vec2 et self sont automatiquement préparés. Si modifié après intersection, il faut penser à les re-préparer
|
1778
|
+
avec self.reset_linestring() ou self.prepare_shapely(). Dans le cas contraire, les anciens vecteurs préparés seront utilisés.
|
1666
1779
|
|
1667
1780
|
Return :
|
1668
1781
|
- le point d'intersection
|
@@ -1670,8 +1783,13 @@ class vector:
|
|
1670
1783
|
|
1671
1784
|
Utilisation de Shapely
|
1672
1785
|
"""
|
1673
|
-
|
1674
|
-
|
1786
|
+
|
1787
|
+
# check if the vectors are closed
|
1788
|
+
ls1 = self.linestring
|
1789
|
+
ls2 = vec2.linestring
|
1790
|
+
# ls1 = self.asshapely_ls() if self._linestring is None else self._linestring
|
1791
|
+
# ls2 = vec2.asshapely_ls() if vec2._linestring is None else vec2._linestring
|
1792
|
+
|
1675
1793
|
|
1676
1794
|
myinter = ls1.intersection(ls2)
|
1677
1795
|
|
@@ -1702,15 +1820,15 @@ class vector:
|
|
1702
1820
|
def reset_linestring(self):
|
1703
1821
|
"""Remise à zéro de l'objet Shapely"""
|
1704
1822
|
|
1705
|
-
if self.
|
1706
|
-
if is_prepared(self.
|
1707
|
-
destroy_prepared(self.
|
1708
|
-
self.
|
1823
|
+
if self._linestring is not None:
|
1824
|
+
if is_prepared(self._linestring):
|
1825
|
+
destroy_prepared(self._linestring)
|
1826
|
+
self._linestring=None
|
1709
1827
|
|
1710
|
-
if self.
|
1711
|
-
if is_prepared(self.
|
1712
|
-
destroy_prepared(self.
|
1713
|
-
self.
|
1828
|
+
if self._polygon is not None:
|
1829
|
+
if is_prepared(self._polygon):
|
1830
|
+
destroy_prepared(self._polygon)
|
1831
|
+
self._polygon=None
|
1714
1832
|
|
1715
1833
|
def add_vertex(self,addedvert: Union[list[wolfvertex], wolfvertex]):
|
1716
1834
|
"""
|
@@ -1980,7 +2098,7 @@ class vector:
|
|
1980
2098
|
|
1981
2099
|
if self.myprop.filled:
|
1982
2100
|
|
1983
|
-
ls = self.
|
2101
|
+
ls = self.polygon
|
1984
2102
|
|
1985
2103
|
if False:
|
1986
2104
|
|
@@ -2059,6 +2177,20 @@ class vector:
|
|
2059
2177
|
else:
|
2060
2178
|
self.textimage = None
|
2061
2179
|
|
2180
|
+
def plot_legend_mpl(self, ax:plt.Axes):
|
2181
|
+
"""
|
2182
|
+
Plot Legend on Matplotlib Axes
|
2183
|
+
"""
|
2184
|
+
|
2185
|
+
if self.myprop.legendvisible and self.myprop.used:
|
2186
|
+
|
2187
|
+
ax.text(self.myprop.legendx, self.myprop.legendy, self.myprop.legendtext,
|
2188
|
+
fontsize=self.myprop.legendfontsize,
|
2189
|
+
fontname=self.myprop.legendfontname,
|
2190
|
+
color=getRGBfromI(self.myprop.legendcolor),
|
2191
|
+
rotation=self.myprop.legendorientation,
|
2192
|
+
ha='center', va='center')
|
2193
|
+
|
2062
2194
|
def plot_image(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None):
|
2063
2195
|
""" plot attached images """
|
2064
2196
|
|
@@ -2076,6 +2208,28 @@ class vector:
|
|
2076
2208
|
else:
|
2077
2209
|
logging.warning(_('No image texture available for plot'))
|
2078
2210
|
|
2211
|
+
def plot_matplotlib(self, ax:plt.Axes):
|
2212
|
+
"""
|
2213
|
+
Plot Matplotlib
|
2214
|
+
"""
|
2215
|
+
|
2216
|
+
if self.myprop.used:
|
2217
|
+
|
2218
|
+
if self.myprop.filled:
|
2219
|
+
rgb=getRGBfromI(self.myprop.color)
|
2220
|
+
if self.myprop.transparent:
|
2221
|
+
ax.fill([curvert.x for curvert in self.myvertices], [curvert.y for curvert in self.myvertices], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.,self.myprop.alpha))
|
2222
|
+
else:
|
2223
|
+
ax.fill([curvert.x for curvert in self.myvertices], [curvert.y for curvert in self.myvertices], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.))
|
2224
|
+
else:
|
2225
|
+
rgb=getRGBfromI(self.myprop.color)
|
2226
|
+
if self.myprop.transparent:
|
2227
|
+
ax.plot([curvert.x for curvert in self.myvertices], [curvert.y for curvert in self.myvertices], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.,self.myprop.alpha), linewidth=self.myprop.width)
|
2228
|
+
else:
|
2229
|
+
ax.plot([curvert.x for curvert in self.myvertices], [curvert.y for curvert in self.myvertices], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.), linewidth=self.myprop.width)
|
2230
|
+
|
2231
|
+
self.plot_legend_mpl(ax)
|
2232
|
+
|
2079
2233
|
def _get_textfont(self):
|
2080
2234
|
""" Retunr a 'Text_Infos' instance for the legend """
|
2081
2235
|
|
@@ -2177,7 +2331,7 @@ class vector:
|
|
2177
2331
|
while k<self.nbvertices:
|
2178
2332
|
self.myvertices.pop(k)
|
2179
2333
|
|
2180
|
-
if self.
|
2334
|
+
if self._linestring is not None or self._polygon is not None:
|
2181
2335
|
self.prepare_shapely()
|
2182
2336
|
|
2183
2337
|
self._reset_listogl()
|
@@ -2783,6 +2937,11 @@ class vector:
|
|
2783
2937
|
copied_vector = vector(name=name)
|
2784
2938
|
|
2785
2939
|
copied_vector.myvertices = copy.deepcopy(self.myvertices)
|
2940
|
+
# FIXME : deepcopy of properties is not working
|
2941
|
+
# copied_vector.myprop = copy.deepcopy(self.myprop)
|
2942
|
+
copied_vector.zdatum = self.zdatum
|
2943
|
+
copied_vector.closed = self.closed
|
2944
|
+
copied_vector.add_zdatum = self.add_zdatum
|
2786
2945
|
|
2787
2946
|
return copied_vector
|
2788
2947
|
|
@@ -2793,19 +2952,35 @@ class vector:
|
|
2793
2952
|
|
2794
2953
|
return self.deepcopy_vector(name, parentzone)
|
2795
2954
|
|
2955
|
+
@property
|
2956
|
+
def centroid(self):
|
2957
|
+
"""
|
2958
|
+
Return the centroid of the vector
|
2959
|
+
"""
|
2960
|
+
|
2961
|
+
return self.polygon.centroid
|
2962
|
+
|
2796
2963
|
def set_legend_to_centroid(self, text:str='', visible:bool=True):
|
2797
2964
|
"""
|
2798
2965
|
Positionne la légende au centre du vecteur
|
2799
2966
|
"""
|
2800
2967
|
self.myprop.legendvisible = visible
|
2801
2968
|
|
2802
|
-
|
2803
|
-
centroid = ls.centroid
|
2969
|
+
centroid = self.centroid
|
2804
2970
|
|
2805
2971
|
self.myprop.legendx = centroid.x
|
2806
2972
|
self.myprop.legendy = centroid.y
|
2807
2973
|
self.myprop.legendtext = text if text else self.myname
|
2808
2974
|
|
2975
|
+
def set_legend_position_to_centroid(self):
|
2976
|
+
"""
|
2977
|
+
Positionne la légende au centre du vecteur
|
2978
|
+
"""
|
2979
|
+
|
2980
|
+
centroid = self.centroid
|
2981
|
+
self.myprop.legendx = centroid.x
|
2982
|
+
self.myprop.legendy = centroid.y
|
2983
|
+
|
2809
2984
|
def set_z(self, new_z:np.ndarray):
|
2810
2985
|
""" Set the z values of the vertices """
|
2811
2986
|
self.z = new_z
|
@@ -3111,7 +3286,6 @@ class vector:
|
|
3111
3286
|
if self.parentzone is not None:
|
3112
3287
|
self.parentzone.reset_listogl()
|
3113
3288
|
|
3114
|
-
|
3115
3289
|
def select_points_inside(self, xy:cloud_vertices | np.ndarray):
|
3116
3290
|
""" Select the points inside a polygon
|
3117
3291
|
|
@@ -3119,7 +3293,7 @@ class vector:
|
|
3119
3293
|
:return: list of boolean
|
3120
3294
|
"""
|
3121
3295
|
|
3122
|
-
self.prepare_shapely()
|
3296
|
+
self.prepare_shapely(True)
|
3123
3297
|
|
3124
3298
|
if isinstance(xy, cloud_vertices):
|
3125
3299
|
xy = xy.get_xyz()[:,0:2]
|
@@ -3176,7 +3350,7 @@ class vector:
|
|
3176
3350
|
"""
|
3177
3351
|
|
3178
3352
|
if self.closed:
|
3179
|
-
return self.
|
3353
|
+
return self.polygon.area
|
3180
3354
|
else:
|
3181
3355
|
return 0.
|
3182
3356
|
|
@@ -3266,6 +3440,62 @@ class zone:
|
|
3266
3440
|
# Object can be created from a shapely object
|
3267
3441
|
self.import_shapelyobj(fromshapely)
|
3268
3442
|
|
3443
|
+
def add_values(self, key:str, values:np.ndarray):
|
3444
|
+
""" add values to the zone """
|
3445
|
+
|
3446
|
+
if self.nbvectors != values.shape[0]:
|
3447
|
+
logging.warning(_('Number of vectors and values do not match'))
|
3448
|
+
return
|
3449
|
+
|
3450
|
+
for curvec, curval in zip(self.myvectors, values):
|
3451
|
+
curvec.add_value(key, curval)
|
3452
|
+
|
3453
|
+
def get_values(self, key:str) -> np.ndarray:
|
3454
|
+
""" get values from the zone """
|
3455
|
+
|
3456
|
+
return np.array([curvec.get_value(key) for curvec in self.myvectors])
|
3457
|
+
|
3458
|
+
def set_colors_from_value(self, key:str, cmap:wolfpalette | Colormap | cm.ScalarMappable, vmin:float= 0., vmax:float= 1.):
|
3459
|
+
""" Set the colors for the zone """
|
3460
|
+
|
3461
|
+
for curvec in self.myvectors:
|
3462
|
+
curvec.set_color_from_value(key, cmap, vmin, vmax)
|
3463
|
+
|
3464
|
+
def set_alpha(self, alpha:int):
|
3465
|
+
""" Set the alpha for the zone """
|
3466
|
+
|
3467
|
+
for curvec in self.myvectors:
|
3468
|
+
curvec.set_alpha(alpha)
|
3469
|
+
|
3470
|
+
def set_filled(self, filled:bool):
|
3471
|
+
""" Set the filled for the zone """
|
3472
|
+
|
3473
|
+
for curvec in self.myvectors:
|
3474
|
+
curvec.set_filled(filled)
|
3475
|
+
|
3476
|
+
def check_if_open(self):
|
3477
|
+
""" Check if the vectors in the zone are open """
|
3478
|
+
for curvec in self.myvectors:
|
3479
|
+
curvec.check_if_open()
|
3480
|
+
|
3481
|
+
def buffer(self, distance:float, resolution:int=16, inplace:bool = False) -> 'zone':
|
3482
|
+
""" Create a new zone with a buffer around each vector """
|
3483
|
+
|
3484
|
+
if inplace:
|
3485
|
+
newzone = self
|
3486
|
+
else:
|
3487
|
+
newzone = zone(name=self.myname)
|
3488
|
+
|
3489
|
+
retmap = list(map(lambda x: x.buffer(distance, resolution, inplace), self.myvectors))
|
3490
|
+
|
3491
|
+
if inplace:
|
3492
|
+
return self
|
3493
|
+
|
3494
|
+
for curvec in retmap:
|
3495
|
+
newzone.add_vector(curvec, forceparent=True)
|
3496
|
+
|
3497
|
+
return newzone
|
3498
|
+
|
3269
3499
|
def set_legend_text(self, text:str):
|
3270
3500
|
"""
|
3271
3501
|
Set the legend text for the zone
|
@@ -3274,6 +3504,14 @@ class zone:
|
|
3274
3504
|
for curvect in self.myvectors:
|
3275
3505
|
curvect.set_legend_text(text)
|
3276
3506
|
|
3507
|
+
def set_legend_text_from_values(self, key:str):
|
3508
|
+
"""
|
3509
|
+
Set the legend text for the zone from a value
|
3510
|
+
"""
|
3511
|
+
|
3512
|
+
for curvect in self.myvectors:
|
3513
|
+
curvect.set_legend_text_from_value(key)
|
3514
|
+
|
3277
3515
|
def set_legend_position(self, x, y):
|
3278
3516
|
"""
|
3279
3517
|
Set the legend position for the zone
|
@@ -3285,7 +3523,12 @@ class zone:
|
|
3285
3523
|
@property
|
3286
3524
|
def area(self):
|
3287
3525
|
""" Compute the area of the zone """
|
3288
|
-
return sum(
|
3526
|
+
return sum(self.areas)
|
3527
|
+
|
3528
|
+
@property
|
3529
|
+
def areas(self):
|
3530
|
+
""" List of all areas """
|
3531
|
+
return [curvec.surface for curvec in self.myvectors]
|
3289
3532
|
|
3290
3533
|
def set_cache(self):
|
3291
3534
|
"""
|
@@ -3644,6 +3887,16 @@ class zone:
|
|
3644
3887
|
for curvect in self.myvectors:
|
3645
3888
|
curvect.plot_image(sx, sy, xmin, ymin, xmax, ymax, size)
|
3646
3889
|
|
3890
|
+
def plot_matplotlib(self, ax:plt.Axes):
|
3891
|
+
"""
|
3892
|
+
Plot the zone using matplotlib
|
3893
|
+
|
3894
|
+
:param ax: matplotlib Axes
|
3895
|
+
:param kwargs: additional arguments
|
3896
|
+
"""
|
3897
|
+
|
3898
|
+
for curvect in self.myvectors:
|
3899
|
+
curvect.plot_matplotlib(ax)
|
3647
3900
|
|
3648
3901
|
def select_vectors_from_point(self,x:float,y:float,inside=True):
|
3649
3902
|
"""
|
@@ -5294,11 +5547,11 @@ class zone:
|
|
5294
5547
|
|
5295
5548
|
def set_legend_to_centroid(self):
|
5296
5549
|
"""
|
5297
|
-
Set the legend to the centroid of the
|
5550
|
+
Set the legend to the centroid of the vectors
|
5298
5551
|
"""
|
5299
5552
|
|
5300
5553
|
for curvec in self.myvectors:
|
5301
|
-
curvec.
|
5554
|
+
curvec.set_legend_position_to_centroid()
|
5302
5555
|
|
5303
5556
|
class Zones(wx.Frame, Element_To_Draw):
|
5304
5557
|
"""
|
@@ -5413,24 +5666,29 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5413
5666
|
self._rotation_center = None
|
5414
5667
|
self._rotation_step = None
|
5415
5668
|
|
5669
|
+
only_firstlast = False # By default, we are using all vertices
|
5416
5670
|
if self.filename!='':
|
5417
5671
|
# lecture du fichier
|
5418
5672
|
|
5419
5673
|
if self.filename.endswith('.dxf'):
|
5420
5674
|
self.is2D=False
|
5421
5675
|
self.import_dxf(self.filename)
|
5676
|
+
only_firstlast = True # We limit the number of vertices to the first and last ones to accelerate the process
|
5422
5677
|
|
5423
5678
|
elif self.filename.endswith('.shp'):
|
5424
5679
|
self.is2D=False
|
5425
5680
|
self.import_shapefile(self.filename, bbox=bbox)
|
5681
|
+
only_firstlast = True # We limit the number of vertices to the first and last ones to accelerate the process
|
5426
5682
|
|
5427
5683
|
elif self.filename.endswith('.gpkg'):
|
5428
5684
|
self.is2D=False
|
5429
5685
|
self.import_gpkg(self.filename, bbox=bbox)
|
5686
|
+
only_firstlast = True # We limit the number of vertices to the first and last ones to accelerate the process
|
5430
5687
|
|
5431
5688
|
elif Path(filename).is_dir() and self.filename.endswith('.gdb'):
|
5432
5689
|
self.is2D=False
|
5433
5690
|
self.import_gdb(self.filename, bbox=bbox)
|
5691
|
+
only_firstlast = True # We limit the number of vertices to the first and last ones to accelerate the process
|
5434
5692
|
|
5435
5693
|
elif self.filename.endswith('.vec') or self.filename.endswith('.vecz'):
|
5436
5694
|
|
@@ -5476,13 +5734,149 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5476
5734
|
logging.warning(_('Error while reading extra properties of {}'.format(self.filename)))
|
5477
5735
|
|
5478
5736
|
if find_minmax:
|
5479
|
-
|
5737
|
+
logging.info(_('Finding min and max values'))
|
5738
|
+
self.find_minmax(True, only_firstlast)
|
5480
5739
|
|
5481
5740
|
if colors is not None:
|
5482
5741
|
self.colorize_data(colors, filled=True)
|
5483
5742
|
|
5484
5743
|
if plotted and self.has_OGLContext and not self.shared:
|
5744
|
+
logging.info(_('Preparing OpenGL lists'))
|
5485
5745
|
self.prep_listogl()
|
5746
|
+
logging.info(_('OpenGL lists ready'))
|
5747
|
+
|
5748
|
+
@property
|
5749
|
+
def mynames(self) -> list[str]:
|
5750
|
+
""" Return the names of all zones """
|
5751
|
+
|
5752
|
+
return [curzone.myname for curzone in self.myzones]
|
5753
|
+
|
5754
|
+
def add_values(self, key:str, values:np.ndarray | dict):
|
5755
|
+
"""
|
5756
|
+
Add values to the zones
|
5757
|
+
"""
|
5758
|
+
|
5759
|
+
if isinstance(values, dict):
|
5760
|
+
for k, val in values.items():
|
5761
|
+
if not isinstance(val, np.ndarray):
|
5762
|
+
val = np.asarray(val)
|
5763
|
+
|
5764
|
+
if k in self.mynames:
|
5765
|
+
self[k].add_values(key, val)
|
5766
|
+
|
5767
|
+
elif isinstance(values, np.ndarray):
|
5768
|
+
if values.shape[0] != self.nbzones:
|
5769
|
+
logging.warning(_('Number of values does not match the number of zones'))
|
5770
|
+
return
|
5771
|
+
|
5772
|
+
for idx, curzone in enumerate(self.myzones):
|
5773
|
+
curzone.add_values(key, values[idx])
|
5774
|
+
|
5775
|
+
def get_values(self, key:str) -> np.ndarray:
|
5776
|
+
"""
|
5777
|
+
Get values from the zones
|
5778
|
+
"""
|
5779
|
+
|
5780
|
+
return np.asarray([curzone.get_values(key) for curzone in self.myzones])
|
5781
|
+
|
5782
|
+
def set_colors_from_value(self, key:str, cmap:wolfpalette | str | Colormap | cm.ScalarMappable, vmin:float = 0., vmax:float = 1.):
|
5783
|
+
"""
|
5784
|
+
Set colors to the zones
|
5785
|
+
"""
|
5786
|
+
|
5787
|
+
if isinstance(cmap, str):
|
5788
|
+
cmap = cm.get_cmap(cmap)
|
5789
|
+
|
5790
|
+
for curzone in self.myzones:
|
5791
|
+
curzone.set_colors_from_value(key, cmap, vmin, vmax)
|
5792
|
+
|
5793
|
+
def set_alpha(self, alpha:int):
|
5794
|
+
"""
|
5795
|
+
Set alpha to the zones
|
5796
|
+
"""
|
5797
|
+
|
5798
|
+
for curzone in self.myzones:
|
5799
|
+
curzone.set_alpha(alpha)
|
5800
|
+
|
5801
|
+
def set_filled(self, filled:bool):
|
5802
|
+
"""
|
5803
|
+
Set filled to the zones
|
5804
|
+
"""
|
5805
|
+
|
5806
|
+
for curzone in self.myzones:
|
5807
|
+
curzone.set_filled(filled)
|
5808
|
+
|
5809
|
+
def check_if_open(self):
|
5810
|
+
""" Check if the vectors in the zone are open """
|
5811
|
+
for curzone in self.myzones:
|
5812
|
+
curzone.check_if_open()
|
5813
|
+
|
5814
|
+
def concatenate_all_vectors(self) -> list[vector]:
|
5815
|
+
""" Concatenate all vectors in the zones """
|
5816
|
+
ret = []
|
5817
|
+
for curzone in self.myzones:
|
5818
|
+
ret.extend(curzone.myvectors)
|
5819
|
+
return ret
|
5820
|
+
|
5821
|
+
def prepare_shapely(self):
|
5822
|
+
""" Prepare shapely objects for all vectors in zones """
|
5823
|
+
allvec = self.concatenate_all_vectors()
|
5824
|
+
list(map(lambda x: x.prepare_shapely(True), allvec))
|
5825
|
+
|
5826
|
+
def filter_contains(self, others:list[vector]) -> "Zones":
|
5827
|
+
""" Create a new "Zones" instance with
|
5828
|
+
vectors in 'others' contained in the zones """
|
5829
|
+
|
5830
|
+
if isinstance(others, Zones):
|
5831
|
+
allvec = others.concatenate_all_vectors()
|
5832
|
+
elif isinstance(others, list):
|
5833
|
+
allvec = others
|
5834
|
+
else:
|
5835
|
+
logging.warning(_('Unknown type for others'))
|
5836
|
+
return None
|
5837
|
+
|
5838
|
+
centroids = [curvec.centroid for curvec in allvec]
|
5839
|
+
newzones = Zones()
|
5840
|
+
|
5841
|
+
for curzone in self.myzones:
|
5842
|
+
if curzone.nbvectors != 1:
|
5843
|
+
logging.warning(_('Zone {} has more than one vector'.format(curzone.myname)))
|
5844
|
+
continue
|
5845
|
+
|
5846
|
+
poly = curzone[0].polygon
|
5847
|
+
# element-wise comparison
|
5848
|
+
contains = list(map(lambda x: poly.contains(x), centroids))
|
5849
|
+
|
5850
|
+
newzone = zone(name=curzone.myname, parent=newzones)
|
5851
|
+
newzone.myvectors = list(map(lambda x: allvec[x], np.where(contains)[0]))
|
5852
|
+
newzones.add_zone(newzone, forceparent=True)
|
5853
|
+
|
5854
|
+
return newzones
|
5855
|
+
|
5856
|
+
@property
|
5857
|
+
def areas(self):
|
5858
|
+
""" List of areas of all zones """
|
5859
|
+
|
5860
|
+
return [curzone.areas for curzone in self.myzones]
|
5861
|
+
|
5862
|
+
def buffer(self, distance:float, resolution:int = 16, inplace:bool = True):
|
5863
|
+
""" Buffer all zones """
|
5864
|
+
|
5865
|
+
if inplace:
|
5866
|
+
newzones = self
|
5867
|
+
else:
|
5868
|
+
newzones = Zones()
|
5869
|
+
|
5870
|
+
retmap = list(map(lambda x: x.buffer(distance, resolution, inplace=inplace), self.myzones))
|
5871
|
+
|
5872
|
+
for curzone in retmap:
|
5873
|
+
newzones.add_zone(curzone, forceparent=True)
|
5874
|
+
|
5875
|
+
newzones.find_minmax(True)
|
5876
|
+
if inplace:
|
5877
|
+
return self
|
5878
|
+
|
5879
|
+
return newzones
|
5486
5880
|
|
5487
5881
|
def set_cache(self):
|
5488
5882
|
""" Set cache for all zones """
|
@@ -5571,6 +5965,22 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5571
5965
|
for curzone in self.myzones:
|
5572
5966
|
curzone.set_legend_text(text)
|
5573
5967
|
|
5968
|
+
def set_legend_text_from_values(self, key:str):
|
5969
|
+
"""
|
5970
|
+
Set the legend text for the zones from the values
|
5971
|
+
"""
|
5972
|
+
|
5973
|
+
for curzone in self.myzones:
|
5974
|
+
curzone.set_legend_text_from_values(key)
|
5975
|
+
|
5976
|
+
def set_legend_to_centroid(self):
|
5977
|
+
"""
|
5978
|
+
Set the legend to the centroid of the zones
|
5979
|
+
"""
|
5980
|
+
|
5981
|
+
for curzone in self.myzones:
|
5982
|
+
curzone.set_legend_to_centroid()
|
5983
|
+
|
5574
5984
|
def set_legend_position(self, x, y):
|
5575
5985
|
"""
|
5576
5986
|
Set the legend position for the zones
|
@@ -5583,7 +5993,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5583
5993
|
def nbzones(self):
|
5584
5994
|
return len(self.myzones)
|
5585
5995
|
|
5586
|
-
def import_shapefile(self, fn:str,
|
5996
|
+
def import_shapefile(self, fn:str,
|
5997
|
+
bbox:Polygon = None, colname:str = None):
|
5587
5998
|
"""
|
5588
5999
|
Import shapefile by using geopandas
|
5589
6000
|
|
@@ -5591,41 +6002,69 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5591
6002
|
|
5592
6003
|
"""
|
5593
6004
|
|
6005
|
+
logging.info(_('Importing shapefile {}'.format(fn)))
|
5594
6006
|
content = gpd.read_file(fn, bbox=bbox)
|
5595
6007
|
|
5596
|
-
|
5597
|
-
|
6008
|
+
self.import_GeoDataFrame(content, colname=colname)
|
6009
|
+
|
6010
|
+
def import_GeoDataFrame(self, content:gpd.GeoDataFrame,
|
6011
|
+
bbox:Polygon = None, colname:str = None):
|
6012
|
+
"""
|
6013
|
+
Import a GeoDataFrame geopandas
|
6014
|
+
|
6015
|
+
Shapefile == 1 zone
|
6016
|
+
"""
|
6017
|
+
|
6018
|
+
logging.info(_('Importing GeoDataFrame'))
|
6019
|
+
|
6020
|
+
if bbox is not None:
|
6021
|
+
# filter content
|
6022
|
+
content = content.cx[bbox.bounds[0]:bbox.bounds[2], bbox.bounds[1]:bbox.bounds[3]]
|
6023
|
+
|
6024
|
+
logging.info(_('Converting DataFrame into zones'))
|
6025
|
+
if colname is not None and colname not in content.columns:
|
6026
|
+
logging.warning(_('Column {} not found in the DataFrame'.format(colname)))
|
6027
|
+
logging.info(_('We are using the available known columns'))
|
6028
|
+
colname = ''
|
6029
|
+
|
6030
|
+
def add_zone_from_row(row):
|
6031
|
+
idx, row = row
|
6032
|
+
keys = list(row.keys())
|
6033
|
+
if colname in keys:
|
6034
|
+
name = row[colname]
|
6035
|
+
elif 'NAME' in keys:
|
5598
6036
|
name = row['NAME']
|
5599
|
-
elif 'location' in
|
6037
|
+
elif 'location' in keys:
|
5600
6038
|
name = row['location'] # tuilage gdal
|
5601
|
-
elif '
|
6039
|
+
elif 'Communes' in keys:
|
6040
|
+
name = row['Communes']
|
6041
|
+
elif 'name' in keys:
|
5602
6042
|
name = row['name']
|
5603
|
-
elif 'MAJ_NIV3T' in
|
6043
|
+
elif 'MAJ_NIV3T' in keys:
|
5604
6044
|
# WALOUS
|
5605
6045
|
name = row['MAJ_NIV3T']
|
5606
|
-
elif 'NATUR_DESC' in
|
6046
|
+
elif 'NATUR_DESC' in keys:
|
5607
6047
|
name = row['NATUR_DESC']
|
6048
|
+
elif 'mun_name_f' in keys:
|
6049
|
+
name = row['mun_name_f'].replace('[','').replace(']','').replace("'",'')
|
6050
|
+
elif 'mun_name_fr' in keys:
|
6051
|
+
name = row['mun_name_fr']
|
5608
6052
|
else:
|
5609
6053
|
name = str(idx)
|
5610
6054
|
|
5611
6055
|
poly = row['geometry']
|
5612
6056
|
|
5613
6057
|
newzone = zone(name=name, parent = self, fromshapely = poly)
|
5614
|
-
|
5615
|
-
|
5616
|
-
def export_to_shapefile(self, filename:str):
|
5617
|
-
"""
|
5618
|
-
Export to shapefile.
|
6058
|
+
return newzone
|
5619
6059
|
|
5620
|
-
|
6060
|
+
self.myzones = list(map(add_zone_from_row, content.iterrows()))
|
5621
6061
|
|
5622
|
-
|
6062
|
+
pass
|
5623
6063
|
|
5624
|
-
|
6064
|
+
def export_GeoDataFrame(self) -> gpd.GeoDataFrame:
|
6065
|
+
"""
|
6066
|
+
Export to a GeoDataFrame
|
5625
6067
|
"""
|
5626
|
-
|
5627
|
-
import geopandas as gpd
|
5628
|
-
|
5629
6068
|
names=[]
|
5630
6069
|
geoms=[]
|
5631
6070
|
|
@@ -5642,9 +6081,9 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5642
6081
|
for curvect in curzone.myvectors[:1]:
|
5643
6082
|
if curvect.is2D:
|
5644
6083
|
if curvect.closed:
|
5645
|
-
geoms.append(curvect.
|
6084
|
+
geoms.append(curvect.polygon)
|
5646
6085
|
else:
|
5647
|
-
geoms.append(curvect.
|
6086
|
+
geoms.append(curvect.polygon)
|
5648
6087
|
else:
|
5649
6088
|
if curvect.closed:
|
5650
6089
|
geoms.append(curvect.asshapely_pol3D())
|
@@ -5654,6 +6093,20 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5654
6093
|
gdf = gpd.GeoDataFrame({'id':names,'geometry':geoms})
|
5655
6094
|
gdf.crs = 'EPSG:31370'
|
5656
6095
|
|
6096
|
+
return gdf
|
6097
|
+
|
6098
|
+
def export_to_shapefile(self, filename:str):
|
6099
|
+
"""
|
6100
|
+
Export to shapefile.
|
6101
|
+
|
6102
|
+
The first vector of each zone will be exported.
|
6103
|
+
|
6104
|
+
If you want to export all vectors, you have to use "export_shape" of the zone object.
|
6105
|
+
|
6106
|
+
FIXME: Add support of data fields
|
6107
|
+
"""
|
6108
|
+
|
6109
|
+
gdf = self.export_GeoDataFrame()
|
5657
6110
|
gdf.to_file(filename)
|
5658
6111
|
|
5659
6112
|
def export_active_zone_to_shapefile(self, filename:str):
|
@@ -6070,10 +6523,14 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6070
6523
|
:param only_firstlast : si True, ne prend en compte que le premier et le dernier vertex de chaque vecteur
|
6071
6524
|
"""
|
6072
6525
|
|
6073
|
-
if
|
6074
|
-
|
6075
|
-
zone.find_minmax(update or self._first_find_minmax, only_firstlast)
|
6076
|
-
|
6526
|
+
if self.nbzones > 100:
|
6527
|
+
with ThreadPoolExecutor() as executor:
|
6528
|
+
# zone.find_minmax(update or self._first_find_minmax, only_firstlast)
|
6529
|
+
futures = [executor.submit(zone.find_minmax, update or self._first_find_minmax, only_firstlast) for zone in self.myzones]
|
6530
|
+
wait(futures)
|
6531
|
+
else:
|
6532
|
+
for curzone in self.myzones:
|
6533
|
+
curzone.find_minmax(update or self._first_find_minmax, only_firstlast)
|
6077
6534
|
|
6078
6535
|
if self.nbzones > 0:
|
6079
6536
|
|
@@ -6100,6 +6557,12 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6100
6557
|
for curzone in self.myzones:
|
6101
6558
|
curzone.plot(sx=sx, sy=sy, xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax, size=size)
|
6102
6559
|
|
6560
|
+
def plot_matplotlib(self, ax:plt.Axes):
|
6561
|
+
""" Plot with matplotlib """
|
6562
|
+
|
6563
|
+
for curzone in self.myzones:
|
6564
|
+
curzone.plot_matplotlib(ax)
|
6565
|
+
|
6103
6566
|
def select_vectors_from_point(self, x:float, y:float, inside=True):
|
6104
6567
|
"""
|
6105
6568
|
Sélection de vecteurs dans chaque zones sur base d'une coordonnée
|
@@ -7420,22 +7883,67 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7420
7883
|
|
7421
7884
|
sz = []
|
7422
7885
|
|
7886
|
+
# Getting s values and Z values from the xls grid
|
7887
|
+
# s in column 4 and z in column 2
|
7888
|
+
# The first row is the header
|
7423
7889
|
i = 0
|
7424
7890
|
while self.xls.GetCellValue(i,4) != '':
|
7425
|
-
|
7426
|
-
|
7891
|
+
s = self.xls.GetCellValue(i,4)
|
7892
|
+
z = self.xls.GetCellValue(i,2)
|
7893
|
+
try:
|
7894
|
+
s = float(s)
|
7895
|
+
except:
|
7896
|
+
logging.error(_('Error during update from sz support - check your s data and types (only float)'))
|
7897
|
+
return
|
7898
|
+
|
7899
|
+
try:
|
7900
|
+
if z == '':
|
7901
|
+
logging.warning(_('No z value -- setting to 0.0'))
|
7902
|
+
z = 0.0
|
7903
|
+
else:
|
7904
|
+
z = float(z)
|
7905
|
+
except:
|
7906
|
+
logging.error(_('Error during update from sz support - check your z data and types (only float)'))
|
7907
|
+
return
|
7908
|
+
|
7909
|
+
sz.append((s, z))
|
7910
|
+
i += 1
|
7911
|
+
|
7912
|
+
if len(sz) == 0:
|
7913
|
+
logging.warning(_('No data to update -- Please set s in column "s curvi" (5th) and z in column Z (3th)'))
|
7914
|
+
return
|
7427
7915
|
|
7428
7916
|
logging.info(f'Number of points: {len(sz)}')
|
7429
7917
|
|
7430
7918
|
vec_sz = np.array(sz)
|
7431
7919
|
|
7432
|
-
|
7920
|
+
memory_xyz = []
|
7921
|
+
i = 0
|
7922
|
+
while self.xls.GetCellValue(i,0) != '':
|
7923
|
+
memory_xyz.append((float(self.xls.GetCellValue(i,0)), float(self.xls.GetCellValue(i,1)), float(self.xls.GetCellValue(i,2))))
|
7924
|
+
i += 1
|
7925
|
+
|
7926
|
+
try:
|
7927
|
+
self.update_from_sz_support(vec=self.active_vector, sz=vec_sz)
|
7433
7928
|
|
7434
|
-
|
7435
|
-
|
7436
|
-
|
7437
|
-
|
7929
|
+
# update of the xls grid
|
7930
|
+
for k in range(self.active_vector.nbvertices ):
|
7931
|
+
self.xls.SetCellValue(k,0,str(self.active_vector.myvertices[k].x))
|
7932
|
+
self.xls.SetCellValue(k,1,str(self.active_vector.myvertices[k].y))
|
7933
|
+
except:
|
7934
|
+
logging.error(_('Error during update from sz support - check your data'))
|
7935
|
+
logging.info(_('Resetting the active vector to its original state'))
|
7936
|
+
|
7937
|
+
self.active_vector.myvertices = []
|
7938
|
+
for cur in memory_xyz:
|
7939
|
+
self.active_vector.add_vertex(wolfvertex(cur[0], cur[1], cur[2]))
|
7940
|
+
self.active_vector._reset_listogl()
|
7941
|
+
self.active_vector.update_lengths()
|
7942
|
+
self.active_vector.find_minmax(True)
|
7438
7943
|
|
7944
|
+
for k in range(self.active_vector.nbvertices ):
|
7945
|
+
self.xls.SetCellValue(k,0,str(self.active_vector.myvertices[k].x))
|
7946
|
+
self.xls.SetCellValue(k,1,str(self.active_vector.myvertices[k].y))
|
7439
7947
|
|
7440
7948
|
def update_from_sz_direction(self, xy1:np.ndarray, xy2:np.ndarray, sz:np.ndarray):
|
7441
7949
|
""" Update the active vector from the sz values in the xls grid """
|
@@ -8170,9 +8678,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
8170
8678
|
Zones (a new object).
|
8171
8679
|
"""
|
8172
8680
|
copied_Zones = Zones(idx=name)
|
8173
|
-
|
8174
|
-
|
8175
|
-
|
8681
|
+
copied_Zones.myzones = list(map(lambda zne: zne.deepcopy_zone(parent= copied_Zones), self.myzones))
|
8682
|
+
# for zne in self.myzones:
|
8683
|
+
# new_zne = zne.deepcopy_zone(parent= copied_Zones)
|
8684
|
+
# copied_Zones.add_zone(new_zne,forceparent=True)
|
8176
8685
|
copied_Zones.find_minmax(True)
|
8177
8686
|
return copied_Zones
|
8178
8687
|
|