wolfhece 2.1.108__py3-none-any.whl → 2.1.110__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 +234 -5
- wolfhece/PyVertex.py +17 -1
- wolfhece/PyVertexvectors.py +732 -112
- wolfhece/apps/curvedigitizer.py +197 -141
- wolfhece/apps/version.py +1 -1
- wolfhece/lazviewer/laz_viewer.py +22 -0
- wolfhece/matplotlib_fig.py +433 -66
- wolfhece/pybridges.py +227 -87
- {wolfhece-2.1.108.dist-info → wolfhece-2.1.110.dist-info}/METADATA +1 -1
- {wolfhece-2.1.108.dist-info → wolfhece-2.1.110.dist-info}/RECORD +13 -13
- {wolfhece-2.1.108.dist-info → wolfhece-2.1.110.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.108.dist-info → wolfhece-2.1.110.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.108.dist-info → wolfhece-2.1.110.dist-info}/top_level.txt +0 -0
wolfhece/PyVertexvectors.py
CHANGED
@@ -59,6 +59,12 @@ class Triangulation(Element_To_Draw):
|
|
59
59
|
self.nb_tri = len(tri)
|
60
60
|
self.nb_pts = len(pts)
|
61
61
|
|
62
|
+
self._start_move = None
|
63
|
+
self._move_step = None # step for a move
|
64
|
+
self._rotation_center = None
|
65
|
+
self._rotation_step = None
|
66
|
+
self._cache = None
|
67
|
+
|
62
68
|
if fn !='':
|
63
69
|
self.filename=fn
|
64
70
|
self.read(fn)
|
@@ -370,6 +376,7 @@ class Triangulation(Element_To_Draw):
|
|
370
376
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
|
371
377
|
|
372
378
|
glEndList()
|
379
|
+
glCallList(self.id_list)
|
373
380
|
except:
|
374
381
|
logging.warning('Problem with OpenGL plot - Triangulation.plot')
|
375
382
|
else:
|
@@ -420,6 +427,67 @@ class Triangulation(Element_To_Draw):
|
|
420
427
|
self.nb_pts = len(self.pts)
|
421
428
|
self.nb_tri = len(self.tri)
|
422
429
|
self.valid_format()
|
430
|
+
|
431
|
+
def set_cache(self):
|
432
|
+
""" Set the cache for the vertices """
|
433
|
+
|
434
|
+
self._cache = self.pts.copy()
|
435
|
+
|
436
|
+
def clear_cache(self):
|
437
|
+
""" Clear the cache for the vertices """
|
438
|
+
|
439
|
+
self._cache = None
|
440
|
+
|
441
|
+
def move(self, delta_x:float, delta_y:float, use_cache:bool = True):
|
442
|
+
""" Move the vertices by a delta_x and delta_y
|
443
|
+
|
444
|
+
:param delta_x: delta x [m]
|
445
|
+
:param delta_y: delta y [m]
|
446
|
+
"""
|
447
|
+
|
448
|
+
if use_cache and self._cache is None:
|
449
|
+
self.set_cache()
|
450
|
+
|
451
|
+
if use_cache:
|
452
|
+
self.pts[:,0] = self._cache[:,0] + delta_x
|
453
|
+
self.pts[:,1] = self._cache[:,1] + delta_y
|
454
|
+
else:
|
455
|
+
self.pts[:,0] += delta_x
|
456
|
+
self.pts[:,1] += delta_y
|
457
|
+
|
458
|
+
def rotate(self, angle:float, center:tuple, use_cache:bool = True):
|
459
|
+
""" Rotate the vertices around a center
|
460
|
+
|
461
|
+
:param angle: angle in degrees -- positive for clockwise rotation
|
462
|
+
:param center: center of rotation
|
463
|
+
"""
|
464
|
+
angle = np.radians(angle)
|
465
|
+
c,s = np.cos(angle), np.sin(angle)
|
466
|
+
R = np.array([[c,-s],[s,c]])
|
467
|
+
|
468
|
+
if use_cache and self._cache is None:
|
469
|
+
self.set_cache()
|
470
|
+
|
471
|
+
if use_cache:
|
472
|
+
locxy = self._cache[:,:2] - np.array(center)
|
473
|
+
self.pts[:,:2] = np.dot(R,locxy.T).T + np.array(center)
|
474
|
+
else:
|
475
|
+
locxy = self.pts[:,:2] - np.array(center)
|
476
|
+
self.pts[:,:2] = np.dot(R,locxy.T).T + np.array(center)
|
477
|
+
|
478
|
+
def rotate_xy(self, x:float, y:float, use_cache:bool = True):
|
479
|
+
""" Rotate the vector around the rotation center and a xy point """
|
480
|
+
|
481
|
+
if self._rotation_center is None:
|
482
|
+
logging.error('No rotation center defined -- set it before rotating by this routine')
|
483
|
+
return self
|
484
|
+
|
485
|
+
angle = np.degrees(np.arctan2(-(y-self._rotation_center[1]), x-self._rotation_center[0]))
|
486
|
+
|
487
|
+
if self._rotation_step is not None:
|
488
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
489
|
+
|
490
|
+
return self.rotate(-angle, center=self._rotation_center, use_cache=use_cache)
|
423
491
|
class vectorproperties:
|
424
492
|
""" Vector properties """
|
425
493
|
used:bool
|
@@ -743,6 +811,48 @@ class vectorproperties:
|
|
743
811
|
self.attachedimage = Path(props[('Image','Attached image')])
|
744
812
|
self.imagevisible = props[('Image','To show')]
|
745
813
|
|
814
|
+
posx = props[('Move','Start X')]
|
815
|
+
posy = props[('Move','Start Y')]
|
816
|
+
move_step = props[('Move','Step [m]')]
|
817
|
+
|
818
|
+
if posx != 99999. and posy != 99999.:
|
819
|
+
self.parent._start_move = (posx,posy)
|
820
|
+
else:
|
821
|
+
self.parent._start_move = None
|
822
|
+
|
823
|
+
if move_step != 99999.:
|
824
|
+
self.parent._move_step = move_step
|
825
|
+
else:
|
826
|
+
self.parent._move_step = None
|
827
|
+
|
828
|
+
posx = props[('Rotation','Center X')]
|
829
|
+
posy = props[('Rotation','Center Y')]
|
830
|
+
rot_step = props[('Rotation','Step [degree]')]
|
831
|
+
|
832
|
+
if posx != 99999. and posy != 99999.:
|
833
|
+
self.parent._rotation_center = (posx,posy)
|
834
|
+
else:
|
835
|
+
self.parent._rotation_center = None
|
836
|
+
|
837
|
+
if rot_step != 99999.:
|
838
|
+
self.parent._rotation_step = rot_step
|
839
|
+
else:
|
840
|
+
self.parent._rotation_step = None
|
841
|
+
|
842
|
+
angle = props[('Rotation','Angle [degree]')]
|
843
|
+
dx = props[('Move','Delta X')]
|
844
|
+
dy = props[('Move','Delta Y')]
|
845
|
+
|
846
|
+
if angle != 0. and (dx != 0. or dy != 0.):
|
847
|
+
logging.error('Both rotation and move are selected')
|
848
|
+
elif angle != 0.:
|
849
|
+
if self.parent._rotation_center is not None:
|
850
|
+
self.parent.rotate(angle, self.parent._rotation_center)
|
851
|
+
self.parent.clear_cache()
|
852
|
+
elif dx != 0. or dy != 0.:
|
853
|
+
self.parent.move(dx,dy)
|
854
|
+
self.parent.clear_cache()
|
855
|
+
|
746
856
|
self.load_unload_image()
|
747
857
|
|
748
858
|
try:
|
@@ -881,6 +991,35 @@ if :\n \
|
|
881
991
|
self.myprops[('Image','Attached image')] = str(self.attachedimage)
|
882
992
|
self.myprops[('Image','To show')] = self.imagevisible
|
883
993
|
|
994
|
+
if self.parent._rotation_center is not None:
|
995
|
+
self.myprops[('Rotation','center X')] = self.parent._rotation_center[0]
|
996
|
+
self.myprops[('Rotation','Center Y')] = self.parent._rotation_center[1]
|
997
|
+
else:
|
998
|
+
self.myprops[('Rotation','Center X')] = 99999.
|
999
|
+
self.myprops[('Rotation','Center Y')] = 99999.
|
1000
|
+
|
1001
|
+
if self.parent._rotation_step is not None:
|
1002
|
+
self.myprops[('Rotation','Step [degree]')] = self.parent._rotation_step
|
1003
|
+
else:
|
1004
|
+
self.myprops[('Rotation','Step [degree]')] = 99999.
|
1005
|
+
|
1006
|
+
self.myprops[('Rotation', 'Angle [degree]')] = 0.
|
1007
|
+
|
1008
|
+
if self.parent._start_move is not None:
|
1009
|
+
self.myprops[('Move','Start X')] = self.parent._start_move[0]
|
1010
|
+
self.myprops[('Move','Start Y')] = self.parent._start_move[1]
|
1011
|
+
else:
|
1012
|
+
self.myprops[('Move','Start X')] = 99999.
|
1013
|
+
self.myprops[('Move','Start Y')] = 99999.
|
1014
|
+
|
1015
|
+
if self.parent._move_step is not None:
|
1016
|
+
self.myprops[('Move','Step [m]')] = self.parent._move_step
|
1017
|
+
else:
|
1018
|
+
self.myprops[('Move','Step [m]')] = 99999.
|
1019
|
+
|
1020
|
+
self.myprops[('Move','Delta X')] = 0.
|
1021
|
+
self.myprops[('Move','Delta Y')] = 0.
|
1022
|
+
|
884
1023
|
self.myprops.Populate()
|
885
1024
|
self.myprops.Layout()
|
886
1025
|
self.myprops.SetSizeHints(500,800)
|
@@ -1014,6 +1153,13 @@ class vector:
|
|
1014
1153
|
self.myvertices=[]
|
1015
1154
|
self.myprop=vectorproperties(parent=self)
|
1016
1155
|
|
1156
|
+
self._cache_vertices = None
|
1157
|
+
self._start_move = None
|
1158
|
+
self._move_step = None
|
1159
|
+
|
1160
|
+
self._rotation_center = None
|
1161
|
+
self._rotation_step = None
|
1162
|
+
|
1017
1163
|
self.linestring = None
|
1018
1164
|
self.polygon = None
|
1019
1165
|
|
@@ -1026,6 +1172,94 @@ class vector:
|
|
1026
1172
|
if fromshapely is not None:
|
1027
1173
|
self.import_shapelyobj(fromshapely)
|
1028
1174
|
|
1175
|
+
def set_cache(self):
|
1176
|
+
""" Set the cache for the vertices """
|
1177
|
+
|
1178
|
+
self._cache_vertices = self.asnparray3d()
|
1179
|
+
|
1180
|
+
def clear_cache(self):
|
1181
|
+
""" Clear the cache for the vertices """
|
1182
|
+
|
1183
|
+
self._cache_vertices = None
|
1184
|
+
|
1185
|
+
def move(self, deltax:float, deltay:float, use_cache:bool = True, inplace:bool = True):
|
1186
|
+
"""
|
1187
|
+
Move the vector
|
1188
|
+
|
1189
|
+
:param deltax: delta x
|
1190
|
+
:param deltay: delta y
|
1191
|
+
:param use_cache: use the cache if available
|
1192
|
+
:param inplace: move the vector inplace or return a new vector
|
1193
|
+
"""
|
1194
|
+
|
1195
|
+
if self._move_step is not None:
|
1196
|
+
deltax = np.round(deltax/self._move_step)*self._move_step
|
1197
|
+
deltay = np.round(deltay/self._move_step)*self._move_step
|
1198
|
+
|
1199
|
+
if inplace:
|
1200
|
+
if use_cache and self._cache_vertices is None:
|
1201
|
+
self.set_cache()
|
1202
|
+
|
1203
|
+
if use_cache:
|
1204
|
+
self.xy = self._cache_vertices[:,:2] + np.array([deltax, deltay])
|
1205
|
+
else:
|
1206
|
+
for curvert in self.myvertices:
|
1207
|
+
curvert.x += deltax
|
1208
|
+
curvert.y += deltay
|
1209
|
+
|
1210
|
+
return self
|
1211
|
+
else:
|
1212
|
+
new_vector = self.deepcopy_vector(self.myname + '_moved')
|
1213
|
+
new_vector.move(deltax, deltay, inplace=True)
|
1214
|
+
|
1215
|
+
return new_vector
|
1216
|
+
|
1217
|
+
def rotate(self, angle:float, center:tuple[float,float]=(0.,0.), use_cache:bool = True, inplace:bool = True):
|
1218
|
+
"""
|
1219
|
+
Rotate the vector
|
1220
|
+
|
1221
|
+
:param angle: angle in degrees
|
1222
|
+
:param center: center of the rotation
|
1223
|
+
:param use_cache: use the cache if available
|
1224
|
+
:param inplace: rotate the vector inplace or return a new vector
|
1225
|
+
"""
|
1226
|
+
|
1227
|
+
if inplace:
|
1228
|
+
if use_cache and self._cache_vertices is None:
|
1229
|
+
self.set_cache()
|
1230
|
+
|
1231
|
+
if use_cache:
|
1232
|
+
locxy = self._cache_vertices[:,:2] - np.array(center)
|
1233
|
+
|
1234
|
+
rotation_matrix = np.array([[np.cos(np.radians(angle)), -np.sin(np.radians(angle))],
|
1235
|
+
[np.sin(np.radians(angle)), np.cos(np.radians(angle))]])
|
1236
|
+
|
1237
|
+
self.xy = np.dot(locxy, rotation_matrix) + np.array(center)
|
1238
|
+
else:
|
1239
|
+
for curvert in self.myvertices:
|
1240
|
+
curvert.rotate(angle, center)
|
1241
|
+
|
1242
|
+
return self
|
1243
|
+
else:
|
1244
|
+
new_vector = self.deepcopy_vector(self.myname + '_rotated')
|
1245
|
+
new_vector.rotate(angle, center, inplace=True)
|
1246
|
+
|
1247
|
+
return new_vector
|
1248
|
+
|
1249
|
+
def rotate_xy(self, x:float, y:float, use_cache:bool = True, inplace:bool = True):
|
1250
|
+
""" Rotate the vector around the rotation center and a xy point """
|
1251
|
+
|
1252
|
+
if self._rotation_center is None:
|
1253
|
+
logging.error('No rotation center defined -- set it before rotating by this routine')
|
1254
|
+
return self
|
1255
|
+
|
1256
|
+
angle = np.degrees(np.arctan2(-(y-self._rotation_center[1]), x-self._rotation_center[0]))
|
1257
|
+
|
1258
|
+
if self._rotation_step is not None:
|
1259
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
1260
|
+
|
1261
|
+
return self.rotate(angle, center=self._rotation_center, use_cache=use_cache, inplace=inplace)
|
1262
|
+
|
1029
1263
|
def get_mapviewer(self):
|
1030
1264
|
"""
|
1031
1265
|
Retourne l'instance de la mapviewer
|
@@ -1352,7 +1586,7 @@ class vector:
|
|
1352
1586
|
|
1353
1587
|
for x,y in mypar.coords:
|
1354
1588
|
xy = Point(x,y)
|
1355
|
-
curs = mypar.project(xy,True)
|
1589
|
+
curs = mypar.project(xy, True)
|
1356
1590
|
curz = myls.interpolate(curs,True).z
|
1357
1591
|
|
1358
1592
|
newvert = wolfvertex(x,y,curz)
|
@@ -1924,6 +2158,10 @@ class vector:
|
|
1924
2158
|
|
1925
2159
|
Retient également les longueurs de chaque segment
|
1926
2160
|
"""
|
2161
|
+
if self.nbvertices < 2:
|
2162
|
+
logging.warning(_('No enough vertices in vector to compute lenghts'))
|
2163
|
+
return
|
2164
|
+
|
1927
2165
|
self._lengthparts2D=np.zeros(self.nbvertices-1)
|
1928
2166
|
self._lengthparts3D=np.zeros(self.nbvertices-1)
|
1929
2167
|
|
@@ -2048,7 +2286,7 @@ class vector:
|
|
2048
2286
|
self.myvertices = newvec.myvertices
|
2049
2287
|
self.update_lengths()
|
2050
2288
|
|
2051
|
-
def interpolate(self,s,is3D=True,adim=True,frombegin=True):
|
2289
|
+
def interpolate(self,s,is3D=True,adim=True,frombegin=True) -> wolfvertex:
|
2052
2290
|
"""
|
2053
2291
|
Interpolation linéaire à une abscisse curviligne 's' donnée
|
2054
2292
|
|
@@ -2790,6 +3028,11 @@ class zone:
|
|
2790
3028
|
self.has_legend = False # indicate if at least one vector in the zone has a legend
|
2791
3029
|
self.has_image = False # indicate if at least one vector in the zone has an image
|
2792
3030
|
|
3031
|
+
self._start_move = None # starting point for a move
|
3032
|
+
self._move_step = None # step for a move
|
3033
|
+
self._rotation_center = None # center of rotation
|
3034
|
+
self._rotation_step = None # step for rotation
|
3035
|
+
|
2793
3036
|
if len(lines)>0:
|
2794
3037
|
# Decoding from lines -- lines is a list of strings provided by the parent during reading
|
2795
3038
|
# The order of the lines is important to ensure compatibility with the WOLF2D format
|
@@ -2823,6 +3066,80 @@ class zone:
|
|
2823
3066
|
# Object can be created from a shapely object
|
2824
3067
|
self.import_shapelyobj(fromshapely)
|
2825
3068
|
|
3069
|
+
def set_cache(self):
|
3070
|
+
"""
|
3071
|
+
Set the cache for the zone and all its vectors
|
3072
|
+
"""
|
3073
|
+
for curvect in self.myvectors:
|
3074
|
+
curvect.set_cache()
|
3075
|
+
|
3076
|
+
def clear_cache(self):
|
3077
|
+
"""
|
3078
|
+
Clear the cache for the zone and all its vectors
|
3079
|
+
"""
|
3080
|
+
for curvect in self.myvectors:
|
3081
|
+
curvect.clear_cache()
|
3082
|
+
|
3083
|
+
self._start_move = None
|
3084
|
+
self._move_step = None
|
3085
|
+
self._rotation_center = None
|
3086
|
+
self._rotation_step = None
|
3087
|
+
|
3088
|
+
self.find_minmax(update=True)
|
3089
|
+
|
3090
|
+
def move(self, dx:float, dy:float, use_cache:bool=True, inplace:bool=True):
|
3091
|
+
"""
|
3092
|
+
Move the zone and all its vectors
|
3093
|
+
"""
|
3094
|
+
|
3095
|
+
if self._move_step is not None:
|
3096
|
+
dx = np.round(dx/self._move_step)*self._move_step
|
3097
|
+
dy = np.round(dy/self._move_step)*self._move_step
|
3098
|
+
|
3099
|
+
if inplace:
|
3100
|
+
for curvect in self.myvectors:
|
3101
|
+
curvect.move(dx, dy, use_cache)
|
3102
|
+
return self
|
3103
|
+
else:
|
3104
|
+
newzone = self.deepcopy()
|
3105
|
+
newzone.move(dx, dy, use_cache= False)
|
3106
|
+
return newzone
|
3107
|
+
|
3108
|
+
def rotate(self, angle:float, center:tuple[float,float], use_cache:bool=True, inplace:bool=True):
|
3109
|
+
"""
|
3110
|
+
Rotate the zone and all its vectors
|
3111
|
+
|
3112
|
+
:param angle: angle in degrees (clockwise)
|
3113
|
+
:param center: center of rotation
|
3114
|
+
:param use_cache: use the cache for the vertices
|
3115
|
+
:param inplace: modify the zone in place or return a new one
|
3116
|
+
"""
|
3117
|
+
|
3118
|
+
if inplace:
|
3119
|
+
for curvect in self.myvectors:
|
3120
|
+
curvect.rotate(angle, center, use_cache)
|
3121
|
+
return self
|
3122
|
+
else:
|
3123
|
+
newzone = self.deepcopy()
|
3124
|
+
newzone.rotate(angle, center, use_cache= False)
|
3125
|
+
return newzone
|
3126
|
+
|
3127
|
+
def rotate_xy(self, x:float, y:float, use_cache:bool=True, inplace:bool=True):
|
3128
|
+
"""
|
3129
|
+
Rotate the zone and all its vectors in the xy plane
|
3130
|
+
"""
|
3131
|
+
|
3132
|
+
if self._rotation_center is None:
|
3133
|
+
logging.error(_('No rotation center defined - Set it before rotating by this routine'))
|
3134
|
+
return self
|
3135
|
+
|
3136
|
+
angle = np.degree(np.arctan2(y-self._rotation_center[1], x-self._rotation_center[0]))
|
3137
|
+
|
3138
|
+
if self._rotation_step is not None:
|
3139
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
3140
|
+
|
3141
|
+
return self.rotate(angle, self._rotation_center, use_cache, inplace)
|
3142
|
+
|
2826
3143
|
@property
|
2827
3144
|
def nbvectors(self):
|
2828
3145
|
return len(self.myvectors)
|
@@ -4406,6 +4723,36 @@ class zone:
|
|
4406
4723
|
self.myprops[('Legend','X')] = 99999.
|
4407
4724
|
self.myprops[('Legend','Y')] = 99999.
|
4408
4725
|
self.myprops[('Legend','Text')] = _('Not used')
|
4726
|
+
|
4727
|
+
if self._rotation_center is None:
|
4728
|
+
self.myprops[('Rotation','Center X')] = 99999.
|
4729
|
+
self.myprops[('Rotation','Center Y')] = 99999.
|
4730
|
+
else:
|
4731
|
+
self.myprops[('Rotation','Center X')] = self._rotation_center.x
|
4732
|
+
self.myprops[('Rotation','Center Y')] = self._rotation_center.y
|
4733
|
+
|
4734
|
+
if self._rotation_step is None:
|
4735
|
+
self.myprops[('Rotation','Step [degree]')] = 99999.
|
4736
|
+
else:
|
4737
|
+
self.myprops[('Rotation','Step [degree]')] = self._rotation_step
|
4738
|
+
|
4739
|
+
self.myprops[('Rotation', 'Angle [degree]')] = 0.
|
4740
|
+
|
4741
|
+
if self._move_start is None:
|
4742
|
+
self.myprops[('Move','Start X')] = 99999.
|
4743
|
+
self.myprops[('Move','Start Y')] = 99999.
|
4744
|
+
else:
|
4745
|
+
self.myprops[('Move','Start X')] = self._move_start.x
|
4746
|
+
self.myprops[('Move','Start Y')] = self._move_start.y
|
4747
|
+
|
4748
|
+
if self._move_step is None:
|
4749
|
+
self.myprops[('Move','Step [m]')] = 99999.
|
4750
|
+
else:
|
4751
|
+
self.myprops[('Move','Step [m]')] = self._move_step
|
4752
|
+
|
4753
|
+
self.myprops[('Move', 'Delta X')] = 0.
|
4754
|
+
self.myprops[('Move', 'Delta Y')] = 0.
|
4755
|
+
|
4409
4756
|
self.myprops.Populate()
|
4410
4757
|
self.myprops.set_callbacks(self._callback_prop, self._callback_destroy_props)
|
4411
4758
|
|
@@ -4442,6 +4789,24 @@ class zone:
|
|
4442
4789
|
for curvec in self.myvectors:
|
4443
4790
|
curvec.myprop.fill_property(self.myprops, updateOGL = False)
|
4444
4791
|
|
4792
|
+
angle = self.myprops[('Rotation', 'Angle [degree]')]
|
4793
|
+
dx = self.myprops[('Move', 'Delta X')]
|
4794
|
+
dy = self.myprops[('Move', 'Delta Y')]
|
4795
|
+
|
4796
|
+
if angle!=0. and (dx!=0. or dy!=0.):
|
4797
|
+
logging.warning(_('Rotation and translation are not compatible'))
|
4798
|
+
return
|
4799
|
+
elif angle!=0.:
|
4800
|
+
if self._rotation_center is None:
|
4801
|
+
logging.warning(_('No rotation center defined'))
|
4802
|
+
return
|
4803
|
+
else:
|
4804
|
+
self.rotate(angle, self._rotation_center)
|
4805
|
+
self.clear_cache()
|
4806
|
+
elif dx!=0. or dy!=0.:
|
4807
|
+
self.move(dx, dy)
|
4808
|
+
self.clear_cache()
|
4809
|
+
|
4445
4810
|
if self.parent.mapviewer is not None:
|
4446
4811
|
self.prep_listogl()
|
4447
4812
|
self.parent.mapviewer.Refresh()
|
@@ -4559,6 +4924,11 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4559
4924
|
self.ty=ty
|
4560
4925
|
self.myzones=[]
|
4561
4926
|
|
4927
|
+
self._start_move = None
|
4928
|
+
self._move_step = None
|
4929
|
+
self._rotation_center = None
|
4930
|
+
self._rotation_step = None
|
4931
|
+
|
4562
4932
|
if self.filename!='':
|
4563
4933
|
# lecture du fichier
|
4564
4934
|
|
@@ -4630,6 +5000,70 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
4630
5000
|
if plotted and self.has_OGLContext and not self.shared:
|
4631
5001
|
self.prep_listogl()
|
4632
5002
|
|
5003
|
+
def set_cache(self):
|
5004
|
+
""" Set cache for all zones """
|
5005
|
+
|
5006
|
+
for curzone in self.myzones:
|
5007
|
+
curzone.set_cache()
|
5008
|
+
|
5009
|
+
def clear_cache(self):
|
5010
|
+
""" Clear cache for all zones """
|
5011
|
+
|
5012
|
+
for curzone in self.myzones:
|
5013
|
+
curzone.clear_cache()
|
5014
|
+
|
5015
|
+
def move(self, dx:float, dy:float, use_cache:bool = True, inplace:bool = True):
|
5016
|
+
""" Move all zones """
|
5017
|
+
|
5018
|
+
if self._move_step is not None:
|
5019
|
+
dx = np.round(dx/self._move_step)*self._move_step
|
5020
|
+
dy = np.round(dy/self._move_step)*self._move_step
|
5021
|
+
|
5022
|
+
if inplace:
|
5023
|
+
for curzone in self.myzones:
|
5024
|
+
curzone.move(dx, dy, use_cache=use_cache, inplace=inplace)
|
5025
|
+
|
5026
|
+
return self
|
5027
|
+
|
5028
|
+
else:
|
5029
|
+
newzones = self.deepcopy_zones()
|
5030
|
+
newzones.move(dx, dy, use_cache=False, inplace=True)
|
5031
|
+
newzones.find_minmax(True)
|
5032
|
+
return newzones
|
5033
|
+
|
5034
|
+
def rotate(self, angle:float, center:Point = None, use_cache:bool = True, inplace:bool = True):
|
5035
|
+
""" Rotate all zones """
|
5036
|
+
|
5037
|
+
if self._rotation_step is not None:
|
5038
|
+
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
5039
|
+
|
5040
|
+
if inplace:
|
5041
|
+
for curzone in self.myzones:
|
5042
|
+
curzone.rotate(angle, center, use_cache=use_cache, inplace=inplace)
|
5043
|
+
|
5044
|
+
return self
|
5045
|
+
|
5046
|
+
else:
|
5047
|
+
newzones = self.deepcopy_zones()
|
5048
|
+
newzones.rotate(angle, center, use_cache=False, inplace=True)
|
5049
|
+
newzones.find_minmax(True)
|
5050
|
+
return newzones
|
5051
|
+
|
5052
|
+
def rotate_xy(self, angle:float, center:Point = None, use_cache:bool = True, inplace:bool = True):
|
5053
|
+
""" Rotate all zones """
|
5054
|
+
|
5055
|
+
if inplace:
|
5056
|
+
for curzone in self.myzones:
|
5057
|
+
curzone.rotate_xy(angle, center, use_cache=use_cache, inplace=inplace)
|
5058
|
+
|
5059
|
+
return self
|
5060
|
+
|
5061
|
+
else:
|
5062
|
+
newzones = self.deepcopy_zones()
|
5063
|
+
newzones.rotate_xy(angle, center, use_cache=False, inplace=True)
|
5064
|
+
newzones.find_minmax(True)
|
5065
|
+
return newzones
|
5066
|
+
|
4633
5067
|
def force_unique_zone_name(self):
|
4634
5068
|
"""
|
4635
5069
|
Check if all zones have a unique id
|
@@ -5297,6 +5731,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5297
5731
|
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"))
|
5298
5732
|
self.evaluates.Bind(wx.EVT_BUTTON,self.Onevaluates)
|
5299
5733
|
|
5734
|
+
self.update_from_s = wx.Button(self,label=_('Update from sz (support)'))
|
5735
|
+
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."))
|
5736
|
+
self.update_from_s.Bind(wx.EVT_BUTTON,self.Onupdate_from_sz_support)
|
5737
|
+
|
5300
5738
|
# Modified
|
5301
5739
|
self.zoomonactive = wx.Button(self,label=_('Zoom on active vector'))
|
5302
5740
|
self.zoomonactive.SetToolTip(_("Zoom on the active vector and a default view size of 500 m x 500 m"))
|
@@ -5338,8 +5776,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5338
5776
|
self.slidingpoly.Bind(wx.EVT_BUTTON,self.Oncreateslidingpoly)
|
5339
5777
|
|
5340
5778
|
# Added
|
5341
|
-
self.getxyfromsz = wx.Button(self, label = _('
|
5342
|
-
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 (
|
5779
|
+
self.getxyfromsz = wx.Button(self, label = _('Update from sz (2 points)'))
|
5780
|
+
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)"))
|
5343
5781
|
self.getxyfromsz.Bind(wx.EVT_BUTTON, self.get_xy_from_sz)
|
5344
5782
|
|
5345
5783
|
boxright.Add(self.xls,1,wx.EXPAND)
|
@@ -5363,10 +5801,16 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5363
5801
|
|
5364
5802
|
# boxright.Add(self.zoomonactive,0,wx.EXPAND)
|
5365
5803
|
boxright.Add(boxzoom,0,wx.EXPAND)
|
5366
|
-
|
5804
|
+
|
5805
|
+
box_s = wx.BoxSizer(wx.HORIZONTAL)
|
5806
|
+
boxright.Add(box_s,0,wx.EXPAND)
|
5807
|
+
|
5808
|
+
box_s.Add(self.evaluates,1,wx.EXPAND)
|
5809
|
+
box_s.Add(self.update_from_s,1,wx.EXPAND)
|
5810
|
+
box_s.Add(self.getxyfromsz,1,wx.EXPAND) # Added
|
5811
|
+
|
5367
5812
|
boxright.Add(self.interpxyz,0,wx.EXPAND)
|
5368
5813
|
boxright.Add(self.sascending,0,wx.EXPAND)
|
5369
|
-
boxright.Add(self.getxyfromsz,0,wx.EXPAND) # Added
|
5370
5814
|
|
5371
5815
|
self.butgetval = wx.Button(self,label=_('Get values (self or active array)'))
|
5372
5816
|
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"))
|
@@ -5381,8 +5825,22 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5381
5825
|
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"))
|
5382
5826
|
self.butgetrefvallinked.Bind(wx.EVT_BUTTON,self.Ongetvalueslinkedandref)
|
5383
5827
|
|
5828
|
+
self._move_rotate_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
5829
|
+
|
5830
|
+
self.butmove = wx.Button(self,label=_('Move'))
|
5831
|
+
self.butmove.SetToolTip(_("Move the active vector - If not defined in properties, the first right click is the origin of the move"))
|
5832
|
+
self.butmove.Bind(wx.EVT_BUTTON,self.OnMove)
|
5833
|
+
|
5834
|
+
self.butrotate = wx.Button(self,label=_('Rotate'))
|
5835
|
+
self.butrotate.SetToolTip(_("Rotate the active vector - If not defined in properties, the first right click is the origin of the rotation"))
|
5836
|
+
self.butrotate.Bind(wx.EVT_BUTTON,self.OnRotate)
|
5837
|
+
|
5838
|
+
self._move_rotate_sizer.Add(self.butmove, 1, wx.EXPAND)
|
5839
|
+
self._move_rotate_sizer.Add(self.butrotate, 1, wx.EXPAND)
|
5840
|
+
|
5384
5841
|
boxright.Add(self.butgetvallinked,0,wx.EXPAND)
|
5385
5842
|
boxright.Add(self.butgetrefvallinked,0,wx.EXPAND)
|
5843
|
+
boxright.Add(self._move_rotate_sizer, 0, wx.EXPAND)
|
5386
5844
|
|
5387
5845
|
self.treelist = TreeListCtrl(self,style=TL_CHECKBOX|wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_EDIT_LABELS)
|
5388
5846
|
self.treelist.AppendColumn('Zones')
|
@@ -5401,6 +5859,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5401
5859
|
|
5402
5860
|
self.addzone = wx.Button(self,label=_('Add zone'))
|
5403
5861
|
self.addvector = wx.Button(self,label=_('Add vector'))
|
5862
|
+
|
5863
|
+
self.duplicatezone = wx.Button(self,label=_('Duplicate zone'))
|
5864
|
+
self.duplicatevector = wx.Button(self,label=_('Duplicate vector'))
|
5865
|
+
|
5404
5866
|
self.deletezone = wx.Button(self,label=_('Delete zone'))
|
5405
5867
|
self.findactivevector = wx.Button(self,label=_('Find in all'))
|
5406
5868
|
self.findactivevector.SetToolTip(_("Search and activate the nearest vector by mouse click (Searching window : all zones)"))
|
@@ -5414,8 +5876,24 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5414
5876
|
self.downzone = wx.Button(self,label=_('Down zone'))
|
5415
5877
|
# self.interpolate = wx.Button(self,label=_('Interpolate vector'))
|
5416
5878
|
|
5879
|
+
self._move_rotate_zone_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
5880
|
+
self.butmove_zone = wx.Button(self,label=_('Move zone'))
|
5881
|
+
self.butmove_zone.SetToolTip(_("Move the active zone - If not defined in properties, the first right click is the origin of the move"))
|
5882
|
+
self.butmove_zone.Bind(wx.EVT_BUTTON,self.OnMoveZone)
|
5883
|
+
|
5884
|
+
self.butrotate_zone = wx.Button(self,label=_('Rotate zone'))
|
5885
|
+
self.butrotate_zone.SetToolTip(_("Rotate the active zone - If not defined in properties, the first right click is the origin of the rotation"))
|
5886
|
+
self.butrotate_zone.Bind(wx.EVT_BUTTON,self.OnRotateZone)
|
5887
|
+
|
5888
|
+
self._move_rotate_zone_sizer.Add(self.butmove_zone, 1, wx.EXPAND)
|
5889
|
+
self._move_rotate_zone_sizer.Add(self.butrotate_zone, 1, wx.EXPAND)
|
5890
|
+
|
5417
5891
|
self.addzone.Bind(wx.EVT_BUTTON,self.OnClickadd_zone)
|
5418
5892
|
self.addvector.Bind(wx.EVT_BUTTON,self.OnClickadd_vector)
|
5893
|
+
|
5894
|
+
self.duplicatezone.Bind(wx.EVT_BUTTON,self.OnClickduplicate_zone)
|
5895
|
+
self.duplicatevector.Bind(wx.EVT_BUTTON,self.OnClickduplicate_vector)
|
5896
|
+
|
5419
5897
|
self.deletezone.Bind(wx.EVT_BUTTON,self.OnClickdelete_zone)
|
5420
5898
|
self.deletevector.Bind(wx.EVT_BUTTON,self.OnClickdelete_vector)
|
5421
5899
|
self.upvector.Bind(wx.EVT_BUTTON,self.OnClickup_vector)
|
@@ -5433,6 +5911,11 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5433
5911
|
boxadd.Add(self.addzone,1,wx.EXPAND)
|
5434
5912
|
boxadd.Add(self.addvector,1,wx.EXPAND)
|
5435
5913
|
|
5914
|
+
boxduplicate = wx.BoxSizer(wx.HORIZONTAL)
|
5915
|
+
boxduplicate.Add(self.duplicatezone,1,wx.EXPAND)
|
5916
|
+
boxduplicate.Add(self.duplicatevector,1,wx.EXPAND)
|
5917
|
+
boxadd.Add(boxduplicate,1,wx.EXPAND)
|
5918
|
+
|
5436
5919
|
subboxadd = wx.BoxSizer(wx.HORIZONTAL)
|
5437
5920
|
subboxadd.Add(self.findactivevector,1,wx.EXPAND)
|
5438
5921
|
subboxadd.Add(self.findactivevectorcurz,1,wx.EXPAND)
|
@@ -5467,6 +5950,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5467
5950
|
boxleft.Add(boxdelete,0,wx.EXPAND)
|
5468
5951
|
boxleft.Add(boxupdown,0,wx.EXPAND)
|
5469
5952
|
boxleft.Add(boxtri,0,wx.EXPAND)
|
5953
|
+
boxleft.Add(self._move_rotate_zone_sizer, 0, wx.EXPAND)
|
5470
5954
|
|
5471
5955
|
box.Add(boxleft,1,wx.EXPAND)
|
5472
5956
|
box.Add(boxright,1,wx.EXPAND)
|
@@ -5494,7 +5978,6 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5494
5978
|
|
5495
5979
|
self.init_struct=False
|
5496
5980
|
|
5497
|
-
|
5498
5981
|
def get_xy_from_sz(self, event: wx.Event):
|
5499
5982
|
"""
|
5500
5983
|
Add vertices and their respectives xy coordinates from s and Z entries in the xls grid:
|
@@ -5503,98 +5986,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5503
5986
|
if self.wx_exists:
|
5504
5987
|
if self.verify_activevec():
|
5505
5988
|
return
|
5506
|
-
curv = self.active_vector
|
5507
|
-
n_rows = self.xls.GetNumberRows()
|
5508
|
-
|
5509
|
-
# Getting the 2 first XY coordinates
|
5510
|
-
X =[]
|
5511
|
-
Y = []
|
5512
5989
|
|
5513
|
-
z_row = 1 #Starting from the second row because the first one is the initial point
|
5514
|
-
|
5515
|
-
# First row coordinates
|
5516
|
-
x1 = self.xls.GetCellValue(0,0)
|
5517
|
-
y1 = self.xls.GetCellValue(0,1)
|
5518
|
-
|
5519
|
-
|
5520
|
-
if x1 != '' and y1 != '':
|
5521
|
-
X.append(float(x1))
|
5522
|
-
Y.append(float(y1))
|
5523
|
-
|
5524
|
-
else:
|
5525
|
-
raise Exception('Encode the coordinates of the initial point (S = 0 --> first point)')
|
5526
|
-
|
5527
|
-
# Coordinates of the second points
|
5528
|
-
while z_row < n_rows:
|
5529
|
-
if len(X) < 2 and len(Y) < 2:
|
5530
|
-
x2 = self.xls.GetCellValue(z_row,0)
|
5531
|
-
y2 = self.xls.GetCellValue(z_row,1)
|
5532
|
-
|
5533
|
-
if x2 != '' and y2 != '':
|
5534
|
-
X.append(float(x2))
|
5535
|
-
Y.append(float(y2))
|
5536
|
-
|
5537
|
-
z_row += 1
|
5538
|
-
|
5539
|
-
else:
|
5540
|
-
break
|
5541
|
-
|
5542
|
-
xy1 = np.array([X[0], Y[0]])
|
5543
|
-
xy2 = np.array([X[1], Y[1]])
|
5544
|
-
|
5545
|
-
# Collection of sz coordinates
|
5546
|
-
row = 0
|
5547
|
-
|
5548
|
-
SZ = []
|
5549
|
-
|
5550
|
-
while row < n_rows:
|
5551
|
-
s = self.xls.GetCellValue(row,4)
|
5552
|
-
z = self.xls.GetCellValue(row,2)
|
5553
|
-
|
5554
|
-
if z=='':
|
5555
|
-
z=0.
|
5556
|
-
|
5557
|
-
if s != '':
|
5558
|
-
SZ.append((s,z))
|
5559
|
-
row += 1
|
5560
|
-
|
5561
|
-
elif s=='': #FIXME logging msg to notify the user a point is missing
|
5562
|
-
break
|
5563
|
-
|
5564
|
-
else:
|
5565
|
-
raise Exception (_("Recheck your data inputs"))
|
5566
|
-
break
|
5567
|
-
|
5568
|
-
sz = np.asarray(SZ,dtype='float64') # FIXME The type is required otherwise type == <U
|
5569
|
-
|
5570
|
-
# Creation of vertices
|
5571
|
-
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
5572
|
-
if not np.array_equal(xy1,xy2):
|
5573
|
-
curv.myvertices=[]
|
5574
|
-
curv.nbvertices = 0
|
5575
|
-
|
5576
|
-
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
5577
|
-
norm = np.linalg.norm([dx,dy])
|
5578
|
-
dx, dy = dx/norm, dy/norm
|
5579
|
-
|
5580
|
-
for cur in sz:
|
5581
|
-
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
5582
|
-
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
5583
|
-
|
5584
|
-
# update of the xls grid
|
5585
|
-
for k in range(curv.nbvertices ):
|
5586
|
-
self.xls.SetCellValue(k,0,str(curv.myvertices[k].x))
|
5587
|
-
self.xls.SetCellValue(k,1,str(curv.myvertices[k].y))
|
5588
|
-
|
5589
|
-
|
5590
|
-
def get_xy_from_sz(self, event: wx.Event):
|
5591
|
-
"""
|
5592
|
-
Add vertices and their respectives xy coordinates from s and Z entries in the xls grid:
|
5593
|
-
- NB: The coordinates of the initial point s= 0 and one other points should be explicitly given in the xls grid.
|
5594
|
-
"""
|
5595
|
-
if self.wx_exists:
|
5596
|
-
if self.verify_activevec():
|
5597
|
-
return
|
5598
5990
|
curv = self.active_vector
|
5599
5991
|
n_rows = self.xls.GetNumberRows()
|
5600
5992
|
|
@@ -5663,19 +6055,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5663
6055
|
|
5664
6056
|
sz = np.asarray(SZ,dtype='float64') # FIXME The type is required otherwise type == <U
|
5665
6057
|
|
5666
|
-
|
5667
|
-
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
5668
|
-
if not np.array_equal(xy1,xy2):
|
5669
|
-
curv.myvertices=[]
|
5670
|
-
curv.nbvertices = 0
|
5671
|
-
|
5672
|
-
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
5673
|
-
norm = np.linalg.norm([dx,dy])
|
5674
|
-
dx, dy = dx/norm, dy/norm
|
5675
|
-
|
5676
|
-
for cur in sz:
|
5677
|
-
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
5678
|
-
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
6058
|
+
self.update_from_sz_direction(xy1, xy2, sz)
|
5679
6059
|
|
5680
6060
|
# update of the xls grid
|
5681
6061
|
for k in range(curv.nbvertices ):
|
@@ -5840,6 +6220,56 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
5840
6220
|
self.expand_tree(self.active_zone)
|
5841
6221
|
self.active_zone.reset_listogl()
|
5842
6222
|
|
6223
|
+
def OnMove(self, event:wx.MouseEvent):
|
6224
|
+
"""
|
6225
|
+
Déplacement du vecteur actif
|
6226
|
+
"""
|
6227
|
+
if self.wx_exists:
|
6228
|
+
if self.verify_activevec():
|
6229
|
+
return
|
6230
|
+
|
6231
|
+
self.mapviewer.start_action('move vector', _('Move vector'))
|
6232
|
+
self.active_vector.set_cache()
|
6233
|
+
self.mapviewer.mimicme()
|
6234
|
+
|
6235
|
+
def OnMoveZone(self, event:wx.MouseEvent):
|
6236
|
+
"""
|
6237
|
+
Déplacement de la zone active
|
6238
|
+
"""
|
6239
|
+
if self.wx_exists:
|
6240
|
+
if self.verify_activezone():
|
6241
|
+
return
|
6242
|
+
|
6243
|
+
self.mapviewer.start_action('move zone', _('Move zone'))
|
6244
|
+
self.active_zone.set_cache()
|
6245
|
+
self.mapviewer.mimicme()
|
6246
|
+
|
6247
|
+
def OnRotate(self, event:wx.MouseEvent):
|
6248
|
+
"""
|
6249
|
+
Rotation du vecteur actif
|
6250
|
+
"""
|
6251
|
+
|
6252
|
+
if self.wx_exists:
|
6253
|
+
if self.verify_activevec():
|
6254
|
+
return
|
6255
|
+
|
6256
|
+
self.mapviewer.start_action('rotate vector', _('Rotate vector'))
|
6257
|
+
self.active_vector.set_cache()
|
6258
|
+
self.mapviewer.mimicme()
|
6259
|
+
|
6260
|
+
def OnRotateZone(self, event:wx.MouseEvent):
|
6261
|
+
"""
|
6262
|
+
Rotation de la zone active
|
6263
|
+
"""
|
6264
|
+
|
6265
|
+
if self.wx_exists:
|
6266
|
+
if self.verify_activezone():
|
6267
|
+
return
|
6268
|
+
|
6269
|
+
self.mapviewer.start_action('rotate zone', _('Rotate zone'))
|
6270
|
+
self.active_zone.set_cache()
|
6271
|
+
self.mapviewer.mimicme()
|
6272
|
+
|
5843
6273
|
def OncaptureandDynapar(self, event:wx.MouseEvent):
|
5844
6274
|
"""
|
5845
6275
|
Ajoute des vertices au vecteur courant et crée des parallèles gauche-droite
|
@@ -6399,6 +6829,98 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6399
6829
|
s+=curv._lengthparts3D[k]
|
6400
6830
|
self.xls.SetCellValue(k+1,4,str(s))
|
6401
6831
|
|
6832
|
+
def Onupdate_from_sz_support(self, event:wx.MouseEvent):
|
6833
|
+
""" Update the active vector from the sz values in the xls grid """
|
6834
|
+
|
6835
|
+
if self.active_vector is None:
|
6836
|
+
logging.info(_('No active vector -- Nothing to do'))
|
6837
|
+
return
|
6838
|
+
|
6839
|
+
sz = []
|
6840
|
+
|
6841
|
+
i = 0
|
6842
|
+
while self.xls.GetCellValue(i,4) != '':
|
6843
|
+
sz.append((float(self.xls.GetCellValue(i,4)), float(self.xls.GetCellValue(i,2))))
|
6844
|
+
i += 1
|
6845
|
+
|
6846
|
+
logging.info(f'Number of points: {len(sz)}')
|
6847
|
+
|
6848
|
+
vec_sz = np.array(sz)
|
6849
|
+
|
6850
|
+
self.update_from_sz_support(vec=self.active_vector, sz=vec_sz)
|
6851
|
+
|
6852
|
+
# update of the xls grid
|
6853
|
+
for k in range(self.active_vector.nbvertices ):
|
6854
|
+
self.xls.SetCellValue(k,0,str(self.active_vector.myvertices[k].x))
|
6855
|
+
self.xls.SetCellValue(k,1,str(self.active_vector.myvertices[k].y))
|
6856
|
+
|
6857
|
+
|
6858
|
+
def update_from_sz_direction(self, xy1:np.ndarray, xy2:np.ndarray, sz:np.ndarray):
|
6859
|
+
""" Update the active vector from the sz values in the xls grid """
|
6860
|
+
|
6861
|
+
if self.active_vector is None:
|
6862
|
+
logging.info(_('No active vector -- Nothing to do'))
|
6863
|
+
return
|
6864
|
+
|
6865
|
+
curv = self.active_vector
|
6866
|
+
|
6867
|
+
# Creation of vertices
|
6868
|
+
if sz.shape[1]==2 and xy1.shape==(2,) and xy2.shape==(2,):
|
6869
|
+
if not np.array_equal(xy1,xy2):
|
6870
|
+
curv.myvertices=[]
|
6871
|
+
|
6872
|
+
dx, dy = xy2[0]-xy1[0], xy2[1]-xy1[1]
|
6873
|
+
norm = np.linalg.norm([dx,dy])
|
6874
|
+
dx, dy = dx/norm, dy/norm
|
6875
|
+
|
6876
|
+
for cur in sz:
|
6877
|
+
x, y = xy1[0] + dx*cur[0], xy1[1] + dy*cur[0]
|
6878
|
+
curv.add_vertex(wolfvertex(x, y, float(cur[1])))
|
6879
|
+
|
6880
|
+
self.find_minmax(True)
|
6881
|
+
|
6882
|
+
def update_from_sz_support(self, vec: vector, sz:np.ndarray, dialog_box = True):
|
6883
|
+
|
6884
|
+
if sz.shape[0] ==0:
|
6885
|
+
logging.warning(_('No data to update'))
|
6886
|
+
return
|
6887
|
+
|
6888
|
+
support_vec = vec.deepcopy_vector()
|
6889
|
+
support_vec.update_lengths()
|
6890
|
+
|
6891
|
+
if support_vec.length2D is None or support_vec.length3D is None:
|
6892
|
+
logging.warning(_('The support vector must be updated before updating the active vector'))
|
6893
|
+
return
|
6894
|
+
|
6895
|
+
if dialog_box:
|
6896
|
+
dlg = wx.SingleChoiceDialog(None, "Which mode?", "How to evaluate lengths?", ['2D','3D'])
|
6897
|
+
ret=dlg.ShowModal()
|
6898
|
+
if ret==wx.ID_CANCEL:
|
6899
|
+
dlg.Destroy()
|
6900
|
+
return
|
6901
|
+
|
6902
|
+
method=dlg.GetStringSelection()
|
6903
|
+
dlg.Destroy()
|
6904
|
+
else:
|
6905
|
+
method = '2D'
|
6906
|
+
|
6907
|
+
if method == '2D':
|
6908
|
+
if sz[-1,0] > support_vec.length2D:
|
6909
|
+
logging.warning(_('The last point is beyond the vector length. You must add more points !'))
|
6910
|
+
return
|
6911
|
+
else:
|
6912
|
+
if sz[-1,0] > support_vec.length3D:
|
6913
|
+
logging.warning(_('The last point is beyond the vector length. You must add more points !'))
|
6914
|
+
return
|
6915
|
+
|
6916
|
+
vec.myvertices = []
|
6917
|
+
for s,z in sz:
|
6918
|
+
new_vertex = support_vec.interpolate(s, method == '3D', adim= False)
|
6919
|
+
new_vertex.z = z
|
6920
|
+
vec.add_vertex(new_vertex)
|
6921
|
+
|
6922
|
+
self.find_minmax(True)
|
6923
|
+
|
6402
6924
|
def evaluate_s (self, vec: vector =None, dialog_box = True):
|
6403
6925
|
"""
|
6404
6926
|
Calcule la position curviligne du vecteur encodé
|
@@ -6527,6 +7049,32 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6527
7049
|
else:
|
6528
7050
|
return
|
6529
7051
|
|
7052
|
+
def OnClickduplicate_zone(self, event:wx.MouseEvent):
|
7053
|
+
""" Duplication de la zone active """
|
7054
|
+
if self.wx_exists:
|
7055
|
+
if self.verify_activezone():
|
7056
|
+
return
|
7057
|
+
|
7058
|
+
newzone = self.active_zone.deepcopy_zone()
|
7059
|
+
newzone.myname = self.active_zone.myname + '_copy'
|
7060
|
+
self.add_zone(newzone, forceparent=True)
|
7061
|
+
self.fill_structure()
|
7062
|
+
self.Activate_zone(newzone)
|
7063
|
+
|
7064
|
+
def OnClickduplicate_vector(self, event:wx.MouseEvent):
|
7065
|
+
"""
|
7066
|
+
Duplication du vecteur actif
|
7067
|
+
"""
|
7068
|
+
if self.wx_exists:
|
7069
|
+
if self.verify_activevec():
|
7070
|
+
return
|
7071
|
+
|
7072
|
+
newvec = self.active_vector.deepcopy_vector()
|
7073
|
+
newvec.myname = self.active_vector.myname + '_copy'
|
7074
|
+
self.active_zone.add_vector(newvec, forceparent=True)
|
7075
|
+
self.fill_structure()
|
7076
|
+
self.Activate_vector(newvec)
|
7077
|
+
|
6530
7078
|
def OnClickdelete_zone(self, event:wx.MouseEvent):
|
6531
7079
|
"""
|
6532
7080
|
Suppression de la zone courante
|
@@ -6781,6 +7329,48 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6781
7329
|
for curvec in curzone.myvectors:
|
6782
7330
|
curvec.myprop.fill_property(self._myprops, updateOGL = False)
|
6783
7331
|
|
7332
|
+
posx = self._myprops[('Move','Start X')]
|
7333
|
+
posy = self._myprops[('Move','Start Y')]
|
7334
|
+
if posx != 99999. and posy != 99999.:
|
7335
|
+
self._start_move = (posx,posy)
|
7336
|
+
else:
|
7337
|
+
self._start_move = None
|
7338
|
+
|
7339
|
+
step = self._myprops[('Move','Step [m]')]
|
7340
|
+
if step != 99999.:
|
7341
|
+
self._move_step = step
|
7342
|
+
else:
|
7343
|
+
self._move_step = None
|
7344
|
+
|
7345
|
+
posx = self._myprops[('Rotation','Center X')]
|
7346
|
+
posy = self._myprops[('Rotation','Center Y')]
|
7347
|
+
if posx != 99999. and posy != 99999.:
|
7348
|
+
self._rotation_center = (posx,posy)
|
7349
|
+
else:
|
7350
|
+
self._rotation_center = None
|
7351
|
+
|
7352
|
+
step = self._myprops[('Rotation','Step [degree]')]
|
7353
|
+
if step != 99999.:
|
7354
|
+
self._rotation_step = step
|
7355
|
+
else:
|
7356
|
+
self._rotation_step = None
|
7357
|
+
|
7358
|
+
angle = self._myprops[('Rotation','Angle [degree]')]
|
7359
|
+
dx = self._myprops[('Move','Delta X')]
|
7360
|
+
dy = self._myprops[('Move','Delta Y')]
|
7361
|
+
|
7362
|
+
if angle != 0. and (dx!= 0. or dy!=0.):
|
7363
|
+
logging.error(_('Rotation and move are not compatible - Choose one and only one'))
|
7364
|
+
elif angle!= 0.:
|
7365
|
+
if self._rotation_center is None:
|
7366
|
+
logging.error(_('No rotation center defined - Choose one'))
|
7367
|
+
else:
|
7368
|
+
self.rotate(angle, self._rotation_center)
|
7369
|
+
self.clear_cache()
|
7370
|
+
elif dx!= 0. or dy!=0.:
|
7371
|
+
self.move(dx,dy)
|
7372
|
+
self.clear_cache()
|
7373
|
+
|
6784
7374
|
if self.mapviewer is not None:
|
6785
7375
|
self.prep_listogl()
|
6786
7376
|
self.mapviewer.Refresh()
|
@@ -6798,10 +7388,40 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6798
7388
|
self._myprops[('Legend','X')] = 99999.
|
6799
7389
|
self._myprops[('Legend','Y')] = 99999.
|
6800
7390
|
self._myprops[('Legend','Text')] = _('Not used')
|
7391
|
+
|
7392
|
+
if self._rotation_center is not None:
|
7393
|
+
self._myprops[('Rotation', 'Center X')] = self._rotation_center[0]
|
7394
|
+
self._myprops[('Rotation', 'Center Y')] = self._rotation_center[1]
|
7395
|
+
else:
|
7396
|
+
self._myprops[('Rotation', 'Center X')] = 99999.
|
7397
|
+
self._myprops[('Rotation', 'Center Y')] = 99999.
|
7398
|
+
|
7399
|
+
if self._rotation_step is not None:
|
7400
|
+
self._myprops[('Rotation', 'Step [degree]')] = self._rotation_step
|
7401
|
+
else:
|
7402
|
+
self._myprops[('Rotation', 'Step [degree]')] = 99999.
|
7403
|
+
|
7404
|
+
self._myprops['Rotation', 'Angle [degree]'] = 0.
|
7405
|
+
|
7406
|
+
if self._start_move is not None:
|
7407
|
+
self._myprops[('Move', 'Start X')] = self._start_move[0]
|
7408
|
+
self._myprops[('Move', 'Start Y')] = self._start_move[1]
|
7409
|
+
else:
|
7410
|
+
self._myprops[('Move', 'Start X')] = 99999.
|
7411
|
+
self._myprops[('Move', 'Start Y')] = 99999.
|
7412
|
+
|
7413
|
+
self._myprops[('Move', 'Delta X')] = 0.
|
7414
|
+
self._myprops[('Move', 'Delta Y')] = 0.
|
7415
|
+
|
7416
|
+
if self._move_step is not None:
|
7417
|
+
self._myprops[('Move', 'Step [m]')] = self._move_step
|
7418
|
+
else:
|
7419
|
+
self._myprops[('Move', 'Step [m]')] = 99999.
|
7420
|
+
|
6801
7421
|
self._myprops.Populate()
|
6802
7422
|
self._myprops.set_callbacks(self._callback_prop, self._callback_destroy_props)
|
6803
7423
|
|
6804
|
-
self._myprops.SetTitle(_('Properties for all vectors in {}'.format(self.
|
7424
|
+
self._myprops.SetTitle(_('Properties for all vectors in {}'.format(self.filename)))
|
6805
7425
|
self._myprops.Center()
|
6806
7426
|
self._myprops.Raise()
|
6807
7427
|
|