wolfhece 2.1.107__py3-none-any.whl → 2.1.109__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 +165 -14
- wolfhece/PyGui.py +1 -1
- wolfhece/PyVertex.py +17 -1
- wolfhece/PyVertexvectors.py +676 -112
- wolfhece/PyWMS.py +61 -1
- wolfhece/acceptability/acceptability.py +59 -51
- wolfhece/acceptability/acceptability_gui.py +1043 -153
- wolfhece/acceptability/func.py +83 -48
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/laz_viewer.py +22 -0
- wolfhece/matplotlib_fig.py +69 -20
- wolfhece/picc.py +2 -2
- wolfhece/pybridges.py +227 -87
- wolfhece/scenario/config_manager.py +25 -6
- wolfhece/wolf_array.py +94 -40
- wolfhece/wolf_texture.py +12 -3
- wolfhece/wolf_tiles.py +2 -0
- {wolfhece-2.1.107.dist-info → wolfhece-2.1.109.dist-info}/METADATA +2 -2
- {wolfhece-2.1.107.dist-info → wolfhece-2.1.109.dist-info}/RECORD +22 -22
- {wolfhece-2.1.107.dist-info → wolfhece-2.1.109.dist-info}/WHEEL +1 -1
- {wolfhece-2.1.107.dist-info → wolfhece-2.1.109.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.107.dist-info → wolfhece-2.1.109.dist-info}/top_level.txt +0 -0
wolfhece/PyVertexvectors.py
CHANGED
@@ -743,6 +743,48 @@ class vectorproperties:
|
|
743
743
|
self.attachedimage = Path(props[('Image','Attached image')])
|
744
744
|
self.imagevisible = props[('Image','To show')]
|
745
745
|
|
746
|
+
posx = props[('Move','Start X')]
|
747
|
+
posy = props[('Move','Start Y')]
|
748
|
+
move_step = props[('Move','Step [m]')]
|
749
|
+
|
750
|
+
if posx != 99999. and posy != 99999.:
|
751
|
+
self.parent._start_move = (posx,posy)
|
752
|
+
else:
|
753
|
+
self.parent._start_move = None
|
754
|
+
|
755
|
+
if move_step != 99999.:
|
756
|
+
self.parent._move_step = move_step
|
757
|
+
else:
|
758
|
+
self.parent._move_step = None
|
759
|
+
|
760
|
+
posx = props[('Rotation','Center X')]
|
761
|
+
posy = props[('Rotation','Center Y')]
|
762
|
+
rot_step = props[('Rotation','Step [degree]')]
|
763
|
+
|
764
|
+
if posx != 99999. and posy != 99999.:
|
765
|
+
self.parent._rotation_center = (posx,posy)
|
766
|
+
else:
|
767
|
+
self.parent._rotation_center = None
|
768
|
+
|
769
|
+
if rot_step != 99999.:
|
770
|
+
self.parent._rotation_step = rot_step
|
771
|
+
else:
|
772
|
+
self.parent._rotation_step = None
|
773
|
+
|
774
|
+
angle = props[('Rotation','Angle [degree]')]
|
775
|
+
dx = props[('Move','Delta X')]
|
776
|
+
dy = props[('Move','Delta Y')]
|
777
|
+
|
778
|
+
if angle != 0. and (dx != 0. or dy != 0.):
|
779
|
+
logging.error('Both rotation and move are selected')
|
780
|
+
elif angle != 0.:
|
781
|
+
if self.parent._rotation_center is not None:
|
782
|
+
self.parent.rotate(angle, self.parent._rotation_center)
|
783
|
+
self.parent.clear_cache()
|
784
|
+
elif dx != 0. or dy != 0.:
|
785
|
+
self.parent.move(dx,dy)
|
786
|
+
self.parent.clear_cache()
|
787
|
+
|
746
788
|
self.load_unload_image()
|
747
789
|
|
748
790
|
try:
|
@@ -881,6 +923,35 @@ if :\n \
|
|
881
923
|
self.myprops[('Image','Attached image')] = str(self.attachedimage)
|
882
924
|
self.myprops[('Image','To show')] = self.imagevisible
|
883
925
|
|
926
|
+
if self.parent._rotation_center is not None:
|
927
|
+
self.myprops[('Rotation','center X')] = self.parent._rotation_center[0]
|
928
|
+
self.myprops[('Rotation','Center Y')] = self.parent._rotation_center[1]
|
929
|
+
else:
|
930
|
+
self.myprops[('Rotation','Center X')] = 99999.
|
931
|
+
self.myprops[('Rotation','Center Y')] = 99999.
|
932
|
+
|
933
|
+
if self.parent._rotation_step is not None:
|
934
|
+
self.myprops[('Rotation','Step [degree]')] = self.parent._rotation_step
|
935
|
+
else:
|
936
|
+
self.myprops[('Rotation','Step [degree]')] = 99999.
|
937
|
+
|
938
|
+
self.myprops[('Rotation', 'Angle [degree]')] = 0.
|
939
|
+
|
940
|
+
if self.parent._start_move is not None:
|
941
|
+
self.myprops[('Move','Start X')] = self.parent._start_move[0]
|
942
|
+
self.myprops[('Move','Start Y')] = self.parent._start_move[1]
|
943
|
+
else:
|
944
|
+
self.myprops[('Move','Start X')] = 99999.
|
945
|
+
self.myprops[('Move','Start Y')] = 99999.
|
946
|
+
|
947
|
+
if self.parent._move_step is not None:
|
948
|
+
self.myprops[('Move','Step [m]')] = self.parent._move_step
|
949
|
+
else:
|
950
|
+
self.myprops[('Move','Step [m]')] = 99999.
|
951
|
+
|
952
|
+
self.myprops[('Move','Delta X')] = 0.
|
953
|
+
self.myprops[('Move','Delta Y')] = 0.
|
954
|
+
|
884
955
|
self.myprops.Populate()
|
885
956
|
self.myprops.Layout()
|
886
957
|
self.myprops.SetSizeHints(500,800)
|
@@ -1014,6 +1085,13 @@ class vector:
|
|
1014
1085
|
self.myvertices=[]
|
1015
1086
|
self.myprop=vectorproperties(parent=self)
|
1016
1087
|
|
1088
|
+
self._cache_vertices = None
|
1089
|
+
self._start_move = None
|
1090
|
+
self._move_step = None
|
1091
|
+
|
1092
|
+
self._rotation_center = None
|
1093
|
+
self._rotation_step = None
|
1094
|
+
|
1017
1095
|
self.linestring = None
|
1018
1096
|
self.polygon = None
|
1019
1097
|
|
@@ -1026,6 +1104,94 @@ class vector:
|
|
1026
1104
|
if fromshapely is not None:
|
1027
1105
|
self.import_shapelyobj(fromshapely)
|
1028
1106
|
|
1107
|
+
def set_cache(self):
|
1108
|
+
""" Set the cache for the vertices """
|
1109
|
+
|
1110
|
+
self._cache_vertices = self.asnparray3d()
|
1111
|
+
|
1112
|
+
def clear_cache(self):
|
1113
|
+
""" Clear the cache for the vertices """
|
1114
|
+
|
1115
|
+
self._cache_vertices = None
|
1116
|
+
|
1117
|
+
def move(self, deltax:float, deltay:float, use_cache:bool = True, inplace:bool = True):
|
1118
|
+
"""
|
1119
|
+
Move the vector
|
1120
|
+
|
1121
|
+
:param deltax: delta x
|
1122
|
+
:param deltay: delta y
|
1123
|
+
:param use_cache: use the cache if available
|
1124
|
+
:param inplace: move the vector inplace or return a new vector
|
1125
|
+
"""
|
1126
|
+
|
1127
|
+
if self._move_step is not None:
|
1128
|
+
deltax = np.round(deltax/self._move_step)*self._move_step
|
1129
|
+
deltay = np.round(deltay/self._move_step)*self._move_step
|
1130
|
+
|
1131
|
+
if inplace:
|
1132
|
+
if use_cache and self._cache_vertices is None:
|
1133
|
+
self.set_cache()
|
1134
|
+
|
1135
|
+
if use_cache:
|
1136
|
+
self.xy = self._cache_vertices[:,:2] + np.array([deltax, deltay])
|
1137
|
+
else:
|
1138
|
+
for curvert in self.myvertices:
|
1139
|
+
curvert.x += deltax
|
1140
|
+
curvert.y += deltay
|
1141
|
+
|
1142
|
+
return self
|
1143
|
+
else:
|
1144
|
+
new_vector = self.deepcopy_vector(self.myname + '_moved')
|
1145
|
+
new_vector.move(deltax, deltay, inplace=True)
|
1146
|
+
|
1147
|
+
return new_vector
|
1148
|
+
|
1149
|
+
def rotate(self, angle:float, center:tuple[float,float]=(0.,0.), use_cache:bool = True, inplace:bool = True):
|
1150
|
+
"""
|
1151
|
+
Rotate the vector
|
1152
|
+
|
1153
|
+
:param angle: angle in degrees
|
1154
|
+
:param center: center of the rotation
|
1155
|
+
:param use_cache: use the cache if available
|
1156
|
+
:param inplace: rotate the vector inplace or return a new vector
|
1157
|
+
"""
|
1158
|
+
|
1159
|
+
if inplace:
|
1160
|
+
if use_cache and self._cache_vertices is None:
|
1161
|
+
self.set_cache()
|
1162
|
+
|
1163
|
+
if use_cache:
|
1164
|
+
locxy = self._cache_vertices[:,:2] - np.array(center)
|
1165
|
+
|
1166
|
+
rotation_matrix = np.array([[np.cos(np.radians(angle)), -np.sin(np.radians(angle))],
|
1167
|
+
[np.sin(np.radians(angle)), np.cos(np.radians(angle))]])
|
1168
|
+
|
1169
|
+
self.xy = np.dot(locxy, rotation_matrix) + np.array(center)
|
1170
|
+
else:
|
1171
|
+
for curvert in self.myvertices:
|
1172
|
+
curvert.rotate(angle, center)
|
1173
|
+
|
1174
|
+
return self
|
1175
|
+
else:
|
1176
|
+
new_vector = self.deepcopy_vector(self.myname + '_rotated')
|
1177
|
+
new_vector.rotate(angle, center, inplace=True)
|
1178
|
+
|
1179
|
+
return new_vector
|
1180
|
+
|
1181
|
+
def rotate_xy(self, x:float, y:float, use_cache:bool = True, inplace:bool = True):
|
1182
|
+
""" Rotate the vector around the rotation center and a xy point """
|
1183
|
+
|
1184
|
+
if self._rotation_center is None:
|
1185
|
+
logging.error('No rotation center defined -- set it before rotating by this routine')
|
1186
|
+
return self
|
1187
|
+
|
1188
|
+
angle = np.degrees(np.arctan2(-(y-self._rotation_center[1]), x-self._rotation_center[0]))
|
1189
|
+
|
1190
|
+
if self._rotation_step is not None:
|
1191
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
1192
|
+
|
1193
|
+
return self.rotate(angle, center=self._rotation_center, use_cache=use_cache, inplace=inplace)
|
1194
|
+
|
1029
1195
|
def get_mapviewer(self):
|
1030
1196
|
"""
|
1031
1197
|
Retourne l'instance de la mapviewer
|
@@ -1352,7 +1518,7 @@ class vector:
|
|
1352
1518
|
|
1353
1519
|
for x,y in mypar.coords:
|
1354
1520
|
xy = Point(x,y)
|
1355
|
-
curs = mypar.project(xy,True)
|
1521
|
+
curs = mypar.project(xy, True)
|
1356
1522
|
curz = myls.interpolate(curs,True).z
|
1357
1523
|
|
1358
1524
|
newvert = wolfvertex(x,y,curz)
|
@@ -1924,6 +2090,10 @@ class vector:
|
|
1924
2090
|
|
1925
2091
|
Retient également les longueurs de chaque segment
|
1926
2092
|
"""
|
2093
|
+
if self.nbvertices < 2:
|
2094
|
+
logging.warning(_('No enough vertices in vector to compute lenghts'))
|
2095
|
+
return
|
2096
|
+
|
1927
2097
|
self._lengthparts2D=np.zeros(self.nbvertices-1)
|
1928
2098
|
self._lengthparts3D=np.zeros(self.nbvertices-1)
|
1929
2099
|
|
@@ -2048,7 +2218,7 @@ class vector:
|
|
2048
2218
|
self.myvertices = newvec.myvertices
|
2049
2219
|
self.update_lengths()
|
2050
2220
|
|
2051
|
-
def interpolate(self,s,is3D=True,adim=True,frombegin=True):
|
2221
|
+
def interpolate(self,s,is3D=True,adim=True,frombegin=True) -> wolfvertex:
|
2052
2222
|
"""
|
2053
2223
|
Interpolation linéaire à une abscisse curviligne 's' donnée
|
2054
2224
|
|
@@ -2790,6 +2960,11 @@ class zone:
|
|
2790
2960
|
self.has_legend = False # indicate if at least one vector in the zone has a legend
|
2791
2961
|
self.has_image = False # indicate if at least one vector in the zone has an image
|
2792
2962
|
|
2963
|
+
self._start_move = None # starting point for a move
|
2964
|
+
self._move_step = None # step for a move
|
2965
|
+
self._rotation_center = None # center of rotation
|
2966
|
+
self._rotation_step = None # step for rotation
|
2967
|
+
|
2793
2968
|
if len(lines)>0:
|
2794
2969
|
# Decoding from lines -- lines is a list of strings provided by the parent during reading
|
2795
2970
|
# The order of the lines is important to ensure compatibility with the WOLF2D format
|
@@ -2823,6 +2998,80 @@ class zone:
|
|
2823
2998
|
# Object can be created from a shapely object
|
2824
2999
|
self.import_shapelyobj(fromshapely)
|
2825
3000
|
|
3001
|
+
def set_cache(self):
|
3002
|
+
"""
|
3003
|
+
Set the cache for the zone and all its vectors
|
3004
|
+
"""
|
3005
|
+
for curvect in self.myvectors:
|
3006
|
+
curvect.set_cache()
|
3007
|
+
|
3008
|
+
def clear_cache(self):
|
3009
|
+
"""
|
3010
|
+
Clear the cache for the zone and all its vectors
|
3011
|
+
"""
|
3012
|
+
for curvect in self.myvectors:
|
3013
|
+
curvect.clear_cache()
|
3014
|
+
|
3015
|
+
self._start_move = None
|
3016
|
+
self._move_step = None
|
3017
|
+
self._rotation_center = None
|
3018
|
+
self._rotation_step = None
|
3019
|
+
|
3020
|
+
self.find_minmax(update=True)
|
3021
|
+
|
3022
|
+
def move(self, dx:float, dy:float, use_cache:bool=True, inplace:bool=True):
|
3023
|
+
"""
|
3024
|
+
Move the zone and all its vectors
|
3025
|
+
"""
|
3026
|
+
|
3027
|
+
if self._move_step is not None:
|
3028
|
+
dx = np.round(dx/self._move_step)*self._move_step
|
3029
|
+
dy = np.round(dy/self._move_step)*self._move_step
|
3030
|
+
|
3031
|
+
if inplace:
|
3032
|
+
for curvect in self.myvectors:
|
3033
|
+
curvect.move(dx, dy, use_cache)
|
3034
|
+
return self
|
3035
|
+
else:
|
3036
|
+
newzone = self.deepcopy()
|
3037
|
+
newzone.move(dx, dy, use_cache= False)
|
3038
|
+
return newzone
|
3039
|
+
|
3040
|
+
def rotate(self, angle:float, center:tuple[float,float], use_cache:bool=True, inplace:bool=True):
|
3041
|
+
"""
|
3042
|
+
Rotate the zone and all its vectors
|
3043
|
+
|
3044
|
+
:param angle: angle in degrees (clockwise)
|
3045
|
+
:param center: center of rotation
|
3046
|
+
:param use_cache: use the cache for the vertices
|
3047
|
+
:param inplace: modify the zone in place or return a new one
|
3048
|
+
"""
|
3049
|
+
|
3050
|
+
if inplace:
|
3051
|
+
for curvect in self.myvectors:
|
3052
|
+
curvect.rotate(angle, center, use_cache)
|
3053
|
+
return self
|
3054
|
+
else:
|
3055
|
+
newzone = self.deepcopy()
|
3056
|
+
newzone.rotate(angle, center, use_cache= False)
|
3057
|
+
return newzone
|
3058
|
+
|
3059
|
+
def rotate_xy(self, x:float, y:float, use_cache:bool=True, inplace:bool=True):
|
3060
|
+
"""
|
3061
|
+
Rotate the zone and all its vectors in the xy plane
|
3062
|
+
"""
|
3063
|
+
|
3064
|
+
if self._rotation_center is None:
|
3065
|
+
logging.error(_('No rotation center defined - Set it before rotating by this routine'))
|
3066
|
+
return self
|
3067
|
+
|
3068
|
+
angle = np.degree(np.arctan2(y-self._rotation_center[1], x-self._rotation_center[0]))
|
3069
|
+
|
3070
|
+
if self._rotation_step is not None:
|
3071
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
3072
|
+
|
3073
|
+
return self.rotate(angle, self._rotation_center, use_cache, inplace)
|
3074
|
+
|
2826
3075
|
@property
|
2827
3076
|
def nbvectors(self):
|
2828
3077
|
return len(self.myvectors)
|
@@ -4406,6 +4655,36 @@ class zone:
|
|
4406
4655
|
self.myprops[('Legend','X')] = 99999.
|
4407
4656
|
self.myprops[('Legend','Y')] = 99999.
|
4408
4657
|
self.myprops[('Legend','Text')] = _('Not used')
|
4658
|
+
|
4659
|
+
if self._rotation_center is None:
|
4660
|
+
self.myprops[('Rotation','Center X')] = 99999.
|
4661
|
+
self.myprops[('Rotation','Center Y')] = 99999.
|
4662
|
+
else:
|
4663
|
+
self.myprops[('Rotation','Center X')] = self._rotation_center.x
|
4664
|
+
self.myprops[('Rotation','Center Y')] = self._rotation_center.y
|
4665
|
+
|
4666
|
+
if self._rotation_step is None:
|
4667
|
+
self.myprops[('Rotation','Step [degree]')] = 99999.
|
4668
|
+
else:
|
4669
|
+
self.myprops[('Rotation','Step [degree]')] = self._rotation_step
|
4670
|
+
|
4671
|
+
self.myprops[('Rotation', 'Angle [degree]')] = 0.
|
4672
|
+
|
4673
|
+
if self._move_start is None:
|
4674
|
+
self.myprops[('Move','Start X')] = 99999.
|
4675
|
+
self.myprops[('Move','Start Y')] = 99999.
|
4676
|
+
else:
|
4677
|
+
self.myprops[('Move','Start X')] = self._move_start.x
|
4678
|
+
self.myprops[('Move','Start Y')] = self._move_start.y
|
4679
|
+
|
4680
|
+
if self._move_step is None:
|
4681
|
+
self.myprops[('Move','Step [m]')] = 99999.
|
4682
|
+
else:
|
4683
|
+
self.myprops[('Move','Step [m]')] = self._move_step
|
4684
|
+
|
4685
|
+
self.myprops[('Move', 'Delta X')] = 0.
|
4686
|
+
self.myprops[('Move', 'Delta Y')] = 0.
|
4687
|
+
|
4409
4688
|
self.myprops.Populate()
|
4410
4689
|
self.myprops.set_callbacks(self._callback_prop, self._callback_destroy_props)
|
4411
4690
|
|
@@ -4442,6 +4721,24 @@ class zone:
|
|
4442
4721
|
for curvec in self.myvectors:
|
4443
4722
|
curvec.myprop.fill_property(self.myprops, updateOGL = False)
|
4444
4723
|
|
4724
|
+
angle = self.myprops[('Rotation', 'Angle [degree]')]
|
4725
|
+
dx = self.myprops[('Move', 'Delta X')]
|
4726
|
+
dy = self.myprops[('Move', 'Delta Y')]
|
4727
|
+
|
4728
|
+
if angle!=0. and (dx!=0. or dy!=0.):
|
4729
|
+
logging.warning(_('Rotation and translation are not compatible'))
|
4730
|
+
return
|
4731
|
+
elif angle!=0.:
|
4732
|
+
if self._rotation_center is None:
|
4733
|
+
logging.warning(_('No rotation center defined'))
|
4734
|
+
return
|
4735
|
+
else:
|
4736
|
+
self.rotate(angle, self._rotation_center)
|
4737
|
+
self.clear_cache()
|
4738
|
+
elif dx!=0. or dy!=0.:
|
4739
|
+
self.move(dx, dy)
|
4740
|
+
self.clear_cache()
|
4741
|
+
|
4445
4742
|
if self.parent.mapviewer is not None:
|
4446
4743
|
self.prep_listogl()
|
4447
4744
|
self.parent.mapviewer.Refresh()
|
@@ -4559,6 +4856,11 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4559
4856
|
self.ty=ty
|
4560
4857
|
self.myzones=[]
|
4561
4858
|
|
4859
|
+
self._start_move = None
|
4860
|
+
self._move_step = None
|
4861
|
+
self._rotation_center = None
|
4862
|
+
self._rotation_step = None
|
4863
|
+
|
4562
4864
|
if self.filename!='':
|
4563
4865
|
# lecture du fichier
|
4564
4866
|
|
@@ -4630,6 +4932,70 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4630
4932
|
if plotted and self.has_OGLContext and not self.shared:
|
4631
4933
|
self.prep_listogl()
|
4632
4934
|
|
4935
|
+
def set_cache(self):
|
4936
|
+
""" Set cache for all zones """
|
4937
|
+
|
4938
|
+
for curzone in self.myzones:
|
4939
|
+
curzone.set_cache()
|
4940
|
+
|
4941
|
+
def clear_cache(self):
|
4942
|
+
""" Clear cache for all zones """
|
4943
|
+
|
4944
|
+
for curzone in self.myzones:
|
4945
|
+
curzone.clear_cache()
|
4946
|
+
|
4947
|
+
def move(self, dx:float, dy:float, use_cache:bool = True, inplace:bool = True):
|
4948
|
+
""" Move all zones """
|
4949
|
+
|
4950
|
+
if self._move_step is not None:
|
4951
|
+
dx = np.round(dx/self._move_step)*self._move_step
|
4952
|
+
dy = np.round(dy/self._move_step)*self._move_step
|
4953
|
+
|
4954
|
+
if inplace:
|
4955
|
+
for curzone in self.myzones:
|
4956
|
+
curzone.move(dx, dy, use_cache=use_cache, inplace=inplace)
|
4957
|
+
|
4958
|
+
return self
|
4959
|
+
|
4960
|
+
else:
|
4961
|
+
newzones = self.deepcopy_zones()
|
4962
|
+
newzones.move(dx, dy, use_cache=False, inplace=True)
|
4963
|
+
newzones.find_minmax(True)
|
4964
|
+
return newzones
|
4965
|
+
|
4966
|
+
def rotate(self, angle:float, center:Point = None, use_cache:bool = True, inplace:bool = True):
|
4967
|
+
""" Rotate all zones """
|
4968
|
+
|
4969
|
+
if self._rotation_step is not None:
|
4970
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
4971
|
+
|
4972
|
+
if inplace:
|
4973
|
+
for curzone in self.myzones:
|
4974
|
+
curzone.rotate(angle, center, use_cache=use_cache, inplace=inplace)
|
4975
|
+
|
4976
|
+
return self
|
4977
|
+
|
4978
|
+
else:
|
4979
|
+
newzones = self.deepcopy_zones()
|
4980
|
+
newzones.rotate(angle, center, use_cache=False, inplace=True)
|
4981
|
+
newzones.find_minmax(True)
|
4982
|
+
return newzones
|
4983
|
+
|
4984
|
+
def rotate_xy(self, angle:float, center:Point = None, use_cache:bool = True, inplace:bool = True):
|
4985
|
+
""" Rotate all zones """
|
4986
|
+
|
4987
|
+
if inplace:
|
4988
|
+
for curzone in self.myzones:
|
4989
|
+
curzone.rotate_xy(angle, center, use_cache=use_cache, inplace=inplace)
|
4990
|
+
|
4991
|
+
return self
|
4992
|
+
|
4993
|
+
else:
|
4994
|
+
newzones = self.deepcopy_zones()
|
4995
|
+
newzones.rotate_xy(angle, center, use_cache=False, inplace=True)
|
4996
|
+
newzones.find_minmax(True)
|
4997
|
+
return newzones
|
4998
|
+
|
4633
4999
|
def force_unique_zone_name(self):
|
4634
5000
|
"""
|
4635
5001
|
Check if all zones have a unique id
|
@@ -4663,6 +5029,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4663
5029
|
for idx, row in content.iterrows():
|
4664
5030
|
if 'NAME' in row.keys():
|
4665
5031
|
name = row['NAME']
|
5032
|
+
elif 'location' in row.keys():
|
5033
|
+
name = row['location'] # tuilage gdal
|
4666
5034
|
elif 'name' in row.keys():
|
4667
5035
|
name = row['name']
|
4668
5036
|
elif 'MAJ_NIV3T' in row.keys():
|
@@ -4794,11 +5162,21 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4794
5162
|
content = gpd.read_file(fn, bbox=bbox, layer=curlayer)
|
4795
5163
|
|
4796
5164
|
if len(content)>1000:
|
5165
|
+
logging.warning(_('Number of elements in layer {} : {}'.format(curlayer, len(content))))
|
4797
5166
|
logging.warning(_('Layer {} contains more than 1000 elements -- it may take a while to import'.format(curlayer)))
|
4798
5167
|
|
5168
|
+
if self.wx_exists:
|
5169
|
+
dlg = wx.MessageDialog(None, _('Layer {} contains more than 1000 elements -- it may take a while to import\n\nContinue ?'.format(curlayer)), _('Warning'), wx.OK | wx.CANCEL | wx.ICON_WARNING)
|
5170
|
+
ret = dlg.ShowModal()
|
5171
|
+
dlg.Destroy()
|
5172
|
+
if ret == wx.ID_CANCEL:
|
5173
|
+
return
|
5174
|
+
|
4799
5175
|
for idx, row in content.iterrows():
|
4800
5176
|
if 'NAME' in row.keys():
|
4801
5177
|
name = row['NAME']
|
5178
|
+
elif 'CANU' in row.keys():
|
5179
|
+
name = row['CANU']
|
4802
5180
|
elif 'MAJ_NIV3T' in row.keys():
|
4803
5181
|
# WALOUS
|
4804
5182
|
name = row['MAJ_NIV3T']
|
@@ -5285,6 +5663,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5285
5663
|
self.evaluates.SetToolTip(_("Calculate the curvilinear 's' distance using a '2D' or '3D' approach and store the result in the 5th column of the grid, X being the first one"))
|
5286
5664
|
self.evaluates.Bind(wx.EVT_BUTTON,self.Onevaluates)
|
5287
5665
|
|
5666
|
+
self.update_from_s = wx.Button(self,label=_('Update from sz (support)'))
|
5667
|
+
self.update_from_s.SetToolTip(_("Update the coordinates of the vertices based on the 's' distance \n The interpolation uses the 's' value contained in the 5th column of the grid, X being the first one.\nThe support vector is in XY. It will be replaced."))
|
5668
|
+
self.update_from_s.Bind(wx.EVT_BUTTON,self.Onupdate_from_sz_support)
|
5669
|
+
|
5288
5670
|
# Modified
|
5289
5671
|
self.zoomonactive = wx.Button(self,label=_('Zoom on active vector'))
|
5290
5672
|
self.zoomonactive.SetToolTip(_("Zoom on the active vector and a default view size of 500 m x 500 m"))
|
@@ -5326,8 +5708,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5326
5708
|
self.slidingpoly.Bind(wx.EVT_BUTTON,self.Oncreateslidingpoly)
|
5327
5709
|
|
5328
5710
|
# Added
|
5329
|
-
self.getxyfromsz = wx.Button(self, label = _('
|
5330
|
-
self.getxyfromsz.SetToolTip(_("Populate the X an Y columns based on: \n - Given sz coordinates, \n - The X and Y coordinates of the initial point (s = 0) and, \n - The X and Y coordinates of a second point (
|
5711
|
+
self.getxyfromsz = wx.Button(self, label = _('Update from sz (2 points)'))
|
5712
|
+
self.getxyfromsz.SetToolTip(_("Populate the X an Y columns based on: \n - Given sz coordinates, \n - 2 Points \n - The X and Y coordinates of the initial point (s = 0) and, \n - The X and Y coordinates of a second point (for the direction)"))
|
5331
5713
|
self.getxyfromsz.Bind(wx.EVT_BUTTON, self.get_xy_from_sz)
|
5332
5714
|
|
5333
5715
|
boxright.Add(self.xls,1,wx.EXPAND)
|
@@ -5351,10 +5733,16 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5351
5733
|
|
5352
5734
|
# boxright.Add(self.zoomonactive,0,wx.EXPAND)
|
5353
5735
|
boxright.Add(boxzoom,0,wx.EXPAND)
|
5354
|
-
|
5736
|
+
|
5737
|
+
box_s = wx.BoxSizer(wx.HORIZONTAL)
|
5738
|
+
boxright.Add(box_s,0,wx.EXPAND)
|
5739
|
+
|
5740
|
+
box_s.Add(self.evaluates,1,wx.EXPAND)
|
5741
|
+
box_s.Add(self.update_from_s,1,wx.EXPAND)
|
5742
|
+
box_s.Add(self.getxyfromsz,1,wx.EXPAND) # Added
|
5743
|
+
|
5355
5744
|
boxright.Add(self.interpxyz,0,wx.EXPAND)
|
5356
5745
|
boxright.Add(self.sascending,0,wx.EXPAND)
|
5357
|
-
boxright.Add(self.getxyfromsz,0,wx.EXPAND) # Added
|
5358
5746
|
|
5359
5747
|
self.butgetval = wx.Button(self,label=_('Get values (self or active array)'))
|
5360
5748
|
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"))
|
@@ -5369,8 +5757,22 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5369
5757
|
self.butgetrefvallinked.SetToolTip(_("Get values of all the visible arrays and 2D results on each vertex of the active vector \n and more is the step size of the array is more precise \n\n Create a new zone containing the results"))
|
5370
5758
|
self.butgetrefvallinked.Bind(wx.EVT_BUTTON,self.Ongetvalueslinkedandref)
|
5371
5759
|
|
5760
|
+
self._move_rotate_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
5761
|
+
|
5762
|
+
self.butmove = wx.Button(self,label=_('Move'))
|
5763
|
+
self.butmove.SetToolTip(_("Move the active vector - If not defined in properties, the first right click is the origin of the move"))
|
5764
|
+
self.butmove.Bind(wx.EVT_BUTTON,self.OnMove)
|
5765
|
+
|
5766
|
+
self.butrotate = wx.Button(self,label=_('Rotate'))
|
5767
|
+
self.butrotate.SetToolTip(_("Rotate the active vector - If not defined in properties, the first right click is the origin of the rotation"))
|
5768
|
+
self.butrotate.Bind(wx.EVT_BUTTON,self.OnRotate)
|
5769
|
+
|
5770
|
+
self._move_rotate_sizer.Add(self.butmove, 1, wx.EXPAND)
|
5771
|
+
self._move_rotate_sizer.Add(self.butrotate, 1, wx.EXPAND)
|
5772
|
+
|
5372
5773
|
boxright.Add(self.butgetvallinked,0,wx.EXPAND)
|
5373
5774
|
boxright.Add(self.butgetrefvallinked,0,wx.EXPAND)
|
5775
|
+
boxright.Add(self._move_rotate_sizer, 0, wx.EXPAND)
|
5374
5776
|
|
5375
5777
|
self.treelist = TreeListCtrl(self,style=TL_CHECKBOX|wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_EDIT_LABELS)
|
5376
5778
|
self.treelist.AppendColumn('Zones')
|
@@ -5389,6 +5791,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5389
5791
|
|
5390
5792
|
self.addzone = wx.Button(self,label=_('Add zone'))
|
5391
5793
|
self.addvector = wx.Button(self,label=_('Add vector'))
|
5794
|
+
|
5795
|
+
self.duplicatezone = wx.Button(self,label=_('Duplicate zone'))
|
5796
|
+
self.duplicatevector = wx.Button(self,label=_('Duplicate vector'))
|
5797
|
+
|
5392
5798
|
self.deletezone = wx.Button(self,label=_('Delete zone'))
|
5393
5799
|
self.findactivevector = wx.Button(self,label=_('Find in all'))
|
5394
5800
|
self.findactivevector.SetToolTip(_("Search and activate the nearest vector by mouse click (Searching window : all zones)"))
|
@@ -5402,8 +5808,24 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5402
5808
|
self.downzone = wx.Button(self,label=_('Down zone'))
|
5403
5809
|
# self.interpolate = wx.Button(self,label=_('Interpolate vector'))
|
5404
5810
|
|
5811
|
+
self._move_rotate_zone_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
5812
|
+
self.butmove_zone = wx.Button(self,label=_('Move zone'))
|
5813
|
+
self.butmove_zone.SetToolTip(_("Move the active zone - If not defined in properties, the first right click is the origin of the move"))
|
5814
|
+
self.butmove_zone.Bind(wx.EVT_BUTTON,self.OnMoveZone)
|
5815
|
+
|
5816
|
+
self.butrotate_zone = wx.Button(self,label=_('Rotate zone'))
|
5817
|
+
self.butrotate_zone.SetToolTip(_("Rotate the active zone - If not defined in properties, the first right click is the origin of the rotation"))
|
5818
|
+
self.butrotate_zone.Bind(wx.EVT_BUTTON,self.OnRotateZone)
|
5819
|
+
|
5820
|
+
self._move_rotate_zone_sizer.Add(self.butmove_zone, 1, wx.EXPAND)
|
5821
|
+
self._move_rotate_zone_sizer.Add(self.butrotate_zone, 1, wx.EXPAND)
|
5822
|
+
|
5405
5823
|
self.addzone.Bind(wx.EVT_BUTTON,self.OnClickadd_zone)
|
5406
5824
|
self.addvector.Bind(wx.EVT_BUTTON,self.OnClickadd_vector)
|
5825
|
+
|
5826
|
+
self.duplicatezone.Bind(wx.EVT_BUTTON,self.OnClickduplicate_zone)
|
5827
|
+
self.duplicatevector.Bind(wx.EVT_BUTTON,self.OnClickduplicate_vector)
|
5828
|
+
|
5407
5829
|
self.deletezone.Bind(wx.EVT_BUTTON,self.OnClickdelete_zone)
|
5408
5830
|
self.deletevector.Bind(wx.EVT_BUTTON,self.OnClickdelete_vector)
|
5409
5831
|
self.upvector.Bind(wx.EVT_BUTTON,self.OnClickup_vector)
|
@@ -5421,6 +5843,11 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5421
5843
|
boxadd.Add(self.addzone,1,wx.EXPAND)
|
5422
5844
|
boxadd.Add(self.addvector,1,wx.EXPAND)
|
5423
5845
|
|
5846
|
+
boxduplicate = wx.BoxSizer(wx.HORIZONTAL)
|
5847
|
+
boxduplicate.Add(self.duplicatezone,1,wx.EXPAND)
|
5848
|
+
boxduplicate.Add(self.duplicatevector,1,wx.EXPAND)
|
5849
|
+
boxadd.Add(boxduplicate,1,wx.EXPAND)
|
5850
|
+
|
5424
5851
|
subboxadd = wx.BoxSizer(wx.HORIZONTAL)
|
5425
5852
|
subboxadd.Add(self.findactivevector,1,wx.EXPAND)
|
5426
5853
|
subboxadd.Add(self.findactivevectorcurz,1,wx.EXPAND)
|
@@ -5455,6 +5882,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5455
5882
|
boxleft.Add(boxdelete,0,wx.EXPAND)
|
5456
5883
|
boxleft.Add(boxupdown,0,wx.EXPAND)
|
5457
5884
|
boxleft.Add(boxtri,0,wx.EXPAND)
|
5885
|
+
boxleft.Add(self._move_rotate_zone_sizer, 0, wx.EXPAND)
|
5458
5886
|
|
5459
5887
|
box.Add(boxleft,1,wx.EXPAND)
|
5460
5888
|
box.Add(boxright,1,wx.EXPAND)
|
@@ -5482,7 +5910,6 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5482
5910
|
|
5483
5911
|
self.init_struct=False
|
5484
5912
|
|
5485
|
-
|
5486
5913
|
def get_xy_from_sz(self, event: wx.Event):
|
5487
5914
|
"""
|
5488
5915
|
Add vertices and their respectives xy coordinates from s and Z entries in the xls grid:
|
@@ -5491,98 +5918,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5491
5918
|
if self.wx_exists:
|
5492
5919
|
if self.verify_activevec():
|
5493
5920
|
return
|
5494
|
-
curv = self.active_vector
|
5495
|
-
n_rows = self.xls.GetNumberRows()
|
5496
|
-
|
5497
|
-
# Getting the 2 first XY coordinates
|
5498
|
-
X =[]
|
5499
|
-
Y = []
|
5500
|
-
|
5501
|
-
z_row = 1 #Starting from the second row because the first one is the initial point
|
5502
|
-
|
5503
|
-
# First row coordinates
|
5504
|
-
x1 = self.xls.GetCellValue(0,0)
|
5505
|
-
y1 = self.xls.GetCellValue(0,1)
|
5506
|
-
|
5507
|
-
|
5508
|
-
if x1 != '' and y1 != '':
|
5509
|
-
X.append(float(x1))
|
5510
|
-
Y.append(float(y1))
|
5511
|
-
|
5512
|
-
else:
|
5513
|
-
raise Exception('Encode the coordinates of the initial point (S = 0 --> first point)')
|
5514
|
-
|
5515
|
-
# Coordinates of the second points
|
5516
|
-
while z_row < n_rows:
|
5517
|
-
if len(X) < 2 and len(Y) < 2:
|
5518
|
-
x2 = self.xls.GetCellValue(z_row,0)
|
5519
|
-
y2 = self.xls.GetCellValue(z_row,1)
|
5520
|
-
|
5521
|
-
if x2 != '' and y2 != '':
|
5522
|
-
X.append(float(x2))
|
5523
|
-
Y.append(float(y2))
|
5524
|
-
|
5525
|
-
z_row += 1
|
5526
|
-
|
5527
|
-
else:
|
5528
|
-
break
|
5529
|
-
|
5530
|
-
xy1 = np.array([X[0], Y[0]])
|
5531
|
-
xy2 = np.array([X[1], Y[1]])
|
5532
5921
|
|
5533
|
-
# Collection of sz coordinates
|
5534
|
-
row = 0
|
5535
|
-
|
5536
|
-
SZ = []
|
5537
|
-
|
5538
|
-
while row < n_rows:
|
5539
|
-
s = self.xls.GetCellValue(row,4)
|
5540
|
-
z = self.xls.GetCellValue(row,2)
|
5541
|
-
|
5542
|
-
if z=='':
|
5543
|
-
z=0.
|
5544
|
-
|
5545
|
-
if s != '':
|
5546
|
-
SZ.append((s,z))
|
5547
|
-
row += 1
|
5548
|
-
|
5549
|
-
elif s=='': #FIXME logging msg to notify the user a point is missing
|
5550
|
-
break
|
5551
|
-
|
5552
|
-
else:
|
5553
|
-
raise Exception (_("Recheck your data inputs"))
|
5554
|
-
break
|
5555
|
-
|
5556
|
-
sz = np.asarray(SZ,dtype='float64') # FIXME The type is required otherwise type == <U
|
5557
|
-
|
5558
|
-
# Creation of vertices
|
5559
|
-
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
5560
|
-
if not np.array_equal(xy1,xy2):
|
5561
|
-
curv.myvertices=[]
|
5562
|
-
curv.nbvertices = 0
|
5563
|
-
|
5564
|
-
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
5565
|
-
norm = np.linalg.norm([dx,dy])
|
5566
|
-
dx, dy = dx/norm, dy/norm
|
5567
|
-
|
5568
|
-
for cur in sz:
|
5569
|
-
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
5570
|
-
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
5571
|
-
|
5572
|
-
# update of the xls grid
|
5573
|
-
for k in range(curv.nbvertices ):
|
5574
|
-
self.xls.SetCellValue(k,0,str(curv.myvertices[k].x))
|
5575
|
-
self.xls.SetCellValue(k,1,str(curv.myvertices[k].y))
|
5576
|
-
|
5577
|
-
|
5578
|
-
def get_xy_from_sz(self, event: wx.Event):
|
5579
|
-
"""
|
5580
|
-
Add vertices and their respectives xy coordinates from s and Z entries in the xls grid:
|
5581
|
-
- NB: The coordinates of the initial point s= 0 and one other points should be explicitly given in the xls grid.
|
5582
|
-
"""
|
5583
|
-
if self.wx_exists:
|
5584
|
-
if self.verify_activevec():
|
5585
|
-
return
|
5586
5922
|
curv = self.active_vector
|
5587
5923
|
n_rows = self.xls.GetNumberRows()
|
5588
5924
|
|
@@ -5651,19 +5987,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5651
5987
|
|
5652
5988
|
sz = np.asarray(SZ,dtype='float64') # FIXME The type is required otherwise type == <U
|
5653
5989
|
|
5654
|
-
|
5655
|
-
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
5656
|
-
if not np.array_equal(xy1,xy2):
|
5657
|
-
curv.myvertices=[]
|
5658
|
-
curv.nbvertices = 0
|
5659
|
-
|
5660
|
-
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
5661
|
-
norm = np.linalg.norm([dx,dy])
|
5662
|
-
dx, dy = dx/norm, dy/norm
|
5663
|
-
|
5664
|
-
for cur in sz:
|
5665
|
-
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
5666
|
-
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
5990
|
+
self.update_from_sz_direction(xy1, xy2, sz)
|
5667
5991
|
|
5668
5992
|
# update of the xls grid
|
5669
5993
|
for k in range(curv.nbvertices ):
|
@@ -5828,6 +6152,56 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5828
6152
|
self.expand_tree(self.active_zone)
|
5829
6153
|
self.active_zone.reset_listogl()
|
5830
6154
|
|
6155
|
+
def OnMove(self, event:wx.MouseEvent):
|
6156
|
+
"""
|
6157
|
+
Déplacement du vecteur actif
|
6158
|
+
"""
|
6159
|
+
if self.wx_exists:
|
6160
|
+
if self.verify_activevec():
|
6161
|
+
return
|
6162
|
+
|
6163
|
+
self.mapviewer.start_action('move vector', _('Move vector'))
|
6164
|
+
self.active_vector.set_cache()
|
6165
|
+
self.mapviewer.mimicme()
|
6166
|
+
|
6167
|
+
def OnMoveZone(self, event:wx.MouseEvent):
|
6168
|
+
"""
|
6169
|
+
Déplacement de la zone active
|
6170
|
+
"""
|
6171
|
+
if self.wx_exists:
|
6172
|
+
if self.verify_activezone():
|
6173
|
+
return
|
6174
|
+
|
6175
|
+
self.mapviewer.start_action('move zone', _('Move zone'))
|
6176
|
+
self.active_zone.set_cache()
|
6177
|
+
self.mapviewer.mimicme()
|
6178
|
+
|
6179
|
+
def OnRotate(self, event:wx.MouseEvent):
|
6180
|
+
"""
|
6181
|
+
Rotation du vecteur actif
|
6182
|
+
"""
|
6183
|
+
|
6184
|
+
if self.wx_exists:
|
6185
|
+
if self.verify_activevec():
|
6186
|
+
return
|
6187
|
+
|
6188
|
+
self.mapviewer.start_action('rotate vector', _('Rotate vector'))
|
6189
|
+
self.active_vector.set_cache()
|
6190
|
+
self.mapviewer.mimicme()
|
6191
|
+
|
6192
|
+
def OnRotateZone(self, event:wx.MouseEvent):
|
6193
|
+
"""
|
6194
|
+
Rotation de la zone active
|
6195
|
+
"""
|
6196
|
+
|
6197
|
+
if self.wx_exists:
|
6198
|
+
if self.verify_activezone():
|
6199
|
+
return
|
6200
|
+
|
6201
|
+
self.mapviewer.start_action('rotate zone', _('Rotate zone'))
|
6202
|
+
self.active_zone.set_cache()
|
6203
|
+
self.mapviewer.mimicme()
|
6204
|
+
|
5831
6205
|
def OncaptureandDynapar(self, event:wx.MouseEvent):
|
5832
6206
|
"""
|
5833
6207
|
Ajoute des vertices au vecteur courant et crée des parallèles gauche-droite
|
@@ -6387,6 +6761,98 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6387
6761
|
s+=curv._lengthparts3D[k]
|
6388
6762
|
self.xls.SetCellValue(k+1,4,str(s))
|
6389
6763
|
|
6764
|
+
def Onupdate_from_sz_support(self, event:wx.MouseEvent):
|
6765
|
+
""" Update the active vector from the sz values in the xls grid """
|
6766
|
+
|
6767
|
+
if self.active_vector is None:
|
6768
|
+
logging.info(_('No active vector -- Nothing to do'))
|
6769
|
+
return
|
6770
|
+
|
6771
|
+
sz = []
|
6772
|
+
|
6773
|
+
i = 0
|
6774
|
+
while self.xls.GetCellValue(i,4) != '':
|
6775
|
+
sz.append((float(self.xls.GetCellValue(i,4)), float(self.xls.GetCellValue(i,2))))
|
6776
|
+
i += 1
|
6777
|
+
|
6778
|
+
logging.info(f'Number of points: {len(sz)}')
|
6779
|
+
|
6780
|
+
vec_sz = np.array(sz)
|
6781
|
+
|
6782
|
+
self.update_from_sz_support(vec=self.active_vector, sz=vec_sz)
|
6783
|
+
|
6784
|
+
# update of the xls grid
|
6785
|
+
for k in range(self.active_vector.nbvertices ):
|
6786
|
+
self.xls.SetCellValue(k,0,str(self.active_vector.myvertices[k].x))
|
6787
|
+
self.xls.SetCellValue(k,1,str(self.active_vector.myvertices[k].y))
|
6788
|
+
|
6789
|
+
|
6790
|
+
def update_from_sz_direction(self, xy1:np.ndarray, xy2:np.ndarray, sz:np.ndarray):
|
6791
|
+
""" Update the active vector from the sz values in the xls grid """
|
6792
|
+
|
6793
|
+
if self.active_vector is None:
|
6794
|
+
logging.info(_('No active vector -- Nothing to do'))
|
6795
|
+
return
|
6796
|
+
|
6797
|
+
curv = self.active_vector
|
6798
|
+
|
6799
|
+
# Creation of vertices
|
6800
|
+
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
6801
|
+
if not np.array_equal(xy1,xy2):
|
6802
|
+
curv.myvertices=[]
|
6803
|
+
|
6804
|
+
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
6805
|
+
norm = np.linalg.norm([dx,dy])
|
6806
|
+
dx, dy = dx/norm, dy/norm
|
6807
|
+
|
6808
|
+
for cur in sz:
|
6809
|
+
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
6810
|
+
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
6811
|
+
|
6812
|
+
self.find_minmax(True)
|
6813
|
+
|
6814
|
+
def update_from_sz_support(self, vec: vector, sz:np.ndarray, dialog_box = True):
|
6815
|
+
|
6816
|
+
if sz.shape[0] ==0:
|
6817
|
+
logging.warning(_('No data to update'))
|
6818
|
+
return
|
6819
|
+
|
6820
|
+
support_vec = vec.deepcopy_vector()
|
6821
|
+
support_vec.update_lengths()
|
6822
|
+
|
6823
|
+
if support_vec.length2D is None or support_vec.length3D is None:
|
6824
|
+
logging.warning(_('The support vector must be updated before updating the active vector'))
|
6825
|
+
return
|
6826
|
+
|
6827
|
+
if dialog_box:
|
6828
|
+
dlg = wx.SingleChoiceDialog(None, "Which mode?", "How to evaluate lengths?", ['2D','3D'])
|
6829
|
+
ret=dlg.ShowModal()
|
6830
|
+
if ret==wx.ID_CANCEL:
|
6831
|
+
dlg.Destroy()
|
6832
|
+
return
|
6833
|
+
|
6834
|
+
method=dlg.GetStringSelection()
|
6835
|
+
dlg.Destroy()
|
6836
|
+
else:
|
6837
|
+
method = '2D'
|
6838
|
+
|
6839
|
+
if method == '2D':
|
6840
|
+
if sz[-1,0] > support_vec.length2D:
|
6841
|
+
logging.warning(_('The last point is beyond the vector length. You must add more points !'))
|
6842
|
+
return
|
6843
|
+
else:
|
6844
|
+
if sz[-1,0] > support_vec.length3D:
|
6845
|
+
logging.warning(_('The last point is beyond the vector length. You must add more points !'))
|
6846
|
+
return
|
6847
|
+
|
6848
|
+
vec.myvertices = []
|
6849
|
+
for s,z in sz:
|
6850
|
+
new_vertex = support_vec.interpolate(s, method == '3D', adim= False)
|
6851
|
+
new_vertex.z = z
|
6852
|
+
vec.add_vertex(new_vertex)
|
6853
|
+
|
6854
|
+
self.find_minmax(True)
|
6855
|
+
|
6390
6856
|
def evaluate_s (self, vec: vector =None, dialog_box = True):
|
6391
6857
|
"""
|
6392
6858
|
Calcule la position curviligne du vecteur encodé
|
@@ -6515,6 +6981,32 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6515
6981
|
else:
|
6516
6982
|
return
|
6517
6983
|
|
6984
|
+
def OnClickduplicate_zone(self, event:wx.MouseEvent):
|
6985
|
+
""" Duplication de la zone active """
|
6986
|
+
if self.wx_exists:
|
6987
|
+
if self.verify_activezone():
|
6988
|
+
return
|
6989
|
+
|
6990
|
+
newzone = self.active_zone.deepcopy_zone()
|
6991
|
+
newzone.myname = self.active_zone.myname + '_copy'
|
6992
|
+
self.add_zone(newzone, forceparent=True)
|
6993
|
+
self.fill_structure()
|
6994
|
+
self.Activate_zone(newzone)
|
6995
|
+
|
6996
|
+
def OnClickduplicate_vector(self, event:wx.MouseEvent):
|
6997
|
+
"""
|
6998
|
+
Duplication du vecteur actif
|
6999
|
+
"""
|
7000
|
+
if self.wx_exists:
|
7001
|
+
if self.verify_activevec():
|
7002
|
+
return
|
7003
|
+
|
7004
|
+
newvec = self.active_vector.deepcopy_vector()
|
7005
|
+
newvec.myname = self.active_vector.myname + '_copy'
|
7006
|
+
self.active_zone.add_vector(newvec, forceparent=True)
|
7007
|
+
self.fill_structure()
|
7008
|
+
self.Activate_vector(newvec)
|
7009
|
+
|
6518
7010
|
def OnClickdelete_zone(self, event:wx.MouseEvent):
|
6519
7011
|
"""
|
6520
7012
|
Suppression de la zone courante
|
@@ -6769,6 +7261,48 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6769
7261
|
for curvec in curzone.myvectors:
|
6770
7262
|
curvec.myprop.fill_property(self._myprops, updateOGL = False)
|
6771
7263
|
|
7264
|
+
posx = self._myprops[('Move','Start X')]
|
7265
|
+
posy = self._myprops[('Move','Start Y')]
|
7266
|
+
if posx != 99999. and posy != 99999.:
|
7267
|
+
self._start_move = (posx,posy)
|
7268
|
+
else:
|
7269
|
+
self._start_move = None
|
7270
|
+
|
7271
|
+
step = self._myprops[('Move','Step [m]')]
|
7272
|
+
if step != 99999.:
|
7273
|
+
self._move_step = step
|
7274
|
+
else:
|
7275
|
+
self._move_step = None
|
7276
|
+
|
7277
|
+
posx = self._myprops[('Rotation','Center X')]
|
7278
|
+
posy = self._myprops[('Rotation','Center Y')]
|
7279
|
+
if posx != 99999. and posy != 99999.:
|
7280
|
+
self._rotation_center = (posx,posy)
|
7281
|
+
else:
|
7282
|
+
self._rotation_center = None
|
7283
|
+
|
7284
|
+
step = self._myprops[('Rotation','Step [degree]')]
|
7285
|
+
if step != 99999.:
|
7286
|
+
self._rotation_step = step
|
7287
|
+
else:
|
7288
|
+
self._rotation_step = None
|
7289
|
+
|
7290
|
+
angle = self._myprops[('Rotation','Angle [degree]')]
|
7291
|
+
dx = self._myprops[('Move','Delta X')]
|
7292
|
+
dy = self._myprops[('Move','Delta Y')]
|
7293
|
+
|
7294
|
+
if angle != 0. and (dx!= 0. or dy!=0.):
|
7295
|
+
logging.error(_('Rotation and move are not compatible - Choose one and only one'))
|
7296
|
+
elif angle!= 0.:
|
7297
|
+
if self._rotation_center is None:
|
7298
|
+
logging.error(_('No rotation center defined - Choose one'))
|
7299
|
+
else:
|
7300
|
+
self.rotate(angle, self._rotation_center)
|
7301
|
+
self.clear_cache()
|
7302
|
+
elif dx!= 0. or dy!=0.:
|
7303
|
+
self.move(dx,dy)
|
7304
|
+
self.clear_cache()
|
7305
|
+
|
6772
7306
|
if self.mapviewer is not None:
|
6773
7307
|
self.prep_listogl()
|
6774
7308
|
self.mapviewer.Refresh()
|
@@ -6786,10 +7320,40 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6786
7320
|
self._myprops[('Legend','X')] = 99999.
|
6787
7321
|
self._myprops[('Legend','Y')] = 99999.
|
6788
7322
|
self._myprops[('Legend','Text')] = _('Not used')
|
7323
|
+
|
7324
|
+
if self._rotation_center is not None:
|
7325
|
+
self._myprops[('Rotation', 'Center X')] = self._rotation_center[0]
|
7326
|
+
self._myprops[('Rotation', 'Center Y')] = self._rotation_center[1]
|
7327
|
+
else:
|
7328
|
+
self._myprops[('Rotation', 'Center X')] = 99999.
|
7329
|
+
self._myprops[('Rotation', 'Center Y')] = 99999.
|
7330
|
+
|
7331
|
+
if self._rotation_step is not None:
|
7332
|
+
self._myprops[('Rotation', 'Step [degree]')] = self._rotation_step
|
7333
|
+
else:
|
7334
|
+
self._myprops[('Rotation', 'Step [degree]')] = 99999.
|
7335
|
+
|
7336
|
+
self._myprops['Rotation', 'Angle [degree]'] = 0.
|
7337
|
+
|
7338
|
+
if self._start_move is not None:
|
7339
|
+
self._myprops[('Move', 'Start X')] = self._start_move[0]
|
7340
|
+
self._myprops[('Move', 'Start Y')] = self._start_move[1]
|
7341
|
+
else:
|
7342
|
+
self._myprops[('Move', 'Start X')] = 99999.
|
7343
|
+
self._myprops[('Move', 'Start Y')] = 99999.
|
7344
|
+
|
7345
|
+
self._myprops[('Move', 'Delta X')] = 0.
|
7346
|
+
self._myprops[('Move', 'Delta Y')] = 0.
|
7347
|
+
|
7348
|
+
if self._move_step is not None:
|
7349
|
+
self._myprops[('Move', 'Step [m]')] = self._move_step
|
7350
|
+
else:
|
7351
|
+
self._myprops[('Move', 'Step [m]')] = 99999.
|
7352
|
+
|
6789
7353
|
self._myprops.Populate()
|
6790
7354
|
self._myprops.set_callbacks(self._callback_prop, self._callback_destroy_props)
|
6791
7355
|
|
6792
|
-
self._myprops.SetTitle(_('Properties for all vectors in {}'.format(self.
|
7356
|
+
self._myprops.SetTitle(_('Properties for all vectors in {}'.format(self.filename)))
|
6793
7357
|
self._myprops.Center()
|
6794
7358
|
self._myprops.Raise()
|
6795
7359
|
|