wolfhece 2.1.126__py3-none-any.whl → 2.1.128__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/PyConfig.py +77 -4
- wolfhece/PyDraw.py +765 -13
- wolfhece/PyPalette.py +36 -0
- wolfhece/PyParams.py +2 -2
- wolfhece/PyVertexvectors.py +560 -64
- wolfhece/apps/version.py +1 -1
- wolfhece/coupling/hydrology_2d.py +295 -192
- wolfhece/eikonal.py +505 -0
- wolfhece/hydrology/Catchment.py +48 -48
- wolfhece/hydrology/PyWatershed.py +93 -93
- wolfhece/lagrange_multiplier.py +205 -0
- wolfhece/lazviewer/laz_viewer.py +28 -3
- wolfhece/math_parser/calculator.py +1 -0
- wolfhece/pybridges.py +2 -2
- wolfhece/pypolygons_scen.py +2 -2
- wolfhece/scenario/config_manager.py +12 -12
- wolfhece/wolf_array.py +1048 -42
- wolfhece/wolfresults_2D.py +204 -13
- {wolfhece-2.1.126.dist-info → wolfhece-2.1.128.dist-info}/METADATA +2 -3
- {wolfhece-2.1.126.dist-info → wolfhece-2.1.128.dist-info}/RECORD +23 -21
- {wolfhece-2.1.126.dist-info → wolfhece-2.1.128.dist-info}/WHEEL +1 -1
- {wolfhece-2.1.126.dist-info → wolfhece-2.1.128.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.126.dist-info → wolfhece-2.1.128.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
|
@@ -894,6 +939,10 @@ if :\n \
|
|
894
939
|
self.myprops.addparam('Image','Attached image','',Type_Param.File, '', whichdict='Default')
|
895
940
|
self.myprops.addparam('Image','To show',False,Type_Param.Logical,'',whichdict='Default')
|
896
941
|
|
942
|
+
self.myprops.addparam('Geometry','Length 2D',99999.,Type_Param.Float,'',whichdict='Default')
|
943
|
+
self.myprops.addparam('Geometry','Length 3D',99999.,Type_Param.Float,'',whichdict='Default')
|
944
|
+
self.myprops.addparam('Geometry','Surface',99999.,Type_Param.Float,'',whichdict='Default')
|
945
|
+
|
897
946
|
def destroyprop(self):
|
898
947
|
"""
|
899
948
|
Nullify the properties UI
|
@@ -1021,6 +1070,12 @@ if :\n \
|
|
1021
1070
|
|
1022
1071
|
self.myprops[('Move','Delta X')] = 0.
|
1023
1072
|
self.myprops[('Move','Delta Y')] = 0.
|
1073
|
+
|
1074
|
+
self.parent.update_lengths()
|
1075
|
+
self.myprops[( 'Geometry','Length 2D')] = self.parent.length2D
|
1076
|
+
self.myprops[( 'Geometry','Length 3D')] = self.parent.length3D
|
1077
|
+
self.myprops[( 'Geometry','Surface')] = self.parent.area
|
1078
|
+
|
1024
1079
|
self.myprops.Populate()
|
1025
1080
|
class vector:
|
1026
1081
|
"""
|
@@ -1114,8 +1169,8 @@ class vector:
|
|
1114
1169
|
self._rotation_center = None
|
1115
1170
|
self._rotation_step = None
|
1116
1171
|
|
1117
|
-
self.
|
1118
|
-
self.
|
1172
|
+
self._linestring = None
|
1173
|
+
self._polygon = None
|
1119
1174
|
|
1120
1175
|
# Utile surtout pour les sections en travers
|
1121
1176
|
self.zdatum = 0.
|
@@ -1129,6 +1184,56 @@ class vector:
|
|
1129
1184
|
if fromnumpy is not None:
|
1130
1185
|
self.add_vertices_from_array(fromnumpy)
|
1131
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
|
+
|
1132
1237
|
def set_legend_text(self, text:str):
|
1133
1238
|
""" Set the legend text """
|
1134
1239
|
|
@@ -1155,6 +1260,14 @@ class vector:
|
|
1155
1260
|
|
1156
1261
|
self.myprop.update_myprops()
|
1157
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
|
+
|
1158
1271
|
def set_legend_position(self, x:str | float, y:str | float):
|
1159
1272
|
""" Set the legend position """
|
1160
1273
|
|
@@ -1382,14 +1495,16 @@ class vector:
|
|
1382
1495
|
def import_shapelyobj(self, obj):
|
1383
1496
|
""" Importation d'un objet shapely """
|
1384
1497
|
|
1498
|
+
self.myvertices = []
|
1385
1499
|
if isinstance(obj, LineString):
|
1386
|
-
|
1387
|
-
|
1388
|
-
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
|
+
|
1389
1504
|
elif isinstance(obj, Polygon):
|
1390
|
-
|
1391
|
-
|
1392
|
-
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)
|
1393
1508
|
self.close_force()
|
1394
1509
|
else:
|
1395
1510
|
logging.warning(_('Object type {} not supported -- Update "import_shapelyobj"').format(type(obj)))
|
@@ -1503,7 +1618,7 @@ class vector:
|
|
1503
1618
|
if self.nbvertices==0:
|
1504
1619
|
return False
|
1505
1620
|
|
1506
|
-
poly = self.
|
1621
|
+
poly = self.polygon
|
1507
1622
|
inside2 = poly.contains(Point([x,y]))
|
1508
1623
|
return inside2
|
1509
1624
|
|
@@ -1570,7 +1685,7 @@ class vector:
|
|
1570
1685
|
xyz[:,2]+=self.zdatum
|
1571
1686
|
return xyz
|
1572
1687
|
|
1573
|
-
def prepare_shapely(self, prepare_shapely:bool = True):
|
1688
|
+
def prepare_shapely(self, prepare_shapely:bool = True, linestring:bool = True, polygon:bool = True):
|
1574
1689
|
"""
|
1575
1690
|
Conversion Linestring Shapely et rétention de l'objet afin d'éviter de multiples appel
|
1576
1691
|
par ex. dans une boucle.
|
@@ -1578,17 +1693,23 @@ class vector:
|
|
1578
1693
|
:param prepare_shapely: Préparation de l'objet Shapely pour une utilisation optimisée
|
1579
1694
|
- True par défaut
|
1580
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
|
1581
1698
|
|
1582
1699
|
"""
|
1583
1700
|
|
1584
1701
|
self.reset_linestring()
|
1585
1702
|
|
1586
|
-
|
1587
|
-
|
1703
|
+
if linestring:
|
1704
|
+
self._linestring = self.asshapely_ls()
|
1705
|
+
if polygon:
|
1706
|
+
self._polygon = self.asshapely_pol()
|
1588
1707
|
|
1589
1708
|
if prepare_shapely:
|
1590
|
-
|
1591
|
-
|
1709
|
+
if linestring:
|
1710
|
+
prepare(self._linestring)
|
1711
|
+
if polygon:
|
1712
|
+
prepare(self._polygon)
|
1592
1713
|
|
1593
1714
|
|
1594
1715
|
def projectontrace(self, trace):
|
@@ -1653,6 +1774,8 @@ class vector:
|
|
1653
1774
|
def intersection(self, vec2:"vector" = None, eval_dist=False,norm=False, force_single=False):
|
1654
1775
|
"""
|
1655
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.
|
1656
1779
|
|
1657
1780
|
Return :
|
1658
1781
|
- le point d'intersection
|
@@ -1660,8 +1783,13 @@ class vector:
|
|
1660
1783
|
|
1661
1784
|
Utilisation de Shapely
|
1662
1785
|
"""
|
1663
|
-
|
1664
|
-
|
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
|
+
|
1665
1793
|
|
1666
1794
|
myinter = ls1.intersection(ls2)
|
1667
1795
|
|
@@ -1692,15 +1820,15 @@ class vector:
|
|
1692
1820
|
def reset_linestring(self):
|
1693
1821
|
"""Remise à zéro de l'objet Shapely"""
|
1694
1822
|
|
1695
|
-
if self.
|
1696
|
-
if is_prepared(self.
|
1697
|
-
destroy_prepared(self.
|
1698
|
-
self.
|
1823
|
+
if self._linestring is not None:
|
1824
|
+
if is_prepared(self._linestring):
|
1825
|
+
destroy_prepared(self._linestring)
|
1826
|
+
self._linestring=None
|
1699
1827
|
|
1700
|
-
if self.
|
1701
|
-
if is_prepared(self.
|
1702
|
-
destroy_prepared(self.
|
1703
|
-
self.
|
1828
|
+
if self._polygon is not None:
|
1829
|
+
if is_prepared(self._polygon):
|
1830
|
+
destroy_prepared(self._polygon)
|
1831
|
+
self._polygon=None
|
1704
1832
|
|
1705
1833
|
def add_vertex(self,addedvert: Union[list[wolfvertex], wolfvertex]):
|
1706
1834
|
"""
|
@@ -1970,7 +2098,7 @@ class vector:
|
|
1970
2098
|
|
1971
2099
|
if self.myprop.filled:
|
1972
2100
|
|
1973
|
-
ls = self.
|
2101
|
+
ls = self.polygon
|
1974
2102
|
|
1975
2103
|
if False:
|
1976
2104
|
|
@@ -2049,6 +2177,20 @@ class vector:
|
|
2049
2177
|
else:
|
2050
2178
|
self.textimage = None
|
2051
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
|
+
|
2052
2194
|
def plot_image(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None):
|
2053
2195
|
""" plot attached images """
|
2054
2196
|
|
@@ -2066,6 +2208,28 @@ class vector:
|
|
2066
2208
|
else:
|
2067
2209
|
logging.warning(_('No image texture available for plot'))
|
2068
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
|
+
|
2069
2233
|
def _get_textfont(self):
|
2070
2234
|
""" Retunr a 'Text_Infos' instance for the legend """
|
2071
2235
|
|
@@ -2167,7 +2331,7 @@ class vector:
|
|
2167
2331
|
while k<self.nbvertices:
|
2168
2332
|
self.myvertices.pop(k)
|
2169
2333
|
|
2170
|
-
if self.
|
2334
|
+
if self._linestring is not None or self._polygon is not None:
|
2171
2335
|
self.prepare_shapely()
|
2172
2336
|
|
2173
2337
|
self._reset_listogl()
|
@@ -2773,6 +2937,11 @@ class vector:
|
|
2773
2937
|
copied_vector = vector(name=name)
|
2774
2938
|
|
2775
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
|
2776
2945
|
|
2777
2946
|
return copied_vector
|
2778
2947
|
|
@@ -2783,19 +2952,35 @@ class vector:
|
|
2783
2952
|
|
2784
2953
|
return self.deepcopy_vector(name, parentzone)
|
2785
2954
|
|
2955
|
+
@property
|
2956
|
+
def centroid(self):
|
2957
|
+
"""
|
2958
|
+
Return the centroid of the vector
|
2959
|
+
"""
|
2960
|
+
|
2961
|
+
return self.polygon.centroid
|
2962
|
+
|
2786
2963
|
def set_legend_to_centroid(self, text:str='', visible:bool=True):
|
2787
2964
|
"""
|
2788
2965
|
Positionne la légende au centre du vecteur
|
2789
2966
|
"""
|
2790
2967
|
self.myprop.legendvisible = visible
|
2791
2968
|
|
2792
|
-
|
2793
|
-
centroid = ls.centroid
|
2969
|
+
centroid = self.centroid
|
2794
2970
|
|
2795
2971
|
self.myprop.legendx = centroid.x
|
2796
2972
|
self.myprop.legendy = centroid.y
|
2797
2973
|
self.myprop.legendtext = text if text else self.myname
|
2798
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
|
+
|
2799
2984
|
def set_z(self, new_z:np.ndarray):
|
2800
2985
|
""" Set the z values of the vertices """
|
2801
2986
|
self.z = new_z
|
@@ -3101,7 +3286,6 @@ class vector:
|
|
3101
3286
|
if self.parentzone is not None:
|
3102
3287
|
self.parentzone.reset_listogl()
|
3103
3288
|
|
3104
|
-
|
3105
3289
|
def select_points_inside(self, xy:cloud_vertices | np.ndarray):
|
3106
3290
|
""" Select the points inside a polygon
|
3107
3291
|
|
@@ -3109,7 +3293,7 @@ class vector:
|
|
3109
3293
|
:return: list of boolean
|
3110
3294
|
"""
|
3111
3295
|
|
3112
|
-
self.prepare_shapely()
|
3296
|
+
self.prepare_shapely(True)
|
3113
3297
|
|
3114
3298
|
if isinstance(xy, cloud_vertices):
|
3115
3299
|
xy = xy.get_xyz()[:,0:2]
|
@@ -3166,7 +3350,7 @@ class vector:
|
|
3166
3350
|
"""
|
3167
3351
|
|
3168
3352
|
if self.closed:
|
3169
|
-
return self.
|
3353
|
+
return self.polygon.area
|
3170
3354
|
else:
|
3171
3355
|
return 0.
|
3172
3356
|
|
@@ -3256,6 +3440,62 @@ class zone:
|
|
3256
3440
|
# Object can be created from a shapely object
|
3257
3441
|
self.import_shapelyobj(fromshapely)
|
3258
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
|
+
|
3259
3499
|
def set_legend_text(self, text:str):
|
3260
3500
|
"""
|
3261
3501
|
Set the legend text for the zone
|
@@ -3264,6 +3504,14 @@ class zone:
|
|
3264
3504
|
for curvect in self.myvectors:
|
3265
3505
|
curvect.set_legend_text(text)
|
3266
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
|
+
|
3267
3515
|
def set_legend_position(self, x, y):
|
3268
3516
|
"""
|
3269
3517
|
Set the legend position for the zone
|
@@ -3275,7 +3523,12 @@ class zone:
|
|
3275
3523
|
@property
|
3276
3524
|
def area(self):
|
3277
3525
|
""" Compute the area of the zone """
|
3278
|
-
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]
|
3279
3532
|
|
3280
3533
|
def set_cache(self):
|
3281
3534
|
"""
|
@@ -3634,6 +3887,16 @@ class zone:
|
|
3634
3887
|
for curvect in self.myvectors:
|
3635
3888
|
curvect.plot_image(sx, sy, xmin, ymin, xmax, ymax, size)
|
3636
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)
|
3637
3900
|
|
3638
3901
|
def select_vectors_from_point(self,x:float,y:float,inside=True):
|
3639
3902
|
"""
|
@@ -5284,11 +5547,11 @@ class zone:
|
|
5284
5547
|
|
5285
5548
|
def set_legend_to_centroid(self):
|
5286
5549
|
"""
|
5287
|
-
Set the legend to the centroid of the
|
5550
|
+
Set the legend to the centroid of the vectors
|
5288
5551
|
"""
|
5289
5552
|
|
5290
5553
|
for curvec in self.myvectors:
|
5291
|
-
curvec.
|
5554
|
+
curvec.set_legend_position_to_centroid()
|
5292
5555
|
|
5293
5556
|
class Zones(wx.Frame, Element_To_Draw):
|
5294
5557
|
"""
|
@@ -5403,24 +5666,29 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5403
5666
|
self._rotation_center = None
|
5404
5667
|
self._rotation_step = None
|
5405
5668
|
|
5669
|
+
only_firstlast = False # By default, we are using all vertices
|
5406
5670
|
if self.filename!='':
|
5407
5671
|
# lecture du fichier
|
5408
5672
|
|
5409
5673
|
if self.filename.endswith('.dxf'):
|
5410
5674
|
self.is2D=False
|
5411
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
|
5412
5677
|
|
5413
5678
|
elif self.filename.endswith('.shp'):
|
5414
5679
|
self.is2D=False
|
5415
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
|
5416
5682
|
|
5417
5683
|
elif self.filename.endswith('.gpkg'):
|
5418
5684
|
self.is2D=False
|
5419
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
|
5420
5687
|
|
5421
5688
|
elif Path(filename).is_dir() and self.filename.endswith('.gdb'):
|
5422
5689
|
self.is2D=False
|
5423
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
|
5424
5692
|
|
5425
5693
|
elif self.filename.endswith('.vec') or self.filename.endswith('.vecz'):
|
5426
5694
|
|
@@ -5466,13 +5734,149 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5466
5734
|
logging.warning(_('Error while reading extra properties of {}'.format(self.filename)))
|
5467
5735
|
|
5468
5736
|
if find_minmax:
|
5469
|
-
|
5737
|
+
logging.info(_('Finding min and max values'))
|
5738
|
+
self.find_minmax(True, only_firstlast)
|
5470
5739
|
|
5471
5740
|
if colors is not None:
|
5472
5741
|
self.colorize_data(colors, filled=True)
|
5473
5742
|
|
5474
5743
|
if plotted and self.has_OGLContext and not self.shared:
|
5744
|
+
logging.info(_('Preparing OpenGL lists'))
|
5475
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
|
5476
5880
|
|
5477
5881
|
def set_cache(self):
|
5478
5882
|
""" Set cache for all zones """
|
@@ -5561,6 +5965,22 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5561
5965
|
for curzone in self.myzones:
|
5562
5966
|
curzone.set_legend_text(text)
|
5563
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
|
+
|
5564
5984
|
def set_legend_position(self, x, y):
|
5565
5985
|
"""
|
5566
5986
|
Set the legend position for the zones
|
@@ -5573,7 +5993,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5573
5993
|
def nbzones(self):
|
5574
5994
|
return len(self.myzones)
|
5575
5995
|
|
5576
|
-
def import_shapefile(self, fn:str,
|
5996
|
+
def import_shapefile(self, fn:str,
|
5997
|
+
bbox:Polygon = None, colname:str = None):
|
5577
5998
|
"""
|
5578
5999
|
Import shapefile by using geopandas
|
5579
6000
|
|
@@ -5581,41 +6002,69 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5581
6002
|
|
5582
6003
|
"""
|
5583
6004
|
|
6005
|
+
logging.info(_('Importing shapefile {}'.format(fn)))
|
5584
6006
|
content = gpd.read_file(fn, bbox=bbox)
|
5585
6007
|
|
5586
|
-
|
5587
|
-
|
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:
|
5588
6036
|
name = row['NAME']
|
5589
|
-
elif 'location' in
|
6037
|
+
elif 'location' in keys:
|
5590
6038
|
name = row['location'] # tuilage gdal
|
5591
|
-
elif '
|
6039
|
+
elif 'Communes' in keys:
|
6040
|
+
name = row['Communes']
|
6041
|
+
elif 'name' in keys:
|
5592
6042
|
name = row['name']
|
5593
|
-
elif 'MAJ_NIV3T' in
|
6043
|
+
elif 'MAJ_NIV3T' in keys:
|
5594
6044
|
# WALOUS
|
5595
6045
|
name = row['MAJ_NIV3T']
|
5596
|
-
elif 'NATUR_DESC' in
|
6046
|
+
elif 'NATUR_DESC' in keys:
|
5597
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']
|
5598
6052
|
else:
|
5599
6053
|
name = str(idx)
|
5600
6054
|
|
5601
6055
|
poly = row['geometry']
|
5602
6056
|
|
5603
6057
|
newzone = zone(name=name, parent = self, fromshapely = poly)
|
5604
|
-
|
5605
|
-
|
5606
|
-
def export_to_shapefile(self, filename:str):
|
5607
|
-
"""
|
5608
|
-
Export to shapefile.
|
6058
|
+
return newzone
|
5609
6059
|
|
5610
|
-
|
6060
|
+
self.myzones = list(map(add_zone_from_row, content.iterrows()))
|
5611
6061
|
|
5612
|
-
|
6062
|
+
pass
|
5613
6063
|
|
5614
|
-
|
6064
|
+
def export_GeoDataFrame(self) -> gpd.GeoDataFrame:
|
6065
|
+
"""
|
6066
|
+
Export to a GeoDataFrame
|
5615
6067
|
"""
|
5616
|
-
|
5617
|
-
import geopandas as gpd
|
5618
|
-
|
5619
6068
|
names=[]
|
5620
6069
|
geoms=[]
|
5621
6070
|
|
@@ -5632,9 +6081,9 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5632
6081
|
for curvect in curzone.myvectors[:1]:
|
5633
6082
|
if curvect.is2D:
|
5634
6083
|
if curvect.closed:
|
5635
|
-
geoms.append(curvect.
|
6084
|
+
geoms.append(curvect.polygon)
|
5636
6085
|
else:
|
5637
|
-
geoms.append(curvect.
|
6086
|
+
geoms.append(curvect.polygon)
|
5638
6087
|
else:
|
5639
6088
|
if curvect.closed:
|
5640
6089
|
geoms.append(curvect.asshapely_pol3D())
|
@@ -5644,6 +6093,20 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5644
6093
|
gdf = gpd.GeoDataFrame({'id':names,'geometry':geoms})
|
5645
6094
|
gdf.crs = 'EPSG:31370'
|
5646
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()
|
5647
6110
|
gdf.to_file(filename)
|
5648
6111
|
|
5649
6112
|
def export_active_zone_to_shapefile(self, filename:str):
|
@@ -6060,10 +6523,14 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6060
6523
|
:param only_firstlast : si True, ne prend en compte que le premier et le dernier vertex de chaque vecteur
|
6061
6524
|
"""
|
6062
6525
|
|
6063
|
-
if
|
6064
|
-
|
6065
|
-
zone.find_minmax(update or self._first_find_minmax, only_firstlast)
|
6066
|
-
|
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)
|
6067
6534
|
|
6068
6535
|
if self.nbzones > 0:
|
6069
6536
|
|
@@ -6090,6 +6557,12 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6090
6557
|
for curzone in self.myzones:
|
6091
6558
|
curzone.plot(sx=sx, sy=sy, xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax, size=size)
|
6092
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
|
+
|
6093
6566
|
def select_vectors_from_point(self, x:float, y:float, inside=True):
|
6094
6567
|
"""
|
6095
6568
|
Sélection de vecteurs dans chaque zones sur base d'une coordonnée
|
@@ -6322,10 +6795,20 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6322
6795
|
boxright.Add(self.interpxyz,0,wx.EXPAND)
|
6323
6796
|
boxright.Add(self.sascending,0,wx.EXPAND)
|
6324
6797
|
|
6798
|
+
|
6799
|
+
sizer_values_surface = wx.BoxSizer(wx.HORIZONTAL)
|
6325
6800
|
self.butgetval = wx.Button(self,label=_('Get values'))
|
6326
6801
|
self.butgetval.SetToolTip(_("Get values of the attached/active array (not working with 2D results) on each vertex of the active vector and update the editor"))
|
6327
6802
|
self.butgetval.Bind(wx.EVT_BUTTON,self.Ongetvalues)
|
6328
|
-
|
6803
|
+
|
6804
|
+
self.btn_surface = wx.Button(self,label=_('Surface'))
|
6805
|
+
self.btn_surface.SetToolTip(_("Compute the surface of the active vector/polygon"))
|
6806
|
+
self.btn_surface.Bind(wx.EVT_BUTTON,self.Onsurface)
|
6807
|
+
|
6808
|
+
sizer_values_surface.Add(self.butgetval,1,wx.EXPAND)
|
6809
|
+
sizer_values_surface.Add(self.btn_surface,1,wx.EXPAND)
|
6810
|
+
|
6811
|
+
boxright.Add(sizer_values_surface,0,wx.EXPAND)
|
6329
6812
|
|
6330
6813
|
self.butgetvallinked = wx.Button(self,label=_('Get values (all)'))
|
6331
6814
|
self.butgetvallinked.SetToolTip(_("Get values of all the visible arrays and 2D results on each vertex of the active vector \n\n Create a new zone containing the results"))
|
@@ -6893,6 +7376,18 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6893
7376
|
except:
|
6894
7377
|
raise Warning(_('Not supported in the current parent -- see PyVertexVectors in Ongetvalues function'))
|
6895
7378
|
|
7379
|
+
def Onsurface(self, e:wx.MouseEvent):
|
7380
|
+
"""
|
7381
|
+
Calcul de la surface du vecteur actif
|
7382
|
+
"""
|
7383
|
+
|
7384
|
+
if self.verify_activevec():
|
7385
|
+
return
|
7386
|
+
|
7387
|
+
dlg = wx.MessageDialog(None, _('The surface of the active vector is : {} m²'.format(self.active_vector.surface)), style = wx.OK)
|
7388
|
+
dlg.ShowModal()
|
7389
|
+
dlg.Destroy()
|
7390
|
+
|
6896
7391
|
def Ongetvalueslinked(self, e:wx.MouseEvent):
|
6897
7392
|
"""
|
6898
7393
|
Récupération des valeurs sous toutes les matrices liées pour le vecteur actif
|
@@ -8138,9 +8633,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
8138
8633
|
Zones (a new object).
|
8139
8634
|
"""
|
8140
8635
|
copied_Zones = Zones(idx=name)
|
8141
|
-
|
8142
|
-
|
8143
|
-
|
8636
|
+
copied_Zones.myzones = list(map(lambda zne: zne.deepcopy_zone(parent= copied_Zones), self.myzones))
|
8637
|
+
# for zne in self.myzones:
|
8638
|
+
# new_zne = zne.deepcopy_zone(parent= copied_Zones)
|
8639
|
+
# copied_Zones.add_zone(new_zne,forceparent=True)
|
8144
8640
|
copied_Zones.find_minmax(True)
|
8145
8641
|
return copied_Zones
|
8146
8642
|
|